From 631d332c9023aaca5f8a040993ab146b31e7d837 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Thu, 25 Jun 2020 13:11:54 -0700 Subject: [PATCH] Removed Tiberian Dawn folder. --- code/CMakeSettings.json | 21 + code/TIBERIANDAWN/AADATA.CPP | 795 -- code/TIBERIANDAWN/ABSTRACT.CPP | 133 - code/TIBERIANDAWN/ABSTRACT.H | 127 - code/TIBERIANDAWN/ADATA.CPP | 2575 ------ code/TIBERIANDAWN/AIRCRAFT.CPP | 3548 -------- code/TIBERIANDAWN/AIRCRAFT.H | 256 - code/TIBERIANDAWN/ALLOC.CPP | 590 -- code/TIBERIANDAWN/ANIM.CPP | 1282 --- code/TIBERIANDAWN/ANIM.H | 205 - code/TIBERIANDAWN/AUDIO.CPP | 636 -- code/TIBERIANDAWN/AUDIO.H | 96 - code/TIBERIANDAWN/BASE.CPP | 521 -- code/TIBERIANDAWN/BASE.H | 124 - code/TIBERIANDAWN/BBDATA.CPP | 636 -- code/TIBERIANDAWN/BDATA.CPP | 4938 ----------- code/TIBERIANDAWN/BUILDING.CPP | 5471 ------------- code/TIBERIANDAWN/BUILDING.H | 308 - code/TIBERIANDAWN/BULLET.CPP | 795 -- code/TIBERIANDAWN/BULLET.H | 155 - code/TIBERIANDAWN/CARGO.CPP | 180 - code/TIBERIANDAWN/CARGO.H | 88 - code/TIBERIANDAWN/CCDDE.CPP | 419 - code/TIBERIANDAWN/CCDDE.H | 86 - code/TIBERIANDAWN/CCFILE.CPP | 626 -- code/TIBERIANDAWN/CCFILE.H | 111 - code/TIBERIANDAWN/CC_ICON.RC | 16 - code/TIBERIANDAWN/CDATA.CPP | 2770 ------- code/TIBERIANDAWN/CDFILE.CPP | 534 -- code/TIBERIANDAWN/CDFILE.H | 117 - code/TIBERIANDAWN/CELL.CPP | 2757 ------- code/TIBERIANDAWN/CELL.H | 303 - code/TIBERIANDAWN/CHECKBOX.CPP | 69 - code/TIBERIANDAWN/CHECKBOX.H | 52 - code/TIBERIANDAWN/CHEKLIST.CPP | 165 - code/TIBERIANDAWN/CHEKLIST.H | 83 - code/TIBERIANDAWN/COLRLIST.CPP | 280 - code/TIBERIANDAWN/COLRLIST.H | 84 - code/TIBERIANDAWN/COMBAT.CPP | 233 - code/TIBERIANDAWN/COMBUF.CPP | 1036 --- code/TIBERIANDAWN/COMBUF.H | 178 - code/TIBERIANDAWN/COMPAT.H | 170 - code/TIBERIANDAWN/COMQUEUE.CPP | 1009 --- code/TIBERIANDAWN/COMQUEUE.H | 190 - code/TIBERIANDAWN/CONFDLG.CPP | 247 - code/TIBERIANDAWN/CONFDLG.H | 53 - code/TIBERIANDAWN/CONNECT.CPP | 248 - code/TIBERIANDAWN/CONNECT.H | 340 - code/TIBERIANDAWN/CONNMGR.H | 148 - code/TIBERIANDAWN/CONQUER.CPP | 4257 ---------- code/TIBERIANDAWN/CONQUER.H | 772 -- code/TIBERIANDAWN/CONST.CPP | 425 - code/TIBERIANDAWN/CONTROL.CPP | 199 - code/TIBERIANDAWN/CONTROL.H | 86 - code/TIBERIANDAWN/COORD.CPP | 599 -- code/TIBERIANDAWN/COORDA.ASM | 131 - code/TIBERIANDAWN/COORDA.h | 141 - code/TIBERIANDAWN/CREDITS.CPP | 183 - code/TIBERIANDAWN/CREDITS.H | 71 - code/TIBERIANDAWN/CREW.CPP | 35 - code/TIBERIANDAWN/CREW.H | 62 - code/TIBERIANDAWN/DDE.CPP | 465 -- code/TIBERIANDAWN/DDE.H | 176 - code/TIBERIANDAWN/DEBUG.CPP | 690 -- code/TIBERIANDAWN/DEBUG.H | 39 - code/TIBERIANDAWN/DEFINES.H | 2965 ------- code/TIBERIANDAWN/DESCDLG.CPP | 181 - code/TIBERIANDAWN/DESCDLG.H | 66 - code/TIBERIANDAWN/DIAL8.CPP | 314 - code/TIBERIANDAWN/DIAL8.H | 73 - code/TIBERIANDAWN/DIALOG.CPP | 787 -- code/TIBERIANDAWN/DISPLAY.CPP | 4407 ---------- code/TIBERIANDAWN/DISPLAY.H | 341 - code/TIBERIANDAWN/DLLInterface.cpp | 7702 ----------------- code/TIBERIANDAWN/DLLInterface.h | 928 --- code/TIBERIANDAWN/DLLInterfaceEditor.cpp | 741 -- code/TIBERIANDAWN/DOOR.CPP | 199 - code/TIBERIANDAWN/DOOR.H | 91 - code/TIBERIANDAWN/DPMI.CPP | 172 - code/TIBERIANDAWN/DPMI.H | 172 - code/TIBERIANDAWN/DRIVE.CPP | 2290 ------ code/TIBERIANDAWN/DRIVE.H | 223 - code/TIBERIANDAWN/EDIT.CPP | 468 -- code/TIBERIANDAWN/EDIT.H | 113 - code/TIBERIANDAWN/ENDING.CPP | 258 - code/TIBERIANDAWN/ENDING.H | 39 - code/TIBERIANDAWN/EVENT.CPP | 779 -- code/TIBERIANDAWN/EVENT.H | 224 - code/TIBERIANDAWN/EXPAND.CPP | 420 - code/TIBERIANDAWN/EXTERNS.H | 407 - code/TIBERIANDAWN/FACING.CPP | 180 - code/TIBERIANDAWN/FACING.H | 76 - code/TIBERIANDAWN/FACTORY.CPP | 772 -- code/TIBERIANDAWN/FACTORY.H | 161 - code/TIBERIANDAWN/FIELD.CPP | 213 - code/TIBERIANDAWN/FIELD.H | 82 - code/TIBERIANDAWN/FINDPATH.CPP | 1557 ---- code/TIBERIANDAWN/FLASHER.CPP | 129 - code/TIBERIANDAWN/FLASHER.H | 81 - code/TIBERIANDAWN/FLY.CPP | 130 - code/TIBERIANDAWN/FLY.H | 80 - code/TIBERIANDAWN/FOOT.CPP | 2062 ----- code/TIBERIANDAWN/FOOT.H | 304 - code/TIBERIANDAWN/FTIMER.H | 88 - code/TIBERIANDAWN/FUNCTION.H | 983 --- code/TIBERIANDAWN/FUSE.CPP | 193 - code/TIBERIANDAWN/FUSE.H | 92 - code/TIBERIANDAWN/GADGET.CPP | 801 -- code/TIBERIANDAWN/GADGET.H | 245 - code/TIBERIANDAWN/GAMEDLG.CPP | 419 - code/TIBERIANDAWN/GAMEDLG.H | 49 - code/TIBERIANDAWN/GAUGE.CPP | 536 -- code/TIBERIANDAWN/GAUGE.H | 108 - code/TIBERIANDAWN/GLOBALS.CPP | 1053 --- code/TIBERIANDAWN/GOPTIONS.CPP | 584 -- code/TIBERIANDAWN/GOPTIONS.H | 97 - code/TIBERIANDAWN/GSCREEN.CPP | 529 -- code/TIBERIANDAWN/GSCREEN.H | 144 - code/TIBERIANDAWN/HDATA.CPP | 322 - code/TIBERIANDAWN/HEAP.CPP | 556 -- code/TIBERIANDAWN/HEAP.H | 349 - code/TIBERIANDAWN/HELP.CPP | 403 - code/TIBERIANDAWN/HELP.H | 142 - code/TIBERIANDAWN/HOUSE.CPP | 8640 -------------------- code/TIBERIANDAWN/HOUSE.H | 899 -- code/TIBERIANDAWN/IDATA.CPP | 2153 ----- code/TIBERIANDAWN/INFANTRY.CPP | 3329 -------- code/TIBERIANDAWN/INFANTRY.H | 251 - code/TIBERIANDAWN/INI.CPP | 2331 ------ code/TIBERIANDAWN/INIT.CPP | 3054 ------- code/TIBERIANDAWN/INTERNET.CPP | 886 -- code/TIBERIANDAWN/INTERPAL.CPP | 457 -- code/TIBERIANDAWN/INTRO.CPP | 323 - code/TIBERIANDAWN/INTRO.H | 39 - code/TIBERIANDAWN/IOMAP.CPP | 1121 --- code/TIBERIANDAWN/IOOBJ.CPP | 2698 ------ code/TIBERIANDAWN/IPX.CPP | 1108 --- code/TIBERIANDAWN/IPX.H | 185 - code/TIBERIANDAWN/IPX95.CPP | 103 - code/TIBERIANDAWN/IPX95.H | 54 - code/TIBERIANDAWN/IPXADDR.CPP | 491 -- code/TIBERIANDAWN/IPXADDR.H | 103 - code/TIBERIANDAWN/IPXCONN.CPP | 677 -- code/TIBERIANDAWN/IPXCONN.H | 208 - code/TIBERIANDAWN/IPXGCONN.CPP | 470 -- code/TIBERIANDAWN/IPXGCONN.H | 158 - code/TIBERIANDAWN/IPXMGR.CPP | 1969 ----- code/TIBERIANDAWN/IPXMGR.H | 392 - code/TIBERIANDAWN/IPXPROT.ASM | 110 - code/TIBERIANDAWN/IPXREAL.ASM | 316 - code/TIBERIANDAWN/JSHELL.CPP | 434 - code/TIBERIANDAWN/JSHELL.H | 248 - code/TIBERIANDAWN/KEYFBUFF.ASM | 4015 --------- code/TIBERIANDAWN/KEYFBUFF.INC | 39 - code/TIBERIANDAWN/KEYFRAME.CPP | 599 -- code/TIBERIANDAWN/LAYER.CPP | 161 - code/TIBERIANDAWN/LAYER.H | 64 - code/TIBERIANDAWN/LED.H | 43 - code/TIBERIANDAWN/LINK.CPP | 413 - code/TIBERIANDAWN/LINK.H | 78 - code/TIBERIANDAWN/LIST.CPP | 894 -- code/TIBERIANDAWN/LIST.H | 146 - code/TIBERIANDAWN/LOADDLG.CPP | 735 -- code/TIBERIANDAWN/LOADDLG.H | 89 - code/TIBERIANDAWN/LOGIC.CPP | 342 - code/TIBERIANDAWN/LOGIC.H | 57 - code/TIBERIANDAWN/License.txt | 712 -- code/TIBERIANDAWN/MAP.CPP | 1577 ---- code/TIBERIANDAWN/MAP.H | 174 - code/TIBERIANDAWN/MAPEDDLG.CPP | 3847 --------- code/TIBERIANDAWN/MAPEDIT.CPP | 1923 ----- code/TIBERIANDAWN/MAPEDIT.H | 352 - code/TIBERIANDAWN/MAPEDPLC.CPP | 1996 ----- code/TIBERIANDAWN/MAPEDSEL.CPP | 604 -- code/TIBERIANDAWN/MAPEDTM.CPP | 2074 ----- code/TIBERIANDAWN/MAPSEL.CPP | 1274 --- code/TIBERIANDAWN/MENUS.CPP | 938 --- code/TIBERIANDAWN/MESSAGE.H | 44 - code/TIBERIANDAWN/MISSION.CPP | 474 -- code/TIBERIANDAWN/MISSION.H | 133 - code/TIBERIANDAWN/MIXFILE.CPP | 522 -- code/TIBERIANDAWN/MIXFILE.H | 84 - code/TIBERIANDAWN/MMX.ASM | 328 - code/TIBERIANDAWN/MONOC.CPP | 804 -- code/TIBERIANDAWN/MONOC.H | 187 - code/TIBERIANDAWN/MOUSE.CPP | 354 - code/TIBERIANDAWN/MOUSE.H | 127 - code/TIBERIANDAWN/MPLAYER.CPP | 1417 ---- code/TIBERIANDAWN/MSGBOX.CPP | 479 -- code/TIBERIANDAWN/MSGBOX.H | 57 - code/TIBERIANDAWN/MSGLIST.CPP | 809 -- code/TIBERIANDAWN/MSGLIST.H | 106 - code/TIBERIANDAWN/MiscAsm.cpp | 1578 ---- code/TIBERIANDAWN/NETDLG.CPP | 5434 ------------ code/TIBERIANDAWN/NOSEQCON.CPP | 687 -- code/TIBERIANDAWN/NOSEQCON.H | 126 - code/TIBERIANDAWN/NULLCONN.CPP | 267 - code/TIBERIANDAWN/NULLCONN.H | 137 - code/TIBERIANDAWN/NULLDLG.CPP | 8360 ------------------- code/TIBERIANDAWN/NULLMGR.CPP | 2350 ------ code/TIBERIANDAWN/NULLMGR.H | 214 - code/TIBERIANDAWN/OBJECT.CPP | 1712 ---- code/TIBERIANDAWN/OBJECT.H | 262 - code/TIBERIANDAWN/ODATA.CPP | 922 --- code/TIBERIANDAWN/OPTIONS.CPP | 797 -- code/TIBERIANDAWN/OPTIONS.H | 101 - code/TIBERIANDAWN/OVERLAY.CPP | 429 - code/TIBERIANDAWN/OVERLAY.H | 109 - code/TIBERIANDAWN/PACKET.CPP | 461 -- code/TIBERIANDAWN/PACKET.H | 98 - code/TIBERIANDAWN/PAGFAULT.ASM | 222 - code/TIBERIANDAWN/PHONE.H | 66 - code/TIBERIANDAWN/POWER.CPP | 459 -- code/TIBERIANDAWN/POWER.H | 123 - code/TIBERIANDAWN/PROFILE.CPP | 654 -- code/TIBERIANDAWN/QUEUE.CPP | 4214 ---------- code/TIBERIANDAWN/QUEUE.H | 272 - code/TIBERIANDAWN/RADAR.CPP | 1961 ----- code/TIBERIANDAWN/RADAR.H | 211 - code/TIBERIANDAWN/RADIO.CPP | 249 - code/TIBERIANDAWN/RADIO.H | 105 - code/TIBERIANDAWN/RAND.CPP | 170 - code/TIBERIANDAWN/RAWFILE.CPP | 1346 --- code/TIBERIANDAWN/RAWFILE.H | 332 - code/TIBERIANDAWN/REAL.H | 911 --- code/TIBERIANDAWN/REGION.H | 56 - code/TIBERIANDAWN/REG_ICON.RC | 16 - code/TIBERIANDAWN/REINF.CPP | 663 -- code/TIBERIANDAWN/RESOURCE/TiberianDawn.rc | 102 - code/TIBERIANDAWN/RESOURCE/resource.h | 29 - code/TIBERIANDAWN/RULES.CPP | 126 - code/TIBERIANDAWN/RULES.H | 275 - code/TIBERIANDAWN/SAVEDLG.H | 68 - code/TIBERIANDAWN/SAVELOAD.CPP | 1616 ---- code/TIBERIANDAWN/SCENARIO.CPP | 802 -- code/TIBERIANDAWN/SCORE.CPP | 2322 ------ code/TIBERIANDAWN/SCORE.H | 156 - code/TIBERIANDAWN/SCREEN.H | 65 - code/TIBERIANDAWN/SCROLL.CPP | 255 - code/TIBERIANDAWN/SCROLL.H | 83 - code/TIBERIANDAWN/SDATA.CPP | 470 -- code/TIBERIANDAWN/SEQCONN.CPP | 561 -- code/TIBERIANDAWN/SEQCONN.H | 108 - code/TIBERIANDAWN/SESSION.H | 551 -- code/TIBERIANDAWN/SHAPEBTN.CPP | 163 - code/TIBERIANDAWN/SHAPEBTN.H | 64 - code/TIBERIANDAWN/SIDEBAR.CPP | 2559 ------ code/TIBERIANDAWN/SIDEBAR.H | 395 - code/TIBERIANDAWN/SIDEBARGlyphx.CPP | 833 -- code/TIBERIANDAWN/SIDEBARGlyphx.H | 206 - code/TIBERIANDAWN/SLIDER.CPP | 405 - code/TIBERIANDAWN/SLIDER.H | 107 - code/TIBERIANDAWN/SMUDGE.CPP | 405 - code/TIBERIANDAWN/SMUDGE.H | 105 - code/TIBERIANDAWN/SOUNDDLG.CPP | 431 - code/TIBERIANDAWN/SOUNDDLG.H | 156 - code/TIBERIANDAWN/SPECIAL.CPP | 271 - code/TIBERIANDAWN/SPECIAL.H | 265 - code/TIBERIANDAWN/STAGE.H | 97 - code/TIBERIANDAWN/STARTUP.CPP | 872 -- code/TIBERIANDAWN/STATS.CPP | 676 -- code/TIBERIANDAWN/SUPER.CPP | 383 - code/TIBERIANDAWN/SUPER.H | 87 - code/TIBERIANDAWN/SUPPORT.ASM | 456 -- code/TIBERIANDAWN/Shape.cpp | 111 - code/TIBERIANDAWN/TAB.CPP | 261 - code/TIBERIANDAWN/TAB.H | 79 - code/TIBERIANDAWN/TARCOM.CPP | 180 - code/TIBERIANDAWN/TARCOM.H | 75 - code/TIBERIANDAWN/TARGET.CPP | 529 -- code/TIBERIANDAWN/TARGET.H | 154 - code/TIBERIANDAWN/TCPIP.CPP | 1002 --- code/TIBERIANDAWN/TCPIP.H | 222 - code/TIBERIANDAWN/TDATA.CPP | 1026 --- code/TIBERIANDAWN/TEAM.CPP | 1509 ---- code/TIBERIANDAWN/TEAM.H | 255 - code/TIBERIANDAWN/TEAMTYPE.CPP | 977 --- code/TIBERIANDAWN/TEAMTYPE.H | 261 - code/TIBERIANDAWN/TECHNO.CPP | 4809 ----------- code/TIBERIANDAWN/TECHNO.H | 372 - code/TIBERIANDAWN/TEMPLATE.CPP | 408 - code/TIBERIANDAWN/TEMPLATE.H | 122 - code/TIBERIANDAWN/TERRAIN.CPP | 897 -- code/TIBERIANDAWN/TERRAIN.H | 179 - code/TIBERIANDAWN/TEXTBLIT.H | 51 - code/TIBERIANDAWN/TEXTBTN.CPP | 374 - code/TIBERIANDAWN/TEXTBTN.H | 71 - code/TIBERIANDAWN/THEME.CPP | 560 -- code/TIBERIANDAWN/THEME.H | 84 - code/TIBERIANDAWN/TOGGLE.CPP | 196 - code/TIBERIANDAWN/TOGGLE.H | 79 - code/TIBERIANDAWN/TRIGGER.CPP | 1483 ---- code/TIBERIANDAWN/TRIGGER.H | 261 - code/TIBERIANDAWN/TURRET.CPP | 508 -- code/TIBERIANDAWN/TURRET.H | 82 - code/TIBERIANDAWN/TXTLABEL.CPP | 95 - code/TIBERIANDAWN/TXTLABEL.H | 69 - code/TIBERIANDAWN/TXTPRNT.ASM | 520 -- code/TIBERIANDAWN/TYPE.H | 2016 ----- code/TIBERIANDAWN/UDATA.CPP | 1974 ----- code/TIBERIANDAWN/UNIT.CPP | 4338 ---------- code/TIBERIANDAWN/UNIT.H | 213 - code/TIBERIANDAWN/UTRACKER.CPP | 239 - code/TIBERIANDAWN/UTRACKER.H | 83 - code/TIBERIANDAWN/VECTOR.CPP | 898 -- code/TIBERIANDAWN/VECTOR.H | 988 --- code/TIBERIANDAWN/VISUDLG.CPP | 421 - code/TIBERIANDAWN/VISUDLG.H | 89 - code/TIBERIANDAWN/WATCOM.H | 74 - code/TIBERIANDAWN/WIN32LIB/ALLOC.CPP | 509 -- code/TIBERIANDAWN/WIN32LIB/AUDIO.H | 158 - code/TIBERIANDAWN/WIN32LIB/BUFFER.CPP | 128 - code/TIBERIANDAWN/WIN32LIB/BUFFER.H | 121 - code/TIBERIANDAWN/WIN32LIB/BUFFGLBL.CPP | 80 - code/TIBERIANDAWN/WIN32LIB/DDRAW.CPP | 1002 --- code/TIBERIANDAWN/WIN32LIB/DDRAW.H | 3117 ------- code/TIBERIANDAWN/WIN32LIB/DEFINES.H | 36 - code/TIBERIANDAWN/WIN32LIB/DESCMGMT.H | 90 - code/TIBERIANDAWN/WIN32LIB/DIFFTB.INC | 1445 ---- code/TIBERIANDAWN/WIN32LIB/DIPTHONG.CPP | 325 - code/TIBERIANDAWN/WIN32LIB/DIPTHONG.H | 21 - code/TIBERIANDAWN/WIN32LIB/DPLAY.H | 323 - code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.H | 64 - code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.INC | 90 - code/TIBERIANDAWN/WIN32LIB/DRAWRECT.CPP | 69 - code/TIBERIANDAWN/WIN32LIB/DSETUP.H | 71 - code/TIBERIANDAWN/WIN32LIB/DSOUND.H | 380 - code/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp | 5508 ------------- code/TIBERIANDAWN/WIN32LIB/EXTERNS.H | 37 - code/TIBERIANDAWN/WIN32LIB/FACINGFF.ASM | 162 - code/TIBERIANDAWN/WIN32LIB/FACINGFF.h | 458 -- code/TIBERIANDAWN/WIN32LIB/FASTFILE.H | 39 - code/TIBERIANDAWN/WIN32LIB/FILE.H | 257 - code/TIBERIANDAWN/WIN32LIB/FILEPCX.H | 74 - code/TIBERIANDAWN/WIN32LIB/FILETEMP.H | 58 - code/TIBERIANDAWN/WIN32LIB/FONT.CPP | 138 - code/TIBERIANDAWN/WIN32LIB/FONT.H | 115 - code/TIBERIANDAWN/WIN32LIB/FUNCTION.H | 44 - code/TIBERIANDAWN/WIN32LIB/GBUFFER.CPP | 707 -- code/TIBERIANDAWN/WIN32LIB/GBUFFER.H | 1372 ---- code/TIBERIANDAWN/WIN32LIB/GBUFFER.INC | 48 - code/TIBERIANDAWN/WIN32LIB/GETSHAPE.CPP | 358 - code/TIBERIANDAWN/WIN32LIB/ICONCACH.H | 150 - code/TIBERIANDAWN/WIN32LIB/ICONSET.CPP | 340 - code/TIBERIANDAWN/WIN32LIB/IFF.CPP | 325 - code/TIBERIANDAWN/WIN32LIB/IFF.H | 164 - code/TIBERIANDAWN/WIN32LIB/INDEXTB.INC | 1445 ---- code/TIBERIANDAWN/WIN32LIB/IRANDOM.CPP | 176 - code/TIBERIANDAWN/WIN32LIB/KEYBOARD.CPP | 533 -- code/TIBERIANDAWN/WIN32LIB/KEYBOARD.H | 675 -- code/TIBERIANDAWN/WIN32LIB/KEYBOARD.INC | 126 - code/TIBERIANDAWN/WIN32LIB/KEYSTRUC.INC | 159 - code/TIBERIANDAWN/WIN32LIB/LOAD.CPP | 375 - code/TIBERIANDAWN/WIN32LIB/LOADFONT.CPP | 137 - code/TIBERIANDAWN/WIN32LIB/LOADPAL.CPP | 82 - code/TIBERIANDAWN/WIN32LIB/MCGAPRIM.INC | 119 - code/TIBERIANDAWN/WIN32LIB/MEM.CPP | 1086 --- code/TIBERIANDAWN/WIN32LIB/MEMFLAG.H | 107 - code/TIBERIANDAWN/WIN32LIB/MISC.H | 268 - code/TIBERIANDAWN/WIN32LIB/MODEMREG.H | 69 - code/TIBERIANDAWN/WIN32LIB/MONO.H | 181 - code/TIBERIANDAWN/WIN32LIB/MORPHPAL.CPP | 173 - code/TIBERIANDAWN/WIN32LIB/MOUSE.H | 123 - code/TIBERIANDAWN/WIN32LIB/MOUSE.INC | 64 - code/TIBERIANDAWN/WIN32LIB/MOUSEWW.CPP | 720 -- code/TIBERIANDAWN/WIN32LIB/NEWDEL.CPP | 125 - code/TIBERIANDAWN/WIN32LIB/NYBBTB.INC | 56 - code/TIBERIANDAWN/WIN32LIB/PALETTE.CPP | 381 - code/TIBERIANDAWN/WIN32LIB/PALETTE.H | 82 - code/TIBERIANDAWN/WIN32LIB/PLAYCD.H | 306 - code/TIBERIANDAWN/WIN32LIB/PROFILE.H | 102 - code/TIBERIANDAWN/WIN32LIB/PROFILE.INC | 41 - code/TIBERIANDAWN/WIN32LIB/RAWFILE.H | 254 - code/TIBERIANDAWN/WIN32LIB/REGIONSZ.CPP | 57 - code/TIBERIANDAWN/WIN32LIB/REMAP.ASM | 172 - code/TIBERIANDAWN/WIN32LIB/SET_FONT.CPP | 87 - code/TIBERIANDAWN/WIN32LIB/SHAPE.H | 187 - code/TIBERIANDAWN/WIN32LIB/SHAPE.INC | 212 - code/TIBERIANDAWN/WIN32LIB/SOUND.H | 52 - code/TIBERIANDAWN/WIN32LIB/SOUNDINT.H | 289 - code/TIBERIANDAWN/WIN32LIB/STAMP.INC | 56 - code/TIBERIANDAWN/WIN32LIB/STRUCTS.H | 34 - code/TIBERIANDAWN/WIN32LIB/SVGAPRIM.INC | 74 - code/TIBERIANDAWN/WIN32LIB/TILE.H | 100 - code/TIBERIANDAWN/WIN32LIB/TIMER.CPP | 200 - code/TIBERIANDAWN/WIN32LIB/TIMER.H | 198 - code/TIBERIANDAWN/WIN32LIB/TIMERDWN.CPP | 123 - code/TIBERIANDAWN/WIN32LIB/TIMERINI.CPP | 312 - code/TIBERIANDAWN/WIN32LIB/TOBUFF.ASM | 294 - code/TIBERIANDAWN/WIN32LIB/VIDEO.H | 216 - code/TIBERIANDAWN/WIN32LIB/WINCOMM.H | 454 - code/TIBERIANDAWN/WIN32LIB/WINDOWS.CPP | 973 --- code/TIBERIANDAWN/WIN32LIB/WINHIDE.CPP | 94 - code/TIBERIANDAWN/WIN32LIB/WRITEPCX.CPP | 177 - code/TIBERIANDAWN/WIN32LIB/WSA.CPP | 1153 --- code/TIBERIANDAWN/WIN32LIB/WSA.H | 160 - code/TIBERIANDAWN/WIN32LIB/WWFILE.H | 68 - code/TIBERIANDAWN/WIN32LIB/WWLIB32.H | 65 - code/TIBERIANDAWN/WIN32LIB/WWMEM.H | 67 - code/TIBERIANDAWN/WIN32LIB/WWMEM.INC | 40 - code/TIBERIANDAWN/WIN32LIB/WWSTD.H | 224 - code/TIBERIANDAWN/WIN32LIB/WW_WIN.H | 93 - code/TIBERIANDAWN/WIN32LIB/XORDELTA.ASM | 668 -- code/TIBERIANDAWN/WIN32LIB/_DIPTABL.CPP | 55 - code/TIBERIANDAWN/WIN32LIB/_FILE.H | 180 - code/TIBERIANDAWN/WINASM.ASM | 887 -- code/TIBERIANDAWN/WINSTUB.CPP | 938 --- code/TIBERIANDAWN/WWALLOC.H | 65 - code/TIBERIANDAWN/WWFILE.H | 75 - 409 files changed, 21 insertions(+), 261512 deletions(-) delete mode 100644 code/TIBERIANDAWN/AADATA.CPP delete mode 100644 code/TIBERIANDAWN/ABSTRACT.CPP delete mode 100644 code/TIBERIANDAWN/ABSTRACT.H delete mode 100644 code/TIBERIANDAWN/ADATA.CPP delete mode 100644 code/TIBERIANDAWN/AIRCRAFT.CPP delete mode 100644 code/TIBERIANDAWN/AIRCRAFT.H delete mode 100644 code/TIBERIANDAWN/ALLOC.CPP delete mode 100644 code/TIBERIANDAWN/ANIM.CPP delete mode 100644 code/TIBERIANDAWN/ANIM.H delete mode 100644 code/TIBERIANDAWN/AUDIO.CPP delete mode 100644 code/TIBERIANDAWN/AUDIO.H delete mode 100644 code/TIBERIANDAWN/BASE.CPP delete mode 100644 code/TIBERIANDAWN/BASE.H delete mode 100644 code/TIBERIANDAWN/BBDATA.CPP delete mode 100644 code/TIBERIANDAWN/BDATA.CPP delete mode 100644 code/TIBERIANDAWN/BUILDING.CPP delete mode 100644 code/TIBERIANDAWN/BUILDING.H delete mode 100644 code/TIBERIANDAWN/BULLET.CPP delete mode 100644 code/TIBERIANDAWN/BULLET.H delete mode 100644 code/TIBERIANDAWN/CARGO.CPP delete mode 100644 code/TIBERIANDAWN/CARGO.H delete mode 100644 code/TIBERIANDAWN/CCDDE.CPP delete mode 100644 code/TIBERIANDAWN/CCDDE.H delete mode 100644 code/TIBERIANDAWN/CCFILE.CPP delete mode 100644 code/TIBERIANDAWN/CCFILE.H delete mode 100644 code/TIBERIANDAWN/CC_ICON.RC delete mode 100644 code/TIBERIANDAWN/CDATA.CPP delete mode 100644 code/TIBERIANDAWN/CDFILE.CPP delete mode 100644 code/TIBERIANDAWN/CDFILE.H delete mode 100644 code/TIBERIANDAWN/CELL.CPP delete mode 100644 code/TIBERIANDAWN/CELL.H delete mode 100644 code/TIBERIANDAWN/CHECKBOX.CPP delete mode 100644 code/TIBERIANDAWN/CHECKBOX.H delete mode 100644 code/TIBERIANDAWN/CHEKLIST.CPP delete mode 100644 code/TIBERIANDAWN/CHEKLIST.H delete mode 100644 code/TIBERIANDAWN/COLRLIST.CPP delete mode 100644 code/TIBERIANDAWN/COLRLIST.H delete mode 100644 code/TIBERIANDAWN/COMBAT.CPP delete mode 100644 code/TIBERIANDAWN/COMBUF.CPP delete mode 100644 code/TIBERIANDAWN/COMBUF.H delete mode 100644 code/TIBERIANDAWN/COMPAT.H delete mode 100644 code/TIBERIANDAWN/COMQUEUE.CPP delete mode 100644 code/TIBERIANDAWN/COMQUEUE.H delete mode 100644 code/TIBERIANDAWN/CONFDLG.CPP delete mode 100644 code/TIBERIANDAWN/CONFDLG.H delete mode 100644 code/TIBERIANDAWN/CONNECT.CPP delete mode 100644 code/TIBERIANDAWN/CONNECT.H delete mode 100644 code/TIBERIANDAWN/CONNMGR.H delete mode 100644 code/TIBERIANDAWN/CONQUER.CPP delete mode 100644 code/TIBERIANDAWN/CONQUER.H delete mode 100644 code/TIBERIANDAWN/CONST.CPP delete mode 100644 code/TIBERIANDAWN/CONTROL.CPP delete mode 100644 code/TIBERIANDAWN/CONTROL.H delete mode 100644 code/TIBERIANDAWN/COORD.CPP delete mode 100644 code/TIBERIANDAWN/COORDA.ASM delete mode 100644 code/TIBERIANDAWN/COORDA.h delete mode 100644 code/TIBERIANDAWN/CREDITS.CPP delete mode 100644 code/TIBERIANDAWN/CREDITS.H delete mode 100644 code/TIBERIANDAWN/CREW.CPP delete mode 100644 code/TIBERIANDAWN/CREW.H delete mode 100644 code/TIBERIANDAWN/DDE.CPP delete mode 100644 code/TIBERIANDAWN/DDE.H delete mode 100644 code/TIBERIANDAWN/DEBUG.CPP delete mode 100644 code/TIBERIANDAWN/DEBUG.H delete mode 100644 code/TIBERIANDAWN/DEFINES.H delete mode 100644 code/TIBERIANDAWN/DESCDLG.CPP delete mode 100644 code/TIBERIANDAWN/DESCDLG.H delete mode 100644 code/TIBERIANDAWN/DIAL8.CPP delete mode 100644 code/TIBERIANDAWN/DIAL8.H delete mode 100644 code/TIBERIANDAWN/DIALOG.CPP delete mode 100644 code/TIBERIANDAWN/DISPLAY.CPP delete mode 100644 code/TIBERIANDAWN/DISPLAY.H delete mode 100644 code/TIBERIANDAWN/DLLInterface.cpp delete mode 100644 code/TIBERIANDAWN/DLLInterface.h delete mode 100644 code/TIBERIANDAWN/DLLInterfaceEditor.cpp delete mode 100644 code/TIBERIANDAWN/DOOR.CPP delete mode 100644 code/TIBERIANDAWN/DOOR.H delete mode 100644 code/TIBERIANDAWN/DPMI.CPP delete mode 100644 code/TIBERIANDAWN/DPMI.H delete mode 100644 code/TIBERIANDAWN/DRIVE.CPP delete mode 100644 code/TIBERIANDAWN/DRIVE.H delete mode 100644 code/TIBERIANDAWN/EDIT.CPP delete mode 100644 code/TIBERIANDAWN/EDIT.H delete mode 100644 code/TIBERIANDAWN/ENDING.CPP delete mode 100644 code/TIBERIANDAWN/ENDING.H delete mode 100644 code/TIBERIANDAWN/EVENT.CPP delete mode 100644 code/TIBERIANDAWN/EVENT.H delete mode 100644 code/TIBERIANDAWN/EXPAND.CPP delete mode 100644 code/TIBERIANDAWN/EXTERNS.H delete mode 100644 code/TIBERIANDAWN/FACING.CPP delete mode 100644 code/TIBERIANDAWN/FACING.H delete mode 100644 code/TIBERIANDAWN/FACTORY.CPP delete mode 100644 code/TIBERIANDAWN/FACTORY.H delete mode 100644 code/TIBERIANDAWN/FIELD.CPP delete mode 100644 code/TIBERIANDAWN/FIELD.H delete mode 100644 code/TIBERIANDAWN/FINDPATH.CPP delete mode 100644 code/TIBERIANDAWN/FLASHER.CPP delete mode 100644 code/TIBERIANDAWN/FLASHER.H delete mode 100644 code/TIBERIANDAWN/FLY.CPP delete mode 100644 code/TIBERIANDAWN/FLY.H delete mode 100644 code/TIBERIANDAWN/FOOT.CPP delete mode 100644 code/TIBERIANDAWN/FOOT.H delete mode 100644 code/TIBERIANDAWN/FTIMER.H delete mode 100644 code/TIBERIANDAWN/FUNCTION.H delete mode 100644 code/TIBERIANDAWN/FUSE.CPP delete mode 100644 code/TIBERIANDAWN/FUSE.H delete mode 100644 code/TIBERIANDAWN/GADGET.CPP delete mode 100644 code/TIBERIANDAWN/GADGET.H delete mode 100644 code/TIBERIANDAWN/GAMEDLG.CPP delete mode 100644 code/TIBERIANDAWN/GAMEDLG.H delete mode 100644 code/TIBERIANDAWN/GAUGE.CPP delete mode 100644 code/TIBERIANDAWN/GAUGE.H delete mode 100644 code/TIBERIANDAWN/GLOBALS.CPP delete mode 100644 code/TIBERIANDAWN/GOPTIONS.CPP delete mode 100644 code/TIBERIANDAWN/GOPTIONS.H delete mode 100644 code/TIBERIANDAWN/GSCREEN.CPP delete mode 100644 code/TIBERIANDAWN/GSCREEN.H delete mode 100644 code/TIBERIANDAWN/HDATA.CPP delete mode 100644 code/TIBERIANDAWN/HEAP.CPP delete mode 100644 code/TIBERIANDAWN/HEAP.H delete mode 100644 code/TIBERIANDAWN/HELP.CPP delete mode 100644 code/TIBERIANDAWN/HELP.H delete mode 100644 code/TIBERIANDAWN/HOUSE.CPP delete mode 100644 code/TIBERIANDAWN/HOUSE.H delete mode 100644 code/TIBERIANDAWN/IDATA.CPP delete mode 100644 code/TIBERIANDAWN/INFANTRY.CPP delete mode 100644 code/TIBERIANDAWN/INFANTRY.H delete mode 100644 code/TIBERIANDAWN/INI.CPP delete mode 100644 code/TIBERIANDAWN/INIT.CPP delete mode 100644 code/TIBERIANDAWN/INTERNET.CPP delete mode 100644 code/TIBERIANDAWN/INTERPAL.CPP delete mode 100644 code/TIBERIANDAWN/INTRO.CPP delete mode 100644 code/TIBERIANDAWN/INTRO.H delete mode 100644 code/TIBERIANDAWN/IOMAP.CPP delete mode 100644 code/TIBERIANDAWN/IOOBJ.CPP delete mode 100644 code/TIBERIANDAWN/IPX.CPP delete mode 100644 code/TIBERIANDAWN/IPX.H delete mode 100644 code/TIBERIANDAWN/IPX95.CPP delete mode 100644 code/TIBERIANDAWN/IPX95.H delete mode 100644 code/TIBERIANDAWN/IPXADDR.CPP delete mode 100644 code/TIBERIANDAWN/IPXADDR.H delete mode 100644 code/TIBERIANDAWN/IPXCONN.CPP delete mode 100644 code/TIBERIANDAWN/IPXCONN.H delete mode 100644 code/TIBERIANDAWN/IPXGCONN.CPP delete mode 100644 code/TIBERIANDAWN/IPXGCONN.H delete mode 100644 code/TIBERIANDAWN/IPXMGR.CPP delete mode 100644 code/TIBERIANDAWN/IPXMGR.H delete mode 100644 code/TIBERIANDAWN/IPXPROT.ASM delete mode 100644 code/TIBERIANDAWN/IPXREAL.ASM delete mode 100644 code/TIBERIANDAWN/JSHELL.CPP delete mode 100644 code/TIBERIANDAWN/JSHELL.H delete mode 100644 code/TIBERIANDAWN/KEYFBUFF.ASM delete mode 100644 code/TIBERIANDAWN/KEYFBUFF.INC delete mode 100644 code/TIBERIANDAWN/KEYFRAME.CPP delete mode 100644 code/TIBERIANDAWN/LAYER.CPP delete mode 100644 code/TIBERIANDAWN/LAYER.H delete mode 100644 code/TIBERIANDAWN/LED.H delete mode 100644 code/TIBERIANDAWN/LINK.CPP delete mode 100644 code/TIBERIANDAWN/LINK.H delete mode 100644 code/TIBERIANDAWN/LIST.CPP delete mode 100644 code/TIBERIANDAWN/LIST.H delete mode 100644 code/TIBERIANDAWN/LOADDLG.CPP delete mode 100644 code/TIBERIANDAWN/LOADDLG.H delete mode 100644 code/TIBERIANDAWN/LOGIC.CPP delete mode 100644 code/TIBERIANDAWN/LOGIC.H delete mode 100644 code/TIBERIANDAWN/License.txt delete mode 100644 code/TIBERIANDAWN/MAP.CPP delete mode 100644 code/TIBERIANDAWN/MAP.H delete mode 100644 code/TIBERIANDAWN/MAPEDDLG.CPP delete mode 100644 code/TIBERIANDAWN/MAPEDIT.CPP delete mode 100644 code/TIBERIANDAWN/MAPEDIT.H delete mode 100644 code/TIBERIANDAWN/MAPEDPLC.CPP delete mode 100644 code/TIBERIANDAWN/MAPEDSEL.CPP delete mode 100644 code/TIBERIANDAWN/MAPEDTM.CPP delete mode 100644 code/TIBERIANDAWN/MAPSEL.CPP delete mode 100644 code/TIBERIANDAWN/MENUS.CPP delete mode 100644 code/TIBERIANDAWN/MESSAGE.H delete mode 100644 code/TIBERIANDAWN/MISSION.CPP delete mode 100644 code/TIBERIANDAWN/MISSION.H delete mode 100644 code/TIBERIANDAWN/MIXFILE.CPP delete mode 100644 code/TIBERIANDAWN/MIXFILE.H delete mode 100644 code/TIBERIANDAWN/MMX.ASM delete mode 100644 code/TIBERIANDAWN/MONOC.CPP delete mode 100644 code/TIBERIANDAWN/MONOC.H delete mode 100644 code/TIBERIANDAWN/MOUSE.CPP delete mode 100644 code/TIBERIANDAWN/MOUSE.H delete mode 100644 code/TIBERIANDAWN/MPLAYER.CPP delete mode 100644 code/TIBERIANDAWN/MSGBOX.CPP delete mode 100644 code/TIBERIANDAWN/MSGBOX.H delete mode 100644 code/TIBERIANDAWN/MSGLIST.CPP delete mode 100644 code/TIBERIANDAWN/MSGLIST.H delete mode 100644 code/TIBERIANDAWN/MiscAsm.cpp delete mode 100644 code/TIBERIANDAWN/NETDLG.CPP delete mode 100644 code/TIBERIANDAWN/NOSEQCON.CPP delete mode 100644 code/TIBERIANDAWN/NOSEQCON.H delete mode 100644 code/TIBERIANDAWN/NULLCONN.CPP delete mode 100644 code/TIBERIANDAWN/NULLCONN.H delete mode 100644 code/TIBERIANDAWN/NULLDLG.CPP delete mode 100644 code/TIBERIANDAWN/NULLMGR.CPP delete mode 100644 code/TIBERIANDAWN/NULLMGR.H delete mode 100644 code/TIBERIANDAWN/OBJECT.CPP delete mode 100644 code/TIBERIANDAWN/OBJECT.H delete mode 100644 code/TIBERIANDAWN/ODATA.CPP delete mode 100644 code/TIBERIANDAWN/OPTIONS.CPP delete mode 100644 code/TIBERIANDAWN/OPTIONS.H delete mode 100644 code/TIBERIANDAWN/OVERLAY.CPP delete mode 100644 code/TIBERIANDAWN/OVERLAY.H delete mode 100644 code/TIBERIANDAWN/PACKET.CPP delete mode 100644 code/TIBERIANDAWN/PACKET.H delete mode 100644 code/TIBERIANDAWN/PAGFAULT.ASM delete mode 100644 code/TIBERIANDAWN/PHONE.H delete mode 100644 code/TIBERIANDAWN/POWER.CPP delete mode 100644 code/TIBERIANDAWN/POWER.H delete mode 100644 code/TIBERIANDAWN/PROFILE.CPP delete mode 100644 code/TIBERIANDAWN/QUEUE.CPP delete mode 100644 code/TIBERIANDAWN/QUEUE.H delete mode 100644 code/TIBERIANDAWN/RADAR.CPP delete mode 100644 code/TIBERIANDAWN/RADAR.H delete mode 100644 code/TIBERIANDAWN/RADIO.CPP delete mode 100644 code/TIBERIANDAWN/RADIO.H delete mode 100644 code/TIBERIANDAWN/RAND.CPP delete mode 100644 code/TIBERIANDAWN/RAWFILE.CPP delete mode 100644 code/TIBERIANDAWN/RAWFILE.H delete mode 100644 code/TIBERIANDAWN/REAL.H delete mode 100644 code/TIBERIANDAWN/REGION.H delete mode 100644 code/TIBERIANDAWN/REG_ICON.RC delete mode 100644 code/TIBERIANDAWN/REINF.CPP delete mode 100644 code/TIBERIANDAWN/RESOURCE/TiberianDawn.rc delete mode 100644 code/TIBERIANDAWN/RESOURCE/resource.h delete mode 100644 code/TIBERIANDAWN/RULES.CPP delete mode 100644 code/TIBERIANDAWN/RULES.H delete mode 100644 code/TIBERIANDAWN/SAVEDLG.H delete mode 100644 code/TIBERIANDAWN/SAVELOAD.CPP delete mode 100644 code/TIBERIANDAWN/SCENARIO.CPP delete mode 100644 code/TIBERIANDAWN/SCORE.CPP delete mode 100644 code/TIBERIANDAWN/SCORE.H delete mode 100644 code/TIBERIANDAWN/SCREEN.H delete mode 100644 code/TIBERIANDAWN/SCROLL.CPP delete mode 100644 code/TIBERIANDAWN/SCROLL.H delete mode 100644 code/TIBERIANDAWN/SDATA.CPP delete mode 100644 code/TIBERIANDAWN/SEQCONN.CPP delete mode 100644 code/TIBERIANDAWN/SEQCONN.H delete mode 100644 code/TIBERIANDAWN/SESSION.H delete mode 100644 code/TIBERIANDAWN/SHAPEBTN.CPP delete mode 100644 code/TIBERIANDAWN/SHAPEBTN.H delete mode 100644 code/TIBERIANDAWN/SIDEBAR.CPP delete mode 100644 code/TIBERIANDAWN/SIDEBAR.H delete mode 100644 code/TIBERIANDAWN/SIDEBARGlyphx.CPP delete mode 100644 code/TIBERIANDAWN/SIDEBARGlyphx.H delete mode 100644 code/TIBERIANDAWN/SLIDER.CPP delete mode 100644 code/TIBERIANDAWN/SLIDER.H delete mode 100644 code/TIBERIANDAWN/SMUDGE.CPP delete mode 100644 code/TIBERIANDAWN/SMUDGE.H delete mode 100644 code/TIBERIANDAWN/SOUNDDLG.CPP delete mode 100644 code/TIBERIANDAWN/SOUNDDLG.H delete mode 100644 code/TIBERIANDAWN/SPECIAL.CPP delete mode 100644 code/TIBERIANDAWN/SPECIAL.H delete mode 100644 code/TIBERIANDAWN/STAGE.H delete mode 100644 code/TIBERIANDAWN/STARTUP.CPP delete mode 100644 code/TIBERIANDAWN/STATS.CPP delete mode 100644 code/TIBERIANDAWN/SUPER.CPP delete mode 100644 code/TIBERIANDAWN/SUPER.H delete mode 100644 code/TIBERIANDAWN/SUPPORT.ASM delete mode 100644 code/TIBERIANDAWN/Shape.cpp delete mode 100644 code/TIBERIANDAWN/TAB.CPP delete mode 100644 code/TIBERIANDAWN/TAB.H delete mode 100644 code/TIBERIANDAWN/TARCOM.CPP delete mode 100644 code/TIBERIANDAWN/TARCOM.H delete mode 100644 code/TIBERIANDAWN/TARGET.CPP delete mode 100644 code/TIBERIANDAWN/TARGET.H delete mode 100644 code/TIBERIANDAWN/TCPIP.CPP delete mode 100644 code/TIBERIANDAWN/TCPIP.H delete mode 100644 code/TIBERIANDAWN/TDATA.CPP delete mode 100644 code/TIBERIANDAWN/TEAM.CPP delete mode 100644 code/TIBERIANDAWN/TEAM.H delete mode 100644 code/TIBERIANDAWN/TEAMTYPE.CPP delete mode 100644 code/TIBERIANDAWN/TEAMTYPE.H delete mode 100644 code/TIBERIANDAWN/TECHNO.CPP delete mode 100644 code/TIBERIANDAWN/TECHNO.H delete mode 100644 code/TIBERIANDAWN/TEMPLATE.CPP delete mode 100644 code/TIBERIANDAWN/TEMPLATE.H delete mode 100644 code/TIBERIANDAWN/TERRAIN.CPP delete mode 100644 code/TIBERIANDAWN/TERRAIN.H delete mode 100644 code/TIBERIANDAWN/TEXTBLIT.H delete mode 100644 code/TIBERIANDAWN/TEXTBTN.CPP delete mode 100644 code/TIBERIANDAWN/TEXTBTN.H delete mode 100644 code/TIBERIANDAWN/THEME.CPP delete mode 100644 code/TIBERIANDAWN/THEME.H delete mode 100644 code/TIBERIANDAWN/TOGGLE.CPP delete mode 100644 code/TIBERIANDAWN/TOGGLE.H delete mode 100644 code/TIBERIANDAWN/TRIGGER.CPP delete mode 100644 code/TIBERIANDAWN/TRIGGER.H delete mode 100644 code/TIBERIANDAWN/TURRET.CPP delete mode 100644 code/TIBERIANDAWN/TURRET.H delete mode 100644 code/TIBERIANDAWN/TXTLABEL.CPP delete mode 100644 code/TIBERIANDAWN/TXTLABEL.H delete mode 100644 code/TIBERIANDAWN/TXTPRNT.ASM delete mode 100644 code/TIBERIANDAWN/TYPE.H delete mode 100644 code/TIBERIANDAWN/UDATA.CPP delete mode 100644 code/TIBERIANDAWN/UNIT.CPP delete mode 100644 code/TIBERIANDAWN/UNIT.H delete mode 100644 code/TIBERIANDAWN/UTRACKER.CPP delete mode 100644 code/TIBERIANDAWN/UTRACKER.H delete mode 100644 code/TIBERIANDAWN/VECTOR.CPP delete mode 100644 code/TIBERIANDAWN/VECTOR.H delete mode 100644 code/TIBERIANDAWN/VISUDLG.CPP delete mode 100644 code/TIBERIANDAWN/VISUDLG.H delete mode 100644 code/TIBERIANDAWN/WATCOM.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/ALLOC.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/AUDIO.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/BUFFER.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/BUFFER.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/BUFFGLBL.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DDRAW.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DDRAW.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DEFINES.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DESCMGMT.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DIFFTB.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DIPTHONG.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DIPTHONG.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DPLAY.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DRAWRECT.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DSETUP.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DSOUND.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp delete mode 100644 code/TIBERIANDAWN/WIN32LIB/EXTERNS.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FACINGFF.ASM delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FACINGFF.h delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FASTFILE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FILE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FILEPCX.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FILETEMP.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FONT.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FONT.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/FUNCTION.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/GBUFFER.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/GBUFFER.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/GBUFFER.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/GETSHAPE.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/ICONCACH.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/ICONSET.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/IFF.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/IFF.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/INDEXTB.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/IRANDOM.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/KEYBOARD.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/KEYBOARD.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/KEYBOARD.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/KEYSTRUC.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/LOAD.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/LOADFONT.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/LOADPAL.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MCGAPRIM.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MEM.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MEMFLAG.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MISC.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MODEMREG.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MONO.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MORPHPAL.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MOUSE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MOUSE.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/MOUSEWW.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/NEWDEL.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/NYBBTB.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/PALETTE.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/PALETTE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/PLAYCD.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/PROFILE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/PROFILE.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/RAWFILE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/REGIONSZ.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/REMAP.ASM delete mode 100644 code/TIBERIANDAWN/WIN32LIB/SET_FONT.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/SHAPE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/SHAPE.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/SOUND.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/SOUNDINT.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/STAMP.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/STRUCTS.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/SVGAPRIM.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/TILE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/TIMER.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/TIMER.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/TIMERDWN.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/TIMERINI.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/TOBUFF.ASM delete mode 100644 code/TIBERIANDAWN/WIN32LIB/VIDEO.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WINCOMM.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WINDOWS.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WINHIDE.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WRITEPCX.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WSA.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WSA.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WWFILE.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WWLIB32.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WWMEM.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WWMEM.INC delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WWSTD.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/WW_WIN.H delete mode 100644 code/TIBERIANDAWN/WIN32LIB/XORDELTA.ASM delete mode 100644 code/TIBERIANDAWN/WIN32LIB/_DIPTABL.CPP delete mode 100644 code/TIBERIANDAWN/WIN32LIB/_FILE.H delete mode 100644 code/TIBERIANDAWN/WINASM.ASM delete mode 100644 code/TIBERIANDAWN/WINSTUB.CPP delete mode 100644 code/TIBERIANDAWN/WWALLOC.H delete mode 100644 code/TIBERIANDAWN/WWFILE.H diff --git a/code/CMakeSettings.json b/code/CMakeSettings.json index 5b07d06..f689609 100644 --- a/code/CMakeSettings.json +++ b/code/CMakeSettings.json @@ -23,6 +23,27 @@ "ctestCommandArgs": "", "inheritEnvironments": [ "msvc_x64_x64" ], "variables": [] + }, + { + "name": "Linux-GCC-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "cmakeExecutable": "/usr/bin/cmake", + "remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ], + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x64" ], + "remoteMachineName": "${defaultRemoteMachineName}", + "remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src", + "remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}", + "remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}", + "remoteCopySources": true, + "rsyncCommandArgs": "-t --delete --delete-excluded", + "remoteCopyBuildOutput": false, + "remoteCopySourcesMethod": "rsync", + "addressSanitizerRuntimeFlags": "detect_leaks=0", + "variables": [] } ] } \ No newline at end of file diff --git a/code/TIBERIANDAWN/AADATA.CPP b/code/TIBERIANDAWN/AADATA.CPP deleted file mode 100644 index f2881a2..0000000 --- a/code/TIBERIANDAWN/AADATA.CPP +++ /dev/null @@ -1,795 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\aadata.cpv 2.18 16 Oct 1995 16:49:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * name in * - * File Name : AADATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 22, 1994 * - * * - * Last Update : August 7, 1995 [JLB] * - * Determines * - *---------------------------------------------------------------------------------------------* - * Functions: * - * AircraftTypeClass::AircraftTypeClass -- Constructor for aircraft objects. * - * AircraftTypeClass::Create_And_Place -- Creates and places aircraft using normal game syste* - * AircraftTypeClass::Create_One_Of -- Creates an aircraft object of the appropriate type. * - * AircraftTypeClass::Dimensions -- Fetches the graphic dimensions of the aircraft type. * - * AircraftTypeClass::Display -- Displays a generic version of the aircraft type. * - * AircraftTypeClass::From_Name -- Converts an ASCIIto an aircraft type number. * - * AircraftTypeClass::Max_Pips -- Fetches the maximum number of pips allowed. * - * AircraftTypeClass::Occupy_List -- Returns with occupation list for landed aircraft. * - * AircraftTypeClass::One_Time -- Performs one time initialization of the aircraft type class.* - * AircraftTypeClass::Overlap_List -- the overlap list for a landed aircraft. * - * AircraftTypeClass::Prep_For_Add -- Prepares the scenario editor for adding an aircraft objec* - * AircraftTypeClass::Repair_Cost -- Fetchs the cost per repair step. * - * AircraftTypeClass::Repair_Step -- Fetches the number of health points per repair. * - * AircraftTypeClass::Who_Can_Build_Me -- Determines which object can build the aircraft obje* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -void const * AircraftTypeClass::LRotorData = NULL; -void const * AircraftTypeClass::RRotorData = NULL; - -// A-10 attack plane -static AircraftTypeClass const AttackPlane( - AIRCRAFT_A10, // What kind of aircraft is this. - TXT_A10, // Translated text number for aircraft. - "A10", // INI name of aircraft. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is a leader type? - false, // Does it fire a pair of shots in quick succession? - false, // Is this a typical transport vehicle? - true, // Fixed wing aircraft? - false, // Equipped with a rotor? - false, // Custom rotor sets for each facing? - false, // Can this aircraft land on clear terrain? - false, // Can the aircraft be crushed by a tracked vehicle? - true, // Is it invisible on radar? - false, // Can the player select it so as to give it orders? - true, // Can it be assigned as a target for attack. - false, // Is it insignificant (won't be announced)? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Can it be repaired in a repair facility? - false, // Can the player construct or order this unit? - true, // Is there a crew inside? - 3, // Number of shots it has (default). - 60, // The strength of this unit. - 0, // The range that it reveals terrain around itself. - 800, // Credit cost to construct. - 0, // The scenario this becomes available. - 10,1, // Risk, reward when calculating AI. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // Who can own this aircraft type. - WEAPON_NAPALM,WEAPON_NONE, - ARMOR_ALUMINUM, // Armor type of this aircraft. - MPH_FAST, // Maximum speed of aircraft. - 5, // Rate of turn. - MISSION_HUNT // Default mission for aircraft. -); - -// Transport helicopter. -static AircraftTypeClass const TransportHeli( - AIRCRAFT_TRANSPORT, // What kind of aircraft is this. - TXT_TRANS, // Translated text number for aircraft. - "TRAN", // INI name of aircraft. - 6, // Build level. - STRUCTF_HELIPAD, // Building prerequisite. - false, // Is a leader type? - false, // Does it fire a pair of shots in quick succession? - true, // Is this a typical transport vehicle? - false, // Fixed wing aircraft? - true, // Equipped with a rotor? - true, // Custom rotor sets for each facing? - true, // Can this aircraft land on clear terrain? - false, // Can the aircraft be crushed by a tracked vehicle? - true, // Is it invisible on radar? - true, // Can the player select it so as to give it orders? - true, // Can it be assigned as a target for attack. - false, // Is it insignificant (won't be announced)? - false, // Theater specific graphic image? - false, // Is it equipped with a combat turret? - false, // Can it be repaired in a repair facility? - true, // Can the player construct or order this unit? - true, // Is there a crew inside? - 0, // Number of shots it has (default). - 90, // The strength of this unit. - 0, // The range that it reveals terrain around itself. - 1500, // Credit cost to construct. - 98, // The scenario this becomes available. - 10,80, // Risk, reward when calculating AI. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // Who can own this aircraft type. - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // Armor type of this aircraft. - MPH_MEDIUM_FAST, // Maximum speed of aircraft. - 5, // Rate of turn. - MISSION_HUNT // Default mission for aircraft. -); - -// Apache attach helicopter. -static AircraftTypeClass const AttackHeli( - AIRCRAFT_HELICOPTER, // What kind of aircraft is this. - TXT_HELI, // Translated text number for aircraft. - "HELI", // INI name of aircraft. - 6, // Build level. - STRUCTF_HELIPAD, // Building prerequisite. - true, // Is a leader type? - true, // Does it fire a pair of shots in quick succession? - false, // Is this a typical transport vehicle? - false, // Fixed wing aircraft? - true, // Equipped with a rotor? - false, // Custom rotor sets for each facing? - false, // Can this aircraft land on clear terrain? - false, // Can the aircraft be crushed by a tracked vehicle? - true, // Is it invisible on radar? - true, // Can the player select it so as to give it orders? - true, // Can it be assigned as a target for attack. - false, // Is it insignificant (won't be announced)? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Can it be repaired in a repair facility? - true, // Can the player construct or order this unit? - true, // Is there a crew inside? - 15, // Number of shots it has (default). - 125, // The strength of this unit. - 0, // The range that it reveals terrain around itself. - 1200, // Credit cost to construct. - 10, // The scenario this becomes available. - 10,80, // Risk, reward when calculating AI. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // Who can own this aircraft type. - WEAPON_CHAIN_GUN,WEAPON_NONE, - ARMOR_STEEL, // Armor type of this aircraft. - MPH_FAST, // Maximum speed of aircraft. - 4, // Rate of turn. - MISSION_HUNT // Default mission for aircraft. -); - - -// Orca attack helicopter. -static AircraftTypeClass const OrcaHeli( - AIRCRAFT_ORCA, // What kind of aircraft is this. - TXT_ORCA, // Translated text number for aircraft. - "ORCA", // INI name of aircraft. - 6, // Build level. - STRUCTF_HELIPAD, // Building prerequisite. - true, // Is a leader type? - true, // Does it fire a pair of shots in quick succession? - false, // Is this a typical transport vehicle? - false, // Fixed wing aircraft? - false, // Equipped with a rotor? - false, // Custom rotor sets for each facing? - false, // Can this aircraft land on clear terrain? - false, // Can the aircraft be crushed by a tracked vehicle? - true, // Is it invisible on radar? - true, // Can the player select it so as to give it orders? - true, // Can it be assigned as a target for attack. - false, // Is it insignificant (won't be announced)? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Can it be repaired in a repair facility? - true, // Can the player construct or order this unit? - true, // Is there a crew inside? - 6, // Number of shots it has (default). - 125, // The strength of this unit. - 0, // The range that it reveals terrain around itself. - 1200, // Credit cost to construct. - 10, // The scenario this becomes available. - 10,80, // Risk, reward when calculating AI. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // Who can own this aircraft type. - WEAPON_DRAGON,WEAPON_NONE, - ARMOR_STEEL, // Armor type of this aircraft. - MPH_FAST, // Maximum speed of aircraft. - 4, // Rate of turn. - MISSION_HUNT // Default mission for aircraft. -); - - -// C-17 transport plane. -static AircraftTypeClass const CargoPlane( - AIRCRAFT_CARGO, // What kind of aircraft is this. - TXT_C17, // Translated text number for aircraft. - "C17", // INI name of aircraft. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is a leader type? - false, // Does it fire a pair of shots in quick succession? - true, // Is this a typical transport vehicle? - true, // Fixed wing aircraft? - false, // Equipped with a rotor? - false, // Custom rotor sets for each facing? - false, // Can this aircraft land on clear terrain? - false, // Can the aircraft be crushed by a tracked vehicle? - true, // Is it invisible on radar? - false, // Can the player select it so as to give it orders? - false, // Can it be assigned as a target for attack. - false, // Is it insignificant (won't be announced)? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Can it be repaired in a repair facility? - false, // Can the player construct or order this unit? - true, // Is there a crew inside? - 0, // Number of shots it has (default). - 25, // The strength of this unit. - 0, // The range that it reveals terrain around itself. - 800, // Credit cost to construct. - 0, // The scenario this becomes available. - 10,1, // Risk, reward when calculating AI. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // Who can own this aircraft type. - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // Armor type of this aircraft. - MPH_FAST, // Maximum speed of aircraft. - 5, // Rate of turn. - MISSION_HUNT // Default mission for aircraft. -); - - -AircraftTypeClass const * const AircraftTypeClass::Pointers[AIRCRAFT_COUNT] = { - &TransportHeli, - &AttackPlane, - &AttackHeli, - &CargoPlane, - &OrcaHeli, -}; - - -/*********************************************************************************************** - * AircraftTypeClass::AircraftTypeClass -- Constructor for aircraft objects. * - * * - * This is the constructor for the aircraft object. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -AircraftTypeClass::AircraftTypeClass( - AircraftType airtype, - int name, - char const *ininame, - unsigned char level, - long pre, - bool is_leader, - bool is_twoshooter, - bool is_transporter, - bool is_fixedwing, - bool is_rotorequipped, - bool is_rotorcustom, - bool is_landable, - bool is_crushable, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - bool is_theater, - bool is_repairable, - bool is_buildable, - bool is_crew, - int ammo, - unsigned short strength, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, - WeaponType secondary, - ArmorType armor, - MPHType maxspeed, - int rot, - MissionType deforder) : - TechnoTypeClass(name, - ininame, - level, - pre, - is_leader, - false, - false, - is_transporter, - false, - is_crushable, - is_stealthy, - is_selectable, - is_legal_target, - is_insignificant, - is_immune, - is_theater, - is_twoshooter, - false, - is_repairable, - is_buildable, - is_crew, - ammo, - strength, - maxspeed, - sightrange, - cost, - scenario, - risk, - reward, - ownable, - primary, - secondary, - armor) -{ - IsRotorEquipped = is_rotorequipped; - IsRotorCustom = is_rotorcustom; - IsLandable = is_landable; - IsFixedWing = is_fixedwing; - Type = airtype; - ROT = rot; - Mission = deforder; -} - - -/*********************************************************************************************** - * AircraftTypeClass::From_Name -- Converts an ASCII name into an aircraft type number. * - * * - * This routine is used to convert an ASCII representation of an aircraft into the * - * matching aircraft type number. This is used by the scenario INI reader code. * - * * - * INPUT: name -- Pointer to ASCII name to translate. * - * * - * OUTPUT: Returns the aircraft type number that matches the ASCII name provided. If no * - * match could be found, then AIRCRAFT_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -AircraftType AircraftTypeClass::From_Name(char const *name) -{ - if (name) { - for (AircraftType classid = AIRCRAFT_FIRST; classid < AIRCRAFT_COUNT; classid++) { - if (stricmp(Pointers[classid]->IniName, name) == 0) { - return(classid); - } - } - } - return(AIRCRAFT_NONE); -} - - -/*********************************************************************************************** - * AircraftTypeClass::One_Time -- Performs one time initialization of the aircraft type class. * - * * - * This routine is used to perform the onetime initialization of the aircraft type. This * - * includes primarily the shape and other graphic data loading. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This goes to disk and also must only be called ONCE. * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftTypeClass::One_Time(void) -{ - AircraftType index; - - for (index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) { - char fullname[_MAX_FNAME+_MAX_EXT]; - AircraftTypeClass const & uclass = As_Reference(index); - - /* - ** Fetch the supporting data files for the unit. - */ - char buffer[_MAX_FNAME]; - if ( Get_Resolution_Factor() ) { - sprintf(buffer, "%sICNH", uclass.IniName); - } else { - sprintf(buffer, "%sICON", uclass.IniName); - } - _makepath(fullname, NULL, NULL, buffer, ".SHP"); - ((void const *&)uclass.CameoData) = MixFileClass::Retrieve(fullname); - - /* - ** Generic shape for all houses load method. - */ - _makepath(fullname, NULL, NULL, uclass.IniName, ".SHP"); - ((void const *&)uclass.ImageData) = MixFileClass::Retrieve(fullname); - } - - LRotorData = MixFileClass::Retrieve("LROTOR.SHP"); - RRotorData = MixFileClass::Retrieve("RROTOR.SHP"); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Create_One_Of -- Creates an aircraft object of the appropriate type. * - * * - * This routine is used to create an aircraft object that matches the aircraft type. It * - * serves as a shortcut to creating an object using the "new" operator and "if" checks. * - * * - * INPUT: house -- The house owner of the aircraft that is to be created. * - * * - * OUTPUT: Returns with a pointer to the aircraft created. If the aircraft could not be * - * created, then a NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * AircraftTypeClass::Create_One_Of(HouseClass * house) const -{ - return(new AircraftClass(Type, house->Class->House)); -} - - -#ifdef SCENARIO_EDITOR -/*********************************************************************************************** - * AircraftTypeClass::Prep_For_Add -- Prepares the scenario editor for adding an aircraft objec* - * * - * This routine is used by the scenario editor to prepare for the adding operation. It * - * builds a list of pointers to object types that can be added. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftTypeClass::Prep_For_Add(void) -{ - for (AircraftType index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) { - if (As_Reference(index).Get_Image_Data()) { - Map.Add_To_List(&As_Reference(index)); - } - } -} - - -/*********************************************************************************************** - * AircraftTypeClass::Display -- Displays a generic version of the aircraft type. * - * * - * This routine is used by the scenario editor to display a generic version of the object * - * type. This is displayed in the object selection dialog box. * - * * - * INPUT: x,y -- The coordinates to draw the aircraft at (centered). * - * * - * window -- The window to base the coordinates upon. * - * * - * house -- The owner of this generic aircraft. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftTypeClass::Display(int x, int y, WindowNumberType window, HousesType house) const -{ - int shape = 0; - void const * ptr = Get_Cameo_Data(); - if (!ptr) { - ptr = Get_Image_Data(); - shape = 5; - } - CC_Draw_Shape(ptr, shape, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, HouseClass::As_Pointer(house)->Remap_Table(false, true)); -} -#endif - - -/*********************************************************************************************** - * AircraftTypeClass::Occupy_List -- Returns with occupation list for landed aircraft. * - * * - * This determines the occupation list for the aircraft (if it was landed). * - * * - * INPUT: placement -- Is this for placement legality checking only? The normal condition * - * is for marking occupation flags. * - * * - * OUTPUT: Returns with a pointer to a cell offset occupation list for the aircraft. * - * * - * WARNINGS: This occupation list is only valid if the aircraft is landed. * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -short const * AircraftTypeClass::Occupy_List(bool) const -{ - static short const _list[] = {0, REFRESH_EOL}; - return(_list); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Overlap_List -- Determines the overlap list for a landed aircraft. * - * * - * This routine figures out the overlap list for the aircraft as if it were landed. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the cell offset overlap list for the aircraft. * - * * - * WARNINGS: This overlap list is only valid when the aircraft is landed. * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -short const * AircraftTypeClass::Overlap_List(void) const -{ - static short const _list[] = {-(MAP_CELL_W-1), -MAP_CELL_W, -(MAP_CELL_W+1), -1, 1, (MAP_CELL_W-1), MAP_CELL_W, (MAP_CELL_W+1), REFRESH_EOL}; - return(_list); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Who_Can_Build_Me -- Determines which object can build the aircraft objec * - * * - * Use this routine to determine which object (factory) can build the aircraft. It * - * determines this by scanning through the available factories, looking for one that is * - * of the proper ownership and is available. * - * * - * INPUT: intheory -- When true, it doesn't consider if the factory is currently busy. It * - * only considers that it is the right type. * - * * - * legal -- Should building prerequisite legality checks be performed as well? * - * For building placements, this is usually false. For sidebar button * - * adding, this is usually true. * - * * - * house -- The house of the desired aircraft to be built. * - * * - * OUTPUT: Returns with a pointer to the object that can build the aircraft. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/30/1994 JLB : Created. * - *=============================================================================================*/ -BuildingClass * AircraftTypeClass::Who_Can_Build_Me(bool , bool legal, HousesType house) const -{ - BuildingClass * anybuilding = NULL; - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && - !building->IsInLimbo && - building->House->Class->House == house && - building->Mission != MISSION_DECONSTRUCTION && - ((1L << building->ActLike) & Ownable) && - (!legal || building->House->Can_Build(Type, building->ActLike)) && - building->Class->ToBuild == RTTI_AIRCRAFTTYPE) { - - if (building->IsLeader) return(building); - anybuilding = building; - } - } - return(anybuilding); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Repair_Cost -- Fetchs the cost per repair step. * - * * - * This routine will return the cost for every repair step. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the credit expense for every repair step. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/26/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftTypeClass::Repair_Cost(void) const -{ - return(Fixed_To_Cardinal(Cost/(MaxStrength/REPAIR_STEP), REPAIR_PERCENT)); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Repair_Step -- Fetches the number of health points per repair. * - * * - * For every repair event, the returned number of health points is acquired. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of health points to recover each repair step. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/26/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftTypeClass::Repair_Step(void) const -{ - return(REPAIR_STEP); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Max_Pips -- Fetches the maximum number of pips allowed. * - * * - * Use this routine to retrieve the maximum pip count allowed for this aircraft. This is * - * the maximum number of passengers. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the maximum number of pips for this aircraft. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/26/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftTypeClass::Max_Pips(void) const -{ - if (IsTransporter) { - return(Max_Passengers()); - } else { - if (Primary != WEAPON_NONE) { - return(5); - } - } - return(0); -} - - -/*********************************************************************************************** - * AircraftTypeClass::Create_And_Place -- Creates and places aircraft using normal game system * - * * - * This routine is used to create and place an aircraft through the normal game system. * - * Since creation of aircraft in this fashion is prohibited, this routine does nothing. * - * * - * INPUT: na * - * * - * OUTPUT: Always returns a failure code (false). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/07/1995 JLB : Created. * - *=============================================================================================*/ -bool AircraftTypeClass::Create_And_Place(CELL, HousesType) const -{ - return(false); -} - - - - - -/*********************************************************************************************** - * ATC::Init -- load up terrain set dependant sidebar icons * - * * - * * - * * - * INPUT: theater type * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 4/25/96 0:33AM ST : Created * - *=============================================================================================*/ - -void AircraftTypeClass::Init(TheaterType theater) -{ - if (theater != LastTheater){ - if ( Get_Resolution_Factor() ) { - - AircraftType index; - char buffer[_MAX_FNAME]; - char fullname[_MAX_FNAME+_MAX_EXT]; - void const * cameo_ptr; - - for (index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) { - AircraftTypeClass const & uclass = As_Reference(index); - - ((void const *&)uclass.CameoData) = NULL; - - sprintf(buffer, "%.4sICNH", uclass.IniName); - _makepath (fullname, NULL, NULL, buffer, Theaters[theater].Suffix); - cameo_ptr = MixFileClass::Retrieve(fullname); - if (cameo_ptr){ - ((void const *&)uclass.CameoData) = cameo_ptr; - } - } - } - } -} - - - - - -/*********************************************************************************************** - * AircraftTypeClass::Dimensions -- Fetches the graphic dimensions of the aircraft type. * - * * - * This routine will fetch the pixel dimensions of this aircraft type. These dimensions * - * are used to control map refresh and select box rendering. * - * * - * INPUT: width -- Reference to variable that will be filled in with aircraft width. * - * * - * height -- Reference to variable that will be filled in with aircraft height. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/07/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftTypeClass::Dimensions(int &width, int &height) const -{ - width = 21; - height = 20; -} - - -RTTIType AircraftTypeClass::What_Am_I(void) const {return RTTI_AIRCRAFTTYPE;}; diff --git a/code/TIBERIANDAWN/ABSTRACT.CPP b/code/TIBERIANDAWN/ABSTRACT.CPP deleted file mode 100644 index 49b7d08..0000000 --- a/code/TIBERIANDAWN/ABSTRACT.CPP +++ /dev/null @@ -1,133 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\abstract.cpv 2.20 16 Oct 1995 16:49:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ABSTRACT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/26/95 * - * * - * Last Update : May 22, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * AbstractClass::Distance -- Determines distance to target. * - * AbstractTypeClass::AbstractTypeClass -- Constructor for abstract type objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * AbstractClass::Distance -- Determines distance to target. * - * * - * This will determine the distance (direct line) to the target. The distance is in * - * 'leptons'. This routine is typically used for weapon range checks. * - * * - * INPUT: target -- The target to determine range to. * - * * - * OUTPUT: Returns with the range to the specified target (in leptons). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/17/1994 JLB : Created. * - *=============================================================================================*/ -int AbstractClass::Distance(TARGET target) const -{ - /* - ** Should subtract a fudge-factor distance for building targets. - */ - BuildingClass *obj = As_Building(target); - int dist = Distance(As_Coord(target)); - - /* - ** If the object is a building the adjust it by the average radius - ** of the object. - */ - if (obj && obj->IsActive) { - dist -= ((obj->Class->Width() + obj->Class->Height()) * (0x100 / 4)); - if (dist < 0) dist = 0; - } - - /* - ** Return the distance to the target - */ - return(dist); -} - - -/*********************************************************************************************** - * AbstractTypeClass::AbstractTypeClass -- Constructor for abstract type objects. * - * * - * This is the constructor for AbstractTypeClass objects. It initializes the INI name and * - * the text name for this object type. * - * * - * INPUT: name -- Text number for the full name of the object. * - * * - * ini -- The ini name for this object type. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - *=============================================================================================*/ -AbstractTypeClass::AbstractTypeClass(int name, char const * ini) -{ - Name = name; - strncpy((char *)IniName, ini, sizeof(IniName)); - ((char &)IniName[sizeof(IniName)-1]) = '\0'; -} - -RTTIType AbstractTypeClass::What_Am_I(void) const {return RTTI_ABSTRACTTYPE;}; -COORDINATE AbstractTypeClass::Coord_Fixup(COORDINATE coord) const {return coord;} -int AbstractTypeClass::Full_Name(void) const {return Name;}; -unsigned short AbstractTypeClass::Get_Ownable(void) const {return 0xffff;}; - - - - -void AbstractClass::Delete_This(void) -{ - /* - ** Apparently Watcom preserved the vtable through the virtual destructor chain, otherwise C&C would crash all the time. - ** - ** MSVC doesn't. It overwrites the vtable pointer with the vtable of the class currently being destructed - presumably to - ** prevent virtual functions of the classes already destructed from being called. - ** - ** So this is a hacky workaround to restore the original vtable pointer after the destructor chain has finished, for when the - ** C&C code wants to call a virtual function on an object it just 'deleted'. - ** - ** ST - 1/9/2019 6:02PM - */ - unsigned long *this_ptr = (unsigned long*) this; - unsigned long vtable_ptr = *this_ptr; - - /* - ** delete this calls the operator delete, it doesn't actually deallocate the memory. - */ - delete this; - - *this_ptr = vtable_ptr; -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/ABSTRACT.H b/code/TIBERIANDAWN/ABSTRACT.H deleted file mode 100644 index 1a3720c..0000000 --- a/code/TIBERIANDAWN/ABSTRACT.H +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\abstract.h_v 2.20 16 Oct 1995 16:46:30 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ABSTRACT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/26/95 * - * * - * Last Update : January 26, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef ABSTRACT_H -#define ABSTRACT_H - -DirType Direction(CELL cell1, CELL cell2); -DirType Direction(COORDINATE coord1, COORDINATE coord2); -int Distance(COORDINATE coord1, COORDINATE coord2); -int Distance(CELL coord1, CELL coord2); -COORDINATE As_Coord(TARGET target); - -class AbstractTypeClass; - -class AbstractClass -{ - public: - - /* - ** The coordinate location of the unit. For vehicles, this is the center - ** point. For buildings, it is the upper left corner. - */ - COORDINATE Coord; - - /* - ** The actual object ram-space is located in arrays in the data segment. This flag - ** is used to indicate which objects are free to be reused and which are currently - ** in use by the game. - */ - unsigned IsActive:1; - - /* - ** A flag to indicate that this object was recently created. Since an object's allocation is just a matter of whether - ** the IsActive flag is set, during a logic frame an object with a given ID could be 'deleted' then reallocated - ** as a different type of object in a different location. This flag lets us know that this happened. ST - 8/19/2019 5:33PM - */ - unsigned IsRecentlyCreated:1; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[8]; - - /*----------------------------------------------------------------------------------- - ** Constructor & destructors. - */ - AbstractClass(void) {Coord = 0L;}; - virtual ~AbstractClass(void) {}; - - /* - ** Query functions. - */ - virtual HousesType Owner(void) const {return HOUSE_NONE;}; - - /* - ** Coordinate query support functions. - */ - virtual COORDINATE Center_Coord(void) const {return Coord;}; - virtual COORDINATE Target_Coord(void) const {return Coord;}; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - DirType Direction(AbstractClass const * object) const {return ::Direction(Center_Coord(), object->Target_Coord());}; - DirType Direction(COORDINATE coord) const {return ::Direction(Center_Coord(), coord);}; - DirType Direction(TARGET target) const {return ::Direction(Center_Coord(), As_Coord(target));}; - DirType Direction(CELL cell) const {return ::Direction(Coord_Cell(Center_Coord()), cell);}; - int Distance(TARGET target) const; - int Distance(COORDINATE coord) const {return ::Distance(Center_Coord(), coord);}; - int Distance(CELL cell) const {return ::Distance(Coord_Cell(Center_Coord()), cell);}; - int Distance(AbstractClass const * object) const {return ::Distance(Center_Coord(), object->Target_Coord());}; - - /* - ** Object entry and exit from the game system. - */ - virtual MoveType Can_Enter_Cell(CELL , FacingType = FACING_NONE) const {return MOVE_OK;}; - - /* - ** AI. - */ - virtual void AI(void) {}; - - /* - ** Workaround for difference between watcom and VC destructor behavior - */ - void Delete_This(void); - - /* - ** Set the new recently created flag every time the active flag is set. ST - 8/19/2019 5:41PM - */ - void Set_Active(void) {IsActive = true; IsRecentlyCreated = true;} -}; - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/ADATA.CPP b/code/TIBERIANDAWN/ADATA.CPP deleted file mode 100644 index 3958f21..0000000 --- a/code/TIBERIANDAWN/ADATA.CPP +++ /dev/null @@ -1,2575 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\adata.cpv 2.18 16 Oct 1995 16:49:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ADATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 30, 1994 * - * * - * Last Update : August 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * AnimTypeClass::One_Time -- Performs one time action for animation types. * - * AnimTypeClass::AnimTypeClass -- Constructor for animation types. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -// Dinosaur death animations -static AnimTypeClass const TricDie( - ANIM_TRIC_DIE, // Animation number. - "TRIC", // Data name of animation. - 32, // Maximum dimension of animation. - 4, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - true, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 176, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 20, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const TRexDie( - ANIM_TREX_DIE, // Animation number. - "TREX", // Data name of animation. - 48, // Maximum dimension of animation. - 4, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - true, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 144, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 40, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const StegDie( - ANIM_STEG_DIE, // Animation number. - "STEG", // Data name of animation. - 33, // Maximum dimension of animation. - 4, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - true, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 176, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 22, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const RaptDie( - ANIM_RAPT_DIE, // Animation number. - "RAPT", // Data name of animation. - 24, // Maximum dimension of animation. - 4, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - true, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 144, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 40, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const SAMN( - ANIM_SAM_N, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 4, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAMNW( - ANIM_SAM_NW, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 22, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*1, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAMW( - ANIM_SAM_W, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 40, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*2, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAMSW( - ANIM_SAM_SW, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 58, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*3, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAMS( - ANIM_SAM_S, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 76, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*4, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAMSE( - ANIM_SAM_SE, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 94, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*5, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAME( - ANIM_SAM_E, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 112, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*6, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const SAMNE( - ANIM_SAM_NE, // Animation number. - "SAMFIRE", // Data name of animation. - 55, // Maximum dimension of animation. - 130, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18*7, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 18, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const LZSmoke( - ANIM_LZ_SMOKE, // Animation number. - "SMOKLAND", // Data name of animation. - 32, // Maximum dimension of animation. - 72, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 72, // Loop start frame number. - 91, // Ending frame of loop back. - -1, // Number of animation stages. - 255, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -/* -** Flammable object burning animations. Primarily used on trees and buildings. -*/ -static AnimTypeClass const BurnSmall( - ANIM_BURN_SMALL, // Animation number. - "BURN-S", // Data name of animation. - 11, // Maximum dimension of animation. - 13, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0008, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 30, // Loop start frame number. - 62, // Ending frame of loop back. - -1, // Number of animation stages. - 4, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const BurnMed( - ANIM_BURN_MED, // Animation number. - "BURN-M", // Data name of animation. - 14, // Maximum dimension of animation. - 13, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0010, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 30, // Loop start frame number. - 62, // Ending frame of loop back. - -1, // Number of animation stages. - 4, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const BurnBig( - ANIM_BURN_BIG, // Animation number. - "BURN-L", // Data name of animation. - 23, // Maximum dimension of animation. - 13, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0018, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 30, // Loop start frame number. - 62, // Ending frame of loop back. - -1, // Number of animation stages. - 4, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -/* -** Flammable object burning animations that trail into smoke. Used for -** buildings and the gunboat. -*/ -static AnimTypeClass const OnFireSmall( - ANIM_ON_FIRE_SMALL, // Animation number. - "BURN-S", // Data name of animation. - 11, // Maximum dimension of animation. - 13, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0008, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 30, // Loop start frame number. - 62, // Ending frame of loop back. - -1, // Number of animation stages. - 4, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_SMOKE_M -); -static AnimTypeClass const OnFireMed( - ANIM_ON_FIRE_MED, // Animation number. - "BURN-M", // Data name of animation. - 14, // Maximum dimension of animation. - 13, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0010, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 30, // Loop start frame number. - 62, // Ending frame of loop back. - -1, // Number of animation stages. - 4, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_ON_FIRE_SMALL -); -static AnimTypeClass const OnFireBig( - ANIM_ON_FIRE_BIG, // Animation number. - "BURN-L", // Data name of animation. - 23, // Maximum dimension of animation. - 13, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0018, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 30, // Loop start frame number. - 62, // Ending frame of loop back. - -1, // Number of animation stages. - 4, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_ON_FIRE_MED -); - -/* -** Flame thrower animations. These are direction specific. -*/ -static AnimTypeClass const FlameN( - ANIM_FLAME_N, // Animation number. - "FLAME-N", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameNW( - ANIM_FLAME_NW, // Animation number. - "FLAME-NW", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameW( - ANIM_FLAME_W, // Animation number. - "FLAME-W", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameSW( - ANIM_FLAME_SW, // Animation number. - "FLAME-SW", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameS( - ANIM_FLAME_S, // Animation number. - "FLAME-S", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameSE( - ANIM_FLAME_SE, // Animation number. - "FLAME-SE", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameE( - ANIM_FLAME_E, // Animation number. - "FLAME-E", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const FlameNE( - ANIM_FLAME_NE, // Animation number. - "FLAME-NE", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - true, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -/* -** Chem sprayer animations. These are direction specific. -*/ -static AnimTypeClass const ChemN( - ANIM_CHEM_N, // Animation number. - "CHEM-N", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemNW( - ANIM_CHEM_NW, // Animation number. - "CHEM-NW", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemW( - ANIM_CHEM_W, // Animation number. - "CHEM-W", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemSW( - ANIM_CHEM_SW, // Animation number. - "CHEM-SW", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemS( - ANIM_CHEM_S, // Animation number. - "CHEM-S", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemSE( - ANIM_CHEM_SE, // Animation number. - "CHEM-SE", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemE( - ANIM_CHEM_E, // Animation number. - "CHEM-E", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const ChemNE( - ANIM_CHEM_NE, // Animation number. - "CHEM-NE", // Data name of animation. - 0, // Maximum dimension of animation. - 9, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Grenade( - ANIM_GRENADE, // Animation number. - "VEH-HIT2", // Data name of animation. - 21, // Maximum dimension of animation. - 1, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - true, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_GUN20, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const FBall1( - ANIM_FBALL1, // Animation number. - "FBALL1", // Data name of animation. - 67, // Maximum dimension of animation. - 6, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - true, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOS, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Frag1( - ANIM_FRAG1, // Animation number. - "FRAG1", // Data name of animation. - 45, // Maximum dimension of animation. - 3, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - true, // Forms a crater? - true, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOBIG4, // Sound effect to play. - ANIM_NONE, - 29 // Virtual stages -); - -static AnimTypeClass const Frag3( - ANIM_FRAG2, // Animation number. - "FRAG3", // Data name of animation. - 41, // Maximum dimension of animation. - 3, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - true, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOBIG6, // Sound effect to play. - ANIM_NONE, - 29 // Virtual stages -); - -static AnimTypeClass const VehHit1( - ANIM_VEH_HIT1, // Animation number. - "VEH-HIT1", // Data name of animation. - 30, // Maximum dimension of animation. - 4, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - true, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOS, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const VehHit2( - ANIM_VEH_HIT2, // Animation number. - "VEH-HIT2", // Data name of animation. - 21, // Maximum dimension of animation. - 1, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - true, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOS, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const VehHit3( - ANIM_VEH_HIT3, // Animation number. - "VEH-HIT3", // Data name of animation. - 19, // Maximum dimension of animation. - 3, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - true, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOS, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const ArtExp1( - ANIM_ART_EXP1, // Animation number. - "ART-EXP1", // Data name of animation. - 41, // Maximum dimension of animation. - 1, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - true, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_XPLOSML2, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Napalm1( - ANIM_NAPALM1, // Animation number. - "NAPALM1", // Data name of animation. - 21, // Maximum dimension of animation. - 5, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_FLAMER1, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Napalm2( - ANIM_NAPALM2, // Animation number. - "NAPALM2", // Data name of animation. - 41, // Maximum dimension of animation. - 5, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_FLAMER1, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Napalm3( - ANIM_NAPALM3, // Animation number. - "NAPALM3", // Data name of animation. - 78, // Maximum dimension of animation. - 5, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_FLAMER1, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const SmokePuff( - ANIM_SMOKE_PUFF, // Animation number. - "SMOKEY", // Data name of animation. - 24, // Maximum dimension of animation. - 2, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - true, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Piff( - ANIM_PIFF, // Animation number. - "PIFF", // Data name of animation. - 13, // Maximum dimension of animation. - 1, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const PiffPiff( - ANIM_PIFFPIFF, // Animation number. - "PIFFPIFF", // Data name of animation. - 20, // Maximum dimension of animation. - 2, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Fire3( - ANIM_FIRE_SMALL, // Animation number. - "FIRE3", // Data name of animation. - 23, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0008, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 2, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - -1, // Virtual stages - 0x100, // Virtual scale - ANIM_FIRE_SMALL_VIRTUAL // Virtual anim -); - -static AnimTypeClass const Fire3Virtual( - ANIM_FIRE_SMALL_VIRTUAL, // Animation number. - "FIRE3", // Data name of animation. - 23, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 10, // Loop start frame number. - 21, // Ending frame of loop back. - 29, // Number of animation stages. - 2, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Fire1( - ANIM_FIRE_MED2, // Animation number. - "FIRE1", // Data name of animation. - 23, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0010, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 3, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - -1, // Virtual stages - 0x100, // Virtual scale - ANIM_FIRE_MED2_VIRTUAL // Virtual anim -); - -static AnimTypeClass const Fire1Virtual( - ANIM_FIRE_MED2_VIRTUAL, // Animation number. - "FIRE1", // Data name of animation. - 23, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 10, // Loop start frame number. - 21, // Ending frame of loop back. - 29, // Number of animation stages. - 3, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Fire4( - ANIM_FIRE_TINY, // Animation number. - "FIRE4", // Data name of animation. - 7, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0008, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 3, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - -1, // Virtual stages - 0x100, // Virtual scale - ANIM_FIRE_TINY_VIRTUAL // Virtual anim -); - -static AnimTypeClass const Fire4Virtual( - ANIM_FIRE_TINY_VIRTUAL, // Animation number. - "FIRE4", // Data name of animation. - 7, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 10, // Loop start frame number. - 21, // Ending frame of loop back. - 29, // Number of animation stages. - 3, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - 30 // Virtual stages -); - -static AnimTypeClass const Fire2( - ANIM_FIRE_MED, // Animation number. - "FIRE2", // Data name of animation. - 23, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0010, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 3, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - -1, // Virtual stages - 0x100, // Virtual scale - ANIM_FIRE_MED_VIRTUAL // Virtual anim -); - -static AnimTypeClass const Fire2Virtual( - ANIM_FIRE_MED_VIRTUAL, // Animation number. - "FIRE2", // Data name of animation. - 23, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 10, // Loop start frame number. - 21, // Ending frame of loop back. - 29, // Number of animation stages. - 3, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const OilFieldBurn( - ANIM_OILFIELD_BURN, // Animation number. - "FLMSPT", // Data name of animation. - 42, // Maximum dimension of animation. - 58, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 33, // Loop start frame number. - 99, // Ending frame of loop back. - 66, // Number of animation stages. - 65535, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Gunfire( - ANIM_MUZZLE_FLASH, // Animation number. - "GUNFIRE", // Data name of animation. - 16, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - true, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. -// 2, // Number of times the animation loops. - 1, // Number of animation stages. -// 2, // Number of animation stages. - 1, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - 10 // Virtual stages -); - -#ifdef NEVER -static AnimTypeClass const E1RotFire( - ANIM_E1_ROT_FIRE, // Animation number. - "E1ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 28, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E1RotGrenade( - ANIM_E1_ROT_GRENADE, // Animation number. - "E1ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 24, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E1RotGun( - ANIM_E1_ROT_GUN, // Animation number. - "E1ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 16, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E1RotExp( - ANIM_E1_ROT_EXP, // Animation number. - "E1ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 20, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const E2RotFire( - ANIM_E2_ROT_FIRE, // Animation number. - "E2ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 28, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E2RotGrenade( - ANIM_E2_ROT_GRENADE, // Animation number. - "E2ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 24, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E2RotGun( - ANIM_E2_ROT_GUN, // Animation number. - "E2ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 16, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E2RotExp( - ANIM_E2_ROT_EXP, // Animation number. - "E2ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 20, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const E3RotFire( - ANIM_E3_ROT_FIRE, // Animation number. - "E3ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 28, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E3RotGrenade( - ANIM_E3_ROT_GRENADE, // Animation number. - "E3ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 24, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E3RotGun( - ANIM_E3_ROT_GUN, // Animation number. - "E3ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 16, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E3RotExp( - ANIM_E3_ROT_EXP, // Animation number. - "E3ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 20, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const E4RotFire( - ANIM_E4_ROT_FIRE, // Animation number. - "E4ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 28, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E4RotGrenade( - ANIM_E4_ROT_GRENADE, // Animation number. - "E4ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 24, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E4RotGun( - ANIM_E4_ROT_GUN, // Animation number. - "E4ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 16, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const E4RotExp( - ANIM_E4_ROT_EXP, // Animation number. - "E4ROT", // Data name of animation. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Is a flat on the ground animation? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 30, // Delay between frames. - 20, // Starting frame number. - 0, // Loop start frame number. - 0, // Loopback frame number. - 4, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -#endif - -static AnimTypeClass const SmokeM( - ANIM_SMOKE_M, // Animation number. - "SMOKE_M", // Data name of animation. - 28, // Maximum dimension of animation. - 30, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 67, // Loop start frame number. - -1, // Loopback frame number. - -1, // Number of animation stages. - 6, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE, - 105 // Virtual stages -); - -/* -** Mini-gun fire effect -- used by guard towers. -*/ -static AnimTypeClass const GUNN( - ANIM_GUN_N, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNNW( - ANIM_GUN_NW, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 6, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNW( - ANIM_GUN_W, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 12, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNSW( - ANIM_GUN_SW, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 18, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNS( - ANIM_GUN_S, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 24, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNSE( - ANIM_GUN_SE, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 30, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNE( - ANIM_GUN_E, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 36, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const GUNNE( - ANIM_GUN_NE, // Animation number. - "MINIGUN", // Data name of animation. - 18, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 42, // Starting frame number. - 0, // Loop start frame number. - 0, // Number of times the animation loops. - 6, // Number of animation stages. - 0, // Ending frame of loop back. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); -static AnimTypeClass const IonCannon( - ANIM_ION_CANNON, // Animation number. - "IONSFX", // Data name of animation. - 48, // Maximum dimension of animation. - 11, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - true, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - 15, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_ION_CANNON, // Sound effect to play. - ANIM_ART_EXP1, - 32, // Virtual stages - 0x200 // Virtual scale -); - -static AnimTypeClass const AtomBomb( - ANIM_ATOM_BLAST, // Animation number. - "ATOMSFX", // Data name of animation. - 72, // Maximum dimension of animation. - 19, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - true, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NUKE_EXPLODE, // Sound effect to play. - ANIM_NONE, - 75, // Virtual stages - 0x300 // Virtual scale -); -static AnimTypeClass const AtomDoor( - ANIM_ATOM_DOOR, // Animation number. - "ATOMDOOR", // Data name of animation. - 48, // Maximum dimension of animation. - 19, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - true, // Scorches the ground? - true, // Forms a crater? - true, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const CDeviator( - ANIM_CRATE_DEVIATOR, // Animation number. - "DEVIATOR", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CDollar( - ANIM_CRATE_DOLLAR, // Animation number. - "DOLLAR", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CEarth( - ANIM_CRATE_EARTH, // Animation number. - "EARTH", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CEmpulse( - ANIM_CRATE_EMPULSE, // Animation number. - "EMPULSE", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CInvun( - ANIM_CRATE_INVUN, // Animation number. - "INVUN", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CMine( - ANIM_CRATE_MINE, // Animation number. - "MINE", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CRapid( - ANIM_CRATE_RAPID, // Animation number. - "RAPID", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CStealth( - ANIM_CRATE_STEALTH, // Animation number. - "STEALTH2", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); -static AnimTypeClass const CMissile( - ANIM_CRATE_MISSILE, // Animation number. - "MISSILE2", // Data name of animation. - 48, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 2, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); - -static AnimTypeClass const MoveFlash( - ANIM_MOVE_FLASH, // Animation number. - "MOVEFLSH", // Data name of animation. - 24, // Maximum dimension of animation. - 0, // Biggest animation stage. - true, // Normalized animation rate? - true, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - true, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - 0, // Ending frame of loop back. - -1, // Number of animation stages. - 0, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE // Follow up animation. -); - -static AnimTypeClass const ChemBall( - ANIM_CHEM_BALL, // Animation number. - "CHEMBALL", // Data name of animation. - 21, // Maximum dimension of animation. - 5, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - 1, // Number of times the animation loops. - VOC_FLAMER1, // Sound effect to play. - ANIM_NONE -); - -static AnimTypeClass const Flag( - ANIM_FLAG, // Animation number. - "FLAGFLY", // Data name of animation. - 21, // Maximum dimension of animation. - 0, // Biggest animation stage. - false, // Normalized animation rate? - false, // Uses white translucent table? - false, // Scorches the ground? - false, // Forms a crater? - false, // Sticks to unit in square? - false, // Ground level animation? - false, // Translucent colors in this animation? - false, // Is this a flame thrower animation? - 0x0000, // Damage to apply per tick (fixed point). - 1, // Delay between frames. - 0, // Starting frame number. - 0, // Loop start frame number. - -1, // Ending frame of loop back. - -1, // Number of animation stages. - -1, // Number of times the animation loops. - VOC_NONE, // Sound effect to play. - ANIM_NONE -); - - - -AnimTypeClass const * const AnimTypeClass::Pointers[ANIM_COUNT] = { - &FBall1, - &Grenade, - &Frag1, - &Frag3, - &VehHit1, - &VehHit2, - &VehHit3, - &ArtExp1, - &Napalm1, - &Napalm2, - &Napalm3, - &SmokePuff, - &Piff, - &PiffPiff, - &FlameN, - &FlameNE, - &FlameE, - &FlameSE, - &FlameS, - &FlameSW, - &FlameW, - &FlameNW, - &ChemN, - &ChemNE, - &ChemE, - &ChemSE, - &ChemS, - &ChemSW, - &ChemW, - &ChemNW, - &Fire3, - &Fire2, - &Fire1, - &Fire4, - &Gunfire, -#ifdef NEVER - &E1RotFire, - &E1RotGrenade, - &E1RotGun, - &E1RotExp, - &E2RotFire, - &E2RotGrenade, - &E2RotGun, - &E2RotExp, - &E3RotFire, - &E3RotGrenade, - &E3RotGun, - &E3RotExp, - &E4RotFire, - &E4RotGrenade, - &E4RotGun, - &E4RotExp, -#endif - &SmokeM, - &BurnSmall, - &BurnMed, - &BurnBig, - &OnFireSmall, - &OnFireMed, - &OnFireBig, - &SAMN, - &SAMNE, - &SAME, - &SAMSE, - &SAMS, - &SAMSW, - &SAMW, - &SAMNW, - &GUNN, - &GUNNE, - &GUNE, - &GUNSE, - &GUNS, - &GUNSW, - &GUNW, - &GUNNW, - &LZSmoke, - &IonCannon, - &AtomBomb, - &CDeviator, - &CDollar, - &CEarth, - &CEmpulse, - &CInvun, - &CMine, - &CRapid, - &CStealth, - &CMissile, - &AtomDoor, - &MoveFlash, - &OilFieldBurn, - &TricDie, - &TRexDie, - &StegDie, - &RaptDie, - &ChemBall, - &Flag, - &Fire3Virtual, - &Fire2Virtual, - &Fire1Virtual, - &Fire4Virtual -}; - - -/*********************************************************************************************** - * AnimTypeClass::AnimTypeClass -- Constructor for animation types. * - * * - * This is the constructor for static objects that elaborate the various animation types * - * allowed in the game. Each animation in the game is of one of these types. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/23/1994 JLB : Created. * - *=============================================================================================*/ -AnimTypeClass::AnimTypeClass(AnimType anim, char const *name, int size, int biggest, - bool isnormal, bool iswhitetrans, bool isscorcher, bool iscrater, bool issticky, bool ground, - bool istrans, bool isflame, unsigned int damage, - int delaytime, int start, int loopstart, int loopend, int stages, int loops, - VocType sound, AnimType chainto, int virtualstages, int virtualscale, AnimType virtualanim) : - ObjectTypeClass(true, false, false, true, false, false, true, true, TXT_NONE, name, ARMOR_NONE, 0) -{ - Biggest = biggest; - ChainTo = chainto; - Damage = damage; - Delay = (unsigned char)delaytime; - IsCraterForming = iscrater; - IsFlameThrower = isflame; - IsGroundLayer = ground; - IsNormalized = isnormal; - IsScorcher = isscorcher; - IsSticky = issticky; - IsTranslucent = istrans; - IsWhiteTrans = iswhitetrans; - LoopEnd = loopend; - LoopStart = loopstart; - Loops = (char)loops; - Size = size; - Sound = sound; - Stages = stages; - Start = start; - Type = anim; - VirtualStages = virtualstages; - VirtualScale = virtualscale; - VirtualAnim = virtualanim; -} - - -/*********************************************************************************************** - * AnimTypeClass::One_Time -- Performs one time action for animation types. * - * * - * This will load the animation shape data. It is called by the game initialization * - * process. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine should be called ONLY once. * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void AnimTypeClass::One_Time(void) -{ - AnimType index; - - for (index = ANIM_FIRST; index < ANIM_COUNT; index++) { - char fullname[_MAX_FNAME+_MAX_EXT]; - - _makepath(fullname, NULL, NULL, As_Reference(index).IniName, ".SHP"); - - RawFileClass file(fullname); - if (file.Is_Available()) { - ((void const *&)As_Reference(index).ImageData) = Load_Alloc_Data(file); - } else { - ((void const *&)As_Reference(index).ImageData) = MixFileClass::Retrieve(fullname); - } - } -} - - diff --git a/code/TIBERIANDAWN/AIRCRAFT.CPP b/code/TIBERIANDAWN/AIRCRAFT.CPP deleted file mode 100644 index f0ffded..0000000 --- a/code/TIBERIANDAWN/AIRCRAFT.CPP +++ /dev/null @@ -1,3548 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\aircraft.cpv 2.12 19 Jun 1995 09:27:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : AIRCRAFT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 22, 1994 * - * * - * Last Update : August 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * AircraftClass::AI -- Processes the normal non-graphic AI for the aircraft. * - * AircraftClass::Active_Click_With -- Handles clicking over specified cell. * - * AircraftClass::Active_Click_With -- Handles clicking over specified object. * - * AircraftClass::AircraftClass -- The constructor for aircraft objects. * - * AircraftClass::As_Target -- Returns aircraft as a target number. * - * AircraftClass::Can_Enter_Cell -- Determines if the aircraft can land at this location. * - * AircraftClass::Cell_Seems_Ok -- Checks to see if a cell is good to enter. * - * AircraftClass::Desired_Load_Dir -- Determines where passengers should line up. * - * AircraftClass::Draw_It -- Renders an aircraft object at the location specified. * - * AircraftClass::Enter_Idle_Mode -- Gives the aircraft an appropriate mission. * - * AircraftClass::Exit_Object -- Unloads passenger from aircraft. * - * AircraftClass::Fire_At -- Handles firing a projectile from an aircraft. * - * AircraftClass::Fire_Coord -- Calculates the point of origin for a bullet. * - * AircraftClass::Fire_Direction -- Determines the direction of fire. * - * AircraftClass::Good_Fire_Location -- Searches for and finds a good spot to fire from. * - * AircraftClass::Good_LZ -- Locates a good spot ot land. * - * AircraftClass::In_Which_Layer -- Determine which render layer the aircraft lies. * - * AircraftClass::Init -- Initialize the aircraft system to an empty state. * - * AircraftClass::Is_LZ_Clear -- Determines if landing zone is free for landing. * - * AircraftClass::Mark -- Flags cells under the aircraft so that they will be redrawn. * - * AircraftClass::Mission_Attack -- Handles the attack mission for aircraft. * - * AircraftClass::Mission_Enter -- Control aircraft to fly to the helipad or repair center. * - * AircraftClass::Mission_Guard -- Handles aircraft in guard mode. * - * AircraftClass::Mission_Guard_Area -- Handles the aircraft guard area logic. * - * AircraftClass::Mission_Hunt -- Maintains hunt AI for the aircraft. * - * AircraftClass::Mission_Move -- Handles movement mission. * - * AircraftClass::Mission_Retreat -- Handles the aircraft logic for leaving the battlefield. * - * AircraftClass::Mission_Unload -- Handles unloading cargo. * - * AircraftClass::New_LZ -- Find a good landing zone. * - * AircraftClass::Overlap_List -- Returns with list of cells the aircraft overlaps. * - * AircraftClass::Pip_Count -- Returns the number of "objects" in aircraft. * - * AircraftClass::Player_Assign_Mission -- Handles player input to assign a mission. * - * AircraftClass::Pose_Dir -- Fetches the natural landing facing. * - * AircraftClass::Process_Fly_To -- Handles state machine for flying to destination. * - * AircraftClass::Process_Landing -- Landing process state machine handler. * - * AircraftClass::Process_Take_Off -- State machine support for taking off. * - * AircraftClass::Read_INI -- Reads aircraft object data from an INI file. * - * AircraftClass::Rearm_Delay -- Returns the delay between shots for this aircraft. * - * AircraftClass::Receive_Message -- Handles receipt of radio messages. * - * AircraftClass::Response_Attack -- Gives audio response to attack order. * - * AircraftClass::Response_Move -- Gives audio response to move request. * - * AircraftClass::Response_Select -- Gives audio response when selected. * - * AircraftClass::Scatter -- Causes the aircraft to move away a bit. * - * AircraftClass::Set_Speed -- Sets the speed for the aircraft. * - * AircraftClass::Sort_Y -- Figures the sorting coordinate. * - * AircraftClass::Take_Damage -- Applies damage to the aircraft. * - * AircraftClass::Threat_Range -- Returns with a range to scan for targets. * - * AircraftClass::Unlimbo -- Removes an aircraft from the limbo state. * - * AircraftClass::What_Action -- Determines what action to perform. * - * AircraftClass::What_Action -- Determines what action to perform. * - * AircraftClass::Write_INI -- Writes the current aircraft objects to an INI file. * - * AircraftClass::operator delete -- Deletes the aircraft object. * - * AircraftClass::operator new -- Allocates a new aircraft object from the pool * - * AircraftClass::~AircraftClass -- Destructor for aircraft object. * - * AircraftClass::Validate -- validates aircraft pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * AircraftClass::VTable; - - -/*********************************************************************************************** - * AircraftClass::Validate -- validates aircraft pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int AircraftClass::Validate(void) const -{ - int num; - - num = Aircraft.ID(this); - if (num < 0 || num >= AIRCRAFT_MAX) { - Validate_Error("AIRCRAFT"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * AircraftClass::As_Target -- Returns aircraft as a target number. * - * * - * This routine will convert the aircraft into a target number. This target number can * - * then be assigned to a targeting or navigation computer. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the aircraft as a target number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -TARGET AircraftClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_AIRCRAFT, Aircraft.ID(this))); -} - - -/*********************************************************************************************** - * AircraftClass::operator new -- Allocates a new aircraft object from the pool * - * * - * This routine will allocate an aircraft object from the free aircraft object pool. If * - * there are no free object available, then this routine will fail (return NULL). * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the allocate aircraft object or NULL if none were * - * available. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void * AircraftClass::operator new(size_t) -{ - void * ptr = Aircraft.Allocate(); - if (ptr) { - ((AircraftClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * AircraftClass::operator delete -- Deletes the aircraft object. * - * * - * This routine will return the aircraft object back to the free aircraft object pool. * - * * - * INPUT: ptr -- Pointer to the aircraft object to delete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::operator delete(void *ptr) -{ - if (ptr) { - ((AircraftClass *)ptr)->IsActive = false; - } - Aircraft.Free((AircraftClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * AircraftClass::AircraftClass -- The constructor for aircraft objects. * - * * - * This routine is the constructor for aircraft objects. An aircraft object can be * - * created and possibly placed into the game system by this routine. * - * * - * INPUT: classid -- The type of aircraft to create. * - * * - * house -- The owner of this aircraft. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -AircraftClass::AircraftClass(AircraftType classid, HousesType house) : - Class(&AircraftTypeClass::As_Reference(classid)), - FootClass(house) -{ - /* - ** For two shooters, clear out the second shot flag -- it will be set the first time - ** the object fires. For non two shooters, set the flag since it will never be cleared - ** and the second shot flag tells the system that normal rearm times apply -- this is - ** what is desired for non two shooters. - */ - if (Class->IsTwoShooter) { - IsSecondShot = false; - } else { - IsSecondShot = true; - } - Ammo = Class->MaxAmmo; - AttacksRemaining = 3; - Altitude = FLIGHT_LEVEL; - IsLanding = false; - IsTakingOff = false; - IsHovering = false; - IsHoming = false; - Strength = Class->MaxStrength; - NavCom = TARGET_NONE; - SecondaryFacing = PrimaryFacing; - Jitter = 0; - - /* - ** Keep count of the number of units created. Dont track cargo planes as they are created - ** automatically, not bought. - */ - if (classid != AIRCRAFT_CARGO && GameToPlay == GAME_INTERNET){ - House->AircraftTotals->Increment_Unit_Total((int)classid); - } - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Add(this); -#endif -} - - -/*********************************************************************************************** - * AircraftClass::Unlimbo -- Removes an aircraft from the limbo state. * - * * - * This routine is used to transition the aircraft from the limbo to the non limbo state. * - * It occurs when the aircraft is placed on the map for whatever reason. When it is * - * unlimboed, only then will normal game processing recognize it. * - * * - * INPUT: coord -- The coordinate that the aircraft should appear at. * - * * - * dir -- The direction it should start facing. * - * * - * strength (optional) -- sets initial strength * - * * - * mission (optional) -- sets initial mission * - * * - * OUTPUT: bool; Was the aircraft unlimboed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Unlimbo(COORDINATE coord, DirType dir) -{ - Validate(); - if (FootClass::Unlimbo(coord, dir)) { - - /* - ** Ensure that the owning house knows about the - ** new object. - */ - House->AScan |= (1L << Class->Type); - House->ActiveAScan |= (1L << Class->Type); - - /* - ** Forces the body of the helicopter to face the correct direction. - */ - SecondaryFacing = dir; - - /* - ** Start rotor animation. - */ - Set_Rate(1); - Set_Stage(0); - - /* - ** Presume it starts in flight? - */ - if (Altitude == FLIGHT_LEVEL) { - Set_Speed(0xFF); - } else { - Set_Speed(0); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * AircraftClass::Draw_It -- Renders an aircraft object at the location specified. * - * * - * This routine is used to display the aircraft object at the coordinates specified. * - * The tactical map display uses this routine for all aircraft rendering. * - * * - * INPUT: x,y -- The coordinates to render the aircraft at. * - * * - * window -- The window that the coordinates are based upon. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - void const * shapefile; // Working shape file pointer. - int shapenum = 0; - int facing = Facing_To_32(SecondaryFacing); - - - /* - ** Verify the legality of the unit class. - */ - shapefile = Class->Get_Image_Data(); - if (!shapefile) return; - shapenum = UnitClass::BodyShape[facing]; - - /* - ** The orca attack helicopter uses a special shape set when it is travelling - ** forward above a certain speed. - */ - if (*this == AIRCRAFT_ORCA && Get_Speed() >= MPH_MEDIUM_FAST) { - shapenum += 32; - } - - /* - ** If there is a door on this aircraft (Chinook), then adjust the - ** shape number to match the door open state. - */ - if (!Is_Door_Closed()) { - shapenum = 32 + Door_Stage(); - } - - /* - ** Helicopters that are flying have a "bobbing" effect. - */ - int jitter = 0; - if (Altitude == FLIGHT_LEVEL && !Class->IsFixedWing) { - Jitter++; - - static int _jitter[] = {0,0,0,0,1,1,1,0,0,0,0,0,-1,-1,-1,0}; - jitter = _jitter[Jitter % 16]; - } - - // Virtual window needs to draw the body first so it's considered the primary object and the shadow is a sub-object - if (window == WINDOW_VIRTUAL) { - /* - ** Draw the root body of the unit. - */ - Techno_Draw_Object(shapefile, shapenum, x, (y - Altitude) + jitter, window); - - /* - ** Special manual shadow draw code. - */ - if (Visual_Character() <= VISUAL_DARKEN) { - CC_Draw_Shape(this, shapefile, shapenum, x + 1, y + 2, window, SHAPE_PREDATOR | SHAPE_CENTER | SHAPE_WIN_REL | SHAPE_FADING, Map.FadingShade, NULL); - } - } else { - /* - ** Special manual shadow draw code. - */ - if (Visual_Character() <= VISUAL_DARKEN) { - CC_Draw_Shape(this, shapefile, shapenum, x+1, y+2, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, Map.FadingShade, NULL); - } - - /* - ** Draw the root body of the unit. - */ - Techno_Draw_Object(shapefile, shapenum, x, (y-Altitude)+jitter, window); - } - - /* - ** Draw rotor effects. The rotor art can be either generic or custom. Custom rotor - ** art has a different rotor set for each facing. Rotor shapes occur after the first - ** 32 shapes of the helicopter body. - */ - if (Class->IsRotorEquipped) { - ShapeFlags_Type flags = SHAPE_CENTER|SHAPE_WIN_REL; - - /* - ** The rotor shape number depends on whether the helicopter is idling - ** or not. A landed helicopter uses slow moving "idling" blades. - */ - if (Altitude == 0) { - shapenum = (Fetch_Stage()%8)+4; - flags = flags | SHAPE_GHOST; - } else { - shapenum = Fetch_Stage()%4; - flags = flags | SHAPE_FADING|SHAPE_PREDATOR; - } - - if (*this == AIRCRAFT_TRANSPORT) { - int _stretch[FACING_COUNT] = {8, 9, 10, 9, 8, 9, 10, 9}; - - /* - ** Dual rotors offset along flight axis. - */ - short xx = x; - short yy = y-Altitude; - FacingType face = Dir_Facing(SecondaryFacing); - Move_Point(xx, yy, SecondaryFacing.Current(), _stretch[face]); - //CC_Draw_Shape(Class->RRotorData, shapenum, xx, yy-2, window, flags, NULL, Map.UnitShadow); // 6/18/2019 - ST - CC_Draw_Shape(this, "RROTOR", Class->RRotorData, shapenum, xx, yy - 2, window, flags, NULL, Map.UnitShadow); - - Move_Point(xx, yy, SecondaryFacing.Current()+DIR_S, _stretch[face]*2); - //CC_Draw_Shape(this, Class->LRotorData, shapenum, xx, yy-2, window, flags, NULL, Map.UnitShadow); // 6/18/2019 - ST - CC_Draw_Shape(this, "LROTOR", Class->LRotorData, shapenum, xx, yy - 2, window, flags, NULL, Map.UnitShadow); - - } else { - - /* - ** Single rotor centered about shape. - */ - //CC_Draw_Shape(this, Class->RRotorData, shapenum, x, (y-Altitude)-2, window, flags, NULL, Map.UnitShadow); // 6/18/2019 - ST - CC_Draw_Shape(this, "RROTOR", Class->RRotorData, shapenum, x, (y - Altitude) - 2, window, flags, NULL, Map.UnitShadow); - } - } - - FootClass::Draw_It(x, y-Altitude, window); -} - - -/*********************************************************************************************** - * AircraftClass::Read_INI -- Reads aircraft object data from an INI file. * - * * - * This routine is used to read the aircraft object data from the INI file buffer * - * specified. This is used by the scenario loader code to interpret the INI file and * - * create the specified objects therein. * - * * - * INPUT: buffer -- Pointer to the INI buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Read_INI(char *buffer) -{ - AircraftClass *air; // Working unit pointer. - char *tbuffer; // Accumulation buffer of unit IDs. - HousesType inhouse; // Unit house. - AircraftType classid; // Unit class. - int len; // Length of data in buffer. - char buf[128]; - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - while (*tbuffer != '\0') { - - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - inhouse = HouseTypeClass::From_Name(strtok(buf, ",")); - if (inhouse != HOUSE_NONE) { - classid = AircraftTypeClass::From_Name(strtok(NULL, ",")); - - if (classid != AIRCRAFT_NONE) { - - if (HouseClass::As_Pointer(inhouse) != NULL) { - air = new AircraftClass(classid, inhouse); - if (air) { - COORDINATE coord; - int strength; - DirType dir; - - /* - ** Read the raw data. - */ - strength = atoi(strtok(NULL, ",")); - coord = Cell_Coord((CELL)atoi(strtok(NULL, ","))); - dir = (DirType)atoi(strtok(NULL, ",")); - - if (!Map.In_Radar(Coord_Cell(coord))) { - delete air; - } else { - - air->Strength = Fixed_To_Cardinal(air->Class->MaxStrength, strength); - if (air->Unlimbo(coord, dir)) { - air->Assign_Mission(AircraftClass::Mission_From_Name(strtok(NULL, ",\n\r"))); - } else { - delete air; - } - } - } - } - } - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * AircraftClass::Write_INI -- Writes the current aircraft objects to an INI file. * - * * - * This routine is used to output the current list of aircraft objects to the INI file * - * buffer specified. It is typically used by the scenario editor. * - * * - * INPUT: buffer -- Pointer to the buffer that holds the INI file data. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Write_INI(char *buffer) -{ - int index; - char uname[10]; - char buf[128]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing unit data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Write the unit data out. - */ - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass * unit; - - unit = Aircraft.Ptr(index); - if (!unit->IsInLimbo) { - - sprintf(uname, "%03d", index); - sprintf(buf, "%s,%s,%d,%u,%d,%s", - unit->House->Class->IniName, - unit->Class->IniName, - unit->Health_Ratio(), - Coord_Cell(unit->Coord), - unit->PrimaryFacing.Current(), - MissionClass::Mission_Name(unit->Mission) - ); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Hunt -- Maintains hunt AI for the aircraft. * - * * - * Hunt AI consists of finding a target and attacking it. If there is no target assigned * - * and this unit doesn't automatically hunt for more targets, then it will change * - * mission to a more passive (land and await further orders) type. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of ticks before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Mission_Hunt(void) -{ - Validate(); - if (Class->IsFixedWing) { - if (Class->Primary == WEAPON_NONE && Class->Secondary == WEAPON_NONE) { - Assign_Mission(MISSION_RETREAT); - return(1); - } - enum { - LOOK_FOR_TARGET, - FLY_TO_TARGET, - DROP_BOMBS - }; - switch (Status) { - - /* - ** Acquiring target stage. - */ - case LOOK_FOR_TARGET: - if (Target_Legal(TarCom)) { - Status = FLY_TO_TARGET; - return(1); - } else { - Assign_Target(Greatest_Threat(THREAT_NORMAL)); - - /* - ** If there is no target, then this aircraft should just do its normal thing. - */ - if (!Target_Legal(TarCom)) { - Enter_Idle_Mode(); - } - } - break; - - /* - ** Homing in on target stage. - */ - case FLY_TO_TARGET: - if (Target_Legal(TarCom)) { - IsHoming = true; - if (!PrimaryFacing.Is_Rotating()) { - PrimaryFacing.Set_Desired(Direction(TarCom)); - } - if (Distance(TarCom) < 0x0380) { - IsHoming = false; - Status = DROP_BOMBS; - return(1); - } - } else { - Status = LOOK_FOR_TARGET; - } - break; - - /* - ** Dropping a stream of bombs phase. - */ - case DROP_BOMBS: - if (!Ammo) { - AttacksRemaining--; - if (!AttacksRemaining) { - Assign_Mission(MISSION_RETREAT); - Commence(); - } else { - Ammo = Class->MaxAmmo; - Status = LOOK_FOR_TARGET; - } - } - if (!Target_Legal(TarCom)) { - Status = LOOK_FOR_TARGET; - } else { - Fire_At(TarCom, 0); - Map[::As_Cell(TarCom)].Incoming(Coord, true); - return(5); - } - break; - } - } else { - if (!Ammo) { - Enter_Idle_Mode(); - } else { - Assign_Mission(MISSION_ATTACK); - return(1); -// return(FootClass::Mission_Hunt()); - } - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * AircraftClass::AI -- Processes the normal non-graphic AI for the aircraft. * - * * - * This handles the non-graphic AI processing for the aircraft. This usually entails * - * maintenance and other AI functions. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::AI(void) -{ - Validate(); - /* - ** A Mission change can always occur if the aircraft is landed or flying. - */ - if (!IsLanding && !IsTakingOff) { - Commence(); - } - - FootClass::AI(); - - /* - ** A Mission change can always occur if the aircraft is landed or flying. - */ - if (!IsLanding && !IsTakingOff) { - Commence(); - } - - /* - ** Handle any body rotation at this time. Body rotation can occur even if the - ** flying object is not actually moving. - */ - if (PrimaryFacing.Is_Rotating()) { - if (PrimaryFacing.Rotation_Adjust(Class->ROT)) { - Mark(); - } - } - if (Class->IsFixedWing) { - SecondaryFacing = PrimaryFacing; - } - if (SecondaryFacing.Is_Rotating()) { - if (SecondaryFacing.Rotation_Adjust(Class->ROT)) { - Mark(); - } - } - if (Physics(Coord, PrimaryFacing) != RESULT_NONE) { - Mark(); - } - - /* - ** Perform sighting every so often as controlled by the sight timer. - */ - //if (IsOwnedByPlayer && Class->SightRange && SightTimer.Expired()) { // Changed for multiple player mapping - if (House->IsHuman && Class->SightRange && SightTimer.Expired()) { - Map.Sight_From(House, Coord_Cell(Coord), Class->SightRange, false); - SightTimer = TICKS_PER_SECOND; - } - - /* - ** Handle landing and taking off logic. Helicopters are prime users of this technique. The - ** aircraft will either gain or lose altitude as appropriate. As the aircraft transitions - ** between flying level and ground level, it will be moved into the appropriate render - ** layer. - */ - if (Is_Door_Closed() && (IsLanding || IsTakingOff)) { - Mark(); - LayerType layer = In_Which_Layer(); - - if (IsLanding) { - if (Altitude) Altitude--; - if (!Altitude) { - IsLanding = false; - Set_Speed(0); - if (Target_Legal(NavCom) && As_Techno(NavCom) == Contact_With_Whom()) { - if (In_Radio_Contact() && Transmit_Message(RADIO_IM_IN) != RADIO_ROGER) { - Scatter(0, true); - } - } - } - } - if (IsTakingOff) { - Altitude++; - if (Altitude >= FLIGHT_LEVEL) { - Altitude = FLIGHT_LEVEL; - IsTakingOff = false; - } - } - - /* - ** Make adjustments for altitude by moving from one layer to another as - ** necessary. - */ - if (layer != In_Which_Layer()) { - - /* - ** When the aircraft is about to enter the ground layer, perform on last - ** check to see if it is legal to enter that location. If not, then - ** start the take off process. Let the normal logic handle this - ** change of plans. - */ - bool ok = true; - if (In_Which_Layer() == LAYER_GROUND) { - if (!Is_LZ_Clear(::As_Target(Coord_Cell(Coord)))) { - IsTakingOff = true; - Altitude++; - ok = false; - } - } - - if (ok) { - /* - ** If landing in a cell that already contains an object, then - ** the landing attempt must be aborted. - */ - Map.Remove(this, layer); - Map.Submit(this, In_Which_Layer()); - - /* - ** When the aircraft is close to the ground, it should exist as a ground object. - ** This aspect is controlled by the Place_Down and Pick_Up functions. - */ - if (In_Which_Layer() == LAYER_GROUND) { - Assign_Destination(TARGET_NONE); // Clear the navcom. - Transmit_Message(RADIO_TETHER); - Map.Place_Down(Coord_Cell(Coord), this); - //if (IsOwnedByPlayer) { // Changed for multiple player mapping. ST - 3/6/2019 1:31PM - if (House->IsHuman) { - Map.Sight_From(House, Coord_Cell(Coord), 1, false); - } - } else { - Transmit_Message(RADIO_UNTETHER); - Map.Pick_Up(Coord_Cell(Coord), this); - - /* - ** If the navigation computer is not attached to the object this - ** aircraft is in radio contact with, then assume that radio - ** contact is now superfluous. Break radio contact. - */ - if (In_Radio_Contact() && Target_Legal(NavCom) && NavCom != Contact_With_Whom()->As_Target()) { - Transmit_Message(RADIO_OVER_OUT); - } - } - } - } - } - - /* - ** Always flag the map draw process to occur if there is an aircraft in the view. - ** This ensures that it will be rendered even if there is nothing else that flagged - ** the map to be redrawn. - */ - if (Map.In_View(Coord_Cell(Coord))) { - Map.Flag_To_Redraw(false); - Map.DisplayClass::IsToRedraw = true; - } - - /* - ** When aircraft leave the edge of the map, they might get destroyed. This occurs if the - ** aircraft is a non-player produced unit and it has completed its mission. A transport - ** helicopter that has already delivered reinforcements is a good example of this. - */ - if (!Map.In_Radar(Coord_Cell(Coord))) { - if (Mission == MISSION_RETREAT /*|| (*this == AIRCRAFT_CARGO && !Is_Something_Attached())*/) { - - /* - ** Check to see if there are any civilians aboard. If so, then flag the house - ** that the civilian evacuation trigger event has been fulfilled. - */ - while (Is_Something_Attached()) { - FootClass * obj = Detach_Object(); - if (obj->What_Am_I() == RTTI_INFANTRY && ((InfantryClass *)obj)->Class->IsCivilian && !((InfantryClass *)obj)->IsTechnician) { - House->IsCivEvacuated = true; - } - - /* - ** Transport planes that leave can only be because they carry purchased - ** equipment and must be have their cost refunded. - */ - if (*this == AIRCRAFT_CARGO) { - House->Refund_Money(obj->Class_Of().Cost_Of()); - } - delete obj; - } - Stun(); - Delete_This(); - return; - } - } else { - IsLocked = true; -// House->NewAScan |= (1L << Class->Type); - -#ifdef NEVER - /* - ** Transport helicopters must ensure that their passengers are properly - ** considered "alive" by setting the appropriate scan bits. - */ - FootClass const * foot = Attached_Object(); - while (foot) { - switch (foot->What_Am_I()) { - case RTTI_UNIT: - House->NewUScan |= (1L << ((UnitTypeClass const &)Class_Of()).Type); - break; - - case RTTI_INFANTRY: - House->NewIScan |= (1L << ((InfantryTypeClass const &)Class_Of()).Type); - break; - } - - foot = (FootClass const *)foot->Next; - } -#endif - } -} - - -/*********************************************************************************************** - * AircraftClass::Mark -- Flags cells under the aircraft so that they will be redrawn. * - * * - * This routine is used to flag the cells under the aircraft so that those cells will * - * be redrawn during the next map drawing process. This is a necessary step whenever the * - * aircraft moves or changes shape. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Mark(MarkType mark) -{ - Validate(); - if (FootClass::Mark(mark)) { - Map.Refresh_Cells(Coord_Cell(Coord), Occupy_List()); - Map.Refresh_Cells(Coord_Cell(Coord), Overlap_List()); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * AircraftClass::Overlap_List -- Returns with list of cells the aircraft overlaps. * - * * - * When aircraft are flying, they can overlap quite a number of cells. These cells can * - * be determined from the coordinate where the aircraft is centered and the size of the * - * aircraft's shape. Landed aircraft are a special case and are usually much smaller * - * than when flying. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to a cell offset list that specifies all cells that * - * the aircraft overlaps given the aircraft's current state. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - *=============================================================================================*/ -short const *AircraftClass::Overlap_List(void) const -{ - Validate(); - static short const _list[] = { - -(MAP_CELL_W-1), -MAP_CELL_W, -(MAP_CELL_W+1), - -1, 0, 1, - (MAP_CELL_W-1), MAP_CELL_W, (MAP_CELL_W+1), - -((MAP_CELL_W*2)-1), -(MAP_CELL_W*2), -((MAP_CELL_W*2)+1), - -((MAP_CELL_W*3)-1), -(MAP_CELL_W*3), -((MAP_CELL_W*3)+1), - REFRESH_EOL - }; - - if (Altitude) { - return(_list); - //return Coord_Spillage_List(Coord, 25); - } - return(Class->Overlap_List()); -} - - -/*********************************************************************************************** - * AircraftClass::Init -- Initialize the aircraft system to an empty state. * - * * - * This routine is used to clear out the aircraft allocation system. It is called in * - * preparation for a scenario load or save game load. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Init(void) -{ - AircraftClass *ptr; - - Aircraft.Free_All(); - - ptr = new AircraftClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Unload -- Handles unloading cargo. * - * * - * This function is used to handle finding, heading toward, landing, and unloading the * - * cargo from the aircraft. Once unloading of cargo has occurred, then the aircraft follows * - * a different mission. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of game ticks to delay before calling this function again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/31/94 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Mission_Unload(void) -{ - Validate(); - if (Class->IsFixedWing) { - enum { - PICK_AIRSTRIP, - FLY_TO_AIRSTRIP, - BUG_OUT - }; - - switch (Status) { - - /* - ** Find a suitable airfield to land at. - */ - case PICK_AIRSTRIP: - if (!Target_Legal(NavCom) || !In_Radio_Contact()) { - - BuildingClass * target_building = As_Building(NavCom); - BuildingClass * building = (target_building != NULL && *target_building == STRUCT_AIRSTRIP) ? target_building : Find_Docking_Bay(STRUCT_AIRSTRIP, false); - if (building) { - if (Transmit_Message(RADIO_HELLO, building) == RADIO_ROGER) { - Set_Speed(0xFF); - Assign_Destination(building->As_Target()); - if (Team) { - Team->Target = NavCom; - } - Status = FLY_TO_AIRSTRIP; - } - } - - /* - ** If a suitable airfield could not be found, then just randomly change - ** direction and then try again later. - */ - if (Status == PICK_AIRSTRIP) { - - /* - ** If there are no more airstrips, regardless of busy state, then - ** abort this transport plane completely. - */ - if (!(House->ActiveBScan & STRUCTF_AIRSTRIP)) { - Assign_Mission(MISSION_RETREAT); - } - - /* - ** Pick a new direction and fly off. - */ - PrimaryFacing.Set_Desired(Random_Pick(DIR_N, DIR_MAX)); - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - return(TICKS_PER_SECOND*3); - } - } else { - Status = FLY_TO_AIRSTRIP; - } - break; - - /* - ** Home in on target. When close enough, drop the cargo. - */ - case FLY_TO_AIRSTRIP: - if (!Target_Legal(NavCom) || !In_Radio_Contact()) { - Status = PICK_AIRSTRIP; - } else { - - /* - ** If, for some reason, there is no cargo, then don't stick around. - */ - if (!Is_Something_Attached()) { - Status = BUG_OUT; - return(1); - } - - if (!PrimaryFacing.Is_Rotating()) { - PrimaryFacing.Set_Desired(Direction(As_Movement_Coord(NavCom))); - } - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - - int navdist = Distance(As_Movement_Coord(NavCom)); - Altitude = FLIGHT_LEVEL; - if (navdist < 0x0600) { - Altitude = Fixed_To_Cardinal(FLIGHT_LEVEL, Cardinal_To_Fixed(0x0600, navdist)); - } - - if (navdist < 0x0080) { - FootClass * unit = (FootClass *)Detach_Object(); - - if (unit) { - CELL cell = Contact_With_Whom()->Find_Exit_Cell(unit); - if (cell) { - ScenarioInit++; - if (!unit->Unlimbo(Cell_Coord(cell))) { - Attach(unit); - } else { - - /* - ** Cargo planes announce reinforcements when they unload - ** their cargo. - */ - if (*this == AIRCRAFT_CARGO && House == PlayerPtr) { - Speak(VOX_REINFORCEMENTS, NULL, Cell_Coord(cell)); - } - unit->IsALoaner = false; - unit->IsLocked = true; - unit->Scatter(0, true); - } - ScenarioInit--; - - Transmit_Message(RADIO_OVER_OUT); - Assign_Target(TARGET_NONE); - } else { - Attach(unit); - } - -// if (Is_Something_Attached()) { -// Status = PICK_AIRSTRIP; -// } else { - Status = BUG_OUT; -// } - } else { - Status = BUG_OUT; - } - } - return(1); - } - break; - - /* - ** All cargo unloaded, head off the map. - */ - case BUG_OUT: - Assign_Mission(MISSION_RETREAT); - return(1); - } - - } else { - enum { - SEARCH_FOR_LZ, - FLY_TO_LZ, - LAND_ON_LZ, - UNLOAD_PASSENGERS, - TAKE_OFF, - }; - - switch (Status) { - - /* - ** Search for an appropriate destination spot if one isn't already assigned. - */ - case SEARCH_FOR_LZ: - if (Altitude == 0 && (Target_Legal(NavCom) || Coord == As_Coord(NavCom))) { - Status = UNLOAD_PASSENGERS; - } else { - if (!Is_LZ_Clear(NavCom)) { - Assign_Destination(New_LZ(::As_Target(Waypoint[WAYPT_REINF]))); - } else { - if (Altitude == FLIGHT_LEVEL) { - Status = FLY_TO_LZ; - } else { - Status = TAKE_OFF; - } - } - } - break; - - /* - ** Fly to destination. - */ - case FLY_TO_LZ: - if (Is_LZ_Clear(NavCom)) { - int distance = Process_Fly_To(true); - - if (distance < 0x0100) { - SecondaryFacing.Set_Desired(Pose_Dir()); - - if (distance < 0x0010) { - Status = LAND_ON_LZ; - } - return(1); - } else { - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - return(5); - } - } else { - Status = SEARCH_FOR_LZ; - } - break; - - /* - ** Landing phase. Just delay until landing is complete. At that time, - ** transition to the unloading phase. - */ - case LAND_ON_LZ: - if (IsTakingOff) { - Status = TAKE_OFF; - } else { - if (Process_Landing()) { - Status = UNLOAD_PASSENGERS; - } - } - return(1); - - /* - ** Hold while unloading passengers. When passengers are unloaded the order for this - ** transport gets changed to MISSION_RETREAT. - */ - case UNLOAD_PASSENGERS: - if (!IsTethered) { - if (Is_Something_Attached()) { - FootClass * unit = (FootClass *)Detach_Object(); - - /* - ** First thing is to lift the transport off of the map so that the unlimbo - ** process for the passengers is more likely to succeed. - */ - Map.Pick_Up(Coord_Cell(Coord), this); - - if (!Exit_Object(unit)) { - delete unit; - } - - /* - ** Restore the transport back down on the map. - */ - Map.Place_Down(Coord_Cell(Coord), this); - - if (!Is_Something_Attached()) { - Enter_Idle_Mode(); - } - - } else { - - Enter_Idle_Mode(); - } - } - break; - - /* - ** Aircraft is now taking off. Once the aircraft reaches flying altitude then it - ** will either take off or look for another landing spot to try again. - */ - case TAKE_OFF: { - if (Process_Take_Off()) { - if (Is_Something_Attached()) { - Status = SEARCH_FOR_LZ; - - /* - ** Break off radio contact with the helipad it is taking off from. - */ - if (In_Radio_Contact() && Map[Coord_Cell(Coord)].Cell_Building() == Contact_With_Whom()) { - Transmit_Message(RADIO_OVER_OUT); - } - } else { - Enter_Idle_Mode(); - } - } - return(1); - } - } - } - return(10); -} - - -/*********************************************************************************************** - * AircraftClass::Is_LZ_Clear -- Determines if landing zone is free for landing. * - * * - * This routine examines the landing zone (as specified by the target parameter) in order * - * to determine if it is free to be landed upon. Call this routine when it is necessary * - * to double check this. Typically this occurs right before a helicopter lands and also * - * when determining the landing zone in the first place. * - * * - * INPUT: target -- The target that is the "landing zone". * - * * - * OUTPUT: bool; Is the landing zone clear for landing? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/31/94 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Is_LZ_Clear(TARGET target) const -{ - Validate(); - if (!Target_Legal(target)) return(false); - CELL cell = ::As_Cell(target); - if (!Map.In_Radar(cell)) return(false); - - ObjectClass * object = Map[cell].Cell_Object(); - if (object) { - if (object == this) return(true); - - if (In_Radio_Contact() && Contact_With_Whom() == object) { - return(true); - } - return(false); - } - - if (!Map[cell].Is_Generally_Clear()) return(false); - - return(true); -} - - -/*********************************************************************************************** - * AircraftClass::In_Which_Layer -- Determine which render layer the aircraft lies. * - * * - * This routine is used to figure out which rendering layer the aircraft is located in. * - * It can be determined from the aircraft's height. The layer value is used to handle the * - * display sequence. Objects in lower layers appear beneath objects in higher layers. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the layer that the aircraft is currently located in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/01/1994 JLB : Created. * - *=============================================================================================*/ -LayerType AircraftClass::In_Which_Layer(void) const -{ - Validate(); - if (Class->IsFixedWing) return(LAYER_TOP); - - if (Altitude < FLIGHT_LEVEL - (FLIGHT_LEVEL/3)) { - return(LAYER_GROUND); - } - return(LAYER_TOP); -} - - -/*********************************************************************************************** - * AircraftClass::Sort_Y -- Figures the sorting coordinate. * - * * - * This routine is used to determine the coordinate to use for sorting the aircraft. This * - * sorting value is used when the aircraft is on the ground. At that time the aircraft * - * must be rendered in proper relationship to the other ground objects. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate to use when sorting the aircraft with other ground * - * objects. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/02/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE AircraftClass::Sort_Y(void) const -{ - Validate(); - return(Coord_Add(Coord, 0x00800000L)); -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Retreat -- Handles the aircraft logic for leaving the battlefield. * - * * - * This mission will be followed when the aircraft decides that it is time to leave the * - * battle. Typically, this occurs when a loaner transport has dropped off its load or when * - * an attack air vehicle has expended its ordinance. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game ticks to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - * 08/13/1995 JLB : Handles aircraft altitude gain after takeoff logic. * - *=============================================================================================*/ -int AircraftClass::Mission_Retreat(void) -{ - Validate(); - if (Class->IsFixedWing) { - if (Class->IsFixedWing && Altitude < FLIGHT_LEVEL) { - Altitude++; - return(3); - } - return(TICKS_PER_SECOND*10); - } - - enum { - TAKE_OFF, - FACE_MAP_EDGE, - KEEP_FLYING - }; - switch (Status) { - - /* - ** Take off if landed. - */ - case TAKE_OFF: - if (Process_Take_Off()) { - Status = FACE_MAP_EDGE; - } - return(1); - - /* - ** Set facing and speed toward the friendly map edge. - */ - case FACE_MAP_EDGE: - Set_Speed(0xFF); - - /* - ** Take advantage of the fact that the source map edge enumerations happen to - ** occur in a clockwise order and are the first four enumerations of the map - ** edge default for the house. If this value is masked and then shifted, a - ** normalized direction value results. Use this value to head the aircraft - ** toward the "friendly" map edge. - */ - PrimaryFacing.Set_Desired((DirType)((House->Edge & 0x03) << 6)); - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - Status = KEEP_FLYING; - break; - - /* - ** Just do nothing since we are headed toward the map edge. When the edge is - ** reached, the aircraft should be automatically eliminated. - */ - case KEEP_FLYING: - break; - - default: - break; - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * AircraftClass::Exit_Object -- Unloads passenger from aircraft. * - * * - * This routine is called when the aircraft is to unload a passenger. The passenger must * - * be able to move under its own power. Typical situation is when a transport helicopter * - * is to unload an infantry unit. * - * * - * INPUT: unit -- Pointer to the unit that is to be unloaded from this aircraft. * - * * - * OUTPUT: bool; Was the unit unloaded successfully? * - * * - * WARNINGS: The unload process is merely started by this routine. Radio contact is * - * established with the unloading unit and when the unit is clear of the aircraft * - * the radio contact will be broken and then the aircraft is free to pursue * - * other. * - * * - * HISTORY: * - * 01/10/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Exit_Object(TechnoClass * unit) -{ - Validate(); - static FacingType _toface[FACING_COUNT] = {FACING_S, FACING_SW, FACING_SE, FACING_NW, FACING_NE, FACING_N, FACING_W, FACING_E}; - CELL cell; - - /* - ** Find a free cell to drop the unit off at. - */ - FacingType face; - for (face = FACING_N; face < FACING_COUNT; face++) { - cell = Adjacent_Cell(Coord_Cell(Coord), _toface[face]); - if (unit->Can_Enter_Cell(cell) == MOVE_OK) break; - } - - // Should perform a check here to see if no cell could be found. - - /* - ** If the passenger can be placed on the map, then start it moving toward the - ** destination cell and establish radio contact with the transport. This is used - ** to make sure that the transport waits until the passenger is clear before - ** unloading the next passenger or taking off. - */ - if (unit->Unlimbo(Coord, Facing_Dir(_toface[face]))) { - unit->Assign_Mission(MISSION_MOVE); - unit->Assign_Destination(::As_Target(cell)); - if (Transmit_Message(RADIO_HELLO, unit) == RADIO_ROGER) { - Transmit_Message(RADIO_UNLOAD); - } - unit->Look(false); - return(1); - } - return(0); -} - - -/*********************************************************************************************** - * AircraftClass::Fire_At -- Handles firing a projectile from an aircraft. * - * * - * Sometimes, aircraft firing needs special handling. Example: for napalm bombs, the * - * bomb travels forward at nearly the speed of the delivery aircraft, not necessarily the * - * default speed defined in the BulletTypeClass structure. * - * * - * INPUT: target -- The target that the projectile is heading for. * - * * - * which -- Which weapon to use in the attack. 0=primary, 1=secondary. * - * * - * OUTPUT: Returns with a pointer to the bullet that was created as a result of this attack. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -BulletClass * AircraftClass::Fire_At(TARGET target, int which) -{ - Validate(); - BulletClass * bullet = FootClass::Fire_At(target, which); - - if (bullet) { - - /* - ** Aircraft reveal when firing - */ - HouseClass *player = HouseClass::As_Pointer(Owner()); - if (player != nullptr && player->IsHuman) { - Map.Sight_From(player, Coord_Cell(Center_Coord()), 1, false); - } - - /* - ** Play the sound effect associated with this weapon. - */ - WeaponTypeClass const * weapon = (which == 0) ? &Weapons[Class->Primary] : &Weapons[Class->Secondary]; - Sound_Effect(weapon->Sound, Coord); - - - /* - ** Falling bullets move at a speed proportionate to the delivery craft. - */ - if (bullet->Class->IsDropping) { - bullet->Fly_Speed(40, bullet->Class->MaxSpeed); - } - } - return(bullet); -} - - -/*********************************************************************************************** - * AircraftClass::Take_Damage -- Applies damage to the aircraft. * - * * - * This routine is used to apply damage to the specified aircraft. This is where any * - * special crash animation will be initiated. * - * * - * INPUT: damage -- Reference to the damage that will be applied to the aircraft. * - * This value will be filled in with the actual damage that was * - * applied. * - * * - * distance -- Distance from the source of the explosion to this aircraft. * - * * - * warhead -- The warhead type that the damage occurs from. * - * * - * source -- Pointer to the originator of the damage. This can be used so that * - * proper "thank you" can be delivered. * - * * - * OUTPUT: Returns with the result of the damage as it affects this aircraft. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/26/1995 JLB : Created. * - *=============================================================================================*/ -ResultType AircraftClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - Validate(); - ResultType res = RESULT_NONE; - - /* - ** Flying aircraft take half damage. - */ - if (Altitude) { - damage /= 2; - } - - /* - ** In order for a this to be damaged, it must either be a unit - ** with a crew or a sandworm. - */ - res = FootClass::Take_Damage(damage, distance, warhead, source); - - switch (res) { - case RESULT_DESTROYED: - { - Kill_Cargo(source); - Death_Announcement(); - COORDINATE coord = Target_Coord(); - if (!(coord & 0xC000C000L)) { - new AnimClass(ANIM_FBALL1, coord); - } - Delete_This(); - } - break; - - default: - case RESULT_HALF: - break; - } - - return(res); -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Move -- Handles movement mission. * - * * - * This state machine routine is used when an aircraft (usually helicopter) is to move * - * from one location to another. It will handle any necessary take off and landing this * - * may require. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames that should elapse before this routine * - * is called again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Mission_Move(void) -{ - Validate(); - if (Class->IsFixedWing) { - - /* - ** Force aircraft in movement mission into a retreat - ** mission so that it leaves the map. - */ - if (*this == AIRCRAFT_A10) { - Assign_Mission(MISSION_RETREAT); - Commence(); - return(1); - } - - enum { - FLY_TO_AIRSTRIP, - BUG_OUT - }; - switch (Status) { - /* - ** Home in on target. When close enough, drop the cargo. - */ - case FLY_TO_AIRSTRIP: - if (!Target_Legal(NavCom) || !In_Radio_Contact()) { - return(TICKS_PER_SECOND); - } else { - - /* - ** If, for some reason, there is no cargo, then don't stick around. - */ - if (!Is_Something_Attached()) { - Status = BUG_OUT; - return(1); - } - - - if (!PrimaryFacing.Is_Rotating()) { - PrimaryFacing.Set_Desired(Direction(NavCom)); - } - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - if (Distance(NavCom) < 0x0080) { - FootClass * unit = (FootClass *)Detach_Object(); - - if (unit) { - ScenarioInit++; - if (!unit->Unlimbo(Coord_Snap(Contact_With_Whom()->Coord))) { - Attach(unit); - } - ScenarioInit--; - - Transmit_Message(RADIO_OVER_OUT); - Assign_Target(TARGET_NONE); - } - Status = BUG_OUT; - } - } - return(1); - - case BUG_OUT: - return(TICKS_PER_SECOND); - } - return(5); - } - - enum { - VALIDATE_LZ, - TAKE_OFF, - FLY_TO_LZ, - LAND - }; - switch (Status) { - - /* - ** Double check and change LZ if necessary. - */ - case VALIDATE_LZ: - if (!Target_Legal(NavCom)) { - Enter_Idle_Mode(); - } else { - if (!Is_LZ_Clear(NavCom) || !Cell_Seems_Ok(As_Cell(NavCom))) { - Assign_Destination(New_LZ(NavCom)); - } else { - Status = TAKE_OFF; - } - } - break; - - /* - ** Take off if necessary. - */ - case TAKE_OFF: - if (!Target_Legal(NavCom)) { - Status = VALIDATE_LZ; - } else { - if (Process_Take_Off()) { - /* - ** After takeoff is complete, break radio contact with any helipad that this - ** helicopter is taking off from. - */ - if (In_Radio_Contact() && Map[Coord_Cell(Coord)].Cell_Building() == Contact_With_Whom()) { - Transmit_Message(RADIO_OVER_OUT); - } - - Status = FLY_TO_LZ; - } - return(1); - } - break; - - /* - ** Fly toward target. - */ - case FLY_TO_LZ: - if (Is_LZ_Clear(NavCom)) { - int distance = Process_Fly_To(true); - - if (distance < 0x0080) { - if (Target_Legal(TarCom)) { - SecondaryFacing.Set_Desired(Direction(TarCom)); - } else { - SecondaryFacing.Set_Desired(Pose_Dir()); - } - - if (distance < 0x0010) { - Status = LAND; - } - return(1); - } - - SecondaryFacing.Set_Desired(::Direction(Fire_Coord(0), As_Coord(NavCom))); - } else { - Assign_Destination(New_LZ(NavCom)); - if (!Target_Legal(NavCom)) { - Status = LAND; - } - } - return(1); - - /* - ** Land on target. - */ - case LAND: - if (IsTakingOff) { - Assign_Destination(New_LZ(NavCom)); - Status = TAKE_OFF; - } - if (Process_Landing()) { - if (MissionQueue == MISSION_NONE) { - Enter_Idle_Mode(); - } - } - return(1); - } - - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * AircraftClass::Enter_Idle_Mode -- Gives the aircraft an appropriate mission. * - * * - * Use this routine when the mission for the aircraft is in doubt. This routine will find * - * an appropriate mission for the aircraft and dispatch it. * - * * - * INPUT: initial -- Is this called when the unit just leaves a factory or is initially * - * or is initially placed on the map? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/05/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Enter_Idle_Mode(bool ) -{ - Validate(); - MissionType mission = MISSION_GUARD; - if (In_Which_Layer() == LAYER_GROUND) { - if (IsALoaner) { - if (Is_Something_Attached()) { - mission = MISSION_UNLOAD; - } else { - if (Team) { - Team->Remove(this); - } - mission = MISSION_RETREAT; - } - } else { -#ifdef NEVER - if (In_Radio_Contact() && Contact_With_Whom() == Map[Coord_Cell(Coord)].Cell_Techno()) { - Transmit_Message(RADIO_IM_IN); - } -#endif - Assign_Destination(TARGET_NONE); - Assign_Target(TARGET_NONE); - mission = MISSION_GUARD; - } - } else { - if (Is_Something_Attached()) { - if (IsALoaner) { - if (Team) { - mission = MISSION_GUARD; - } else { - mission = MISSION_UNLOAD; - Assign_Destination(Good_LZ()); - } - } else { - Assign_Destination(Good_LZ()); - mission = MISSION_MOVE; - } - } else { - - /* - ** If this transport is a loaner and part of a team, then remove it from - ** the team it is attached to. - */ - if (IsALoaner) { - if (Team) { - Team->Remove(this); - } - } - - if (Class->Primary != WEAPON_NONE) { - - /* - ** Weapon equipped helicopters that run out of ammo and were - ** brought in as reinforcements will leave the map. - */ - if (Ammo == 0 && !House->IsHuman && IsALoaner) { - mission = MISSION_RETREAT; - } else { - - /* - ** Normal aircraft try to find a good landing spot to rest. - */ - BuildingClass * building = Find_Docking_Bay(STRUCT_HELIPAD, false); - Assign_Destination(TARGET_NONE); - if (building && Transmit_Message(RADIO_HELLO, building) == RADIO_ROGER) { - mission = MISSION_ENTER; - } else { - Assign_Destination(Good_LZ()); - mission = MISSION_MOVE; - } - } - } else { - if (Team) return; - - Assign_Destination(Good_LZ()); - mission = MISSION_MOVE; - } - } - } - Assign_Mission(mission); - Commence(); -} - - -/*********************************************************************************************** - * AircraftClass::Process_Fly_To -- Handles state machine for flying to destination. * - * * - * This support routine is used when the helicopter is to fly to the destination. It can * - * optionally slow the helicopter down as it approaches the destination. * - * * - * INPUT: slowdown -- Should the aircraft be slowed down when it approaches the dest? * - * * - * OUTPUT: Returns with the distance remaining between the aircraft and the destination. * - * * - * WARNINGS: Because the aircraft can be move at a fast speed, the distance to target value * - * will probably never be zero. The likely case will be that the aircraft * - * overshoots the target. * - * * - * HISTORY: * - * 06/14/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Process_Fly_To(bool slowdown) -{ - Validate(); - COORDINATE coord; - if (Is_Target_Building(NavCom)) { - coord = As_Building(NavCom)->Docking_Coord(); - } else { - coord = As_Coord(NavCom); - } - int distance = Distance(coord); - - PrimaryFacing.Set_Desired(Direction(coord)); - - if (slowdown) { - int speed = MIN(distance, 0x0300); - speed = Bound(speed/3, 0x0020, 0x00FF); - if (Speed != speed) { - Set_Speed(speed); - } - } - - if (distance < 0x0010) { - if (slowdown) { - Set_Speed(0); - } - distance = 0; - } - return(distance); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * AircraftClass::Debug_Dump -- Displays the status of the aircraft to the mono monitor. * - * * - * This displays the current status of the aircraft class to the mono monitor. By this * - * display bugs may be tracked down or prevented. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Debug_Dump(MonoClass *mono) const -{ - Validate(); - mono->Set_Cursor(0, 0); - mono->Print( - "ÚName:ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂMission:ÄÄÄÂTarCom:ÂNavCom:ÂRadio:ÂCoord:ÄÄÂAltitudeÂSt:Ä¿\n" - "³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂNÂYÂHealth:ÄÂFdir:ÂÄBdir:ÄÂSpeed:ÂÄÄÄÄÄÁÄÄÄÄÄÄÂCargo:ÄÄÄÄÁÄÄÄÄ´\n" - "³Active........³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Limbo.........³ ³ ÃÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n" - "³Owned.........³ ³ ³Last Message: ³\n" - "³Discovered....³ ³ ÃTimer:ÂArm:ÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂFlash:ÂStage:ÂTeam:ÄÄÄÄÂArch:´\n" - "³Selected......³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Teathered.....³ ³ ÃÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ\n" - "³Locked on Map.³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³Is A Loaner...³ ³ ³ \n" - "³Is Landing....³ ³ ³ \n" - "³Is Taking Off.³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³Recoiling.....³ ³ ³ \n" - "³To Display....³ ³ ³ \n" - "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÙ \n"); - mono->Set_Cursor(1, 1);mono->Printf("%s:%s", House->Class->IniName, Class->IniName); - mono->Set_Cursor(36, 3);mono->Printf("%02X:%02X", SecondaryFacing.Current(), SecondaryFacing.Desired()); - mono->Set_Cursor(42, 1);mono->Printf("%04X", NavCom); - mono->Set_Cursor(66, 1);mono->Printf("%d", Altitude); - mono->Set_Cursor(44, 3);mono->Printf("%d", Get_Speed()); - mono->Text_Print("X", 16 + (IsLanding?2:0), 12); - mono->Text_Print("X", 16 + (IsTakingOff?2:0), 13); - FootClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * AircraftClass::Active_Click_With -- Handles clicking over specified object. * - * * - * This routine is used when the player clicks over the speicifed object. It will assign * - * the appropriate mission to the aircraft. * - * * - * INPUT: action -- The action that was nominally determined by the What_Action function. * - * * - * object -- The object over which the mouse was clicked. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine will alter the game sequence and causes an event packet to be * - * propogated to all connected machines. * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Active_Click_With(ActionType action, ObjectClass * object) -{ - Validate(); - switch (action) { - case ACTION_ENTER: - Player_Assign_Mission(MISSION_ENTER, TARGET_NONE, object->As_Target()); - break; - - case ACTION_SELF: - Player_Assign_Mission(MISSION_UNLOAD, TARGET_NONE, TARGET_NONE); - break; - - default: - break; - } - FootClass::Active_Click_With(action, object); -} - - -/*********************************************************************************************** - * AircraftClass::Active_Click_With -- Handles clicking over specified cell. * - * * - * This routine is used when the player clicks the mouse of the specified cell. It will * - * assign the appropriate mission to the aircraft. * - * * - * INPUT: action -- The action nominally determined by What_Action(). * - * * - * cell -- The cell over which the mouse was clicked. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine will affect the game sequence and causes an event object to be * - * propogated to all connected machines. * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Active_Click_With(ActionType action, CELL cell) -{ - Validate(); -#ifdef NEVER - switch (action) { - case ACTION_MOVE: - if (Map[cell].IsVisible) { - Player_Assign_Mission(MISSION_MOVE, TARGET_NONE, ::As_Target(cell)); - } - break; - - case ACTION_NOMOVE: - break; - - case ACTION_ATTACK: - Player_Assign_Mission(MISSION_ATTACK, ::As_Target(cell)); - break; - } -#endif - FootClass::Active_Click_With(action, cell); -} - - -/*********************************************************************************************** - * AircraftClass::Player_Assign_Mission -- Handles player input to assign a mission. * - * * - * This routine is called as a result of player input with the intent to change the * - * mission of the aircraft. * - * * - * INPUT: mission -- The mission requested of the aircraft. * - * * - * target -- The value to assign to the aircraft's targeting computer. * - * * - * dest. -- The value to assign to the aircraft's navigation computer. * - * * - * OUTPUT: none * - * * - * WARNINGS: The mission specified will be executed at an indeterminate future game frame. * - * This is controlled by net/modem propogation delay. * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Player_Assign_Mission(MissionType mission, TARGET target, TARGET destination) -{ - Validate(); - if (AllowVoice) { - if (mission == MISSION_ATTACK) { - Response_Attack(); - } else { - Response_Move(); - } - } - Queue_Mission(As_Target(), mission, target, destination); -} - - -/*********************************************************************************************** - * AircraftClass::What_Action -- Determines what action to perform. * - * * - * This routine is used to determine what action will likely be performed if the mouse * - * were clicked over the object specified. The display system calls this routine to * - * control the mouse shape. * - * * - * INPUT: target -- Pointer to the object that the mouse is currently over. * - * * - * OUTPUT: Returns with the action that will occur if the mouse were clicked over the * - * object specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -ActionType AircraftClass::What_Action(ObjectClass * target) const -{ - Validate(); - ActionType action = FootClass::What_Action(target); - - if (action == ACTION_SELF && (!How_Many() || (Altitude > 0) || IsTethered)) { - action = ACTION_NONE; - } - - if (action == ACTION_ATTACK && Class->Primary == WEAPON_NONE) { - action = ACTION_NONE; - } - - //Changed for multiplayer ST - 3/13/2019 5:31PM - //if (IsOwnedByPlayer && House->Is_Ally(target) && target->What_Am_I() == RTTI_BUILDING && ((AircraftClass *)this)->Transmit_Message(RADIO_CAN_LOAD, (TechnoClass*)target) == RADIO_ROGER) { - if (Is_Owned_By_Player() && House->Is_Ally(target) && target->What_Am_I() == RTTI_BUILDING && ((AircraftClass *)this)->Transmit_Message(RADIO_CAN_LOAD, (TechnoClass*)target) == RADIO_ROGER) { - action = ACTION_ENTER; - } - return(action); -} - - -/*********************************************************************************************** - * AircraftClass::What_Action -- Determines what action to perform. * - * * - * This routine will determine what action would occur if the mouse were clicked over the * - * cell specified. The display system calls this routine to determine what mouse shape * - * to use. * - * * - * INPUT: cell -- The cell over which the mouse is currently positioned. * - * * - * OUTPUT: Returns with the action that will be performed if the mouse were clicked at the * - * specified cell location. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -ActionType AircraftClass::What_Action(CELL cell) const -{ - Validate(); - ActionType action = FootClass::What_Action(cell); - - //using function for IsVisible so we have different results for different players - JAS 2019/09/30 - if (action == ACTION_MOVE && !Map[cell].Is_Visible(PlayerPtr)) { - action = ACTION_NOMOVE; - } - - if (action == ACTION_ATTACK && Class->Primary == WEAPON_NONE) { - action = ACTION_NONE; - } - return(action); -} - - -/*********************************************************************************************** - * AircraftClass::Pose_Dir -- Fetches the natural landing facing. * - * * - * Use this routine to get the desired facing the aircraft should assume when landing. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the normal default facing the aircraft should have when landed. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -DirType AircraftClass::Pose_Dir(void) const -{ - Validate(); - if (*this == AIRCRAFT_TRANSPORT) { - return(DIR_N); - } - return(DIR_NE); -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Attack -- Handles the attack mission for aircraft. * - * * - * This routine is the state machine that handles the attack mission for aircraft. It will * - * handling homing in on and firing on the target in the aircraft's targeting computer. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game ticks to pass before this routine must be called * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Mission_Attack(void) -{ - Validate(); - if (Class->IsFixedWing) { - Assign_Mission(MISSION_HUNT); - return(1); - } - - enum { - VALIDATE_AZ, - PICK_ATTACK_LOCATION, - TAKE_OFF, - FLY_TO_POSITION, - FIRE_AT_TARGET, - FIRE_AT_TARGET2, - RETURN_TO_BASE - }; - switch (Status) { - - /* - ** Double check target and validate the attack zone. - */ - case VALIDATE_AZ: - if (!Target_Legal(TarCom)) { - Status = RETURN_TO_BASE; - } else { - Status = PICK_ATTACK_LOCATION; - } - break; - - /* - ** Pick a good location to attack from. - */ - case PICK_ATTACK_LOCATION: - if (!Target_Legal(TarCom)) { - Status = RETURN_TO_BASE; - } else { - Assign_Destination(Good_Fire_Location(TarCom)); - if (Target_Legal(NavCom)) { - Status = TAKE_OFF; - } else { - Status = RETURN_TO_BASE; - } - } - break; - - /* - ** Take off (if necessary). - */ - case TAKE_OFF: - if (!Target_Legal(TarCom)) { - Status = RETURN_TO_BASE; - } else { - if (Process_Take_Off()) { - Status = FLY_TO_POSITION; - - /* - ** Break off radio contact with the helipad it is taking off from. - */ - if (In_Radio_Contact() && Map[Coord_Cell(Coord)].Cell_Building() == Contact_With_Whom()) { - Transmit_Message(RADIO_OVER_OUT); - } - - /* - ** Start flying toward the destination by skewing at first. - ** As the flight progresses, the body will rotate to face - ** the direction of travel. - */ - int diff = SecondaryFacing.Difference(Direction(NavCom)); - diff = Bound(diff, -128, 128); - PrimaryFacing = SecondaryFacing.Current()+diff; - } - return(1); - } - break; - - /* - ** Fly to attack location. - */ - case FLY_TO_POSITION: - if (Target_Legal(TarCom)) { - - /* - ** If the navcom was cleared mysteriously, then try to pick - ** a new attack location. This is a likely event if the player - ** clicks on a new target while in flight to an existing target. - */ - if (!Target_Legal(NavCom)) { - Status = PICK_ATTACK_LOCATION; - return(1); - } - - int distance = Process_Fly_To(true); - - if (distance < 0x0200) { - SecondaryFacing.Set_Desired(Direction(TarCom)); - - if (distance < 0x0010) { - Status = FIRE_AT_TARGET; - Assign_Destination(TARGET_NONE); - } - } else { - SecondaryFacing.Set_Desired(::Direction(Fire_Coord(0), As_Coord(NavCom))); - return(1); - } - } else { - Status = RETURN_TO_BASE; - } - return(1); - - /* - ** Fire at the target. - */ - case FIRE_AT_TARGET: - if (!Target_Legal(TarCom)) { - Status = RETURN_TO_BASE; - return(1); - } - - PrimaryFacing.Set_Desired(Direction(TarCom)); - SecondaryFacing.Set_Desired(Direction(TarCom)); - switch (Can_Fire(TarCom, 0)) { - case FIRE_CLOAKED: - Do_Uncloak(); - break; - - case FIRE_OK: - Fire_At(TarCom, 0); - Map[::As_Cell(TarCom)].Incoming(Coord, true); - Status = FIRE_AT_TARGET2; - break; - - default: - if (!Ammo) { - Status = RETURN_TO_BASE; - } else { - Status = FIRE_AT_TARGET2; - } - break; - } - return(1); - - /* - ** Fire at the target. - */ - case FIRE_AT_TARGET2: - if (!Target_Legal(TarCom)) { - Status = RETURN_TO_BASE; - return(1); - } - - PrimaryFacing.Set_Desired(Direction(TarCom)); - SecondaryFacing.Set_Desired(Direction(TarCom)); - switch (Can_Fire(TarCom, 0)) { - case FIRE_CLOAKED: - Do_Uncloak(); - break; - - case FIRE_REARM: - break; - - case FIRE_OK: - Fire_At(TarCom, 0); - Map[::As_Cell(TarCom)].Incoming(Coord, true); - - if (Ammo) { - Status = PICK_ATTACK_LOCATION; - } else { - Status = RETURN_TO_BASE; - } - break; - - default: - if (!Ammo) { - Status = RETURN_TO_BASE; - } else { - Status = PICK_ATTACK_LOCATION; - } - break; - } - break; - - /* - ** Fly back to landing spot. - */ - case RETURN_TO_BASE: - Assign_Destination(TARGET_NONE); - Enter_Idle_Mode(); - break; - } - - return(TICKS_PER_SECOND/2); -} - - -/*********************************************************************************************** - * AircraftClass::New_LZ -- Find a good landing zone. * - * * - * Use this routine to locate a good landing zone that is nearby the location specified. * - * By using this routine it is possible to assign the same landing zone to several * - * aircraft and they will land nearby without conflict. * - * * - * INPUT: oldlz -- Target value of desired landing zone (usually a cell target value). * - * * - * OUTPUT: Returns with the new good landing zone. It might be the same value passed in. * - * * - * WARNINGS: The landing zone might be a goodly distance away from the ideal if there is * - * extensive blocking terrain in the vicinity. * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -TARGET AircraftClass::New_LZ(TARGET oldlz) const -{ - Validate(); - if (Target_Legal(oldlz) && (!Is_LZ_Clear(oldlz) || !Cell_Seems_Ok(As_Cell(oldlz)))) { - COORDINATE coord = As_Coord(oldlz); - - /* - ** Scan outward in a series of concentric rings up to certain distance - ** in cells. - */ - for (int radius = 0; radius < 16; radius++) { - FacingType modifier = Random_Pick(FACING_N, FACING_NW); - CELL lastcell = -1; - - /* - ** Perform a radius scan out from the original center location. Try to - ** find a cell that is allowed to be a legal LZ. - */ - for (FacingType facing = FACING_N; facing < FACING_COUNT; facing++) { - CELL newcell = Coord_Cell(Coord_Move(coord, Facing_Dir(facing+modifier), radius * ICON_LEPTON_W)); - if (Map.In_Radar(newcell)) { - TARGET newtarget = ::As_Target(newcell); - - if (newcell != lastcell && Is_LZ_Clear(newtarget) && Cell_Seems_Ok(newcell)) { - return(newtarget); - } - lastcell = newcell; - } - } - } - } - return(oldlz); -} - - -/*********************************************************************************************** - * AircraftClass::Fire_Coord -- Calculates the point of origin for a bullet. * - * * - * This routine is used to find the exact coordinate where the bullet should appear if * - * fired from this object. * - * * - * INPUT: which -- Which weapon to consider. * - * * - * OUTPUT: Returns with the coordinate of where the projectile will appear if fired. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/15/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE AircraftClass::Fire_Coord(int ) const -{ - Validate(); - return(Coord_Move(Coord_Add(XYP_Coord(0, -Altitude), Coord), SecondaryFacing, 0x040)); -} - - -COORDINATE AircraftClass::Target_Coord(void) const -{ - Validate(); - return(Coord_Add(XYP_Coord(0, -Altitude), Coord)); -} - - -/*********************************************************************************************** - * AircraftClass::Receive_Message -- Handles receipt of radio messages. * - * * - * This routine receives all radio messages directed at this aircraft. It is used to handle * - * all inter-object coordination. Typically, this would be for transport helicopters and * - * other complex landing operations required of helicopters. * - * * - * INPUT: from -- The source of this radio message. * - * * - * message -- The message itself. * - * * - * param -- An optional parameter that may be used to transfer additional * - * data. * - * * - * OUTPUT: Returns with the radio response from the aircraft. * - * * - * WARNINGS: Some radio messages are handled by the base classes. * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -RadioMessageType AircraftClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - Validate(); - switch (message) { - - case RADIO_PREPARED: - if (Target_Legal(TarCom)) return(RADIO_NEGATIVE); - if ((Altitude == 0 && Ammo == Class->MaxAmmo) || (Altitude > 0 && Ammo > 0)) return(RADIO_ROGER); - return(RADIO_NEGATIVE); - - /* - ** Something disasterous has happened to the object in contact with. Fall back - ** and regroup. This means that any landing process is immediately aborted. - */ - case RADIO_RUN_AWAY: - if (IsLanding) { - IsLanding = false; - IsTakingOff = true; - } - Scatter(0, true); - break; - - /* - ** The ground control requests that this specified landing spot be used. - */ - case RADIO_MOVE_HERE: - FootClass::Receive_Message(from, message, param); - if (Is_Target_Building(param)) { - if (Transmit_Message(RADIO_CAN_LOAD, As_Techno(param)) != RADIO_ROGER) { - return(RADIO_NEGATIVE); - } - Assign_Mission(MISSION_ENTER); - Assign_Destination((TARGET)param); - } else { - Assign_Mission(MISSION_MOVE); - Assign_Destination((TARGET)param); - } - Commence(); - return(RADIO_ROGER); - - /* - ** Ground control is requesting if the aircraft requires navigation direction. - */ - case RADIO_NEED_TO_MOVE: - FootClass::Receive_Message(from, message, param); - if (!Target_Legal(NavCom) && !IsTakingOff && !IsLanding) { - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - - /* - ** This message is sent by the passenger when it determines that it has - ** entered the transport. - */ - case RADIO_IM_IN: - if (How_Many() == Class->Max_Passengers()) { - Close_Door(5, 4); - } - - /* - ** If a civilian has entered the transport, then the transport will immediately - ** fly off the map. - */ - if (from->What_Am_I() == RTTI_INFANTRY && ((InfantryClass *)from)->Class->IsCivilian && !((InfantryClass *)from)->IsTechnician) { - Assign_Mission(MISSION_RETREAT); - } - return(RADIO_ATTACH); - - /* - ** Docking maintenance message received. Check to see if new orders should be given - ** to the impatient unit. - */ - case RADIO_DOCKING: - if (Class->IsTransporter && How_Many() < Class->Max_Passengers()) { - FootClass::Receive_Message(from, message, param); - - if (!IsTethered && !IsLanding && !IsTakingOff && Altitude == 0) { - - Open_Door(5, 4); - - /* - ** If the potential passenger needs someplace to go, then figure out a good - ** spot and tell it to go. - */ - if (Transmit_Message(RADIO_NEED_TO_MOVE, from) == RADIO_ROGER) { - CELL cell; - DirType dir = Desired_Load_Dir(from, cell); - - /* - ** If no adjacent free cells are detected, then passenger loading - ** cannot occur. Break radio contact. - */ - if (cell == 0) { - Transmit_Message(RADIO_OVER_OUT, from); - } else { - param = (long)::As_Target(cell); - - /* - ** Tell the potential passenger where it should go. If the passenger is - ** already at the staging location, then tell it to move onto the transport - ** directly. - */ - if (Transmit_Message(RADIO_MOVE_HERE, param, from) == RADIO_YEA_NOW_WHAT) { - param = (long)As_Target(); - Transmit_Message(RADIO_TETHER); - if (Transmit_Message(RADIO_MOVE_HERE, param, from) != RADIO_ROGER) { - Transmit_Message(RADIO_OVER_OUT, from); - } else { - Contact_With_Whom()->Unselect(); - } - } - } - } - } - return(RADIO_ROGER); - } - break; - - /* - ** Asks if the passenger can load on this transport. - */ - case RADIO_CAN_LOAD: - if (!In_Radio_Contact() && Class->IsTransporter && How_Many() < Class->Max_Passengers() && from && House->Class->House == from->Owner() && Altitude == 0) { - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - } - - /* - ** Let the base class take over processing this message. - */ - return(FootClass::Receive_Message(from, message, param)); -} - - -/*********************************************************************************************** - * AircraftClass::Desired_Load_Dir -- Determines where passengers should line up. * - * * - * This routine is used by the transport helicopter to determine the location where the * - * infantry passengers should line up before loading. * - * * - * INPUT: object -- The object that is trying to load up on this transport. * - * * - * -- Reference to the cell that the passengers should move to before the * - * actual load process may begin. * - * * - * OUTPUT: Returns with the direction that the helicopter should face for the load operation. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - * 07/30/1995 JLB : Revamped to scan all adjacent cells. * - *=============================================================================================*/ -DirType AircraftClass::Desired_Load_Dir(ObjectClass * object, CELL & moveto) const -{ - Validate(); - CELL center = Coord_Cell(Center_Coord()); - for (int sweep = FACING_N; sweep < FACING_S; sweep++) { - moveto = Adjacent_Cell(center, FACING_S+sweep); - if (Map.In_Radar(moveto) && (Coord_Cell(object->Center_Coord()) == moveto || Map[moveto].Is_Generally_Clear())) return(DIR_N); - - moveto = Adjacent_Cell(center, FACING_S-sweep); - if (Map.In_Radar(moveto) && (Coord_Cell(object->Center_Coord()) == moveto || Map[moveto].Is_Generally_Clear())) return(DIR_N); - } - return(DIR_N); -} - - -/*********************************************************************************************** - * AircraftClass::Process_Take_Off -- State machine support for taking off. * - * * - * This routine is used by the main game state machine processor. This utility routine * - * handles a helicopter as it transitions from landed to flying state. * - * * - * INPUT: none * - * * - * OUTPUT: Has the helicopter reached flight level now? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Process_Take_Off(void) -{ - Validate(); - IsLanding = false; - IsTakingOff = true; - switch (Altitude) { - case 0: - Close_Door(5, 4); - PrimaryFacing = SecondaryFacing; - break; - - case FLIGHT_LEVEL/2: - PrimaryFacing.Set_Desired(Direction(NavCom)); - break; - - case FLIGHT_LEVEL-(FLIGHT_LEVEL/3): - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - Set_Speed(0x20); - break; - - case FLIGHT_LEVEL-(FLIGHT_LEVEL/5): - Set_Speed(0x40); - break; - - case FLIGHT_LEVEL: - Set_Speed(0xFF); - IsTakingOff = false; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * AircraftClass::Process_Landing -- Landing process state machine handler. * - * * - * This is a support routine that is called by the main state machine routines. This * - * routine is responsible for handling the helicopter as it transitions from flight to * - * landing. * - * * - * INPUT: none * - * * - * OUTPUT: Has the helicopter completely landed now? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Process_Landing(void) -{ - Validate(); - IsTakingOff = false; - IsLanding = true; - switch (Altitude) { - case 0: - IsLanding = false; - return(true); - - case FLIGHT_LEVEL/2: - Set_Speed(0); - break; - - case FLIGHT_LEVEL: - break; - } - return(false); -} - - -/*********************************************************************************************** - * AircraftClass::Can_Enter_Cell -- Determines if the aircraft can land at this location. * - * * - * This routine is used when the passability of a cell needs to be determined. This is * - * necessary when scanning for a location that the aircraft can land. * - * * - * INPUT: cell -- The cell location to check for landing. * - * * - * OUTPUT: Returns a value indicating if the cell is a legal landing spot or not. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - *=============================================================================================*/ -MoveType AircraftClass::Can_Enter_Cell(CELL cell, FacingType ) const -{ - Validate(); - if (!Map.In_Radar(cell)) return(MOVE_NO); - - CellClass * cellptr = &Map[cell]; - - if (!cellptr->Is_Generally_Clear(true)) return(MOVE_NO); - - if (GameToPlay == GAME_NORMAL && IsOwnedByPlayer && !cellptr->Is_Visible(PlayerPtr)) return(MOVE_NO); - - return(MOVE_OK); -} - - -/*********************************************************************************************** - * AircraftClass::Good_Fire_Location -- Searches for and finds a good spot to fire from. * - * * - * Given the specified target, this routine will locate a good spot for the aircraft to * - * fire at the target. * - * * - * INPUT: target -- The target that is desired to be attacked. * - * * - * OUTPUT: Returns with the target location of the place that firing should be made from. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - * 06/14/1995 JLB : Finer resolution on ring scan. * - *=============================================================================================*/ -TARGET AircraftClass::Good_Fire_Location(TARGET target) const -{ - Validate(); - if (Target_Legal(target)) { - int range = Weapon_Range(0); - COORDINATE tcoord = As_Coord(target); - CELL bestcell = 0; - CELL best2cell = 0; - int bestval = -1; - int best2val = -1; - - for (int r = range-0x0180; r > 0x0180; r -= 0x0100) { - for (int face = 0; face < 255; face += 16) { - COORDINATE newcoord = Coord_Move(tcoord, (DirType)face, r); - CELL newcell = Coord_Cell(newcoord); - - if (Map.In_Radar(newcell) && (GameToPlay != GAME_NORMAL || Map[newcell].Is_Visible(PlayerPtr)) && Cell_Seems_Ok(newcell, true)) { - int dist = Distance(newcoord); - if (bestval == -1 || dist < bestval) { - best2val = bestval; - best2cell = bestcell; - bestval = dist; - bestcell = newcell; - } - } - } - if (bestval != -1) break; - } - - if (best2val == -1) { - best2cell = bestcell; - } - - /* - ** If it found a good firing location, then return this location as - ** a target value. - */ - if (bestval != -1) { - if (Random_Pick(0, 1) == 0) { - return(::As_Target(bestcell)); - } else { - return(::As_Target(best2cell)); - } - } - } - return(TARGET_NONE); -} - - -/*********************************************************************************************** - * AircraftClass::Cell_Seems_Ok -- Checks to see if a cell is good to enter. * - * * - * This routine examines the navigation computers of other aircraft in order to see if the * - * specified cell is safe to fly to. The intent of this routine is to avoid unneccessary * - * mid-air collisions. * - * * - * INPUT: cell -- The cell to examine for clear airspace. * - * * - * strict -- Should the scan consider the aircraft, that is making this check, a * - * blocking aircraft. Typically, the aircraft itself is not considered * - * a blockage -- an aircraft can always exist where it is currently * - * located. A strict check is useful for helicopters that need to move * - * around at the slightest provocation. * - * * - * OUTPUT: Is the specified cell free from airspace conflicts? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Cell_Seems_Ok(CELL cell, bool strict) const -{ - Validate(); - /* - ** Make sure that no other aircraft are heading to the selected location. If they - ** are, then don't consider the location as valid. - */ - TARGET astarget = ::As_Target(cell); - bool ok = true; - for (int index = 0; index < Aircraft.Count(); index++) { - AircraftClass * air = Aircraft.Ptr(index); - if (air && (strict || air != this) && !air->IsInLimbo) { - if (Coord_Cell(air->Coord) == cell || air->NavCom == astarget) { - return(false); - } - } - } - return(true); -} - - -/*********************************************************************************************** - * AircraftClass::Pip_Count -- Returns the number of "objects" in aircraft. * - * * - * This routine is used by the render logic to draw the little container "pips". This * - * corresponds to the number of passengers for a transport helicopter or the number of * - * shots remaining for an attack helicopter. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of "pips" to render on the aircraft. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/11/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Pip_Count(void) const -{ - Validate(); - int retval = 0; - - if (Class->IsTransporter) { - retval = How_Many(); - } else { - if (Ammo) { - retval = Cardinal_To_Fixed(Class->MaxAmmo, Ammo); - retval = Fixed_To_Cardinal(Class->Max_Pips(), retval); - if (!retval) retval = 1; - } - } - return(retval); -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Enter -- Control aircraft to fly to the helipad or repair center. * - * * - * This routine is used when the aircraft needs to fly for either rearming or repairing. * - * It tries to establish contact with the support building. Once contact is established * - * the ground controller takes care of commanding the aircraft. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before this routine should be called again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - * 07/04/1995 JLB : Ground controller gives orders. * - *=============================================================================================*/ -int AircraftClass::Mission_Enter(void) -{ - Validate(); - enum { - INITIAL, - TAKEOFF, - ALTITUDE, - TRAVEL, - LANDING - }; - switch (Status) { - case INITIAL: - if (Altitude < FLIGHT_LEVEL || IsLanding) { - Status = TAKEOFF; - } else { - Status = ALTITUDE; - } - break; - - case TAKEOFF: - if (Process_Take_Off()) { - /* - ** After takeoff is complete, break radio contact with any helipad that this - ** helicopter is taking off from. - */ - if (In_Radio_Contact() && Map[Coord_Cell(Coord)].Cell_Building() == Contact_With_Whom()) { - Transmit_Message(RADIO_OVER_OUT); - } - Status = ALTITUDE; - } - break; - - case ALTITUDE: - /* - ** Establish radio contact with the building this helicopter is trying - ** to land at. - */ - if (In_Radio_Contact()) { - Status = TRAVEL; - } else { - TechnoClass * tech = As_Techno(NavCom); - if (tech && Transmit_Message(RADIO_CAN_LOAD, tech) == RADIO_ROGER) { - Transmit_Message(RADIO_HELLO, tech); - Transmit_Message(RADIO_DOCKING); - Status = TRAVEL; - } else { - Assign_Destination(TARGET_NONE); - Enter_Idle_Mode(); - } - } - break; - - case TRAVEL: - Transmit_Message(RADIO_DOCKING); - if (!In_Radio_Contact()) { - Assign_Destination(TARGET_NONE); - Enter_Idle_Mode(); - } else { - int distance = Process_Fly_To(true); - - if (distance < 0x0080) { - if (Target_Legal(TarCom)) { - SecondaryFacing.Set_Desired(Direction(TarCom)); - } else { - SecondaryFacing.Set_Desired(Pose_Dir()); - } - - if (distance < 0x0010) { - Status = LANDING; - } - break; - } else { - SecondaryFacing.Set_Desired(::Direction(Fire_Coord(0), As_Coord(NavCom))); - } - return(3); - } - break; - - case LANDING: - if (IsTakingOff) { - Assign_Destination(TARGET_NONE); - Enter_Idle_Mode(); - } - if (Process_Landing()) { - switch (Transmit_Message(RADIO_IM_IN)) { - case RADIO_ROGER: - Assign_Mission(MISSION_GUARD); - break; - - case RADIO_ATTACH: - Limbo(); - Contact_With_Whom()->Attach(this); - break; - - default: - Enter_Idle_Mode(); - } - } - break; - } - return(1); -} - - -/*********************************************************************************************** - * AircraftClass::Good_LZ -- Locates a good spot ot land. * - * * - * This routine is used when helicopters need a place to land, but there are no obvious * - * spots (i.e., helipad) available. It will try to land near a friendly helipad or friendly * - * building if there are no helipads anywhere. In the event that there are no friendly * - * buildings anywhere on the map, then just land right where it is flying. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the target location where this aircraft should land. This value may * - * not be a clear cell, but the normal landing logic will resolve that problem. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - *=============================================================================================*/ -TARGET AircraftClass::Good_LZ(void) const -{ - Validate(); - /* - ** Scan through all of the buildings and try to land near - ** the helipad (if there is one) or the nearest friendly building. - */ - CELL bestcell; - int bestdist = -1; - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && !building->IsInLimbo && building->House == House) { - int dist = Distance(building); - if (*building == STRUCT_HELIPAD) { - dist /= 4; - } - if (bestdist == -1 || dist < bestdist) { - bestdist = dist; - bestcell = Coord_Cell(building->Center_Coord()); - } - } - } - - /* - ** Return with the suitable location if one was found. - */ - if (bestdist != -1) { - return(::As_Target(bestcell)); - } - - /* - ** No good location was found. Just try to land here. - */ - return(::As_Target(Coord_Cell(Coord))); -} - - -/*********************************************************************************************** - * AircraftClass::Set_Speed -- Sets the speed for the aircraft. * - * * - * This routine will set the speed for the aircraft. The speed is specified as a fraction * - * of full speed. * - * * - * INPUT: speed -- The fixed point fractional speed setting. 0x00 is stopped, 0xFF is full * - * speed. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Set_Speed(int speed) -{ - Validate(); - MPHType sp = MPHType(min((unsigned)(Class->MaxSpeed * House->AirspeedBias), MPH_LIGHT_SPEED)); - Fly_Speed(speed, sp); -} - - -/*********************************************************************************************** - * AircraftClass::Fire_Direction -- Determines the direction of fire. * - * * - * This routine will determine what direction a projectile would take if it were fired * - * from the aircraft. This is the direction that the aircraft's body is facing. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the direction of projectile fire. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -DirType AircraftClass::Fire_Direction(void) const -{ - Validate(); - return(SecondaryFacing.Current()); -} - - -/*********************************************************************************************** - * AircraftClass::~AircraftClass -- Destructor for aircraft object. * - * * - * This is the destructor for aircraft. It will limbo the aircraft if it isn't already * - * and also removes the aircraft from any team it may be attached to. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 JLB : Created. * - *=============================================================================================*/ -AircraftClass::~AircraftClass(void) -{ - if (GameActive && Class) { - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Remove(this); -#endif - - /* - ** If there are any cargo members, delete them. - */ - while (Is_Something_Attached()) { - delete Detach_Object(); - } - - Limbo(); - } - - if (GameActive && Class && Team) Team->Remove(this); -} - - -/*********************************************************************************************** - * AircraftClass::Scatter -- Causes the aircraft to move away a bit. * - * * - * This routine will cause the aircraft to move away from its current location and then * - * enter some idle mode. Typically this is called when the aircraft is attacked while on * - * the ground. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Scatter(COORDINATE , bool , bool ) -{ - Validate(); - if (IsLanding || Altitude == 0) { - IsLanding = false; - IsTakingOff = true; - } - Enter_Idle_Mode(); -} - - -/*********************************************************************************************** - * AircraftClass::Rearm_Delay -- Returns the delay between shots for this aircraft. * - * * - * Aircraft have a faster rearm delay than their weapon would otherwise indicate. This is * - * necessary to give helicopters a combat edge while still allowing them to share the * - * weapon types used by ground units. * - * * - * INPUT: second -- Is this for the second shot? The second shot uses the full rearm * - * delay. The first shot, if part of a two shot weapon, is given an * - * abbreviated rearm time. * - * * - * OUTPUT: Returns with the game frames to delay before the next shot can fire. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Rearm_Delay(bool second) const -{ - Validate(); - return(FootClass::Rearm_Delay(second)/2); -} - - -/*********************************************************************************************** - * AircraftClass::Threat_Range -- Returns with a range to scan for targets. * - * * - * This routine returns with the distance to scan for targets according to the type of * - * search requested. The search type is typically the weapon (or short) range and vicinity * - * distances. This is used by Guard and Guard Area missions. Aircraft never consider their * - * weapon range in this determination since they can fly so fast, weapon range is * - * meaningless. * - * * - * INPUT: control -- The range control parameter; * - * -1 = range doesn't matter -- return -1 for compatability reasons. * - * 0 = short range scan * - * 1 = long range scan * - * * - * OUTPUT: Returns with the lepton distance to use for the scan operation. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Threat_Range(int control) const -{ - Validate(); - if (control == -1) return(-1); - - int range = 20 * ICON_LEPTON_W; - if (control == 1) { - range *= 2; - } - return(range); -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Guard -- Handles aircraft in guard mode. * - * * - * Aircraft don't like to be in guard mode if in flight. If this situation is detected, * - * then figure out what the aircraft should be doing and go do it. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: This routine typically calls the normal guard logic for ground units. * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Mission_Guard(void) -{ - Validate(); - if (Altitude == FLIGHT_LEVEL) { - - /* - ** If part of a team, then do nothing, since the team - ** handler will take care of giving this aircraft a - ** mission. - */ - if (Team) { - if (Target_Legal(NavCom)) { - Assign_Mission(MISSION_MOVE); - } - return(TICKS_PER_SECOND); - } - - if (Class->Primary == WEAPON_NONE) { - Assign_Destination(::As_Target(Coord_Cell(Coord))); - Assign_Mission(MISSION_MOVE); - } else { - Enter_Idle_Mode(); - } - return(1); - } - if (House->IsHuman) return(TICKS_PER_SECOND); - - /* - ** Special case to force the GDI helicopter to be brain dead in the Nod - ** mission where it is supposed to be captured. - */ - if (GameToPlay == GAME_NORMAL && Scenario == 7 && House->Class->House == HOUSE_GOOD) { - return(TICKS_PER_SECOND*20); - } - - /* - ** If the aircraft is very badly damaged, then it will search for a - ** repair bay first. - */ - if (House->Available_Money() >= 100 && Health_Ratio() <= 0x0080) { - if (!In_Radio_Contact() || - (Altitude == 0 && - (Contact_With_Whom()->What_Am_I() != RTTI_BUILDING || *((BuildingClass *)Contact_With_Whom()) != STRUCT_REPAIR))) { - - - BuildingClass * building = Find_Docking_Bay(STRUCT_REPAIR, true); - if (building) { - Assign_Destination(building->As_Target()); - Assign_Target(TARGET_NONE); - Assign_Mission(MISSION_ENTER); - return(1); - } - } - } - - /* - ** If the aircraft cannot attack anything because of lack of ammo, - ** abort any normal guard logic in order to look for a helipad - ** to rearm. - */ - if (Ammo == 0 && Class->Primary != WEAPON_NONE) { - if (!In_Radio_Contact()) { - BuildingClass * building = Find_Docking_Bay(STRUCT_HELIPAD, false); - if (building) { - Assign_Destination(building->As_Target()); - Assign_Target(TARGET_NONE); - Assign_Mission(MISSION_ENTER); - return(1); - } - } -// return(TICKS_PER_SECOND*3); - } - - /* - ** If the aircraft already has a target, then attack it if possible. - */ - if (Target_Legal(TarCom)) { - Assign_Mission(MISSION_ATTACK); - return(1); - } - - /* - ** Transport helicopters don't really do anything but just sit there. - */ - if (Class->Primary == WEAPON_NONE) { - return(TICKS_PER_SECOND*3); - } - - /* - ** Computer controlled helicopters will defend themselves by bouncing around - ** and looking for a free helipad. - */ - if (Altitude == 0 && !In_Radio_Contact()) { - Scatter(0, true); - return(TICKS_PER_SECOND*3); - } - - return(FootClass::Mission_Guard()); -} - - -/*********************************************************************************************** - * AircraftClass::Mission_Guard_Area -- Handles the aircraft guard area logic. * - * * - * This routine handles area guard logic for aircraft. Aircraft require special handling * - * for this mode since they are to guard area only if they are in a position to do so. * - * Otherwise they just defend themselves. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - *=============================================================================================*/ -int AircraftClass::Mission_Guard_Area(void) -{ - Validate(); - if (Altitude == FLIGHT_LEVEL) { - Enter_Idle_Mode(); - return(1); - } - if (House->IsHuman) return(TICKS_PER_SECOND); - - if (Altitude == 0 && !In_Radio_Contact()) { - Scatter(0, true); - return(TICKS_PER_SECOND*3); - } - - if (Target_Legal(TarCom)) { - Assign_Mission(MISSION_ATTACK); - return(1); - } - return(FootClass::Mission_Guard_Area()); -} - - -/*********************************************************************************************** - * AircraftClass::Response_Attack -- Gives audio response to attack order. * - * * - * This routine is used to give an audio response to an attack order. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Response_Attack(void) -{ - Validate(); - static VocType _response[] = { - VOC_AFFIRM, - VOC_ACKNOWL, - VOC_YESSIR, - VOC_YESSIR, - VOC_YESSIR - }; - VocType response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - if (AllowVoice) { - Sound_Effect(response, 0, -(Aircraft.ID(this)+1)); - } -} - - -/*********************************************************************************************** - * AircraftClass::Response_Move -- Gives audio response to move request. * - * * - * This routine is used to give an audio response to movement orders. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Response_Move(void) -{ - Validate(); - static VocType _response[] = { - VOC_MOVEOUT, - VOC_MOVEOUT, - VOC_MOVEOUT, - VOC_ACKNOWL, - VOC_AFFIRM, - VOC_AFFIRM - }; - VocType response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - if (AllowVoice) { - Sound_Effect(response, 0, -(Aircraft.ID(this)+1)); - } -} - - -/*********************************************************************************************** - * AircraftClass::Response_Select -- Gives audio response when selected. * - * * - * This routine is called when an audio response for selection is desired. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - *=============================================================================================*/ -void AircraftClass::Response_Select(void) -{ - Validate(); - static VocType _response[] = { - VOC_VEHIC, - VOC_UNIT, - VOC_YESSIR, - VOC_YESSIR, - VOC_YESSIR, - VOC_AWAIT - }; - VocType response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - if (AllowVoice) { - Sound_Effect(response, 0, -(Aircraft.ID(this)+1)); - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/AIRCRAFT.H b/code/TIBERIANDAWN/AIRCRAFT.H deleted file mode 100644 index 2f2124d..0000000 --- a/code/TIBERIANDAWN/AIRCRAFT.H +++ /dev/null @@ -1,256 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\aircraft.h_v 2.17 16 Oct 1995 16:47:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : AIRCRAFT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 22, 1994 * - * * - * Last Update : November 28, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef AIRCRAFT_H -#define AIRCRAFT_H - -#include "radio.h" -#include "fly.h" -#include "target.h" - - -class AircraftClass : public FootClass, public FlyClass -{ - public: - /* - ** This is a pointer to the class control structure for the aircraft. - */ - AircraftTypeClass const * const Class; - - //----------------------------------------------------------------------------- - void * operator new(size_t); - void operator delete(void *); - operator AircraftType(void) const {return Class->Type;}; - AircraftClass(void) : Class(0) {}; - AircraftClass(AircraftType classid, HousesType house); - virtual ~AircraftClass(void); - virtual RTTIType What_Am_I(void) const {return RTTI_AIRCRAFT;}; - - static void Init(void); - enum {FLIGHT_LEVEL=24}; - - virtual int Mission_Attack(void); - virtual int Mission_Unload(void); - virtual int Mission_Hunt(void); - virtual int Mission_Retreat(void); - virtual int Mission_Move(void); - virtual int Mission_Enter(void); - virtual int Mission_Guard(void); - virtual int Mission_Guard_Area(void); - - /* - ** State machine support routines. - */ - bool Process_Take_Off(void); - bool Process_Landing(void); - int Process_Fly_To(bool slowdown); - - /* - ** Query functions. - */ - virtual int Threat_Range(int control) const; - virtual int Rearm_Delay(bool second) const; - virtual MoveType Can_Enter_Cell(CELL cell, FacingType facing=FACING_NONE) const; - virtual LayerType In_Which_Layer(void) const; - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - virtual ActionType What_Action(ObjectClass * target) const; - virtual ActionType What_Action(CELL cell) const; - virtual DirType Desired_Load_Dir(ObjectClass * passenger, CELL & moveto) const; - virtual int Pip_Count(void) const; - TARGET Good_Fire_Location(TARGET target) const; - bool Cell_Seems_Ok(CELL cell, bool landing=false) const; - DirType Pose_Dir(void) const; - TARGET Good_LZ(void) const; - virtual DirType Fire_Direction(void) const; - - /* - ** Landing zone support functionality. - */ - bool Is_LZ_Clear(TARGET target) const; - TARGET New_LZ(TARGET oldlz) const; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Sort_Y(void) const; - virtual COORDINATE Fire_Coord(int which) const; - virtual COORDINATE Target_Coord(void) const; - - /* - ** Object entry and exit from the game system. - */ - virtual bool Unlimbo(COORDINATE , DirType facing = DIR_N); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual int Exit_Object(TechnoClass *); - virtual bool Mark(MarkType mark=MARK_CHANGE); - virtual short const * Overlap_List(void) const; - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual void Set_Speed(int speed); - - /* - ** User I/O. - */ - virtual void Active_Click_With(ActionType action, ObjectClass * object); - virtual void Active_Click_With(ActionType action, CELL cell); - virtual void Player_Assign_Mission(MissionType mission, TARGET target=TARGET_NONE, TARGET destination=TARGET_NONE); - virtual void Response_Select(void); - virtual void Response_Move(void); - virtual void Response_Attack(void); - - /* - ** Combat related. - */ -// virtual bool Target_Something_Nearby(ThreatType threat=THREAT_NORMAL); - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source); - virtual BulletClass * Fire_At(TARGET target, int which); - virtual TARGET As_Target(void) const; - - /* - ** AI. - */ - virtual void AI(void); - virtual void Enter_Idle_Mode(bool initial = false); - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual void Scatter(COORDINATE threat, bool forced=false, bool nokidding=false); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static char * INI_Name(void) {return "AIRCRAFT";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - public: - - /* - ** This is the facing used for the body of the aircraft. Typically, this is the same - ** as the PrimaryFacing, but in the case of helicopters, it can be different. - */ - FacingClass SecondaryFacing; - - private: - - /* - ** Aircraft can be in either state of landing, taking off, or in steady altitude. - ** These flags are used to control transition between flying and landing. It is - ** necessary to handle the transition in this manner so that it occurs smoothly - ** during the graphic processing section. - */ - unsigned IsLanding:1; - unsigned IsTakingOff:1; - - /* - ** It is very common for aircraft to be homing in on a target. When this flag is - ** true, the aircraft will constantly adjust its facing toward the TarCom. When the - ** target is very close (one cell away or less), then this flag is automatically cleared. - ** This is because the homing algorithm is designed to get the aircraft to the destination - ** but no more. Checking when this flag is cleared is a way of flagging transition into - ** a new mode. Example: Transport helicopters go into a hovering into correct position - ** mode when the target is reached. - */ - unsigned IsHoming:1; - - /* - ** Helicopters that are about to land must hover into a position exactly above the landing - ** zone. When this flag is true, the aircraft will be adjusted so that it is exactly over - ** the TarCom. The facing of the aircraft is not altered by this movement. The affect - ** like the helicopter is hovering and shifting sideways to position over the landing - ** zone. When the position is over the landing zone, then this flag is set to false. - */ - unsigned IsHovering:1; - - /* - ** This is the jitter tracker to be used when the aircraft is a helicopter and - ** is flying. It is most noticable when the helicopter is hovering. - */ - unsigned char Jitter; - - public: - /* - ** This is the altitude of the aircraft. It is expressed in pixels that - ** the shadow is offset to the south. If the altitude reaches zero, then - ** the aircraft has landed. The altitude for normal aircraft is at - ** Flight_Level(). - */ - int Altitude; - - private: - - /* - ** This timer controls when the aircraft will reveal the terrain around itself. - ** When this timer expires and this aircraft has a sight range, then the - ** look around process will occur. - */ - TCountDownTimerClass SightTimer; - - /* - ** Most attack aircraft can make several attack runs. This value contains the - ** number of attack runs the aircraft has left. When this value reaches - ** zero then the aircraft is technically out of ammo. - */ - char AttacksRemaining; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/ALLOC.CPP b/code/TIBERIANDAWN/ALLOC.CPP deleted file mode 100644 index b1a8c45..0000000 --- a/code/TIBERIANDAWN/ALLOC.CPP +++ /dev/null @@ -1,590 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : ALLOC.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : February 1, 1992 * - * * - * Last Update : March 9, 1995 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Alloc -- Allocates system RAM. * - * Ram_Free -- Determines the largest free chunk of RAM. * - * Free -- Free an Alloc'ed block of RAM. * - * Resize_Alloc -- Change the size of an allocated block. * - * Heap_Size -- Size of the heap we have. * - * Total_Ram_Free -- Total amount of free RAM. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#if (0) - -#include -#include -#include -#include -#include -#include - - -#ifndef WWMEM_H -#include "wwmem.h" -#endif - - -extern "C" unsigned long Largest_Mem_Block ( void ) ; - -// -// use double-word alignment for allocs -// -#define LONG_ALIGNMENT 1 - -/* -** Define the equates necessary to call a DPMI interrupt. -*/ -#define DPMI_INT 0x0031 -#define DPMI_LOCK_MEM 0x0600 -#define DPMI_UNLOCK_MEM 0x0601 -#define LOGGING FALSE -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -unsigned long MinRam=0L; // Record of least memory at worst case. -unsigned long MaxRam=0L; // Record of total allocated at worst case. -static unsigned long TotalRam = 0L; -static unsigned long Memory_Calls = 0L; -static unsigned long RequestedSystemRam = 8*1024*1024; -static unsigned long LargestRamBlock = 0L; - -void (*Memory_Error)(void) = NULL; -void (*Memory_Error_Exit)(char *string) = NULL; - -/*************************************************************************** - * DPMI_LOCK -- handles locking a block of DPMI memory * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/23/1995 PWG : Created. * - *=========================================================================*/ -#include"mono.h" -void DPMI_Lock(VOID const *ptr, long const size) -{ - union REGS regs; - struct SREGS sregs; - - /* - ** Lock memory - ** AX = 0x600 - ** BX:CX = starting linear address of memory to lock - ** SI:DI = size of region to lock (in bytes) - ** - If Failure, carry flag is set. - */ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_LOCK_MEM; - regs.x.ebx = ((long)ptr & 0xffff0000) >> 16; - regs.x.ecx = ((long)ptr & 0x0000ffff); - regs.x.esi = ((long)size & 0xffff0000) >> 16; - regs.x.edi = ((long)size & 0x0000ffff); - int386x (DPMI_INT, ®s, ®s, &sregs); // call DPMI -// if (regs.x.cflag) { -// } -#if(0) - char *temp = (char *)ptr; - char hold; - for (int lp = 0; lp < size; lp += 2048) { - hold = *temp; - temp += 2048; - } -#endif - -} - -/*************************************************************************** - * DPMI_UNLOCK -- Handles unlocking a locked block of DPMI * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/23/1995 PWG : Created. * - *=========================================================================*/ -void DPMI_Unlock(void const *ptr, long const size) -{ - union REGS regs; - struct SREGS sregs; - - /* - ** Unlock the memory - */ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_UNLOCK_MEM; // DPMI function to call - regs.x.ebx = ((long)ptr & 0xffff0000) >> 16; - regs.x.ecx = ((long)ptr & 0x0000ffff); - regs.x.esi = ((long)size & 0xffff0000) >> 16; - regs.x.edi = ((long)size & 0x0000ffff); - int386x (DPMI_INT, ®s, ®s, &sregs); // call DPMI -// if (regs.x.cflag) { -// } - -} - -/*************************************************************************** - * Alloc -- Allocates system RAM. * - * * - * This is the basic RAM allocation function. It is used for all * - * memory allocations needed by the system or the main program. * - * * - * INPUT: bytes_to_alloc -- LONG value of the number of bytes to alloc. * - * * - * flags -- Memory allocation control flags. * - * MEM_NORMAL: No special flags. * - * MEM_CLEAR: Zero out memory block. * - * MEM_NEW: Called by a new. * - * * - * OUTPUT: Returns with pointer to allocated block. If NULL was returned * - * it indicates a failure to allocate. Note: NULL will never be * - * returned if the standard library allocation error routine is * - * used. * - * * - * WARNINGS: If you replace the standard memory allocation error routine * - * and make it so that Alloc CAN return with a NULL, be sure * - * and check for this in your code. * - * * - * HISTORY: * - * 09/03/1991 JLB : Documented. * - * 08/09/1993 JLB : Updated with EMS memory support. * - * 04/28/1994 JAW : Updated to 32bit Protected mode. * - * 03/09/1995 JLB : Fixed * - *=========================================================================*/ -void *Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags) -{ - union REGS regs ; - struct SREGS sregs ; - unsigned char *retval=NULL; // Pointer to allocated block. - unsigned long original_size; // Original allocation size. - unsigned long bytesfree; // Number of free bytes. - long *longptr=NULL; // Pointer used to store selector - static unsigned char _allocinit=0; - - - // - // Init memory system by finding largest block to alloc - // then allocate it to get one large heap and free it. - // There may be more memory available from DPMI but we only are - // for now allocating and freeing the first largest block. - // - if ( !_allocinit ) { - unsigned long largestblock = Largest_Mem_Block(); - largestblock -= 1024; // subtract for heap header and misc - largestblock &= 0xffff0000; // forcing to 64K boundary - - if ( largestblock ) { - LargestRamBlock = MIN( largestblock, RequestedSystemRam ); - unsigned char *lptr = (unsigned char *)malloc( LargestRamBlock ); - if ( lptr ) { - free( (void *)lptr ); - } - } - - /* - ** Initialize the total ram available value. - */ - TotalRam = Total_Ram_Free(MEM_NORMAL); - - _allocinit = 1; - } - - /* - ** Save the original allocated space size so that we can clear the - ** exact amount of RAM if they specified MEM_CLEAR. - */ - original_size = bytes_to_alloc; - - /* - ** Reserve one byte for the header of the memory we allocated. - ** We will store the flags variable there for later use. - */ -#if (LONG_ALIGNMENT) - bytes_to_alloc += (flags & MEM_LOCK) ? 8 : 4; -#else - bytes_to_alloc += (flags & MEM_LOCK) ? 5 : 1; -#endif - - - // Try to allocate the memory out of the protected mode memory - // chain if we did not require a real mode allocation. If this - // fails we will have to try to allocate it out of real mode memory. - // Real mode memory is a last resort because some types of applications - // require real mode memory. - if (!(flags & MEM_REAL)) { - retval = (unsigned char*)malloc(bytes_to_alloc); - } - - // Try to allocate the memory out of the real mode memory using DPMI - // service 0x100. Note that retval will be null if we are requesting - // real mode memory so that we do not have to explicitly check for the - // real mode flag. Remember we need to reserve room for the dos - // selector value at the beginning of our allocated block so rather than - // adding fifteen and rounding, we need to add 19 and round. - if (!retval) { - flags = (MemoryFlagType)(flags | MEM_REAL); - regs.x.eax = 0x100; - regs.x.ebx = (bytes_to_alloc + 19) >> 4; - if (regs.x.ebx & 0xFFFF0000) { - retval = NULL; - } else { - segread ( & sregs ) ; - int386x ( 0x31 , & regs, & regs , & sregs ) ; - if (regs.x.cflag) - retval = NULL; - else { -#if (LONG_ALIGNMENT) - longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 4); -#else - longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 1); -#endif - *longptr++ = regs.x.edx & 0xFFFF; - retval = (unsigned char *)longptr; - } - } - } - - // If the alloc failed then we need to signify a memory error. - if (retval == NULL) { - if (Memory_Error != NULL) - Memory_Error(); - return NULL; - } - - // If the memory needs to be DPMI locked then we should store the - // original size in the header before we store the flags. - if (flags & MEM_LOCK) { - longptr = (long *)retval; - *longptr++ = original_size; - retval = (unsigned char *)longptr; - } - - - // Now that we know the alloc was sucessful (and for an extra byte - // more than the user wanted) we need to stick in the memory flags. -#if (LONG_ALIGNMENT) - if ( !(flags & (MEM_LOCK|MEM_REAL)) ) { - // - // WARNING!!!!!!!!!! - // USE this only with the WATCOM malloc ALLOCATION!!!!!!!!! - // it reads the actual block size before the ptr returned. - // then eors and uses the upper word for a validation later on free. - // - longptr = (long *)retval; - *longptr = ((*(longptr - 1)) ^ 0xffffffff) & 0xffff0000; - *retval++ = flags; - *retval++ = (unsigned char)(flags ^ 0xff); - retval += 2; - } - else { - *retval++ = flags; - *retval++ = (unsigned char)(flags ^ 0xff); - *retval++ = 0; - *retval++ = 0; - } -#else - *retval++ = (unsigned char)(flags | (((flags ^ 0x07) & 0x07) << 5)); -#endif - - // If the memory needed to be DPMI locked then set it up so it - // is locked. - if (flags & MEM_LOCK) { - DPMI_Lock(retval, original_size); - } - - /* Clear the space if they wanted it clear */ - - if (flags & MEM_CLEAR) { - unsigned char *ptr; // Working memory block pointer. - - ptr = retval; - memset(ptr, '\0', original_size); - } - - bytesfree = Total_Ram_Free(MEM_NORMAL); - if (bytesfree < MinRam) { - MinRam = bytesfree; - } - if (TotalRam-bytesfree > MaxRam) { - MaxRam = TotalRam-bytesfree; - } - - Memory_Calls++; - -#if(LOGGING) - int val = _heapchk(); - - FILE *file = fopen("mem.txt","at"); - fprintf(file, "%P Alloc size = %d, Actual Size = %d, flags = %d, heap = %d\n", - retval, - original_size, - bytes_to_alloc, - flags, - val); - fclose(file); -#endif - - return(retval); -} - - -/*************************************************************************** - * Free -- Free an Alloc'ed block of RAM. * - * * - * FUNCTION: * - * * - * INPUT: A pointer to a block of RAM from Alloc. * - * * - * OUTPUT: None. * - * * - * WARNINGS: Don't use this for an Alloc_Block'ed RAM block. * - * * - * HISTORY: * - * 05/25/1990 : Created. * - ***************************************************************************/ -void Free(void const *pointer) -{ - union REGS regs ; - struct SREGS sregs ; - - void const *original = pointer; - char string[80]; - - if (pointer) { - /* - ** Get a pointer to the flags that we stored off. - */ -#if (LONG_ALIGNMENT) - unsigned char *byteptr = ((unsigned char *)pointer) - 4; - - // - // validate the flags with and eor of the flags - // - if ( *byteptr != ((*(byteptr + 1)) ^ 0xff) ) { - if (Memory_Error_Exit != NULL) { - sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer ); - Memory_Error_Exit( string ); - } - } - else { - if ( !(*byteptr & (MEM_LOCK|MEM_REAL)) ) { - unsigned short *wordptr = (unsigned short *)(byteptr - 2); - - // - // WARNING!!!!!!!!!! - // USE this only with the WATCOM malloc ALLOCATION!!!!!!!!! - // it reads the actual block size before the ptr to be freed. - // then compares with the EOR to the value stored during allocation. - // - if ( *wordptr != ((*(wordptr + 2)) ^ 0xffff) ) { - if (Memory_Error_Exit != NULL) { - sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer ); - Memory_Error_Exit( string ); - } - } - } - else if ( *(byteptr + 2) || *(byteptr + 3) ) { - if (Memory_Error_Exit != NULL) { - sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer ); - Memory_Error_Exit( string ); - } - } - } -// if ( *byteptr != (*(byteptr + 1) ^ 0xff) || -// *(byteptr + 2) || *(byteptr + 3) ) { -// if (Memory_Error_Exit != NULL) { -// sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer ); -// Memory_Error_Exit( string ); -// } -// } -#else - unsigned char *byteptr = ((unsigned char *)pointer) - 1; - - if ( (*byteptr & 0xe0) != (((*byteptr ^ 0x07) & 0x07) << 5) ) { - if (Memory_Error_Exit != NULL) { - sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer ); - Memory_Error_Exit( string ); - } - } -#endif - - /* - ** Check to see if this was locked me and if it was unlock it. - */ - if (*byteptr & MEM_LOCK) { - long *longptr = ((long *)byteptr) - 1; - DPMI_Unlock(pointer, *longptr); - pointer = (void *)longptr; - } else - pointer = (void *)byteptr; - -#if(LOGGING) - int val = _heapchk(); - FILE *file = fopen("mem.txt","at"); - fprintf(file, "%P Free flags = %d, Heap = %d\n", - original, - *byteptr, - val); - fclose(file); -#endif - - // If the pointer is a real mode pointer than it will point to the - // first megabyte of system memory. If it does than we need to - // use DPMI to free it. - if (*byteptr & MEM_REAL) { - regs.x.eax = 0x101; - regs.x.edx = *(((long *)pointer) - 1); - segread ( & sregs ) ; - int386x(0x31, ®s, ®s, &sregs); - } else { - free((void *)pointer); - } - Memory_Calls--; - } -} - - -/*************************************************************************** - * Resize_Alloc -- Change the size of an allocated block. * - * * - * This routine will take a previously allocated block and change its * - * size without unnecessarily altering its contents. * - * * - * INPUT: pointer -- Pointer to the original memory allocation. * - * * - * new_size -- Size in bytes that it will be converted to. * - * * - * OUTPUT: Returns with a pointer to the new allocation. * - * * - * WARNINGS: ??? * - * * - * HISTORY: * - * 02/01/1992 JLB : Commented. * - *=========================================================================*/ -void *Resize_Alloc(void *original_ptr, unsigned long new_size_in_bytes) -{ - - unsigned long *temp; -// unsigned long diff, flags; - - temp = (unsigned long*)original_ptr; - - /* ReAlloc the space */ - temp = (unsigned long *)realloc(temp, new_size_in_bytes); - if (temp == NULL) { - if (Memory_Error != NULL) - Memory_Error(); - return NULL; - } - - return(temp); -} - - -/*************************************************************************** - * Ram_Free -- Determines the largest free chunk of RAM. * - * * - * Use this routine to determine the largest free chunk of available * - * RAM for allocation. It also performs a check of the memory chain. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the size of the largest free chunk of RAM. * - * * - * WARNINGS: This does not return the TOTAL memory free, only the * - * largest free chunk. * - * * - * HISTORY: * - * 09/03/1991 JLB : Commented. * - *=========================================================================*/ -long Ram_Free(MemoryFlagType) -{ - return(_memmax()); -// return Largest_Mem_Block(); -} - - -/*************************************************************************** - * Heap_Size -- Size of the heap we have. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - *=========================================================================*/ -long Heap_Size(MemoryFlagType ) -{ - if (!TotalRam) { - TotalRam = Total_Ram_Free(MEM_NORMAL); - } - return(TotalRam); -} - - -/*************************************************************************** - * Total_Ram_Free -- Total amount of free RAM. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - * 03/09/1995 JLB : Uses prerecorded heap size maximum. * - *=========================================================================*/ -long Total_Ram_Free(MemoryFlagType ) -{ - return(_memavl()); -// return Largest_Mem_Block () ; -} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/ANIM.CPP b/code/TIBERIANDAWN/ANIM.CPP deleted file mode 100644 index 12644a1..0000000 --- a/code/TIBERIANDAWN/ANIM.CPP +++ /dev/null @@ -1,1282 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\anim.cpv 2.18 16 Oct 1995 16:48:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Dune * - * * - * File Name : ANIM.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 3, 1991 * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * AnimClass::AI -- This is the low level anim processor. * - * AnimClass::Adjust_Coord -- Adjusts anim coordinates * - * AnimClass::AnimClass -- The constructor for animation objects. * - * AnimClass::As_Target -- Converts the animation into a target value. * - * AnimClass::Attach_To -- Attaches animation to object specified. * - * AnimClass::Sort_Above -- Sorts the animation above the target specified. * - * AnimClass::Center_Coord -- Determine center of animation. * - * AnimClass::Detach -- Remove animation if attached to target. * - * AnimClass::Draw_It -- Draws the animation at the location specified. * - * AnimClass::In_Which_Layer -- Determines what render layer the anim should be in. * - * AnimClass::Init -- Performs pre-scenario initialization. * - * AnimClass::Mark -- Signals to map that redrawing is necessary. * - * AnimClass::Middle -- Processes any middle events. * - * AnimClass::Occupy_List -- Determines the occupy list for the animation. * - * AnimClass::Overlap_List -- Determines the overlap list for the animation. * - * AnimClass::Render -- Draws an animation object. * - * AnimClass::Sort_Y -- Returns with the sorting coordinate for the animation. * - * AnimClass::Start -- Processes initial animation side effects. * - * AnimClass::delete -- Returns an anim object back to the free pool. * - * AnimClass::new -- Allocates an anim object from the pool. * - * AnimClass::~AnimClass -- Destructor for anim objects. * - * AnimClass::Validate -- validates anim pointer * - * Shorten_Attached_Anims -- Reduces attached animation durations. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * AnimClass::VTable; - - -/*********************************************************************************************** - * AnimClass::Validate -- validates anim pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int AnimClass::Validate(void) const -{ - int num; - - num = Anims.ID(this); - if (num < 0 || num >= ANIM_MAX) { - Validate_Error("ANIM"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * Shorten_Attached_Anims -- Reduces attached animation durations. * - * * - * This routine is used to reduce the amount of time any attached animations will process. * - * Typical use of this is when an object is on fire and the object should now be destroyed * - * but the attached animations are to run until completion before destruction can follow. * - * This routine will make the animation appear to run its course, but in as short of time * - * as possible. The shortening effect is achieved by reducing the number of times the * - * animation will loop. * - * * - * INPUT: obj -- Pointer to the object that all attached animations will be processed. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/11/1994 JLB : Created. * - *=============================================================================================*/ -void Shorten_Attached_Anims(ObjectClass * obj) -{ - if (obj) { - for (int index = 0; index < Anims.Count(); index++) { - AnimClass & anim = *Anims.Ptr(index); - - if (anim.Object == obj) { - anim.Loops = 0; - } - } - } -} - - -/*********************************************************************************************** - * AnimClass::Sort_Y -- Returns with the sorting coordinate for the animation. * - * * - * This routine is used by the sorting system. Animations that are located in the ground * - * layer will be sorted by this the value returned from this function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the sort coordinate to use for this animation. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 12/15/1994 JLB : Handles flat anims (infantry decay anims). * - *=============================================================================================*/ -COORDINATE AnimClass::Sort_Y(void) const -{ - Validate(); - if (Object) { - return(Coord_Add(Object->Sort_Y(), 0x00010000L)); - } - if (Target_Legal(SortTarget)) { - ObjectClass * obj = As_Object(SortTarget); - if (obj && obj->IsActive) { - return(Coord_Add(obj->Sort_Y(), 0x00010000L)); - } - } - if (*this == ANIM_MOVE_FLASH) { - return(Coord_Add(Center_Coord(), XYP_COORD(0, -24))); - } - if (*this == ANIM_LZ_SMOKE) { - return(Coord_Add(Center_Coord(), XYP_COORD(0, 14))); - } - return(Coord); -} - - -/*********************************************************************************************** - * AnimClass::Center_Coord -- Determine center of animation. * - * * - * This support function will return the "center" of the animation. The actual coordinate * - * of the animation may be dependant on if the the animation is attached to an object. * - * In such a case, it must factor in the object's location. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the coordinate of the center of the animation. The coordinate is in real * - * game coordinates -- taking into consideration if the animation is attached. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE AnimClass::Center_Coord(void) const -{ - Validate(); - if (Object) { - return(Coord_Add(Coord, Object->Center_Coord())); - } - return(Coord); -} - - -/*********************************************************************************************** - * AnimClass::Render -- Draws an animation object. * - * * - * This is the working routine that renders the animation shape. It gets called once * - * per animation per frame. It needs to be fast. * - * * - * INPUT: bool; Should the animation be rendered in spite of render flag? * - * * - * OUTPUT: bool; Was the animation rendered? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -bool AnimClass::Render(bool forced) -{ - Validate(); - if (Delay) return(false); - IsToDisplay = true; - return(ObjectClass::Render(forced)); -} - - -/*********************************************************************************************** - * AnimClass::Draw_It -- Draws the animation at the location specified. * - * * - * This routine is used to render the animation object at the location specified. This is * - * how the map imagery gets updated. * - * * - * INPUT: x,y -- The pixel coordinates to draw the animation at. * - * * - * window -- The to base the draw coordinates upon. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - * 05/19/1995 JLB : Added white translucent effect. * - *=============================================================================================*/ -//#pragma off (unreferenced) -void AnimClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - - bool render_legacy = !IsInvisible && (Class->VirtualAnim == ANIM_NONE || window != WINDOW_VIRTUAL); - bool render_virtual = VirtualAnim != NULL && window == WINDOW_VIRTUAL; - if (render_legacy) { - void const * shapefile = Class->Get_Image_Data(); - if (shapefile) { - void const * transtable = NULL; - int shapenum = Class->Start + Fetch_Stage(); - void const * remap = NULL; - ShapeFlags_Type flags = SHAPE_CENTER|SHAPE_WIN_REL; - - /* - ** Some animations require special fixups. - */ - switch (Class->Type) { - case ANIM_ION_CANNON: - if (window != WINDOW_VIRTUAL) { - y -= Get_Build_Frame_Height(shapefile) >> 1; - } else { - flags = flags | SHAPE_BOTTOM; - } - y += 12; - break; - - case ANIM_RAPT_DIE: - case ANIM_STEG_DIE: - case ANIM_TREX_DIE: - case ANIM_TRIC_DIE: - case ANIM_ATOM_BLAST: - transtable = Map.UnitShadow; - break; - - case ANIM_FLAG: - x += (ICON_PIXEL_W / 2) - 2; - y += (3 * ICON_PIXEL_H / 4) - Get_Build_Frame_Height(shapefile); - transtable = Map.UnitShadow; - break; - } - - /* - ** If the translucent table hasn't been determined yet, then check to see if it - ** should use the white or normal translucent tables. - */ - if (!transtable && Class->IsWhiteTrans) transtable = Map.WhiteTranslucentTable; - if (!transtable && Class->IsTranslucent) transtable = Map.TranslucentTable; - - /* - ** Set the shape flags to properly take into account any fading or ghosting - ** table necessary. - */ - if (IsAlternate) { - flags = flags | SHAPE_FADING; - if (OwnerHouse != HOUSE_NONE) { - remap = HouseClass::As_Pointer(OwnerHouse)->Remap_Table(false, false); - } else { - remap = Map.RemapTables[HOUSE_GOOD][0]; - } - } - if (transtable) flags = flags | SHAPE_GHOST; - - /* - ** Draw the animation shape, but ignore legacy if beyond normal stage count. - */ - if ((window == WINDOW_VIRTUAL) || (Fetch_Stage() < Class->Stages)) { - CC_Draw_Shape(this, shapefile, shapenum, x, y, window, flags, remap, transtable, Class->VirtualScale); - } - } - } - if (render_virtual) { - VirtualAnim->Make_Visible(); - VirtualAnim->Draw_It(x, y, window); - VirtualAnim->Make_Invisible(); - } -} - - -/*********************************************************************************************** - * AnimClass::Mark -- Signals to map that redrawing is necessary. * - * * - * This routine is used by the animation logic system to inform the map that the cells * - * under the animation must be rerendered. * - * * - * INPUT: * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -bool AnimClass::Mark(MarkType mark) -{ - Validate(); - if (ObjectClass::Mark(mark)) { - Map.Refresh_Cells(Coord_Cell(Center_Coord()), Overlap_List()); -// ObjectClass::Mark(mark); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * AnimClass::Overlap_List -- Determines the overlap list for the animation. * - * * - * Use this routine to fetch the overlap list for the animation. This overlap list is the * - * cells that this animation spills over. * - * * - * INPUT: none * - * * - * OUTPUT: Returns a pointer to the overlap list for this particular instance of the * - * animation. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -short const * AnimClass::Overlap_List(void) const -{ - Validate(); - static short const OverlapN[] = {0, -MAP_CELL_W, -(MAP_CELL_W+1), -(MAP_CELL_W-1), -(2*MAP_CELL_W), -(2*MAP_CELL_W-1), -(2*MAP_CELL_W+1), REFRESH_EOL}; - static short const OverlapNW[] = {0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), -(MAP_CELL_W+2), -(MAP_CELL_W*2+2), -(MAP_CELL_W*2+1), REFRESH_EOL}; - static short const OverlapW[] = {0, -1, -2, -(MAP_CELL_W+1), -(MAP_CELL_W+2), REFRESH_EOL}; - static short const OverlapSW[] = {0, -1, MAP_CELL_W, (MAP_CELL_W-1), (MAP_CELL_W-2), (MAP_CELL_W*2-2), (MAP_CELL_W*2-1), REFRESH_EOL}; - static short const OverlapS[] = {0, MAP_CELL_W-1, MAP_CELL_W, MAP_CELL_W+1, 2*MAP_CELL_W+1, 2*MAP_CELL_W, 2*MAP_CELL_W-1, REFRESH_EOL}; - static short const OverlapSE[] = {0, 1, MAP_CELL_W, (MAP_CELL_W+1), (MAP_CELL_W+2), (MAP_CELL_W*2+2), (MAP_CELL_W*2+1), REFRESH_EOL}; - static short const OverlapE[] = {0, 1, 2, -(MAP_CELL_W-1), -(MAP_CELL_W-2), REFRESH_EOL}; - static short const OverlapNE[] = {0, 1, -MAP_CELL_W, -(MAP_CELL_W-1), -(MAP_CELL_W-2), -(MAP_CELL_W*2-2), -(MAP_CELL_W*2-1), REFRESH_EOL}; - static short const OverlapIon[] = { - (-MAP_CELL_W * 7) - 1, (-MAP_CELL_W * 7), (-MAP_CELL_W * 7) + 1, - (-MAP_CELL_W * 6) - 1, (-MAP_CELL_W * 6), (-MAP_CELL_W * 6) + 1, - (-MAP_CELL_W * 5) - 1, (-MAP_CELL_W * 5), (-MAP_CELL_W * 5) + 1, - (-MAP_CELL_W * 4) - 1, (-MAP_CELL_W * 4), (-MAP_CELL_W * 4) + 1, - (-MAP_CELL_W * 3) - 1, (-MAP_CELL_W * 3), (-MAP_CELL_W * 3) + 1, - (-MAP_CELL_W * 2) - 1, (-MAP_CELL_W * 2), (-MAP_CELL_W * 2) + 1, - (-MAP_CELL_W * 1) - 1, (-MAP_CELL_W * 1), (-MAP_CELL_W * 1) + 1, - (-MAP_CELL_W * 0) - 1, (-MAP_CELL_W * 0), (-MAP_CELL_W * 0) + 1, - REFRESH_EOL - }; - - static short const OverlapAtom[] = { - (-MAP_CELL_W * 2) - 1, (-MAP_CELL_W * 2), (-MAP_CELL_W * 2) + 1, - (-MAP_CELL_W * 1) - 1, (-MAP_CELL_W * 1), (-MAP_CELL_W * 1) + 1, - (-MAP_CELL_W * 0) - 1, (-MAP_CELL_W * 0), (-MAP_CELL_W * 0) + 1, - ( MAP_CELL_W * 1) - 1, ( MAP_CELL_W * 1), ( MAP_CELL_W * 1) + 1, - ( MAP_CELL_W * 2) - 1, ( MAP_CELL_W * 2), ( MAP_CELL_W * 2) + 1, - REFRESH_EOL - }; - - static short const OverlapFlag[] = { 0, 1, -MAP_CELL_W, -(MAP_CELL_W-1), MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL }; - - switch (Class->Type) { - case ANIM_CHEM_N: - case ANIM_FLAME_N: - return(OverlapN); - - case ANIM_CHEM_NW: - case ANIM_FLAME_NW: - return(OverlapNW); - - case ANIM_CHEM_W: - case ANIM_FLAME_W: - return(OverlapW); - - case ANIM_CHEM_SW: - case ANIM_FLAME_SW: - return(OverlapSW); - - case ANIM_CHEM_S: - case ANIM_FLAME_S: - return(OverlapS); - - case ANIM_CHEM_SE: - case ANIM_FLAME_SE: - return(OverlapSE); - - case ANIM_CHEM_E: - case ANIM_FLAME_E: - return(OverlapE); - - case ANIM_CHEM_NE: - case ANIM_FLAME_NE: - return(OverlapNE); - - case ANIM_ION_CANNON: - return(OverlapIon); - - case ANIM_ATOM_BLAST: - return(OverlapAtom); - - case ANIM_FLAG: - return(OverlapFlag); - - default: - break; - } - return(Coord_Spillage_List(Center_Coord(), Class->Size)); -} - - -/*********************************************************************************************** - * AnimClass::Occupy_List -- Determines the occupy list for the animation. * - * * - * Animations always occupy only the cell that their center is located over. As such, this * - * routine always returns a simple (center cell) occupation list. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the occupation list for the animation. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -short const * AnimClass::Occupy_List(void) const -{ - Validate(); - static short _simple[] = {REFRESH_EOL}; - - return(_simple); -} - - -/*********************************************************************************************** - * AnimClass::Init -- Performs pre-scenario initialization. * - * * - * This routine is used to initialize the animation system prior to a scenario being loaded * - * or reloaded. It effectively removes all animations from the system. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void AnimClass::Init(void) -{ - AnimClass *ptr; - - Anims.Free_All(); - - ptr = new AnimClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * AnimClass::new -- Allocates an anim object from the pool. * - * * - * This routine is used to allocate a free anim class object from the preallocated pool * - * in the near heap. If there are no free animation objects, then null is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to a free anim object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void *AnimClass::operator new(size_t) -{ - void * ptr = Anims.Allocate(); - if (ptr) { - ((AnimClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * AnimClass::delete -- Returns an anim object back to the free pool. * - * * - * This routine is used to return an anim object back to the pool of free anim objects. * - * Anim objects so returned are available to be reallocated for the next animation. * - * * - * INPUT: ptr -- Pointer to the anim object to return to the pool. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void AnimClass::operator delete(void *ptr) -{ - if (ptr) { - ((AnimClass *)ptr)->IsActive = false; - } - Anims.Free((AnimClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * AnimClass::AnimClass -- The constructor for animation objects. * - * * - * This routine is used as the constructor of animation objects. It initializes and adds * - * the animation object to the display and logic systems. * - * * - * INPUT: animnum -- The animation number to start. * - * * - * coord -- The location of the animation. * - * * - * timedelay-- The delay before the animation starts. * - * * - * loop -- The number of times to loop this animation. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 08/03/1994 JLB : Added a delayed affect parameter. * - *=============================================================================================*/ -AnimClass::AnimClass(AnimType animnum, COORDINATE coord, unsigned char timedelay, char loop, bool alt) : - Class(&AnimTypeClass::As_Reference(animnum)) -{ - Object = 0; - SortTarget = TARGET_NONE; - OwnerHouse = HOUSE_NONE; - - if (Class->Stages == -1) { - ((int&)Class->Stages) = Get_Build_Frame_Count(Class->Get_Image_Data()); - } - if (Class->LoopEnd == -1) { - ((int&)Class->LoopEnd) = Class->Stages; - } - if (Class->IsNormalized) { - Set_Rate(Options.Normalize_Delay(Class->Delay)); - } else { - Set_Rate(Class->Delay); - } - Set_Stage(0); - - Accum = 0; - coord = Adjust_Coord(coord); - Unlimbo(coord); - - VisibleFlags = 0xffff; - - /* - ** Drop zone smoke always reveals the map around itself. - */ - if (*this == ANIM_LZ_SMOKE) { - // Added PlayerPtr here as Sight_From now needs to know who to perform the action for. This should be OK as it's not used in MP. ST - 3/28/2019 2:43PM - Map.Sight_From(PlayerPtr, Coord_Cell(coord), 4, false); - } - - /* - ** Determine the time before the first animation process. For time delayed - ** animations, this is the value passed as a parameter. - */ - Delay = timedelay; - - if (Class->Loops >= 0) { - Loops = (char)(MAX(loop, (char)1) * Class->Loops); - Loops = (char)MAX(Loops, (char)1); - } else { - Loops = Class->Loops; - } - - IsToDelete = false; - IsBrandNew = true; - IsAlternate = alt; - IsInvisible = false; - - /* - ** If the animation starts immediately, then play the associated sound effect now. - */ - if (!Delay) { - Start(); - } - - /* - ** Check for a virtual animation - */ - if (Class->VirtualAnim != ANIM_NONE) { - VirtualAnim = new AnimClass(Class->VirtualAnim, 0, timedelay, loop, alt); - if (VirtualAnim != NULL) { - VirtualAnim->Make_Invisible(); - } - } else { - VirtualAnim = NULL; - } -} - - -/*********************************************************************************************** - * AnimClass::~AnimClass -- Destructor for anim objects. * - * * - * This destructor handles removing the animation object from the system. It might require * - * informing any object this animation is attached to that it is no longer attached. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/29/1994 JLB : Created. * - *=============================================================================================*/ -AnimClass::~AnimClass(void) -{ - Validate(); - if (GameActive) { - - /* - ** If this anim is attached to another object - ** then check to see if this is the last anim attached to it. If this - ** is the case, then inform the object that it is no longer attached to - ** an animation. - */ - if (Object) { - /* - ** Remove the object from the appropriate display list. - */ - Map.Remove(this, In_Which_Layer()); - - /* - ** Scan for any other animations that are attached to the object that - ** this animation is attached to. If there are no others, then inform the - ** attached object of this fact. - */ - int index; - for (index = 0; index < Anims.Count(); index++) { - if (Anims.Ptr(index) != this && Anims.Ptr(index)->Object == Object) break; - } - - /* - ** Tell the object that it is no longer being damaged. - */ - if (index == Anims.Count()) { - Object->Fire_Out(); - if (Object->In_Which_Layer() == LAYER_GROUND) Object->Mark(MARK_OVERLAP_UP); - Object->IsAnimAttached = false; - if (Object->In_Which_Layer() == LAYER_GROUND) Object->Mark(MARK_OVERLAP_DOWN); - } - Coord = Coord_Add(Object->Center_Coord(), Coord); - Object = NULL; - } - - Limbo(); - } -} - - -/*********************************************************************************************** - * AnimClass::AI -- This is the low level anim processor. * - * * - * This routine is called once per frame per animation. It handles transition between * - * animation frames and marks the map for redraw as necessary. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Speed is of upmost importance. * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void AnimClass::AI(void) -{ - Validate(); - /* - ** For ground level based animations (ones that can run slowly as well as - ** occur behind other ground objects) always cause the cell to be redrawn. - */ - if (!Delay && Class->IsGroundLayer) { - Map.Refresh_Cells(Coord_Cell(Center_Coord()), Overlap_List()); - } - - /* - ** Special case check to make sure that building on top of a smoke marker - ** causes the smoke marker to vanish. - */ - if (Class->Type == ANIM_LZ_SMOKE && Map[Coord_Cell(Center_Coord())].Cell_Building()) { - IsToDelete = true; - } - - /* - ** Delete this animation and bail early if the animation is flagged to be deleted - ** immediately. - */ - if (IsToDelete) { - Delete_This(); - return; - } - - /* - ** If this is a brand new animation, then don't process it the first logic pass - ** since it might end up skipping the first animation frame before it has had a - ** chance to draw it. - */ - if (IsBrandNew) { - IsBrandNew = false; - return; - } - - if (Delay) { - Delay--; - if (!Delay) { - Start(); - } - } else { - - /* - ** This is necessary because there is no recording of animations on the map - ** and thus the animation cannot be intelligently flagged for redraw. Most - ** animations move fast enough that they would need to be redrawn every - ** game frame anyway so this isn't TOO bad. - */ - Mark(MARK_CHANGE); - - if (StageClass::Graphic_Logic()) { - int stage = Fetch_Stage(); - - /* - ** If this animation is attached to another object and it is a - ** damaging kind of animation, then do the damage to the other - ** object. - */ - if (Object && Class->Damage && stage < Class->Stages) { - unsigned int accum = Accum; - - accum += Class->Damage; - - if (accum > 255) { - - /* - ** Administer the damage. If the object was destroyed by this anim, - ** then the attached damaging anim is also destroyed. - */ - int damage = accum >> 8; - if (Object->Take_Damage(damage, 0, WARHEAD_FIRE) == RESULT_DESTROYED) { - //Object = 0; - Delete_This(); - if (VirtualAnim != NULL) { - VirtualAnim->Delete_This(); - } - return; - } - } - Accum = (unsigned char)(accum & 0x00FF); - } - - /* - ** During the biggest stage (covers the most ground), perform any ground altering - ** action required. This masks craters and scorch marks, so that they appear - ** naturally rather than "popping" into existance while in plain sight. - */ - if (Class->Start+stage == Class->Biggest) { - Middle(); - } - - /* - ** Check to see if the last frame has been displayed. If so, then the - ** animation either ends or loops. - */ - if ((Loops <= 1 && stage >= Class->Stages) || (Loops > 1 && stage >= Class->LoopEnd-Class->Start)) { - - /* - ** Determine if this animation should loop another time. If so, then start the loop - ** but if not, then proceed into the animation termination handler. - */ - if (Loops > 0) Loops--; - if (Loops != 0) { - Set_Stage(Class->LoopStart); - } else { - if (Class->VirtualAnim != ANIM_NONE) { - Make_Invisible(); - if (VirtualAnim == NULL) { - if (Class->ChainTo != ANIM_NONE) { - Chain(); - } - else { - Delete_This(); - } - } - } - else { - if ((Class->VirtualStages < 0) || (stage >= Class->VirtualStages)) { - if (Class->ChainTo != ANIM_NONE) { - Chain(); - } - else { - Delete_This(); - } - } - } - } - } - } - } -} - - -/*********************************************************************************************** - * AnimClass::Attach_To -- Attaches animation to object specified. * - * * - * An animation can be "attached" to an object. In such cases, the animation is rendered * - * as an offset from the center of the object it is attached to. This allows affects such * - * as fire or smoke to be consistently placed on the vehicle it is associated with. * - * * - * INPUT: obj -- Pointer to the object to attach the animation to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -void AnimClass::Attach_To(ObjectClass * obj) -{ - Validate(); - if (!obj) return; - - if (obj->In_Which_Layer() == LAYER_GROUND) obj->Mark(MARK_OVERLAP_UP); - obj->IsAnimAttached = true; - if (obj->In_Which_Layer() == LAYER_GROUND) obj->Mark(MARK_OVERLAP_DOWN); - Map.Remove(this, In_Which_Layer()); - Object = obj; - Map.Submit(this, In_Which_Layer()); - Coord = Coord_Sub(Coord, obj->Center_Coord()); -} - - -/*********************************************************************************************** - * AnimClass::Sort_Above -- Sorts the animation right above the specified target. * - * * - * Allows an animation to always be sorted above a particular target. Typically used * - * for explosions and other effects that look weird beneath those objects. * - * * - * INPUT: target -- Target to sort above. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/14/2019 SKY : Created. * - *=============================================================================================*/ -void AnimClass::Sort_Above(TARGET target) -{ - SortTarget = target; -} - - -/*********************************************************************************************** - * AnimClass::In_Which_Layer -- Determines what render layer the anim should be in. * - * * - * Use this routine to find out which display layer (ground or air) that the animation * - * should be in. This information is used to place the animation into the correct display * - * list. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the layer that the animation should exist in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/25/1994 JLB : Created. * - *=============================================================================================*/ -LayerType AnimClass::In_Which_Layer(void) const -{ - Validate(); - if (Object || Class->IsGroundLayer) { - return(LAYER_GROUND); - } - return(LAYER_AIR); -} - - -/*********************************************************************************************** - * AnimClass::Start -- Processes initial animation side effects. * - * * - * This routine is called when the animation first starts. Sometimes there are side effects * - * associated with this animation that must occur immediately. Typically, this is the * - * sound effect assigned to this animation. If this animation is supposed to attach itself * - * to any object at its location, then do so at this time as well. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/30/1995 JLB : Created. * - *=============================================================================================*/ -void AnimClass::Start(void) -{ - Validate(); - CELL cell = Coord_Cell(Coord); - - Mark(); - - /* - ** Play the sound effect for this animation. - */ - Sound_Effect(Class->Sound, Coord); - - /* - ** If the stage where collateral effects occur is the first stage of the animation, then - ** perform this action now. Subsiquent checks against this stage value starts with the - ** second frame of the animation. - */ - if (!Class->Biggest) { - Middle(); - } - - /* - ** If this is the kind of animation that sticks to whatever object is in the same - ** location, then attach the animation to the object. If the animation is already - ** attached, then do nothing. - */ - if (!Object && Class->IsSticky && Map.In_Radar(cell)) { - UnitClass * unit = Map[cell].Cell_Unit(); - - if (unit && *unit == UNIT_GUNBOAT) { - Attach_To(unit); - } - } -} - - -/*********************************************************************************************** - * AnimClass::Middle -- Processes any middle events. * - * * - * This routine is called when the animation as reached its largest stage. Typically, this * - * routine is used to cause scorches or craters to appear at a cosmetically pleasing * - * moment. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/30/1995 JLB : Created. * - *=============================================================================================*/ -void AnimClass::Middle(void) -{ - Validate(); - CELL cell = Coord_Cell(Center_Coord()); - CellClass * cellptr = &Map[cell]; - - if (Class->Type == ANIM_ATOM_BLAST) { - - /* - ** Find someone to blame the explosion on. This is necessary in - ** order to properly enact retribution and record the kill for - ** score purposes. - */ - BuildingClass * building = NULL; - TechnoClass * backup = NULL; - if (OwnerHouse != HOUSE_NONE) { - for (int index = 0; index < Logic.Count(); index++) { - ObjectClass * obj = Logic[index]; - - if (obj && obj->Is_Techno() && obj->Owner() == OwnerHouse) { - backup = (TechnoClass *)obj; - if (obj->What_Am_I() == RTTI_BUILDING && *((BuildingClass *)obj) == STRUCT_TEMPLE) { - building = (BuildingClass *)obj; - break; - } - } - } - - if (!building) building = (BuildingClass *)backup; - } - - int radius = 3; - int rawdamage = 200; - if (GameToPlay == GAME_NORMAL) { - radius = 4; - rawdamage = 1000; - Fade_Palette_To(WhitePalette, 30, NULL); - } - for (int x = -radius; x <= radius; x++) { - for (int y = -radius; y <= radius; y++) { - int xpos = Cell_X(cell) + x; - int ypos = Cell_Y(cell) + y; - - /* - ** If the potential damage cell is outside of the map bounds, - ** then don't process it. This unusual check method ensures that - ** damage won't wrap from one side of the map to the other. - */ - if ((unsigned)xpos > MAP_CELL_W) { - continue; - } - if ((unsigned)ypos > MAP_CELL_H) { - continue; - } - CELL tcell = XY_Cell(xpos, ypos); - if (!Map.In_Radar(tcell)) continue; - - int damage = rawdamage / ((ABS(radius)/2)+1); - Explosion_Damage(Cell_Coord(tcell), damage, building, WARHEAD_FIRE); - new SmudgeClass(Random_Pick(SMUDGE_SCORCH1, SMUDGE_SCORCH6), Cell_Coord(tcell)); - } - } - Shake_The_Screen(3); - if (GameToPlay == GAME_NORMAL) { - Fade_Palette_To(GamePalette, 15, NULL); - } - } - - /* - ** If this animation leaves scorch marks (e.g., napalm), then do so at this time. - */ - if (Class->IsScorcher) { - new SmudgeClass(Random_Pick(SMUDGE_SCORCH1, SMUDGE_SCORCH6), Center_Coord()); - } - - /* - ** Some animations leave a crater when they occur. Artillery is a good example. - ** Craters always remove the Tiberium where they occur. - */ - if (Class->IsCraterForming) { - - /* - ** Craters reduce the level of Tiberium in the cell. - */ - cellptr->Reduce_Tiberium(6); - - /* - ** If there already is a crater in the cell, then just expand the - ** crater. - */ - new SmudgeClass(SMUDGE_CRATER1, Center_Coord()); - } - - /* - ** Flame throwers leave scorch marks in unusual positions. In addition, they leave fire - ** shards in unusual positions as well. - */ - if (Class->IsFlameThrower) { - COORDINATE c2 = Coord_Move(Center_Coord(), (DirType)((Class->Type - ANIM_FLAME_N)<<5), 0x00E0); - CELL cell = Coord_Cell(c2); - COORDINATE c3 = Map.Closest_Free_Spot(Coord_Move(Center_Coord(), (DirType)((Class->Type - ANIM_FLAME_N)<<5), 0x0140), true); - - c2 = Map.Closest_Free_Spot(c2, true); - if (c3 && (Random_Pick(0, 1) == 1)) { - if (!Map[Coord_Cell(c3)].Cell_Terrain()) { - new AnimClass(ANIM_FIRE_SMALL, c3, 0, 2); - } - } - if (c2 && (Random_Pick(0, 1) == 1)) { - if (!Map[Coord_Cell(c2)].Cell_Terrain()) { - new AnimClass(ANIM_FIRE_SMALL, c2, 0, 2); - } - } - new SmudgeClass(SMUDGE_SCORCH1, c2); - if (c3 && (Random_Pick(0, 1) == 1)) { - if (!Map[Coord_Cell(c3)].Cell_Terrain()) { - new AnimClass(ANIM_SMOKE_M, c3); - } - } - } - - AnimClass * newanim; - - /* - ** If this animation spawns side effects during its lifetime, then - ** do so now. - */ - switch (Class->Type) { - case ANIM_ION_CANNON: { - BuildingClass * building = NULL; - TechnoClass * backup = NULL; - if (OwnerHouse != HOUSE_NONE) { - for (int index = 0; index < Logic.Count(); index++) { - ObjectClass * obj = Logic[index]; - - if (obj && obj->Is_Techno() && obj->Owner() == OwnerHouse && !obj->IsInLimbo) { - backup = (TechnoClass *)obj; - if (obj->What_Am_I() == RTTI_BUILDING && *((BuildingClass *)obj) == STRUCT_EYE) { - building = (BuildingClass *)obj; - break; - } - } - } - - if (!building) building = (BuildingClass *)backup; - } - Explosion_Damage(Center_Coord(), 600, building, WARHEAD_PB); - } - break; - - case ANIM_NAPALM1: - case ANIM_NAPALM2: - case ANIM_NAPALM3: - new AnimClass(ANIM_FIRE_SMALL, Map.Closest_Free_Spot(Coord_Scatter(Center_Coord(), 0x0040), true), 0, ((Random_Pick(0, 1) == 1) ? 1 : 2)); - if (Random_Pick(0, 1) == 1) { - new AnimClass(ANIM_FIRE_SMALL, Map.Closest_Free_Spot(Coord_Scatter(Center_Coord(), 0x00A0), true), 0, ((Random_Pick(0, 1) == 1) ? 1 : 2)); - } - if (Random_Pick(0, 1) == 1) { - new AnimClass(ANIM_FIRE_MED, Map.Closest_Free_Spot(Coord_Scatter(Center_Coord(), 0x0070), true), 0, ((Random_Pick(0, 1) == 1) ? 1 : 2)); - } - break; - - case ANIM_FIRE_MED: - case ANIM_FIRE_MED2: - newanim = new AnimClass(ANIM_FIRE_SMALL, Center_Coord(), 0, ((Random_Pick(0, 1) == 1) ? 1 : 2)); - if (newanim && Object) { - newanim->Attach_To(Object); - } - break; - - default: - break; - } -} - - -void AnimClass::Chain(void) -{ - /* - ** The animation should end now, but first check to see if - ** it needs to chain into another animation. If so, then the - ** animation isn't technically over. It metamorphoses into the - ** new form. - */ - if (Class->ChainTo != ANIM_NONE) { - ((AnimTypeClass const *&)Class) = &AnimTypeClass::As_Reference(Class->ChainTo); - - if (Class->IsNormalized) { - Set_Rate(Options.Normalize_Delay(Class->Delay)); - } else { - Set_Rate(Class->Delay); - } - Set_Stage(Class->Start); - } -} - - -/*********************************************************************************************** - * AnimClass::As_Target -- Converts the animation into a target value. * - * * - * This support routine is used to convert the animation (as a pointer) into a target * - * value (which is a number). * - * * - * INPUT: none * - * * - * OUTPUT: Returns the animation as a target value. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -TARGET AnimClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_ANIMATION, Anims.ID(this))); -} - - -/*************************************************************************** - * AnimClass::Adjust_Coord -- Adjusts anim coordinates * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 05/17/1995 PWG : Created. * - *=========================================================================*/ -COORDINATE AnimClass::Adjust_Coord(COORDINATE coord) -{ - Validate(); - int x,y; - - switch (Class->Type) { - case ANIM_ATOM_DOOR: - x = -1; - y = -36; - break; - - default: - return(coord); - } - COORDINATE addval = XYPixel_Coord(x, y); - coord = Coord_Add(coord, addval); - return(coord); -} - - -/*********************************************************************************************** - * AnimClass::Detach -- Remove animation if attached to target. * - * * - * This routine is called when the specified target is being removed from the game. If this * - * animation happens to be attached to this object, then the animation must be remove as * - * well. * - * * - * INPUT: target -- The target that is about to be destroyed. * - * * - * all -- Is the target being destroyed RIGHT NOW? If not, then it will be * - * destroyed soon. In that case, the animation should continue to remain * - * attached for cosmetic reasons. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/30/1995 JLB : Created. * - * 07/02/1995 JLB : Detach is a precursor to animation destruction. * - *=============================================================================================*/ -void AnimClass::Detach(TARGET target, bool all) -{ - Validate(); - if (all) { - if (VirtualAnim && VirtualAnim->As_Target() == target) { - VirtualAnim = NULL; - } - if (Object && Object->As_Target() == target) { - Map.Remove(this, In_Which_Layer()); - Object = NULL; - IsToDelete = true; - } - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/ANIM.H b/code/TIBERIANDAWN/ANIM.H deleted file mode 100644 index 2a78888..0000000 --- a/code/TIBERIANDAWN/ANIM.H +++ /dev/null @@ -1,205 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\anim.h_v 2.20 16 Oct 1995 16:45:40 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ANIM.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 30, 1994 * - * * - * Last Update : May 30, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef ANIM_H -#define ANIM_H - -#include "type.h" - -/********************************************************************************************** -** This is the class that controls the shape animation objects. Shape animation objects are -** displayed over the top of the game map. Typically, they are used for explosion and fire -** effects. -*/ -class AnimClass : public ObjectClass, private StageClass { - public: - - static void * AnimClass::operator new(size_t size); - static void AnimClass::operator delete(void *ptr); - AnimClass(void) : Class(0) {OwnerHouse=HOUSE_NONE;Object=0;}; // Default constructor does nothing. - AnimClass(AnimType animnum, COORDINATE coord, unsigned char timedelay=0, char loop=1, bool alt=false); - virtual ~AnimClass(void); - operator AnimType(void) const {return Class->Type;}; - virtual RTTIType What_Am_I(void) const {return RTTI_ANIM;}; - virtual HousesType Owner(void) const {return OwnerHouse;}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - static void Init(void); - - void Attach_To(ObjectClass *obj); - void Sort_Above(TARGET target); - void Make_Invisible(void) {IsInvisible = true;}; - void Make_Visible(void) {IsInvisible = false;}; - - /* - ** 2019/09/19 JAS - ** Added functions for accessing which players can see this anim - */ - void Set_Visible_Flags(unsigned flags) { VisibleFlags = flags; } - unsigned Get_Visible_Flags() const { return (Delay == 0) ? VisibleFlags : 0; } - - virtual bool Can_Place_Here(COORDINATE ) const {return true;} - virtual bool Mark(MarkType mark=MARK_CHANGE); - virtual bool Render(bool forced); - virtual COORDINATE Center_Coord(void) const; - virtual COORDINATE Sort_Y(void) const; - virtual LayerType In_Which_Layer(void) const; - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - virtual short const * Occupy_List(void) const; - virtual short const * Overlap_List(void) const; - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual void AI(void); - virtual TARGET As_Target(void) const; - virtual void Detach(TARGET target, bool all); - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** If this animation is attached to an object, then this points to that object. An - ** animation that is attached will follow that object as it moves. This is important - ** for animations such as flames and smoke. - */ - ObjectClass * Object; - - /* - ** If specified, this animation uses the sort target for Y sorting - */ - TARGET SortTarget; - - /* - ** If this animation has an owner, then it will be recorded here. An owner - ** is used when damage is caused by this animation during the middle of its - ** animation. - */ - HousesType OwnerHouse; - - /* - ** This counter tells how many more times the animation should loop before it - ** terminates. - */ - char Loops; - - protected: - void Middle(void); - void Start(void); - void Chain(void); - - private: - /* - ** Define a function to make adjustments for where special animations - ** are going to render. - */ - COORDINATE Adjust_Coord(COORDINATE coord); - - /* - ** Delete this animation at the next opportunity. This is flagged when the - ** animation is to be prematurely ended as a result of some outside event. - */ - unsigned IsToDelete:1; - - /* - ** If the animation has just been created, then don't do any animation - ** processing until it has been through the render loop at least once. - */ - unsigned IsBrandNew:1; - - /* - ** Use alternate color when drawing - */ - unsigned IsAlternate:1; - - /* - ** If this animation is invisible, then this flag will be true. An invisible - ** animation is one that is created for the sole purpose of keeping all - ** machines syncronised. It will not be displayed. - */ - unsigned IsInvisible:1; - - /* - ** 2019/09/19 JAS - ** Flags storing which players can see this anim. - */ - unsigned VisibleFlags; - - /* - ** This points to the type of animation object this is. - */ - AnimTypeClass const * const Class; - - /* - ** Is this animation in a temporary suspended state? If so, then it won't - ** be rendered until this flag is false. The flag will be set to false - ** after the first countdown timer reaches 0. - */ - unsigned char Delay; - - /* - ** If this is an animation that damages whatever it is attached to, then this - ** value holds the accumulation of fractional damage points. When the accumulated - ** fractions reach 256, then one damage point is applied to the attached object. - */ - unsigned char Accum; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; - - /* - ** This points to the virtual animation. - */ - AnimClass * VirtualAnim; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; -}; - - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/AUDIO.CPP b/code/TIBERIANDAWN/AUDIO.CPP deleted file mode 100644 index 674679e..0000000 --- a/code/TIBERIANDAWN/AUDIO.CPP +++ /dev/null @@ -1,636 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\audio.cpv 2.17 16 Oct 1995 16:50:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : AUDIO.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : May 4, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Is_Speaking -- Checks to see if the eva voice is still playing. * - * Sound_Effect -- General purpose sound player. * - * Sound_Effect -- Plays a sound effect in the tactical map. * - * Speak -- Computer speaks to the player. * - * Speak_AI -- Handles starting the EVA voices. * - * Stop_Speaking -- Forces the EVA voice to stop talking. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - - - -/* -** -** -** Win32lib stubs -** -** -** -*/ - - -SFX_Type SoundType; -Sample_Type SampleType; - -int File_Stream_Sample(char const *filename, BOOL real_time_start) {return 1;}; -int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start) {return 1;}; -void __cdecl Sound_Callback(void) {}; -void __cdecl far maintenance_callback(void) {}; -void *Load_Sample(char const *filename) {return NULL;}; -long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size) {return 0;} -long Sample_Read(int fh, void *buffer, long size) {return 0;}; -void Free_Sample(void const *sample) {}; -BOOL Audio_Init( HWND window , int bits_per_sample, BOOL stereo , int rate , int reverse_channels) {return 0;}; -void Sound_End(void) {}; -void Stop_Sample(int handle) {}; -BOOL Sample_Status(int handle) {return 0;}; -BOOL Is_Sample_Playing(void const * sample) {return 0;}; -void Stop_Sample_Playing(void const * sample) {}; -int Play_Sample(void const *sample, int priority, int volume, signed short panloc) {return 1;}; -int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id) {return 1;}; -int Set_Sound_Vol(int volume) {return 0;}; -int Set_Score_Vol(int volume) {return 0;}; -void Fade_Sample(int handle, int ticks) {}; -int Get_Free_Sample_Handle(int priority) {return 1;}; -int Get_Digi_Handle(void) {return 1;} -long Sample_Length(void const *sample) {return 0;}; -void Restore_Sound_Buffers (void) {}; -BOOL Set_Primary_Buffer_Format(void) {return 0;}; -BOOL Start_Primary_Sound_Buffer (BOOL forced) {return 0;}; -void Stop_Primary_Sound_Buffer (void) {}; - - - - - - - - - - - - -/*************************************************************************** -** Controls what special effects may occur on the sound effect. -*/ -typedef enum { - IN_NOVAR, // No variation or alterations allowed. - IN_JUV, // Juvenile sound effect alternate option. - IN_VAR, // Infantry variance response modification. -} ContextType; - -// static struct { // MBL 02.21.2019 -// Had to name the struct for VS 2017 distributed build. ST - 4/10/2019 3:59PM -struct SoundEffectNameStruct { - char const *Name; // Digitized voice file name. - int Priority; // Playback priority of this sample. - ContextType Where; // In what game context does this sample exist. -} SoundEffectName[VOC_COUNT] = { - - /* - ** Special voices (typically associated with the commando). - */ - {"BOMBIT1", 20, IN_NOVAR}, // VOC_RAMBO_PRESENT "I've got a present for ya" - {"CMON1", 20, IN_NOVAR}, // VOC_RAMBO_CMON "c'mon" - {"GOTIT1", 20, IN_NOVAR}, // VOC_RAMBO_UGOTIT "you got it" * - {"KEEPEM1", 20, IN_NOVAR}, // VOC_RAMBO_COMIN "keep 'em commin'" - {"LAUGH1", 20, IN_NOVAR}, // VOC_RAMBO_LAUGH "hahaha" - {"LEFTY1", 20, IN_NOVAR}, // VOC_RAMBO_LEFTY "that was left handed" * - {"NOPRBLM1", 20, IN_NOVAR}, // VOC_RAMBO_NOPROB "no problem" -// {"OHSH1", 20, IN_NOVAR}, // VOC_RAMBO_OHSH "oh shiiiiii...." - {"ONIT1", 20, IN_NOVAR}, // VOC_RAMBO_ONIT "I'm on it" - {"RAMYELL1", 20, IN_NOVAR}, // VOC_RAMBO_YELL "ahhhhhhh" - {"ROKROLL1", 20, IN_NOVAR}, // VOC_RAMBO_ROCK "time to rock and roll" - {"TUFFGUY1", 20, IN_NOVAR}, // VOC_RAMBO_TUFF "real tuff guy" * - {"YEAH1", 20, IN_NOVAR}, // VOC_RAMBO_YEA "yea" * - {"YES1", 20, IN_NOVAR}, // VOC_RAMBO_YES "yes" * - {"YO1", 20, IN_NOVAR}, // VOC_RAMBO_YO "yo" - - /* - ** Civilian voices (technicians too). - */ - {"GIRLOKAY", 20, IN_NOVAR}, // VOC_GIRL_OKAY - {"GIRLYEAH", 20, IN_NOVAR}, // VOC_GIRL_YEAH - {"GUYOKAY1", 20, IN_NOVAR}, // VOC_GUY_OKAY - {"GUYYEAH1", 20, IN_NOVAR}, // VOC_GUY_YEAH - - /* - ** Infantry and vehicle responses. - */ - {"2DANGR1", 10, IN_VAR}, // VOC_2DANGER "negative, too dangerous" - {"ACKNO", 10, IN_VAR}, // VOC_ACKNOWL "acknowledged" - {"AFFIRM1", 10, IN_VAR}, // VOC_AFFIRM "affirmative" - {"AWAIT1", 10, IN_VAR}, // VOC_AWAIT1 "awaiting orders" -// {"BACKUP", 10, IN_VAR}, // VOC_BACKUP "send backup" -// {"HELP", 10, IN_VAR}, // VOC_HELP "send help" - {"MOVOUT1", 10, IN_VAR}, // VOC_MOVEOUT "movin' out" - {"NEGATV1", 10, IN_VAR}, // VOC_NEGATIVE "negative" - {"NOPROB", 10, IN_VAR}, // VOC_NO_PROB "not a problem" - {"READY", 10, IN_VAR}, // VOC_READY "ready and waiting" - {"REPORT1", 10, IN_VAR}, // VOC_REPORT "reporting" - {"RITAWAY", 10, IN_VAR}, // VOC_RIGHT_AWAY "right away sir" - {"ROGER", 10, IN_VAR}, // VOC_ROGER "roger" -// {"SIR1", 10, IN_VAR}, // VOC_SIR1 "sir?" -// {"SQUAD1", 10, IN_VAR}, // VOC_SQUAD1 "squad reporting" -// {"TARGET1", 10, IN_VAR}, // VOC_PRACTICE "target practice" - {"UGOTIT", 10, IN_VAR}, // VOC_UGOTIT "you got it" - {"UNIT1", 10, IN_VAR}, // VOC_UNIT1 "unit reporting" - {"VEHIC1", 10, IN_VAR}, // VOC_VEHIC1 "vehicle reporting" - {"YESSIR1", 10, IN_VAR}, // VOC_YESSIR "yes sir" - - /* - ** Sound effects that have a juvenile counterpart. - */ - {"BAZOOK1", 1, IN_JUV}, // VOC_BAZOOKA Gunfire - {"BLEEP2", 1, IN_JUV}, // VOC_BLEEP Clean metal bing - {"BOMB1", 1, IN_JUV}, // VOC_BOMB1 Crunchy parachute bomb type explosion - {"BUTTON", 1, IN_JUV}, // VOC_BUTTON Dungeon Master button click - {"COMCNTR1", 10, IN_JUV}, // VOC_RADAR_ON Elecronic static with beeps - {"CONSTRU2", 10, IN_JUV}, // VOC_CONSTRUCTION construction sounds - {"CRUMBLE", 1, IN_JUV}, // VOC_CRUMBLE muffled crumble sound - {"FLAMER2", 4, IN_JUV}, // VOC_FLAMER1 flame thrower - {"GUN18", 4, IN_JUV}, // VOC_RIFLE rifle shot - {"GUN19", 4, IN_JUV}, // VOC_M60 machine gun burst -- 6 rounds - {"GUN20", 4, IN_JUV}, // VOC_GUN20 bat hitting heavy metal door - {"GUN5", 4, IN_JUV}, // VOC_M60A medium machine gun burst - {"GUN8", 4, IN_JUV}, // VOC_MINI mini gun burst - {"GUNCLIP1", 1, IN_JUV}, // VOC_RELOAD gun clip reload - {"HVYDOOR1", 5, IN_JUV}, // VOC_SLAM metal plates slamming together - {"HVYGUN10", 1, IN_JUV}, // VOC_HVYGUN10 loud sharp cannon - {"ION1", 1, IN_JUV}, // VOC_ION_CANNON partical beam - {"MGUN11", 1, IN_JUV}, // VOC_MGUN11 alternate tripple burst - {"MGUN2", 1, IN_JUV}, // VOC_MGUN2 M-16 tripple burst - {"NUKEMISL", 1, IN_JUV}, // VOC_NUKE_FIRE long missile sound - {"NUKEXPLO", 1, IN_JUV}, // VOC_NUKE_EXPLODE long but not loud explosion - {"OBELRAY1", 1, IN_JUV}, // VOC_LASER humming laser beam - {"OBELPOWR", 1, IN_JUV}, // VOC_LASER_POWER warming-up sound of laser beam - {"POWRDN1", 1, IN_JUV}, // VOC_RADAR_OFF doom door slide - {"RAMGUN2", 1, IN_JUV}, // VOC_SNIPER silenced rifle fire - {"ROCKET1", 1, IN_JUV}, // VOC_ROCKET1 rocket launch variation #1 - {"ROCKET2", 1, IN_JUV}, // VOC_ROCKET2 rocket launch variation #2 - {"SAMMOTR2", 1, IN_JUV}, // VOC_MOTOR dentists drill - {"SCOLD2", 1, IN_JUV}, // VOC_SCOLD cannot perform action feedback tone - {"SIDBAR1C", 1, IN_JUV}, // VOC_SIDEBAR_OPEN xylophone clink - {"SIDBAR2C", 1, IN_JUV}, // VOC_SIDEBAR_CLOSE xylophone clink - {"SQUISH2", 1, IN_JUV}, // VOC_SQUISH2 crushing infantry - {"TNKFIRE2", 1, IN_JUV}, // VOC_TANK1 sharp tank fire with recoil - {"TNKFIRE3", 1, IN_JUV}, // VOC_TANK2 sharp tank fire - {"TNKFIRE4", 1, IN_JUV}, // VOC_TANK3 sharp tank fire - {"TNKFIRE6", 1, IN_JUV}, // VOC_TANK4 big gun tank fire - {"TONE15", 0, IN_JUV}, // VOC_UP credits counting up - {"TONE16", 0, IN_JUV}, // VOC_DOWN credits counting down - {"TONE2", 1, IN_JUV}, // VOC_TARGET target sound - {"TONE5", 10, IN_JUV}, // VOC_SONAR sonar echo - {"TOSS", 1, IN_JUV}, // VOC_TOSS air swish - {"TRANS1", 1, IN_JUV}, // VOC_CLOAK stealth tank - {"TREEBRN1", 1, IN_JUV}, // VOC_BURN burning crackle - {"TURRFIR5", 1, IN_JUV}, // VOC_TURRET muffled gunfire - {"XPLOBIG4", 5, IN_JUV}, // VOC_XPLOBIG4 very long muffled explosion - {"XPLOBIG6", 5, IN_JUV}, // VOC_XPLOBIG6 very long muffled explosion - {"XPLOBIG7", 5, IN_JUV}, // VOC_XPLOBIG7 very long muffled explosion - {"XPLODE", 1, IN_JUV}, // VOC_XPLODE long soft muffled explosion - {"XPLOS", 4, IN_JUV}, // VOC_XPLOS short crunchy explosion - {"XPLOSML2", 5, IN_JUV}, // VOC_XPLOSML2 muffled mechanical explosion - - /* - ** Generic sound effects (no variations). - */ - {"NUYELL1", 10, IN_NOVAR}, // VOC_SCREAM1 short infantry scream - {"NUYELL3", 10, IN_NOVAR}, // VOC_SCREAM3 short infantry scream - {"NUYELL4", 10, IN_NOVAR}, // VOC_SCREAM4 short infantry scream - {"NUYELL5", 10, IN_NOVAR}, // VOC_SCREAM5 short infantry scream - {"NUYELL6", 10, IN_NOVAR}, // VOC_SCREAM6 short infantry scream - {"NUYELL7", 10, IN_NOVAR}, // VOC_SCREAM7 short infantry scream - {"NUYELL10", 10, IN_NOVAR}, // VOC_SCREAM10 short infantry scream - {"NUYELL11", 10, IN_NOVAR}, // VOC_SCREAM11 short infantry scream - {"NUYELL12", 10, IN_NOVAR}, // VOC_SCREAM12 short infantry scream - {"YELL1", 1, IN_NOVAR}, // VOC_YELL1 long infantry scream - - {"MYES1", 10, IN_NOVAR}, // VOC_YES "Yes?" - {"MCOMND1", 10, IN_NOVAR}, // VOC_COMMANDER "Commander?" - {"MHELLO1", 10, IN_NOVAR}, // VOC_HELLO "Hello?" - {"MHMMM1", 10, IN_NOVAR}, // VOC_HMMM "Hmmm?" -// {"MHASTE1", 10, IN_NOVAR}, // VOC_PROCEED1 "I will proceed, post haste." -// {"MONCE1", 10, IN_NOVAR}, // VOC_PROCEED2 "I will proceed, at once." -// {"MIMMD1", 10, IN_NOVAR}, // VOC_PROCEED3 "I will proceed, immediately." -// {"MPLAN1", 10, IN_NOVAR}, // VOC_EXCELLENT1 "That is an excellent plan." -// {"MPLAN2", 10, IN_NOVAR}, // VOC_EXCELLENT2 "Yes, that is an excellent plan." - {"MPLAN3", 10, IN_NOVAR}, // VOC_EXCELLENT3 "A wonderful plan." -// {"MACTION1", 10, IN_NOVAR}, // VOC_EXCELLENT4 "Astounding plan of action commander." -// {"MREMARK1", 10, IN_NOVAR}, // VOC_EXCELLENT5 "Remarkable contrivance." - {"MCOURSE1", 10, IN_NOVAR}, // VOC_OF_COURSE "Of course." - {"MYESYES1", 10, IN_NOVAR}, // VOC_YESYES "Yes yes yes." - {"MTIBER1", 10, IN_NOVAR}, // VOC_QUIP1 "Mind the Tiberium." -// {"MMG1", 10, IN_NOVAR}, // VOC_QUIP2 "A most remarkable Metasequoia Glyptostroboides." - {"MTHANKS1", 10, IN_NOVAR}, // VOC_THANKS "Thank you." - - {"CASHTURN", 1, IN_NOVAR}, // VOC_CASHTURN Sound of money being piled up. - {"BLEEP2", 10, IN_NOVAR}, // VOC_BLEEPY3 Clean computer bleep sound. - {"DINOMOUT", 10, IN_NOVAR}, // VOC_DINOMOUT Movin' out in dino-speak. - {"DINOYES", 10, IN_NOVAR}, // VOC_DINOYES Yes Sir in dino-speak. - {"DINOATK1", 10, IN_NOVAR}, // VOC_DINOATK1 Dino attack sound. - {"DINODIE1", 10, IN_NOVAR}, // VOC_DINODIE1 Dino die sound. - -#ifdef PETROGLYPH_EXAMPLE_MOD - {"NUKE_LOB", 10, IN_NOVAR} // VOC_NUKE_LOB Mod expansion unit firing sound -#endif //PETROGLYPH_EXAMPLE_MOD - -}; - - -// -// External handlers. ST - 2/20/2019 3:41PM -// -extern void On_Sound_Effect(int sound_index, int variation, COORDINATE coord); -// extern void On_Speech(int speech_index); // MBL 02.06.2020 -extern void On_Speech(int speech_index, HouseClass *house); -extern void On_Ping(const HouseClass* player_ptr, COORDINATE coord); - -/*********************************************************************************************** - * Sound_Effect -- Plays a sound effect in the tactical map. * - * * - * This routine is used when a sound effect occurs in the game world. It handles fading * - * the sound according to distance. * - * * - * INPUT: voc -- The sound effect number to play. * - * * - * coord -- The world location that the sound originates from. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/12/1994 JLB : Created. * - * 01/05/1995 JLB : Reduces sound more dramatically when off screen. * - *=============================================================================================*/ -void Sound_Effect(VocType voc, COORDINATE coord, int variation) -{ - // - // Intercept sound effect calls. ST - 2/20/2019 3:37PM - // - On_Sound_Effect((int)voc, variation, coord); - -#if (0) - unsigned distance; - CELL cell_pos; - int pan_value; - - if (!Options.Volume || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) { - return; - } - if (coord) { - cell_pos = Coord_Cell(coord); - } - - distance = 0xFF; - pan_value = 0; - if (coord && !Map.In_View(cell_pos)) { - distance = Map.Cell_Distance(cell_pos, Coord_Cell(Map.TacticalCoord)); - distance = (unsigned int)MIN((int)distance, (int)MAP_CELL_W); - distance = Cardinal_To_Fixed(MAP_CELL_W, distance); - distance = MIN(distance, 0xFFu); - distance ^= 0xFF; - - distance /= 2; - distance = MAX(distance, 25U); - - pan_value = Cell_X(cell_pos); - pan_value -= Coord_XCell(Map.TacticalCoord) + (Lepton_To_Cell(Map.TacLeptonWidth) >> 1); - if (ABS(pan_value) > Lepton_To_Cell(Map.TacLeptonWidth >> 1)) { - pan_value *= 0x8000; - pan_value /= (MAP_CELL_W >> 2); - pan_value = Bound(pan_value, -0x7FFF, 0x7FFF); -// pan_value = MAX((int)pan_value, (int)-0x7FFF); -// pan_value = MIN((int)pan_value, 0x7FFF); - } else { - pan_value = 0; - } - } - - Sound_Effect(voc, (VolType)Fixed_To_Cardinal(distance, Options.Volume), variation, pan_value); -#endif -} - - -/*********************************************************************************************** - * Sound_Effect -- General purpose sound player. * - * * - * This is used for general purpose sound effects. These are sounds that occur outside * - * of the game world. They do not have a corresponding game world location as their source. * - * * - * INPUT: voc -- The sound effect number to play. * - * * - * volume -- The volume to assign to this sound effect. * - * * - * OUTPUT: Returns with the sound handle (-1 if no sound was played). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/12/1994 JLB : Created. * - * 11/12/1994 JLB : Handles cache logic. * - * 05/04/1995 JLB : Variation adjustments. * - *=============================================================================================*/ -int Sound_Effect(VocType voc, VolType volume, int variation, signed short pan_value) -{ - char name[_MAX_FNAME+_MAX_EXT]; // Working filename of sound effect. - - if (!Options.Volume || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) { - return(-1); - } - - /* - ** Fetch a pointer to the sound effect data. Modify the sound as appropriate and desired. - */ - char const * ext = ".AUD"; - if (Special.IsJuvenile && SoundEffectName[voc].Where == IN_JUV) { - ext = ".JUV"; - } else { - if (SoundEffectName[voc].Where == IN_VAR) { - - /* - ** For infantry, use a variation on the response. For vehicles, always - ** use the vehicle response table. - */ - if (variation < 0) { - if (ABS(variation) % 2) { - ext = ".V00"; - } else { - ext = ".V02"; - } - } else { - if (variation % 2) { - ext = ".V01"; - } else { - ext = ".V03"; - } - } - } - } - _makepath(name, NULL, NULL, SoundEffectName[voc].Name, ext); - void const * ptr = MixFileClass::Retrieve(name); - - /* - ** If the sound data pointer is not null, then presume that it is valid. - */ - if (ptr) { - return(Play_Sample(ptr, Fixed_To_Cardinal(SoundEffectName[voc].Priority, (int)volume), (int)volume, pan_value)); - } - return(-1); -} - - -/* -** This elaborates all the EVA speech voices. -*/ -char const * Speech[VOX_COUNT] = { - "ACCOM1", // mission accomplished - "FAIL1", // your mission has failed - "BLDG1", // unable to comply, building in progress - "CONSTRU1", // construction complete - "UNITREDY", // unit ready - "NEWOPT1", // new construction options - "DEPLOY1", // cannot deploy here - "GDIDEAD1", // GDI unit destroyed - "NODDEAD1", // Nod unit destroyed - "CIVDEAD1", // civilian killed -// "EVAYES1", // affirmative -// "EVANO1", // negative -// "UPUNIT1", // upgrade complete, new unit available -// "UPSTRUC1", // upgrade complete, new structure available - "NOCASH1", // insufficient funds - "BATLCON1", // battle control terminated - "REINFOR1", // reinforcements have arrived - "CANCEL1", // canceled - "BLDGING1", // building - "LOPOWER1", // low power - "NOPOWER1", // insufficient power - "MOCASH1", // need more funds - "BASEATK1", // our base is under attack - "INCOME1", // incoming missile - "ENEMYA", // enemy planes approaching - "NUKE1", // nuclear warhead approaching - VOX_INCOMING_NUKE -// "RADOK1", // radiation levels are acceptable -// "RADFATL1", // radiation levels are fatal - "NOBUILD1", // unable to build more - "PRIBLDG1", // primary building selected -// "REPDONE1", // repairs completed - "NODCAPT1", // Nod building captured - "GDICAPT1", // GDI building captured -// "SOLD1", // structure sold - "IONCHRG1", // ion cannon charging - "IONREDY1", // ion cannon ready - "NUKAVAIL", // nuclear weapon available - "NUKLNCH1", // nuclear weapon launched - VOX_NUKE_LAUNCHED - "UNITLOST", // unit lost - "STRCLOST", // structure lost - "NEEDHARV", // need harvester - "SELECT1", // select target - "AIRREDY1", // airstrike ready - "NOREDY1", // not ready - "TRANSSEE", // Nod transport sighted - "TRANLOAD", // Nod transport loaded - "ENMYAPP1", // enemy approaching - "SILOS1", // silos needed - "ONHOLD1", // on hold - "REPAIR1", // repairing - "ESTRUCX", // enemy structure destroyed - "GSTRUC1", // GDI structure destroyed - "NSTRUC1", // NOD structure destroyed - "ENMYUNIT", // Enemy unit destroyed -// "GUKILL1", // gold unit destroyed -// "GSTRUD1", // gold structure destroyed -// "GONLINE1", // gold player online -// "GLEFT1", // gold player has departed -// "GOLDKILT", // gold player destroyed -// "GOLDWIN", // gold player is victorious -// "RUKILL1", // red unit destroyed -// "RSTRUD1", // red structure destroyed -// "RONLINE1", // red player online -// "RLEFT1", // red player has departed -// "REDKILT", // red player destroyed -// "REDWIN", // red player is victorious -// "GYUKILL1", // grey unit destroyed -// "GYSTRUD1", // grey structure destroyed -// "GYONLINE", // grey player online -// "GYLEFT1", // grey player has departed -// "GREYKILT", // grey player destroyed -// "GREYWIN", // grey player is victorious -// "OUKILL1", // orange unit destroyed -// "OSTRUD1", // orange structure destroyed -// "OONLINE1", // orange player online -// "OLEFT1", // orange player has departed -// "ORANKILT", // orange player destroyed -// "ORANWIN", // orange player is victorious -// "GNUKILL1", // green unit destroyed -// "GNSTRUD1", // green structure destroyed -// "GNONLINE", // green player online -// "GNLEFT1", // green player has departed -// "GRENKILT", // green player destroyed -// "GRENWIN", // green player is victorious -// "BUKILL1", // blue unit destroyed -// "BSTRUD1", // blue structure destroyed -// "BONLINE1", // blue player online -// "BLEFT1", // blue player has departed -// "BLUEKILT", // blue player destroyed -// "BLUEWIN" // blue player is victorious -}; -static VoxType CurrentVoice = VOX_NONE; - - -/*********************************************************************************************** - * Speak -- Computer speaks to the player. * - * * - * This routine is used to have the game computer (EVA) speak to the player. * - * * - * INPUT: voice -- The voice number to speak (see defines.h). * - * * - * OUTPUT: Returns with the handle of the playing speech (-1 if no voice started). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/12/1994 JLB : Created. * - *=============================================================================================*/ -void Speak(VoxType voice, HouseClass *house, COORDINATE coord) -{ - // MBL 02.22.2019 - if (voice == VOX_NONE) - { - return; - } - - // - // Intercept speech calls. ST - 2/20/2019 3:37PM - // - // On_Speech((int)voice); // MBL 02.06.2020 - On_Speech((int)voice, house); - if (coord) { - On_Ping(house, coord); - } - -#if (0) - if (Options.Volume && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) { - SpeakQueue = voice; - } -#endif -} - - -/*********************************************************************************************** - * Speak_AI -- Handles starting the EVA voices. * - * * - * This starts the EVA voice talking as well. If there is any speech request in the queue, * - * it will be started when the current voice is finished. Call this routine as often as * - * possible (once per game tick is sufficient). * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -void Speak_AI(void) -{ -// MBL 06.17.2019 KO -#if 0 - static VoxType _last = VOX_NONE; - if (SampleType == 0) return; - - if (!Is_Sample_Playing(SpeechBuffer)) { - CurrentVoice = VOX_NONE; - if (SpeakQueue != VOX_NONE) { - if (SpeakQueue != _last) { - char name[_MAX_FNAME+_MAX_EXT]; - - _makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD"); - if (CCFileClass(name).Read(SpeechBuffer, SPEECH_BUFFER_SIZE)) { - Play_Sample(SpeechBuffer, 254, Options.Volume); - } - _last = SpeakQueue; - } else { - Play_Sample(SpeechBuffer, 254, Options.Volume); - } - SpeakQueue = VOX_NONE; - } - } -#endif -} - - -/*********************************************************************************************** - * Stop_Speaking -- Forces the EVA voice to stop talking. * - * * - * Use this routine to immediately stop the EVA voice from speaking. It also clears out * - * the pending voice queue. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -void Stop_Speaking(void) -{ - SpeakQueue = VOX_NONE; - if (SampleType != 0) { - Stop_Sample_Playing(SpeechBuffer); - } -} - - -/*********************************************************************************************** - * Is_Speaking -- Checks to see if the eva voice is still playing. * - * * - * Call this routine when the EVA voice being played needs to be checked. A typical use * - * of this would be when some action needs to be delayed until the voice has finished -- * - * say the end of the game. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the EVA voice still playing? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/12/1995 JLB : Created. * - *=============================================================================================*/ -bool Is_Speaking(void) -{ - Speak_AI(); - if (SampleType != 0 && (SpeakQueue != VOX_NONE || Is_Sample_Playing(SpeechBuffer))) { - return(true); - } - return(false); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/AUDIO.H b/code/TIBERIANDAWN/AUDIO.H deleted file mode 100644 index 6c2380a..0000000 --- a/code/TIBERIANDAWN/AUDIO.H +++ /dev/null @@ -1,96 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\audio.h_v 2.18 16 Oct 1995 16:45:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : AUDIO.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 21, 1994 * - * * - * Last Update : June 21, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef AUDIO_H -#define AUDIO_H - -#include "memory.h" - -class AudioClass { - char const * Name; // Name of audio asset. - void const * Data; // Loaded audio data. - int Handle; // Handle of asset (as it is playing). - MemoryClass *Mem; // Pointer to memory handler class. - unsigned IsMIDI:1; // Is this a midi file? - - public: - AudioClass(void); - AudioClass(char const *name, MemoryClass &mem); - virtual ~AudioClass(void); - - bool Load(char const *name = 0); - bool Free(void); - bool Play(int volume = 0xFF); - bool Stop(void); - bool Pause(void); - bool Resume(void); - bool Set_Name(char const *name); - bool Is_Playing(void) const; - bool Is_Loaded(void) const; - bool Is_MIDI(void) const; -}; - -inline AudioClass::AudioClass(void) -{ - Name = 0; - Data = 0; - Mem = 0; - Handle = -1; -}; - -inline AudioClass::AudioClass(char const *name, MemoryClass &mem) -{ - if (mem) { - Mem = &mem; - } else { - Mem = &::Mem; // Uses global default memory handler. - } - Name = strdup(name); - Data = 0; - Handle = -1; -}; - -inline AudioClass::~AudioClass(void) -{ - if (GameActive) { - if (Name) free(Name); - if (Data) Mem->Free(Data); - Name = 0; - Data = 0; - Handle = -1; - } -}; - - -#endif diff --git a/code/TIBERIANDAWN/BASE.CPP b/code/TIBERIANDAWN/BASE.CPP deleted file mode 100644 index 40186ae..0000000 --- a/code/TIBERIANDAWN/BASE.CPP +++ /dev/null @@ -1,521 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\base.cpv 1.9 16 Oct 1995 16:48:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BASE.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : 03/27/95 * - * * - * Last Update : March 27, 1995 * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * BaseClass::Get_Building -- Returns ptr to the built building for the given node * - * BaseClass::Get_Node -- Returns ptr to the node corresponding to given object * - * BaseClass::Is_Built -- Tells if given item in the list has been built yet * - * BaseClass::Is_Node -- Tells if the given building is part of our base list * - * BaseClass::Load -- loads from a saved game file * - * BaseClass::Next_Buildable -- returns ptr to the next node that needs to be built * - * BaseClass::Read_INI -- INI reading routine * - * BaseClass::Save -- saves to a saved game file * - * BaseClass::Write_INI -- INI writing routine * - * BaseNodeClass::operator != -- inequality operator * - * BaseNodeClass::operator == -- equality operator * - * BaseNodeClass::operator > -- greater-than operator * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * BaseNodeClass::operator == -- equality operator * - * * - * INPUT: * - * node node to test against * - * * - * OUTPUT: * - * true = equal, false = not equal * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -int BaseNodeClass::operator == (BaseNodeClass const & node) -{ - return(Type == node.Type && Coord == node.Coord); -} - - -/*********************************************************************************************** - * BaseNodeClass::operator != -- inequality operator * - * * - * INPUT: * - * node node to test against * - * * - * OUTPUT: * - * comparison result * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -int BaseNodeClass::operator !=(BaseNodeClass const & node) -{ - return(Type != node.Type || Coord != node.Coord); -} - - -/*********************************************************************************************** - * BaseNodeClass::operator > -- greater-than operator * - * * - * INPUT: * - * node node to test against * - * * - * OUTPUT: * - * comparison result * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -int BaseNodeClass::operator > (BaseNodeClass const & ) -{ - return(true); -} - - -/*********************************************************************************************** - * BaseClass::Read_INI -- INI reading routine * - * * - * INI entry format: * - * BLDG=COORD * - * BLDG=COORD * - * ... * - * * - * INPUT: * - * buffer pointer to loaded INI file * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * This routines assumes there is only one base defined for the scenario. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -void BaseClass::Read_INI(char *buffer) -{ - char buf[128]; - char uname[10]; - BaseNodeClass node; // node to add to list - - /* - ** First, determine the house of the human player, and set the Base's house - ** accordingly. - */ - WWGetPrivateProfileString("BASIC", "Player", "GoodGuy", buf, 20, buffer); - if (HouseTypeClass::From_Name(buf) == HOUSE_GOOD) { - House = HOUSE_BAD; - } else { - House = HOUSE_GOOD; - } - - /* - ** Read the number of buildings that will go into the base node list - */ - int count = WWGetPrivateProfileInt (INI_Name(),"Count",0,buffer); - - /* - ** Read each entry in turn, in the same order they were written out. - */ - for (int i = 0; i < count; i++) { - - /* - ** Get an INI entry - */ - sprintf(uname,"%03d",i); - WWGetPrivateProfileString(INI_Name(), uname, NULL, buf, sizeof(buf)-1, buffer); - - /* - ** Set the node's building type - */ - node.Type = BuildingTypeClass::From_Name(strtok(buf,",")); - - /* - ** Read & set the node's coordinate - */ - node.Coord = atol(strtok(NULL,",")); - - /* - ** Add this node to the Base's list - */ - Nodes.Add(node); - } -} - - -/*********************************************************************************************** - * BaseClass::Write_INI -- INI writing routine * - * * - * INI entry format: * - * BLDG=COORD * - * BLDG=COORD * - * ... * - * * - * INPUT: * - * buffer pointer to loaded INI file staging area * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * This routines assumes there is only one base defined for the scenario. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -void BaseClass::Write_INI(char *buffer) -{ - char buf[128]; - char uname[10]; - - /* - ** Clear out all existing teamtype data from the INI file. - */ - WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer); - - /* - ** Save the # of buildings in the Nodes list. This is essential because - ** they must be read in the same order they were created, so "000" must be - ** read first, etc. - */ - WWWritePrivateProfileInt (INI_Name(),"Count",Nodes.Count(),buffer); - - /* - ** Write each entry into the INI - */ - for (int i = 0; i < Nodes.Count(); i++) { - sprintf(uname,"%03d",i); - sprintf(buf,"%s,%d", - BuildingTypeClass::As_Reference(Nodes[i].Type).IniName, - Nodes[i].Coord); - - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } -} - - -/*********************************************************************************************** - * BaseClass::Load -- loads from a saved game file * - * * - * INPUT: * - * file open file * - * * - * OUTPUT: * - * true = success, false = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -bool BaseClass::Load(FileClass &file) -{ - int num_struct; - int i; - BaseNodeClass node; - - /* - ** Read in & check the size of this class - */ - if (file.Read(&i, sizeof(i)) != sizeof(i)) { - return(false); - } - - if (i != sizeof(*this)) { - return(false); - } - - /* - ** Read in the House & the number of structures in the base - */ - if (file.Read(&House,sizeof(House)) != sizeof(House)) { - return(false); - } - - if (file.Read(&num_struct,sizeof(num_struct)) != sizeof(num_struct)) { - return(false); - } - - /* - ** Read each node entry & add it to the list - */ - for (i = 0; i < num_struct; i++) { - if (file.Read(&node,sizeof(node)) != sizeof(node)) { - return(false); - } - Nodes.Add(node); - } - - return(true); -} - - -/*********************************************************************************************** - * BaseClass::Save -- saves to a saved game file * - * * - * INPUT: * - * file open file * - * * - * OUTPUT: * - * true = success, false = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -bool BaseClass::Save(FileClass &file) -{ - int num_struct; - int i; - BaseNodeClass node; - - /* - ** Write the size of this class - */ - i = sizeof(*this); - if (file.Write(&i,sizeof(i)) != sizeof(i)) { - return(false); - } - - /* - ** Write the House & the number of structures in the base - */ - if (file.Write(&House,sizeof(House)) != sizeof(House)) { - return(false); - } - - num_struct = Nodes.Count(); - if (file.Write(&num_struct,sizeof(num_struct)) != sizeof(num_struct)) { - return(false); - } - - /* - ** Write each node entry - */ - for (i = 0; i < num_struct; i++) { - node = Nodes[i]; - if (file.Write(&node,sizeof(node)) != sizeof(node)) { - return(false); - } - } - - return(true); -} - - -/*********************************************************************************************** - * BaseClass::Is_Built -- Tells if given item in the list has been built yet * - * * - * INPUT: * - * index index into base list * - * * - * OUTPUT: * - * true = yes, false = no * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -bool BaseClass::Is_Built(int index) -{ - if (Get_Building(index) != NULL) { - return(true); - } else { - return(false); - } -} - - -/*********************************************************************************************** - * BaseClass::Get_Building -- Returns ptr to the built building for the given node * - * * - * INPUT: * - * obj pointer to building to test * - * * - * OUTPUT: * - * ptr to already-built building, NULL if none * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -BuildingClass * BaseClass::Get_Building(int index) -{ - BuildingClass *bldg; - ObjectClass *obj[4]; - - /* - ** Check the location on the map where this building should be; if it's - ** there, return a pointer to it. - */ - CELL cell = Coord_Cell(Nodes[index].Coord); - - obj[0] = Map[cell].Cell_Building(); - obj[1] = Map[cell].Overlapper[0]; - obj[2] = Map[cell].Overlapper[1]; - obj[3] = Map[cell].Overlapper[2]; - - bldg = NULL; - for (int i = 0; i < 4; i++) { - if (obj[i] && - obj[i]->Coord == Nodes[index].Coord && - obj[i]->What_Am_I() == RTTI_BUILDING && - ((BuildingClass *)obj[i])->Class->Type == Nodes[index].Type) { - - bldg = (BuildingClass *)obj[i]; - break; - } - } - - return(bldg); -} - - -/*********************************************************************************************** - * BaseClass::Is_Node -- Tells if the given building is part of our base list * - * * - * INPUT: * - * obj pointer to building to test * - * * - * OUTPUT: * - * true = building is a node in the list, false = isn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -bool BaseClass::Is_Node(BuildingClass *obj) -{ - if (Get_Node(obj) != NULL) { - return(true); - } else { - return(false); - } -} - - -/*********************************************************************************************** - * BaseClass::Get_Node -- Returns ptr to the node corresponding to given object * - * * - * INPUT: * - * obj pointer to building to test * - * * - * OUTPUT: * - * ptr to node * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -BaseNodeClass * BaseClass::Get_Node(BuildingClass *obj) -{ - for (int i = 0; i < Nodes.Count(); i++) { - if (obj->Class->Type == Nodes[i].Type && obj->Coord == Nodes[i].Coord) { - return(&Nodes[i]); - } - } - return(NULL); -} - - -/*********************************************************************************************** - * BaseClass::Next_Buildable -- returns ptr to the next node that needs to be built * - * * - * If 'type' is not NONE, returns ptr to the next "hole" in the list of the given type. * - * Otherwise, returns ptr to the next hole in the list of any type. * - * * - * INPUT: * - * type type of building to check for * - * * - * OUTPUT: * - * ptr to a BaseNodeClass, NULL if none * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -BaseNodeClass * BaseClass::Next_Buildable(StructType type) -{ - /* - ** Loop through all node entries, returning a pointer to the first - ** un-built one that matches the requested type. - */ - for (int i = 0; i < Nodes.Count(); i++) { - - /* - ** For STRUCT_NONE, return the first hole found - */ - if (type == STRUCT_NONE) { - if (!Is_Built(i)) { - return(&Nodes[i]); - } - - } else { - - /* - ** For a "real" building type, return the first hold for that type - */ - if (Nodes[i].Type==type && !Is_Built(i)) { - return(&Nodes[i]); - } - } - } - - -// If no entry could be found, then create a fake one that will allow -// placement of the building. Make it static and reuse the next time this -// routine is called. - - return(NULL); -} diff --git a/code/TIBERIANDAWN/BASE.H b/code/TIBERIANDAWN/BASE.H deleted file mode 100644 index e6c6c2a..0000000 --- a/code/TIBERIANDAWN/BASE.H +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\base.h_v 1.12 16 Oct 1995 16:46:38 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BASE.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : 03/27/95 * - * * - * Last Update : March 27, 1995 * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef BASE_H -#define BASE_H - - -/**************************************************************************** -** This class defines one "node" in the pre-built base list. Each node -** contains a type of building to build, and the COORD to build it at. -*/ -class BaseNodeClass -{ - public: - BaseNodeClass(void) {}; - int operator == (BaseNodeClass const & node); - int operator != (BaseNodeClass const & node); - int operator > (BaseNodeClass const & node); - - StructType Type; - COORDINATE Coord; -}; - - -/**************************************************************************** -** This is the class that defines a pre-built base for the computer AI. -** (Despite its name, this is NOT the "base" class for C&C's class hierarchy!) -*/ -class BaseClass -{ - public: - - /********************************************************************** - ** Constructor/Destructor - */ - BaseClass(void) {}; - virtual ~BaseClass() {Nodes.Clear();} - - /********************************************************************** - ** Initialization - */ - void Init(void) {Nodes.Clear();} - - /********************************************************************** - ** The standard suite of load/save support routines - */ - void Read_INI(char *buffer); - void Write_INI(char *buffer); - static char *INI_Name(void) {return "Base";} - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void) {}; - virtual void Decode_Pointers(void) {}; - - /********************************************************************** - ** Tells if the given node has been built or not - */ - bool Is_Built(int index); - - /********************************************************************** - ** Returns a pointer to the object for the given node - */ - BuildingClass * Get_Building(int index); - - /********************************************************************** - ** Tells if the given building ptr is a node in this base's list. - */ - bool Is_Node (BuildingClass *obj); - - /********************************************************************** - ** Returns a pointer to the requested node. - */ - BaseNodeClass * Get_Node(BuildingClass *obj); - BaseNodeClass * Get_Node(int index) { return (&Nodes[index]); } - - /********************************************************************** - ** Returns a pointer to the next "hole" in the Nodes list. - */ - BaseNodeClass * Next_Buildable(StructType type = STRUCT_NONE); - - /********************************************************************** - ** This is the list of "nodes" that define the base. Portions of this - ** list can be pre-built by simply saving those buildings in the INI - ** along with non-base buildings, so Is_Built will return true for them. - */ - DynamicVectorClass Nodes; - - /********************************************************************** - ** This is the house this base belongs to. - */ - HousesType House; -}; - - -#endif diff --git a/code/TIBERIANDAWN/BBDATA.CPP b/code/TIBERIANDAWN/BBDATA.CPP deleted file mode 100644 index 3f72a47..0000000 --- a/code/TIBERIANDAWN/BBDATA.CPP +++ /dev/null @@ -1,636 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\bbdata.cpv 2.17 16 Oct 1995 16:49:46 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BBDATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 23, 1994 * - * * - * Last Update : October 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * BulletTypeClass::BulletTypeClass -- Constructor for bullet type objects. * - * BulletTypeClass::Load_Shapes -- Load shape data for bullet types. * - * BulletTypeClass::One_Time -- Performs the one time processing for bullets. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/*************************************************************************** -** Detailed information about each class of bullet (projectile) in the game. -*/ -static BulletTypeClass const ClassSniper( - BULLET_BULLET, - "50cal", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_LIGHT_SPEED, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HOLLOW_POINT, // WARHEAD: If fires weapon, warhead type - ANIM_PIFF // Explosion to use upon impact. -); - -static BulletTypeClass const ClassBullet( - BULLET_BULLET, - "50cal", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_LIGHT_SPEED, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_SA, // WARHEAD: If fires weapon, warhead type - ANIM_PIFF // Explosion to use upon impact. -); - -static BulletTypeClass const ClassSpreadfire( - BULLET_SPREADFIRE, - "50cal", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_LIGHT_SPEED, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_PIFFPIFF // Explosion to use upon impact. -); - -static BulletTypeClass const ClassAPDS( - BULLET_APDS, - "120mm", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_VERY_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_AP, // WARHEAD: If fires weapon, warhead type - ANIM_VEH_HIT3 // Explosion to use upon impact. -); - -static BulletTypeClass const Class120mm( - BULLET_HE, - "120mm", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - true, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - true, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_MEDIUM_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_ART_EXP1 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassMissile( - BULLET_SSM, - "DRAGON", // NAME: Text name of this unit type. - true, // Flies over tall walls? - true, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - true, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - true, // Is projectile inherently inaccurate? - true, // Translucent colors are used? - true, // Good against aircraft? - 7, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_ROCKET, // SPEED: Miles per hour. - 5, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_FRAG1 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassMissile2( - BULLET_SSM2, - "DRAGON", // NAME: Text name of this unit type. - true, // Flies over tall walls? - true, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - true, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - true, // Is projectile inherently inaccurate? - true, // Translucent colors are used? - true, // Good against aircraft? - 9, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_ROCKET, // SPEED: Miles per hour. - 7, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_FRAG1 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassPatriot( - BULLET_SAM, - "MISSILE", // NAME: Text name of this unit type. - true, // Flies over tall walls? - true, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - true, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - true, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_VERY_FAST, // SPEED: Miles per hour. - 10, // ROT: Rate of turn (degrees per tick). - WARHEAD_AP, // WARHEAD: If fires weapon, warhead type - ANIM_VEH_HIT1 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassDragon( - BULLET_TOW, - "DRAGON", // NAME: Text name of this unit type. - true, // Flies over tall walls? - true, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - true, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - true, // Translucent colors are used? - true, // Good against aircraft? - 3, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_ROCKET, // SPEED: Miles per hour. - 5, // ROT: Rate of turn (degrees per tick). - WARHEAD_AP, // WARHEAD: If fires weapon, warhead type - ANIM_VEH_HIT2 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassFlame( - BULLET_FLAME, - "FLAME", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 12, // ARMING: Time to arm projectile after launch. - 12, // RANGE: Inherent override range factor. - MPH_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_FIRE, // WARHEAD: If fires weapon, warhead type - ANIM_NONE // Explosion to use upon impact. -); - -static BulletTypeClass const ClassChem( - BULLET_CHEMSPRAY, - "FLAME", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 12, // ARMING: Time to arm projectile after launch. - 12, // RANGE: Inherent override range factor. - MPH_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_NONE // Explosion to use upon impact. -); - -static BulletTypeClass const ClassNapalm( - BULLET_NAPALM, - "BOMBLET", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - true, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - true, // Translucent colors are used? - false, // Good against aircraft? - 24, // ARMING: Time to arm projectile after launch. - 24, // RANGE: Inherent override range factor. - MPH_MEDIUM_SLOW, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_FIRE, // WARHEAD: If fires weapon, warhead type - ANIM_NAPALM2 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassGrenade( - BULLET_GRENADE, - "BOMB", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - true, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - true, // Is projectile inherently inaccurate? - true, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_MEDIUM_SLOW, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_VEH_HIT2 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassLaser( - BULLET_LASER, - "Laser", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_LIGHT_SPEED, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_LASER, // WARHEAD: If fires weapon, warhead type - ANIM_NONE // Explosion to use upon impact. -); - -static BulletTypeClass const ClassNukeUp( - BULLET_NUKE_UP, - "ATOMICUP", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_VERY_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_FRAG1 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassNukeDown( - BULLET_NUKE_DOWN, - "ATOMICDN", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_VERY_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_ATOM_BLAST // Explosion to use upon impact. -); - -static BulletTypeClass const ClassHonestJohn( - BULLET_HONEST_JOHN, - "MISSILE", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - true, // Will it blow up even if it gets just NEAR to target? - true, // Does it have flickering flame animation? - true, // Can it run out of fuel? - false, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 10, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_FAST, // SPEED: Miles per hour. - 10, // ROT: Rate of turn (degrees per tick). - WARHEAD_FIRE, // WARHEAD: If fires weapon, warhead type - ANIM_NAPALM3 // Explosion to use upon impact. -); - -static BulletTypeClass const ClassHeadButt( - BULLET_HEADBUTT, - "GORE", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_LIGHT_SPEED, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HEADBUTT, // WARHEAD: If fires weapon, warhead type - ANIM_NONE // Explosion to use upon impact. -); - -static BulletTypeClass const ClassTRexBite( - BULLET_TREXBITE, - "CHEW", // NAME: Text name of this unit type. - false, // Flies over tall walls? - false, // Homes in on target? - false, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - true, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - false, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_LIGHT_SPEED, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_FEEDME, // WARHEAD: If fires weapon, warhead type - ANIM_NONE // Explosion to use upon impact. -); - - -#ifdef PETROGLYPH_EXAMPLE_MOD - -static BulletTypeClass const NukeLob( - BULLET_NUKE_LOB, - "BOMB", // NAME: Text name of this unit type. - true, // Flies over tall walls? - false, // Homes in on target? - true, // Projectile arcs to the target? - false, // Is this a dropping bomb-like object? - false, // Is this projectile invisible? - false, // Will it blow up even if it gets just NEAR to target? - false, // Does it have flickering flame animation? - false, // Can it run out of fuel? - true, // Is there no visual difference between projectile facings? - true, // Is projectile inherently inaccurate? - false, // Translucent colors are used? - false, // Good against aircraft? - 0, // ARMING: Time to arm projectile after launch. - 0, // RANGE: Inherent override range factor. - MPH_MEDIUM_FAST, // SPEED: Miles per hour. - 0, // ROT: Rate of turn (degrees per tick). - WARHEAD_HE, // WARHEAD: If fires weapon, warhead type - ANIM_ATOM_BLAST // Explosion to use upon impact. -); - -#endif //PETROGLYPH_EXAMPLE_MOD - - -/* -** This is the array of pointers to the static data associated with -** each bullet (projectile) type. -*/ -BulletTypeClass const * const BulletTypeClass::Pointers[BULLET_COUNT] = { - &ClassSniper, // BULLET_SNIPER - &ClassBullet, // BULLET_BULLET - &ClassAPDS, // BULLET_APDS - &Class120mm, // BULLET_HE - &ClassMissile, // BULLET_SSM - &ClassMissile2, // BULLET_SSM2 - &ClassPatriot, // BULLET_SAM - &ClassDragon, // BULLET_TOW - &ClassFlame, // BULLET_FLAME - &ClassChem, // BULLET_CHEMSPRAY - &ClassNapalm, // BULLET_NAPALM - &ClassGrenade, // BULLET_GRENADE - &ClassLaser, // BULLET_LASER - &ClassNukeUp, // BULLET_NUKE_UP - &ClassNukeDown, // BULLET_NUKE_DOWN - &ClassHonestJohn, // BULLET_HONEST_JOHN - &ClassSpreadfire, // BULLET_SPREADFIRE - &ClassHeadButt, // BULLET_HEADBUTT - &ClassTRexBite, // BULLET_TREXBITE -#ifdef PETROGLYPH_EXAMPLE_MOD - &NukeLob, // BULLET_NUKE_LOB -#endif //PETROGLYPH_EXAMPLE_MOD - -}; - - -/*********************************************************************************************** - * BulletTypeClass::BulletTypeClass -- Constructor for bullet type objects. * - * * - * This is basically a constructor for static type objects used by bullets. All bullets * - * are of a type constructed by this routine at game initialization time. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -BulletTypeClass::BulletTypeClass( - BulletType type, - char const *ininame, - bool is_high, - bool is_homing, - bool is_arcing, - bool is_dropping, - bool is_invisible, - bool is_proximity_armed, - bool is_flame_equipped, - bool is_fueled, - bool is_faceless, - bool is_inaccurate, - bool is_translucent, - bool is_antiaircraft, - int arming, int range, MPHType maxspeed, unsigned rot, - WarheadType warhead, AnimType explosion) : - ObjectTypeClass(true, false, false, true, false, false, true, true, TXT_NONE, ininame, ARMOR_NONE, 0) -{ - Explosion = explosion; - IsHigh = is_high; - IsAntiAircraft = is_antiaircraft; - IsTranslucent = is_translucent; - IsArcing = is_arcing; - IsHoming = is_homing; - IsDropping = is_dropping; - IsInvisible = is_invisible; - IsProximityArmed = is_proximity_armed; - IsFlameEquipped = is_flame_equipped; - IsFueled = is_fueled; - IsFaceless = is_faceless; - IsInaccurate = is_inaccurate; - Type = type; - Warhead = warhead; - MaxSpeed = maxspeed; - ROT = rot; - Arming = arming; - Range = range; -} - - -/*********************************************************************************************** - * BulletTypeClass::One_Time -- Performs the one time processing for bullets. * - * * - * This routine is used to perform any one time processing for the bullet type class. It * - * handles loading of the shape files. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine must be called before any rendering of bullets occurs and should * - * only be called once. * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void BulletTypeClass::One_Time(void) -{ - BulletType index; - - /* - ** Load the bullet shapes. - */ - for (index = BULLET_FIRST; index < BULLET_COUNT; index++) { - BulletTypeClass const & bullet = As_Reference(index); - char fullname[_MAX_FNAME+_MAX_EXT]; - - if (!bullet.IsInvisible) { - _makepath(fullname, NULL, NULL, bullet.IniName, ".SHP"); - - RawFileClass file(fullname); - - if (file.Is_Available()) { - ((void const *&)bullet.ImageData) = Load_Alloc_Data(file); - } else { - ((void const *&)bullet.ImageData) = MixFileClass::Retrieve(fullname); - } - } - } -} - diff --git a/code/TIBERIANDAWN/BDATA.CPP b/code/TIBERIANDAWN/BDATA.CPP deleted file mode 100644 index 635e506..0000000 --- a/code/TIBERIANDAWN/BDATA.CPP +++ /dev/null @@ -1,4938 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\bdata.cpv 2.17 16 Oct 1995 16:50:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BDATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : July 17, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * BuildingTypeClass::As_Reference -- Fetches reference to the building type specified. * - * BuildingTypeClass::Bib_And_Offset -- Determines the bib and appropriate cell offset. * - * BuildingTypeClass::BuildingTypeClass -- This is the constructor for the building types. * - * BuildingTypeClass::Create_And_Place -- Creates and places a building object onto the map. * - * BuildingTypeClass::Create_One_Of -- Creates a building of this type. * - * BuildingTypeClass::Dimensions -- Fetches the pixel dimensions of the building. * - * BuildingTypeClass::Display -- Renders a generic view of building. * - * BuildingTypeClass::Full_Name -- Fetches the full name text number. * - * BuildingTypeClass::Height -- Determins the height of the building in icons. * - * BuildingTypeClass::Init -- Performs theater specific initialization. * - * BuildingTypeClass::Init_Anim -- Initialize an animation control for a building. * - * BuildingTypeClass::Legal_Placement -- Determines if building can be legally placed at pos.* - * BuildingTypeClass::Max_Pips -- Determines the maximum pips to display. * - * BuildingTypeClass::Occupy_List -- Fetches the occupy list for the building. * - * BuildingTypeClass::One_Time -- Performs special one time action for buildings. * - * BuildingTypeClass::Overlap_List -- Fetches the overlap list for the building. * - * BuildingTypeClass::Prep_For_Add -- Prepares scenario editor for adding an object. * - * BuildingTypeClass::Repair_Cost -- Determines cost per "step" of repair. * - * BuildingTypeClass::Repair_Step -- Determines the repair step rate. * - * BuildingTypeClass::Who_Can_Build_Me -- Determines which factory can create the building. * - * BuildingTypeClass::Width -- Determines width of bulding in icons. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#define MCW MAP_CELL_W - -#define XYCELL(x,y) (y*MAP_CELL_W+x) -static short const ExitPyle[] = { - XYCELL(1,2), - XYCELL(2,2), - XYCELL(0,2), - XYCELL(-1,2), - XYCELL(-1,-1), - XYCELL(0,-1), - XYCELL(1,-1), - XYCELL(2,-1), - XYCELL(2,-1), - XYCELL(-1,0), - XYCELL(2,0), - XYCELL(2,1), - XYCELL(-1,1), - REFRESH_EOL -}; -static short const ExitHand[] = { - XYCELL(2,3), - XYCELL(1,3), - XYCELL(0,3), - XYCELL(2,2), - XYCELL(-1,3), - XYCELL(-1,2), - XYCELL(0,0), - XYCELL(1,0), - XYCELL(-1,0), - XYCELL(2,0), - XYCELL(2,1), - XYCELL(-1,1), - REFRESH_EOL -}; -static short const ExitWeap[] = { - XYCELL(-1,3), - XYCELL(0,3), - XYCELL(-1,2), - XYCELL(1,3), -// XYCELL(0,0), -// XYCELL(1,0), -// XYCELL(2,0), -// XYCELL(-1,0), -// XYCELL(3,0), - XYCELL(-1,1), - XYCELL(3,1), - XYCELL(3,2), - XYCELL(3,3), - XYCELL(2,3), - REFRESH_EOL -}; -static short const ExitAirstrip[] = { - XYCELL(-1,-1), - XYCELL(-1,0), - XYCELL(-1,1), - XYCELL(-1,2), - XYCELL(0,-1), - XYCELL(0,2), - XYCELL(1,-1), - XYCELL(1,2), - XYCELL(2,-1), - XYCELL(2,2), - XYCELL(3,-1), - XYCELL(3,2), - XYCELL(4,-1), - XYCELL(4,0), - XYCELL(4,1), - XYCELL(4,2), - REFRESH_EOL -}; - -static short const OListSAM[] = {-MCW, -(MCW-1), REFRESH_EOL}; -static short const List32[] = {0, 1, 2, MCW, MCW+1, MCW+2, REFRESH_EOL}; -static short const List22_0011[] = {MCW, MCW+1, REFRESH_EOL}; -static short const List22_1100[] = {0, 1, REFRESH_EOL}; -static short const ListFix[] = {1, MCW, MCW+1, MCW+2, MCW+MCW+1, REFRESH_EOL}; -static short const StoreList[] = {0, 1, REFRESH_EOL}; -static short const List2[] = {0, 1, MCW+1, MCW, REFRESH_EOL}; -static short const List42[] = {0, 1, 2, 3, MCW, MCW+1, MCW+2, MCW+3, REFRESH_EOL}; -static short const ListWestwood[] = {1, 2, 3, MCW+1, MCW+2, MCW+3, REFRESH_EOL}; -static short const OListWestwood[] = {0, MCW, REFRESH_EOL}; -static short const ComList[] = {0, MCW, MCW+1, REFRESH_EOL}; -static short const List21[] = {0, 1, REFRESH_EOL}; -static short const ListWeap[] = {(MCW*1), (MCW*1)+1, (MCW*1)+2, (MCW*2), (MCW*2)+1, (MCW*2)+2, REFRESH_EOL}; -static short const List12[] = {MCW, REFRESH_EOL}; -static short const ListHand[] = {MCW, MCW+1, MCW*2+1, REFRESH_EOL}; -static short const ListTmpl[] = {MCW, MCW+1, MCW+2, MCW*2, MCW*2+1, MCW*2+2, REFRESH_EOL}; -static short const List0011[] = {(MCW*1), (MCW*1)+1, REFRESH_EOL}; -static short const List1101[] = {0, 1, (MCW*1)+1, REFRESH_EOL}; -static short const List11[] = {0, 1, REFRESH_EOL}; -static short const List1[] = {0, REFRESH_EOL}; -static short const List1100[] = {0, 1, REFRESH_EOL}; -static short const List0010[] = {MCW, REFRESH_EOL}; -static short const List1000[] = {0, REFRESH_EOL}; -static short const List0100[] = {1, REFRESH_EOL}; -static short const List0111[] = {1, (MCW*1), (MCW*1)+1, REFRESH_EOL}; -//static short const List1111[] = {0, 1, (MCW*1), (MCW*1)+1, REFRESH_EOL}; -static short const List1011[] = {0, (MCW*1), (MCW*1)+1, REFRESH_EOL}; -static short const List010111000[] = {1, (MCW*1), (MCW*1)+1, (MCW*1)+2, REFRESH_EOL}; -static short const List101000111[] = {0, 2, (MCW*2), (MCW*2)+1, (MCW*2)+2, REFRESH_EOL}; - -static short const OListFix[] = {0, 2, MCW+MCW, MCW+MCW+2, REFRESH_EOL}; -static short const OListWeap[] = {0, 1, 2, REFRESH_EOL}; -static short const OComList[] = {1, REFRESH_EOL}; -static short const OList12[] = {0, REFRESH_EOL}; -static short const OListHand[] = {0, 1, MCW*2, MCW*1, REFRESH_EOL}; -static short const OListTmpl[] = {0, 1, 2, REFRESH_EOL}; - - -/*************************************************************************** -*/ -static BuildingTypeClass const ClassTemple( - STRUCT_TEMPLE, - TXT_TEMPLE, // NAME: Short name of the structure. - "TMPL", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 7, // Build level. - STRUCTF_RADAR, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1000, // STRNTH: Full strength of building. - 4, // SIGHTRANGE: Range of sighting. - 3000, // COST: Cost to purchase. - 13, // SCENARIO: Starting availability scenario. - 0,20, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points generated. - 150, // DRAIN: Power points required. - BSIZE_33, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)ListTmpl, // OCCUPYLIST: List of active foundation squares. - (short const *)OListTmpl // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassEye( - STRUCT_EYE, - TXT_EYE, // NAME: Short name of the structure. - "EYE", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 7, // Build level. - STRUCTF_RADAR, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - (DirType)160, // Starting idle frame to match construction. - 500, // STRNTH: Full strength of building. - 10, // SIGHTRANGE: Range of sighting. - 2800, // COST: Cost to purchase. - 13, // SCENARIO: Starting availability scenario. - 0,100, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 200, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)ComList, // OCCUPYLIST: List of active foundation squares. - (short const *)OComList // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassWeapon( - STRUCT_WEAP, - TXT_WEAPON_FACTORY, // NAME: Short name of the structure. - "WEAP", // NAME: Short name of the structure. - XYP_COORD(10+(CELL_PIXEL_W/2), ((CELL_PIXEL_H*3)-(CELL_PIXEL_H/2))-21), // Exit point for produced units. - 2, // Build level. - STRUCTF_REFINERY, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - true, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_UNITTYPE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. -#ifdef ADVANCED - 500, // STRNTH: Full strength of building. -#else - 200, // STRNTH: Full strength of building. -#endif - 3, // SIGHTRANGE: Range of sighting. - 2000, // COST: Cost to purchase. - 5, // SCENARIO: Starting availability scenario. - 0,86, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 30, // DRAIN: Power points required. - BSIZE_33, // SIZE: Building size. - (short const *)ExitWeap, // Preferred exit cell list. - (short const *)ListWeap, // OCCUPYLIST: List of active foundation squares. - (short const *)OListWeap // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassGTower( - STRUCT_GTOWER, - TXT_GUARD_TOWER, // NAME: Short name of the structure. - "GTWR", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 2, // Build level. - STRUCTF_BARRACKS, // Building prerequisite. - true, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 500, // COST: Cost to purchase. - 7, // SCENARIO: Starting availability scenario. - 100,25, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_CHAIN_GUN,WEAPON_NONE, -// WEAPON_M60MG,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 00, // POWER: Power points required. - 10, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassATower( - STRUCT_ATOWER, - TXT_AGUARD_TOWER, // NAME: Short name of the structure. - "ATWR", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 4, // Build level. - STRUCTF_RADAR, // Building prerequisite. - true, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - true, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 300, // STRNTH: Full strength of building. - 4, // SIGHTRANGE: Range of sighting. - 1000, // COST: Cost to purchase. - 13, // SCENARIO: Starting availability scenario. - 100,30, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_TOW_TWO,WEAPON_NONE, -// WEAPON_TOMAHAWK,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 20, // DRAIN: Power points required. - BSIZE_12, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List12, // OCCUPYLIST: List of active foundation squares. - (short const *)OList12 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassObelisk( - STRUCT_OBELISK, - TXT_OBELISK, // NAME: Short name of the structure. - "OBLI", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 4, // Build level. - STRUCTF_RADAR, // Building prerequisite. - true, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 5, // SIGHTRANGE: Range of sighting. - 1500, // COST: Cost to purchase. - 11, // SCENARIO: Starting availability scenario. - 100,35, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_OBELISK_LASER,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 150, // DRAIN: Power points required. - BSIZE_12, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List12, // OCCUPYLIST: List of active foundation squares. - (short const *)OList12 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassTurret( - STRUCT_TURRET, - TXT_TURRET, // NAME: Short name of the structure. - "GUN", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 2, // Build level. - STRUCTF_BARRACKS, // Building prerequisite. - true, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - true, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - (DirType)208, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 5, // SIGHTRANGE: Range of sighting. -#ifdef ADVANCED - 600, // COST: Cost to purchase. -#else -#ifdef PATCH - 600, -#else - 250, // COST: Cost to purchase. -#endif -#endif - 8, // SCENARIO: Starting availability scenario. - 300,26, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_TURRET_GUN,WEAPON_NONE, - ARMOR_STEEL, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 20, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassConst( - STRUCT_CONST, - TXT_CONST_YARD, // NAME: Short name of the structure. - "FACT", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - true, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_BUILDINGTYPE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 400, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 5000, // COST: Cost to purchase. - 1, // SCENARIO: Starting availability scenario. - 0,70, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 30, // POWER: Power points required. - 15, // DRAIN: Power points required. - BSIZE_32, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List32, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassRefinery( - STRUCT_REFINERY, - TXT_REFINERY, // NAME: Short name of the structure. - "PROC", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 1, // Build level. - STRUCTF_POWER, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 450, // STRNTH: Full strength of building. - 4, // SIGHTRANGE: Range of sighting. - 2000, // COST: Cost to purchase. - 2, // SCENARIO: Starting availability scenario. - 0,55, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 1000, // CAPACITY: Spice storage capacity. - 10, // POWER: Power points required. - 40, // DRAIN: Power points required. - BSIZE_33, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List010111000, // OCCUPYLIST: List of active foundation squares. - (short const *)List101000111 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassStorage( - STRUCT_STORAGE, - TXT_STORAGE, // NAME: Short name of the structure. - "SILO", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 1, // Build level. - STRUCTF_REFINERY, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 150, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 150, // COST: Cost to purchase. -// 300, // COST: Cost to purchase. - 2, // SCENARIO: Starting availability scenario. - 0,16, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 1500, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 10, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)StoreList, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassHelipad( - STRUCT_HELIPAD, - TXT_HELIPAD, // NAME: Short name of the structure. - "HPAD", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 6, // Build level. - STRUCTF_BARRACKS, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - true, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_AIRCRAFTTYPE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 400, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 1500, // COST: Cost to purchase. - 10, // SCENARIO: Starting availability scenario. - 0,65, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 10, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List2, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassCommand( - STRUCT_RADAR, - TXT_COMMAND, // NAME: Short name of the structure. - "HQ", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 2, // Build level. - STRUCTF_REFINERY, // Building prerequisite. - true, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - (DirType)160, // Starting idle frame to match construction. - 500, // STRNTH: Full strength of building. - 10, // SIGHTRANGE: Range of sighting. - 1000, // COST: Cost to purchase. - 3, // SCENARIO: Starting availability scenario. - 0,20, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 40, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)ComList, // OCCUPYLIST: List of active foundation squares. - (short const *)OComList // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassSAM( - STRUCT_SAM, - TXT_SAM, // NAME: Short name of the structure. - "SAM", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 6, // Build level. - STRUCTF_BARRACKS, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - true, // Does it have a rotating turret? - true, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 750, // COST: Cost to purchase. - 5, // SCENARIO: Starting availability scenario. - 300,40, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NIKE,WEAPON_NONE, - ARMOR_STEEL, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 20, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List21, // OCCUPYLIST: List of active foundation squares. - (short const *)OListSAM // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassAirStrip( - STRUCT_AIRSTRIP, - TXT_AIRSTRIP, // NAME: Short name of the structure. - "AFLD", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 2, // Build level. - STRUCTF_REFINERY, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - true, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_UNITTYPE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 500, // STRNTH: Full strength of building. - 5, // SIGHTRANGE: Range of sighting. - 2000, // COST: Cost to purchase. - 5, // SCENARIO: Starting availability scenario. - 300,86, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_STEEL, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 30, // DRAIN: Power points required. - BSIZE_42, // SIZE: Building size. - ExitAirstrip, // Preferred exit cell list. - (short const *)List42, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassPower( - STRUCT_POWER, - TXT_POWER, // NAME: Short name of the structure. - "NUKE", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 0, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 300, // COST: Cost to purchase. - 1, // SCENARIO: Starting availability scenario. - 0,50, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 100, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1011, // OCCUPYLIST: List of active foundation squares. - (short const *)List0100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassAdvancedPower( - STRUCT_ADVANCED_POWER, - TXT_ADVANCED_POWER, // NAME: Short name of the structure. - "NUK2", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 5, // Build level. - STRUCTF_POWER, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 300, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 700, // COST: Cost to purchase. - 13, // SCENARIO: Starting availability scenario. - 0,75, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 200, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1011, // OCCUPYLIST: List of active foundation squares. - (short const *)List0100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassHospital( - STRUCT_HOSPITAL, - TXT_HOSPITAL, // NAME: Short name of the structure. - "HOSP", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_BARRACKS, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 500, // COST: Cost to purchase. - 99, // SCENARIO: Starting availability scenario. - 0,20, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 100, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 20, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List2, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL, // OVERLAPLIST:List of overlap cell offset. - true // Is this building un-sellable? -); - -static BuildingTypeClass const ClassBioLab( - STRUCT_BIO_LAB, - TXT_BIO_LAB, // NAME: Short name of the structure. - "BIO", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_HOSPITAL, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 300, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 500, // COST: Cost to purchase. - 99, // SCENARIO: Starting availability scenario. - 0,1, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 100, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 40, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List2, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassBarracks( - STRUCT_BARRACKS, - TXT_BARRACKS, // NAME: Short name of the structure. - "PYLE", // NAME: Short name of the structure. - XYP_COORD(30,33), // Exit point for produced units. - 0, // Build level. - STRUCTF_POWER, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - true, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_INFANTRYTYPE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 400, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 300, // COST: Cost to purchase. - 1, // SCENARIO: Starting availability scenario. - 0,60, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 20, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - (short const *)ExitPyle, // Preferred exit cell list. - (short const *)List22_1100, // OCCUPYLIST: List of active foundation squares. - (short const *)List22_0011 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassHand( - STRUCT_HAND, - TXT_HAND, // NAME: Short name of the structure. - "HAND", // NAME: Short name of the structure. - XYP_COORD(36,63), // Exit point for produced units. - 0, // Build level. - STRUCTF_POWER, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - true, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_INFANTRYTYPE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 400, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 300, // COST: Cost to purchase. - 2, // SCENARIO: Starting availability scenario. - 0,61, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 20, // DRAIN: Power points required. - BSIZE_23, // SIZE: Building size. - (short const *)ExitHand, // Preferred exit cell list. - (short const *)ListHand, // OCCUPYLIST: List of active foundation squares. - (short const *)OListHand // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassTanker( - STRUCT_TANKER, - TXT_TANKER, // NAME: Short name of the structure. - "ARCO", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_POWER, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 100, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,1, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List21, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassRepair( - STRUCT_REPAIR, - TXT_FIX_IT, // NAME: Short name of the structure. - "FIX", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 5, // Build level. - STRUCTF_POWER, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - false, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - true, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 400, // STRNTH: Full strength of building. - 3, // SIGHTRANGE: Range of sighting. - 1200, // COST: Cost to purchase. - 8, // SCENARIO: Starting availability scenario. - 0,46, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 30, // DRAIN: Power points required. - BSIZE_33, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)ListFix, // OCCUPYLIST: List of active foundation squares. - (short const *)OListFix // OVERLAPLIST:List of overlap cell offset. -); - -#ifdef OBSOLETE -static BuildingTypeClass const ClassRoad( - STRUCT_ROAD, - TXT_ROAD, // NAME: Short name of the structure. - "ROAD", // NAME: Short name of the structure. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - 0, // Building prerequisite. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - false, // Can the player select this? - false, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1, // STRNTH: Full strength of building. - 0, // SIGHTRANGE: Range of sighting. - 50, // COST: Cost to purchase. - 99, // SCENARIO: Starting availability scenario. - 0,0, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_NONE, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); -#endif - -static BuildingTypeClass const ClassV01( - STRUCT_V01, - TXT_CIV1, // NAME: Short name of the structure. - "V01", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0011, // OCCUPYLIST: List of active foundation squares. - (short const *)List1100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV02( - STRUCT_V02, - TXT_CIV2, // NAME: Short name of the structure. - "V02", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0011, // OCCUPYLIST: List of active foundation squares. - (short const *)List1100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV03( - STRUCT_V03, - TXT_CIV3, // NAME: Short name of the structure. - "V03", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0111, // OCCUPYLIST: List of active foundation squares. - (short const *)List1000 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV04( - STRUCT_V04, - TXT_CIV4, // NAME: Short name of the structure. - "V04", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0011, // OCCUPYLIST: List of active foundation squares. - (short const *)List1100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV05( - STRUCT_V05, - TXT_CIV5, // NAME: Short name of the structure. - "V05", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV06( - STRUCT_V06, - TXT_CIV6, // NAME: Short name of the structure. - "V06", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV07( - STRUCT_V07, - TXT_CIV7, // NAME: Short name of the structure. - "V07", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV08( - STRUCT_V08, - TXT_CIV8, // NAME: Short name of the structure. - "V08", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV09( - STRUCT_V09, - TXT_CIV9, // NAME: Short name of the structure. - "V09", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV10( - STRUCT_V10, - TXT_CIV10, // NAME: Short name of the structure. - "V10", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV11( - STRUCT_V11, - TXT_CIV11, // NAME: Short name of the structure. - "V11", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV12( - STRUCT_V12, - TXT_CIV12, // NAME: Short name of the structure. - "V12", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV13( - STRUCT_V13, - TXT_CIV13, // NAME: Short name of the structure. - "V13", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV14( - STRUCT_V14, - TXT_CIV14, // NAME: Short name of the structure. - "V14", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV15( - STRUCT_V15, - TXT_CIV15, // NAME: Short name of the structure. - "V15", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV16( - STRUCT_V16, - TXT_CIV16, // NAME: Short name of the structure. - "V16", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV17( - STRUCT_V17, - TXT_CIV17, // NAME: Short name of the structure. - "V17", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV18( - STRUCT_V18, - TXT_CIV18, // NAME: Short name of the structure. - "V18", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - true, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 1, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV19( - STRUCT_PUMP, - TXT_PUMP, // NAME: Short name of the structure. - "V19", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV20( - STRUCT_V20, - TXT_CIV20, // NAME: Short name of the structure. - "V20", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0011, // OCCUPYLIST: List of active foundation squares. - (short const *)List1100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV21( - STRUCT_V21, - TXT_CIV21, // NAME: Short name of the structure. - "V21", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1101, // OCCUPYLIST: List of active foundation squares. - (short const *)List0010 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV22( - STRUCT_V22, - TXT_CIV22, // NAME: Short name of the structure. - "V22", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV23( - STRUCT_V23, - TXT_CIV23, // NAME: Short name of the structure. - "V23", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV24( - STRUCT_V24, - TXT_CIV24, // NAME: Short name of the structure. - "V24", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0011, // OCCUPYLIST: List of active foundation squares. - (short const *)List1100 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV25( - STRUCT_V25, - TXT_CIV25, // NAME: Short name of the structure. - "V25", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_22, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List0111, // OCCUPYLIST: List of active foundation squares. - (short const *)List1000 // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV26( - STRUCT_V26, - TXT_CIV26, // NAME: Short name of the structure. - "V26", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV27( - STRUCT_V27, - TXT_CIV27, // NAME: Short name of the structure. - "V27", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV28( - STRUCT_V28, - TXT_CIV28, // NAME: Short name of the structure. - "V28", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV29( - STRUCT_V29, - TXT_CIV29, // NAME: Short name of the structure. - "V29", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV30( - STRUCT_V30, - TXT_CIV30, // NAME: Short name of the structure. - "V30", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV31( - STRUCT_V31, - TXT_CIV31, // NAME: Short name of the structure. - "V31", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV32( - STRUCT_V32, - TXT_CIV32, // NAME: Short name of the structure. - "V32", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV33( - STRUCT_V33, - TXT_CIV33, // NAME: Short name of the structure. - "V33", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_21, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List11, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV34( - STRUCT_V34, - TXT_CIV34, // NAME: Short name of the structure. - "V34", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV35( - STRUCT_V35, - TXT_CIV35, // NAME: Short name of the structure. - "V35", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -static BuildingTypeClass const ClassV36( - STRUCT_V36, - TXT_CIV36, // NAME: Short name of the structure. - "V36", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); -static BuildingTypeClass const ClassV37( - STRUCT_V37, - TXT_CIV37, // NAME: Short name of the structure. - "V37", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - true, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 300, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 0, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_42, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)ListWestwood, // OCCUPYLIST: List of active foundation squares. - (short const *)OListWestwood // OVERLAPLIST:List of overlap cell offset. -); -static BuildingTypeClass const ClassMission( - STRUCT_MISSION, - TXT_CIVMISS, // NAME: Short name of the structure. - "MISS", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - true, // Has ability to detect adjacent cloaked objects? - true, // Animation rate is regulated for constant speed? - true, // Requires a bib dirt patch? - true, // Always use the given name for the building? - false, // Is this a wall type structure? - false, // Is it a factory type building? - true, // Can this building be captured? - true, // Does it catch fire? - true, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - true, // Can the player select this? - true, // Is this a legal target for attack or move? - false, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - true, // Can it be repaired? - false, // Can it be manufactured by the player? - true, // Does it contain a crew? - false, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 200, // STRNTH: Full strength of building. - 2, // SIGHTRANGE: Range of sighting. - 1000, // COST: Cost to purchase. - 0, // SCENARIO: Starting availability scenario. - 0,2, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_WOOD, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_32, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List32, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - -// Sandbag wall -static BuildingTypeClass const Sandbag( - STRUCT_SANDBAG_WALL, - TXT_SANDBAG_WALL, // NAME: Short name of the structure. - "SBAG", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 2, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - true, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - false, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1, // STRNTH: Full strength of building. - 0, // SIGHTRANGE: Range of sighting. - 50, // COST: Cost to purchase. - 5, // SCENARIO: Starting availability scenario. - 0,0, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); -// Cyclone fence -static BuildingTypeClass const Cyclone( - STRUCT_CYCLONE_WALL, - TXT_CYCLONE_WALL, // NAME: Short name of the structure. - "CYCL", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 5, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - true, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - false, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1, // STRNTH: Full strength of building. - 0, // SIGHTRANGE: Range of sighting. - 75, // COST: Cost to purchase. - 9, // SCENARIO: Starting availability scenario. - 0,0, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); -// Brick wall -static BuildingTypeClass const Brick( - STRUCT_BRICK_WALL, - TXT_BRICK_WALL, // NAME: Short name of the structure. - "BRIK", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 7, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - true, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - false, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1, // STRNTH: Full strength of building. - 0, // SIGHTRANGE: Range of sighting. - 100, // COST: Cost to purchase. - 13, // SCENARIO: Starting availability scenario. - 0,0, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); -// Barbwire wall -static BuildingTypeClass const Barbwire( - STRUCT_BARBWIRE_WALL, - TXT_BARBWIRE_WALL, // NAME: Short name of the structure. - "BARB", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 98, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - true, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - false, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1, // STRNTH: Full strength of building. - 0, // SIGHTRANGE: Range of sighting. - 25, // COST: Cost to purchase. - 98, // SCENARIO: Starting availability scenario. - 0,0, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_BAD| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); -// Wood wall -static BuildingTypeClass const Wood( - STRUCT_WOOD_WALL, - TXT_WOOD_WALL, // NAME: Short name of the structure. - "WOOD", // NAME: Short name of the structure. - XYP_COORD(0,0), // Exit point for produced units. - 99, // Build level. - STRUCTF_NONE, // PREREQ: Buildings that must exist first. - false, // Has ability to detect adjacent cloaked objects? - false, // Animation rate is regulated for constant speed? - false, // Requires a bib dirt patch? - true, // Always use the given name for the building? - true, // Is this a wall type structure? - false, // Is it a factory type building? - false, // Can this building be captured? - false, // Does it catch fire? - false, // Simple (one frame) damage imagery? - false, // Is it invisible to radar? - false, // Can the player select this? - true, // Is this a legal target for attack or move? - true, // Is this an insignificant building? - false, // Is it immune to normal combat damage? - false, // Theater specific graphic image? - false, // Does it have a rotating turret? - false, // Fires multiple shots in quick succession? - false, // Can it be repaired? - true, // Can it be manufactured by the player? - false, // Does it contain a crew? - true, // Does building care less if placed on concrete? - RTTI_NONE, // The object type produced at this factory. - DIR_N, // Starting idle frame to match construction. - 1, // STRNTH: Full strength of building. - 0, // SIGHTRANGE: Range of sighting. - 25, // COST: Cost to purchase. - 98, // SCENARIO: Starting availability scenario. - 0,0, // RISK/RWRD: Risk/reward rating values. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_NEUTRAL| - HOUSEF_GOOD, // OWNABLE: Ownable by house (bit field). - WEAPON_NONE,WEAPON_NONE, - ARMOR_ALUMINUM, // ARMOR: Armor type - 0, // CANENTER: Units that can enter building. - 0, // CAPACITY: Spice storage capacity. - 0, // POWER: Power points required. - 0, // DRAIN: Power points required. - BSIZE_11, // SIZE: Building size. - NULL, // Preferred exit cell list. - (short const *)List1, // OCCUPYLIST: List of active foundation squares. - (short const *)NULL // OVERLAPLIST:List of overlap cell offset. -); - - -BuildingTypeClass const * const BuildingTypeClass::Pointers[STRUCT_COUNT] = { - &ClassWeapon, // STRUCT_WEAP - &ClassGTower, // STRUCT_GTOWER - &ClassATower, // STRUCT_ATOWER - &ClassObelisk, // STRUCT_OBLISK - &ClassCommand, // STRUCT_RADAR - &ClassTurret, // STRUCT_TURRET - &ClassConst, // STRUCT_CONST - &ClassRefinery, // STRUCT_REFINERY - &ClassStorage, // STRUCT_STORAGE - &ClassHelipad, // STRUCT_HELIPAD - &ClassSAM, // STRUCT_SAM - &ClassAirStrip, // STRUCT_AIRSTRIP - &ClassPower, // STRUCT_POWER - &ClassAdvancedPower, // STRUCT_POWER - &ClassHospital, // STRUCT_HOSPITAL - &ClassBarracks, // STRUCT_BARRACKS - &ClassTanker, // STRUCT_TANKER - &ClassRepair, // STRUCT_REPAIR - &ClassBioLab, // STRUCT_BIO_LAB - &ClassHand, // STRUCT_HAND - &ClassTemple, // STRUCT_TEMPLE - &ClassEye, // STRUCT_EYE - &ClassMission, // STRUCT_MISSION - - &ClassV01, // STRUCT_V1 - &ClassV02, // STRUCT_V2 - &ClassV03, // STRUCT_V3 - &ClassV04, // STRUCT_V4 - &ClassV05, // STRUCT_V5 - &ClassV06, // STRUCT_V6 - &ClassV07, // STRUCT_V7 - &ClassV08, // STRUCT_V8 - &ClassV09, // STRUCT_V9 - &ClassV10, // STRUCT_V10 - &ClassV11, // STRUCT_V11 - &ClassV12, // STRUCT_V12 - &ClassV13, // STRUCT_V13 - &ClassV14, // STRUCT_V14 - &ClassV15, // STRUCT_V15 - &ClassV16, // STRUCT_V16 - &ClassV17, // STRUCT_V17 - &ClassV18, // STRUCT_V18 - &ClassV19, // STRUCT_PUMP - &ClassV20, // STRUCT_V20 - &ClassV21, // STRUCT_V21 - &ClassV22, // STRUCT_V22 - &ClassV23, // STRUCT_V23 - &ClassV24, // STRUCT_V24 - &ClassV25, // STRUCT_V25 - &ClassV26, // STRUCT_V26 - &ClassV27, // STRUCT_V27 - &ClassV28, // STRUCT_V28 - &ClassV29, // STRUCT_V29 - &ClassV30, // STRUCT_V30 - &ClassV31, // STRUCT_V31 - &ClassV32, // STRUCT_V32 - &ClassV33, // STRUCT_V33 - &ClassV34, // STRUCT_V34 - &ClassV35, // STRUCT_V35 - &ClassV36, // STRUCT_V36 - &ClassV37, // STRUCT_V37 -#ifdef OBSOLETE - &ClassRoad, // STRUCT_ROAD -#endif - &Sandbag, // STRUCT_SANDBAG_WALL - &Cyclone, // STRUCT_CYCLONE_WALL - &Brick, // STRUCT_BRICK_WALL - &Barbwire, // STRUCT_BARBWIRE_WALL - &Wood, // STRUCT_WOOD_WALL -}; - -void const *WarFactoryOverlay; - - -/*********************************************************************************************** - * BuildingTypeClass::BuildingTypeClass -- This is the constructor for the building types. * - * * - * This is the constructor used to create the building types. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1994 JLB : Created. * - *=============================================================================================*/ -BuildingTypeClass::BuildingTypeClass( - StructType type, - int name, - char const *ininame, - COORDINATE exitpoint, - unsigned char level, - long pre, - bool is_scanner, - bool is_regulated, - bool is_bibbed, - bool is_nominal, - bool is_wall, - bool is_factory, - bool is_captureable, - bool is_flammable, - bool is_simpledamage, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - bool is_theater, - bool is_turret_equipped, - bool is_twoshooter, - bool is_repairable, - bool is_buildable, - bool is_crew, - bool is_sturdy, - RTTIType tobuild, - DirType sframe, - unsigned short strength, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, WeaponType secondary, - ArmorType armor, - unsigned long canenter, - unsigned capacity, - int power, - int drain, - BSizeType size, - short const *exitlist, - short const *sizelist, - short const *overlap, - bool is_unsellable) : - TechnoTypeClass(name, - ininame, - level, - pre, - false, - is_scanner, - is_nominal, - false, - is_flammable, - false, - is_stealthy, - is_selectable, - is_legal_target, - is_insignificant, - is_immune, - is_theater, - is_twoshooter, - is_turret_equipped, - is_repairable, - is_buildable, - is_crew, - -1, - strength*2, - MPH_IMMOBILE, - sightrange, - cost, - scenario, - risk, - reward, - ownable, - primary, - secondary, - armor) -{ - CanEnter = canenter; - Capacity = capacity; - Drain = drain; - ExitList = exitlist; - ExitPoint = exitpoint; - IsBibbed = is_bibbed; - IsCaptureable = is_captureable; - IsFactory = is_factory; - IsRegulated = is_regulated; - IsUnsellable = is_unsellable; - IsSimpleDamage = is_simpledamage; - IsSturdy = is_sturdy; - IsWall = is_wall; - OccupyList = sizelist; - OverlapList = overlap; - Power = power; - Size = size; - StartFace = sframe; - ToBuild = tobuild; - Type = type; - - Anims[BSTATE_CONSTRUCTION].Start = 0; - Anims[BSTATE_CONSTRUCTION].Count = 1; - Anims[BSTATE_CONSTRUCTION].Rate = 0; - - Anims[BSTATE_IDLE].Start = 0; - Anims[BSTATE_IDLE].Count = 1; - Anims[BSTATE_IDLE].Rate = 0; - - Anims[BSTATE_ACTIVE].Start = 0; - Anims[BSTATE_ACTIVE].Count = 1; - Anims[BSTATE_ACTIVE].Rate = 0; - - Anims[BSTATE_AUX1].Start = 0; - Anims[BSTATE_AUX1].Count = 1; - Anims[BSTATE_AUX1].Rate = 0; - - Anims[BSTATE_AUX2].Start = 0; - Anims[BSTATE_AUX2].Count = 1; - Anims[BSTATE_AUX2].Rate = 0; -} - - -/*********************************************************************************************** - * BuildingTypeClass::One_Time -- Performs special one time action for buildings. * - * * - * This routine is used to do the one time action necessary to handle building type class * - * objects. This entails loading of the building shapes and the brain file used by * - * buildings. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine should only be called ONCE. * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - * 06/11/1994 JLB : Updated construction time and frame count logic. * - *=============================================================================================*/ -void BuildingTypeClass::One_Time(void) -{ - static const struct { - StructType Class; // Building class number. - BStateType Stage; // Animation sequence to assign animation range to. - int Start; // Starting frame number. - int Length; // Number of frames (-1 means use all frames). - int Rate; // Rate of animation. - } _anims[] = { - {STRUCT_OBELISK, BSTATE_ACTIVE, 0, 4, OBELISK_ANIMATION_RATE}, - {STRUCT_ADVANCED_POWER, BSTATE_IDLE, 0, 4, 15}, - {STRUCT_AIRSTRIP, BSTATE_IDLE, 0, 16,3}, - {STRUCT_BARRACKS, BSTATE_ACTIVE, 0, 10,3}, - {STRUCT_BARRACKS, BSTATE_IDLE, 0, 10,3}, - {STRUCT_CONST, BSTATE_ACTIVE, 4, 20,3}, - {STRUCT_CONST, BSTATE_IDLE, 0, 4, 3}, - {STRUCT_EYE, BSTATE_IDLE, 0, 16,4}, - {STRUCT_HELIPAD, BSTATE_ACTIVE, 0, 7, 4}, - {STRUCT_HELIPAD, BSTATE_IDLE, 0, 0, 0}, - {STRUCT_HOSPITAL, BSTATE_IDLE, 0, 4, 3}, - {STRUCT_POWER, BSTATE_IDLE, 0, 4, 15}, - {STRUCT_PUMP, BSTATE_IDLE, 0, 14,4}, - {STRUCT_RADAR, BSTATE_IDLE, 0, 16,4}, - {STRUCT_REFINERY, BSTATE_ACTIVE, 12,7, 4}, // Docking phase. - {STRUCT_REFINERY, BSTATE_AUX1, 19,5, 4}, // Siphoning phase. - {STRUCT_REFINERY, BSTATE_AUX2, 24,6, 4}, // Undocking phase. - {STRUCT_REFINERY, BSTATE_IDLE, 0, 6, 4}, // Idle phase. - {STRUCT_REFINERY, BSTATE_FULL, 6, 6, 4}, // Flashing lights - {STRUCT_REPAIR, BSTATE_ACTIVE, 0, 7, 2}, - {STRUCT_REPAIR, BSTATE_IDLE, 0, 1, 0}, - {STRUCT_TEMPLE, BSTATE_IDLE, 0, 1, 0}, - {STRUCT_V20, BSTATE_IDLE, 0, 3, 3}, - {STRUCT_V21, BSTATE_IDLE, 0, 3, 3}, - {STRUCT_V22, BSTATE_IDLE, 0, 3, 3}, - {STRUCT_V23, BSTATE_IDLE, 0, 3, 3}, - {STRUCT_WEAP, BSTATE_ACTIVE, 0, 1, 0}, - {STRUCT_WEAP, BSTATE_IDLE, 0, 1, 0}, - {STRUCT_TEMPLE, BSTATE_ACTIVE, 0, 5, 1}, - }; - - for (StructType sindex = STRUCT_FIRST; sindex < STRUCT_COUNT; sindex++) { - char fullname[_MAX_FNAME+_MAX_EXT]; - char buffer[_MAX_FNAME]; - BuildingTypeClass const & building = As_Reference(sindex); - - /* - ** Fetch the sidebar cameo image for this building. - */ - if (building.IsBuildable) { - if ( Get_Resolution_Factor() ) { - sprintf(buffer, "%sICNH", building.IniName); - } else { - sprintf(buffer, "%sICON", building.IniName); - } - _makepath(fullname, NULL, NULL, buffer, ".SHP"); - ((void const *&)building.CameoData) = MixFileClass::Retrieve(fullname); - } - - /* - ** Fetch the construction animation for this building. - */ - sprintf(buffer, "%sMAKE", building.IniName); - _makepath(fullname, NULL, NULL, buffer, ".SHP"); - void const * dataptr = MixFileClass::Retrieve(fullname); - ((void const *&)building.BuildupData) = dataptr; - if (dataptr) { - int timedelay = 1; - int count = Get_Build_Frame_Count(dataptr); - if (count) { - timedelay = (5 * TICKS_PER_SECOND) / count; - } - building.Init_Anim(BSTATE_CONSTRUCTION, 0, count, timedelay); - } - - /* - ** Fetch the normal game shape for this building. - */ - _makepath(fullname, NULL, NULL, building.IniName, ".SHP"); - ((void const *&)building.ImageData) = MixFileClass::Retrieve(fullname); - } - - // Try to load weap2.shp - char fullname[_MAX_FNAME+_MAX_EXT]; - _makepath(fullname, NULL, NULL, (char const *)"WEAP2",".SHP"); - WarFactoryOverlay = MixFileClass::Retrieve(fullname); - - /* - ** Install all the special animation sequences for the different building types. - */ - for (unsigned index = 0; index < (sizeof(_anims) / sizeof(_anims[0])); index++) { - BuildingTypeClass const *b = &As_Reference(_anims[index].Class); - if (b) { - b->Init_Anim(_anims[index].Stage, _anims[index].Start, _anims[index].Length, _anims[index].Rate); - } - } -} - - - - -/*********************************************************************************************** - * Struct_From_Name -- Find BData structure from its name. * - * * - * This routine will convert an ASCII name for a building class into * - * the actual building class it represents. * - * * - * INPUT: name -- ASCII representation of a building class. * - * * - * OUTPUT: Returns with the actual building class number that the string * - * represents. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 05/02/1994 JLB : Converted to member function. * - *=============================================================================================*/ -StructType BuildingTypeClass::From_Name(char const *name) -{ - if (name) { - for (StructType classid = STRUCT_FIRST; classid < STRUCT_COUNT; classid++) { - if (stricmp(As_Reference(classid).IniName, name) == 0) { - return(classid); - } - } - } - return(STRUCT_NONE); -} - - -#ifdef SCENARIO_EDITOR -/*********************************************************************************************** - * BuildingTypeClass::Display -- Renders a generic view of building. * - * * - * This routine is used to display a generic representation of the * - * building. Typical use of this occurs with the scenario editor. * - * * - * INPUT: x,y -- Coordinate to display the building (centered). * - * * - * window -- The window the building should be rendered * - * relative to. * - * * - * house -- The house color to use for the building. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingTypeClass::Display(int x, int y, WindowNumberType window, HousesType house) const -{ - void const * ptr = Get_Cameo_Data(); - if (!ptr) { - ptr = Get_Image_Data(); - } - CC_Draw_Shape(ptr, 0, x, y, window, SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL, HouseTypeClass::As_Reference(house).RemapTable); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Prep_For_Add -- Prepares scenario editor for adding a * - * * - * This routine is used to prepare the scenario editor for the addition * - * of a building object to the game. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - * 06/04/1994 JLB : Uses map editing interface routines. * - *=============================================================================================*/ -void BuildingTypeClass::Prep_For_Add(void) -{ - for (StructType index = STRUCT_FIRST; index < STRUCT_COUNT; index++) { - if (As_Reference(index).Get_Image_Data()) { - Map.Add_To_List(&As_Reference(index)); - } - } -} -#endif - - -/*********************************************************************************************** - * BuildingTypeClass::Create_And_Place -- Creates and places a building object onto the map. * - * * - * This routine is used by the scenario editor to create and place buildings on the map. * - * * - * INPUT: cell -- The cell that the building is to be placed upon. * - * * - * house -- The owner of the building. * - * * - * OUTPUT: bool; Was the building successfully created and placed on the map? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -bool BuildingTypeClass::Create_And_Place(CELL cell, HousesType house) const -{ - BuildingClass * ptr; - - ptr = new BuildingClass(Type, house); - if (ptr) { - return(ptr->Unlimbo(Cell_Coord(cell), DIR_N)); - } - return(false); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Create_One_Of -- Creates a building of this type. * - * * - * This routine will create a building object of this type. The building object is in a * - * limbo state. It is presumed that the building object will be unlimboed at the correct * - * place and time. Typical use is when the building is created in a factory situation * - * and will be placed on the map when construction completes. * - * * - * INPUT: house -- Pointer to the house that is to be the owner of the building. * - * * - * OUTPUT: Returns with a pointer to the building. If the building could not be created * - * then a NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/07/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * BuildingTypeClass::Create_One_Of(HouseClass * house) const -{ - HousesType htype = HOUSE_NEUTRAL; - if (house) { - htype = house->Class->House; - } - return(new BuildingClass(Type, htype)); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Init_Anim -- Initialize an animation control for a building. * - * * - * This routine will initialize one animation control element for a * - * specified building. This modifies a "const" class and thus must * - * perform some strategic casting to get away with this. * - * * - * INPUT: state -- The animation state to apply these data values to. * - * * - * start -- Starting frame for the building's animation. * - * * - * count -- The number of frames in this animation. * - * * - * rate -- The countdown timer between animation frames. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/18/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingTypeClass::Init_Anim(BStateType state, int start, int count, int rate) const -{ - ((int &)Anims[state].Start) = start; - ((int &)Anims[state].Count) = count; - ((int &)Anims[state].Rate) = rate; -} - - -/*********************************************************************************************** - * BuildingTypeClass::Legal_Placement -- Determines if building can be legally placed at pos. * - * * - * This routine is used to determine if a building can be legally * - * placed at the specified position. Buildings can only be placed on * - * unoccupied rock terrain. * - * * - * INPUT: pos -- Position that the building would be placed (up-left) * - * * - * OUTPUT: 0=illegal, 1=on concrete, -1..-8=part on concrete. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/15/1991 JLB : Created. * - * 04/26/1992 JLB : Concrete and scenario init adjustment. * - * 05/06/1992 JLB : Good, Bad, and Adjacent checking added. * - * 08/09/1992 JLB : Determines full or partial concrete foundation. * - * 06/07/1994 JLB : Handles concrete special check. * - * 06/21/1994 JLB : Converted to building type class member function. * - *=============================================================================================*/ -int BuildingTypeClass::Legal_Placement(CELL pos) const -{ - short const *offset; // Pointer to cell offset list. - - if (pos == -1) return(false); - -#ifdef NEVER - /* - ** Concrete has special checking performed to determine legal placement. Concrete - ** can legally be placed if there is any cell that would be affected by the concrete - ** placement. Unlike other buildings, only one cell needs to be effective in order - ** to flag legal placement for the entire "structure". - */ - if (Type == STRUCT_CONCRETE_NOD || Type == STRUCT_CONCRETE_GDI) { - offset = Occupy_List(); - while (*offset != REFRESH_EOL) { - if (!Map.Cell_Template(pos + (CELL)*offset++)) { - return(true); - } - } - - /* - ** No squares would be affected by concrete placement so consider legal - ** placement query to be false. - */ - return(false); - } -#endif - - /* - ** Normal buildings must check to see that every foundation square is free of - ** obstacles. If this check passes for all foundation squares, only then does the - ** routine return that it is legal to place. - */ - offset = Occupy_List(true); - while (*offset != REFRESH_EOL) { - CELL cell = pos + *offset++; - if (!Map.In_Radar(cell)) return(false); - if (!Map[cell].Is_Generally_Clear()) { - return(false); - } - } - return(true); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Who_Can_Build_Me -- Determines which factory can create the building. * - * * - * Use this routine to determine which building is available to build the building. If * - * there are no suitable buildings, then NULL is returned. Typical use of this function is * - * to maintain the construction list sidebar. * - * * - * INPUT: intheory -- If true, then it merely checks for a building of the proper ownership * - * when determining if construction is allowed. It doesn't consider the * - * possibility that the construction building is currently busy or not. * - * * - * legal -- Should building prerequisite legality checks be performed as well? * - * For building placements, this is usually false. For sidebar button * - * adding, this is usually true. * - * * - * house -- The owner of the building to be built. Only construction buildings of * - * the same ownership are allowed to build. * - * * - * OUTPUT: Returns with a pointer to the construction object (building) that can build * - * the building type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/29/1994 JLB : Created. * - * 01/02/1995 JLB : Scans in reverse order so that later buildings are biased. * - *=============================================================================================*/ -BuildingClass * BuildingTypeClass::Who_Can_Build_Me(bool intheory, bool legal, HousesType house) const -{ - for (int index = Buildings.Count()-1; index >= 0; index--) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && !building->IsInLimbo && - building->House->Class->House == house && - building->Class->ToBuild == RTTI_BUILDINGTYPE && - building->Mission != MISSION_DECONSTRUCTION && - ((1L << building->ActLike) & Ownable) && - (!legal || building->House->Can_Build(Type, building->ActLike)) && - (intheory || !building->In_Radio_Contact())) { - return(building); - } - } - return(0); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Init -- Performs theater specific initialization. * - * * - * This routine is used to perform any initialization that is custom per theater. * - * Typically, this is fetching the building shape data for those building types that have * - * theater specific art. * - * * - * INPUT: theater -- The theater to base this initialization on. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingTypeClass::Init(TheaterType theater) -{ - if (theater != LastTheater){ - char fullname[_MAX_FNAME+_MAX_EXT]; - - for (StructType sindex = STRUCT_FIRST; sindex < STRUCT_COUNT; sindex++) { - BuildingTypeClass const *classptr = &As_Reference(sindex); - - if (classptr->IsTheater) { - _makepath(fullname, NULL, NULL, classptr->IniName, Theaters[theater].Suffix); - ((void const *&)classptr->ImageData) = MixFileClass::Retrieve(fullname); - } - - if ( Get_Resolution_Factor() ) { - char buffer[_MAX_FNAME]; - char fullname[_MAX_FNAME+_MAX_EXT]; - void const * cameo_ptr; - - ((void const *&)classptr->CameoData) = NULL; - - sprintf(buffer, "%.4sICNH", classptr->IniName); - _makepath (fullname, NULL, NULL, buffer, Theaters[theater].Suffix); - cameo_ptr = MixFileClass::Retrieve(fullname); - if (cameo_ptr){ - ((void const *&)classptr->CameoData) = cameo_ptr; - } - } - } - } -} - - -/*********************************************************************************************** - * BuildingTypeClass::Dimensions -- Fetches the pixel dimensions of the building. * - * * - * This routine will fetch the dimensions of the building (in pixels). These dimensions are * - * used to render the selection rectangle and the health bar. * - * * - * INPUT: width -- Reference to the pixel width (to be filled in). * - * * - * height -- Reference to the pixel height (to be filled in). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingTypeClass::Dimensions(int &width, int &height) const -{ - static struct { - int Width; - int Height; - } _dimensions[BSIZE_COUNT] = { - {1,1}, - {2,1}, - {1,2}, - {2,2}, - {2,3}, - {3,2}, - {3,3}, - {4,2}, - {5,5} - }; - - width = _dimensions[Size].Width * ICON_PIXEL_W; - width -= (width/5); - height = _dimensions[Size].Height * ICON_PIXEL_H; - height -= (height/5); -} - - -/*********************************************************************************************** - * BuildingTypeClass::As_Reference -- Fetches reference to the building type specified. * - * * - * This routine will fetch a reference to the BuildingTypeClass as indicated by the * - * building type number specified. * - * * - * INPUT: type -- The building type number to convert into a BuildingTypeClass reference. * - * * - * OUTPUT: Returns with a reference to the building type class as indicated by the * - * parameter. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -BuildingTypeClass const & BuildingTypeClass::As_Reference(StructType type) -{ - return(* Pointers[type]); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Occupy_List -- Fetches the occupy list for the building. * - * * - * Use this routine to fetch the occupy list pointer for the building. The occupy list is * - * used to determine what cells the building occupies and thus precludes other buildings * - * or objects from using. * - * * - * INPUT: placement -- Is this for placement legality checking only? The normal condition * - * is for marking occupation flags. * - * * - * OUTPUT: Returns with a pointer to a cell offset list to be used to determine what cells * - * this building occupies. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -short const * BuildingTypeClass::Occupy_List(bool placement) const -{ - SmudgeType bib = SMUDGE_NONE; - CELL cell=0; - - if ((placement && Bib_And_Offset(bib, cell)) || (Special.IsRoad && (*this == STRUCT_BARRACKS || (placement && *this == STRUCT_REFINERY)))) { - - /* - ** The barracks is always considered to have a bib under it for placement reasons even - ** if the bib logic is turned off. - */ - if (Special.IsRoad && *this == STRUCT_BARRACKS) { - bib = SMUDGE_BIB3; - cell = 0; - } - - /* - ** If bibs are disabled, then always ensure that the refinery bib is marked - ** as occupied. - */ - if (Special.IsRoad && *this == STRUCT_REFINERY) { - bib = SMUDGE_BIB2; - cell = MAP_CELL_W; - } - - SmudgeTypeClass const & smudge = SmudgeTypeClass::As_Reference(bib); - static short _list[25]; - short * dest = &_list[0]; - - /* - ** Copy the bib overlap list into the working buffer. - */ - short const * src = smudge.Occupy_List(); - while (*src != REFRESH_EOL) { - *dest++ = (*src++) + cell; - } - - /* - ** Append the building occupy list to this working buffer. - */ - src = OccupyList; - while (src && *src != REFRESH_EOL) { - *dest++ = *src++; - } - *dest = REFRESH_EOL; - - return(&_list[0]); - } - - if (OccupyList) { - return(OccupyList); - } - - static short const _templap[] = {REFRESH_EOL}; - return(&_templap[0]); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Overlap_List -- Fetches the overlap list for the building. * - * * - * This routine will fetch the overlap list for the building. The overlap list is used * - * to determine what cells the building's graphics cover, but is not considered to occupy * - * for movement purposes. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the cell offset list that is used to determine the * - * cells that this building overlaps. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -short const * BuildingTypeClass::Overlap_List(void) const -{ - if (OverlapList) { - return(OverlapList); - } - - static short const _templap[] = {REFRESH_EOL}; - return(&_templap[0]); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Width -- Determines width of bulding in icons. * - * * - * Use this routine to determine the width of the building type in icons. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the building width in icons. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/23/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingTypeClass::Width(void) const -{ - static int width[BSIZE_COUNT] = { - 1, - 2, - 1, - 2, - 2, - 3, - 3, - 4, - 5 - }; - return(width[Size]); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Height -- Determins the height of the building in icons. * - * * - * Use this routine to find the height of the building in icons. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the building height in icons. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/23/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingTypeClass::Height(void) const -{ - static int height[BSIZE_COUNT] = { - 1, - 1, - 2, - 2, - 3, - 2, - 3, - 2, - 5 - }; - return(height[Size]); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Repair_Cost -- Determines cost per "step" of repair. * - * * - * Use this routine to determine how much it will cost to repair the building one * - * step. A step is defined as the number of hit points returned from the Repair_Step() * - * function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the credit cost to repair this building one step. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/23/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingTypeClass::Repair_Cost(void) const -{ - int cost = (Raw_Cost()*REPAIR_STEP) / MaxStrength; - cost /= 2; - cost = MAX(cost, 1); - cost = Fixed_To_Cardinal(cost, REPAIR_PERCENT); - return(MAX(cost, 1)); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Repair_Step -- Determines the repair step rate. * - * * - * This routine will determine how many strength points get healed for each "step". The * - * cost to repair one step is determine from the Repair_Cost() function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of health points repaired for each "step". * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/23/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingTypeClass::Repair_Step(void) const -{ - return(REPAIR_STEP); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Bib_And_Offset -- Determines the bib and appropriate cell offset. * - * * - * This routine is used to determine what (if any) bib should be used for this building * - * and also the cell offset for the upper left corner of the bib smudge type. * - * * - * INPUT: bib -- Reference to the bib that should be used for this building. * - * * - * cell -- The cell offset for the upper left corner of the bib. This offset is * - * relative to the upper left corner of the building. * - * * - * OUTPUT: Is a bib required for this building? If the result is true, then the correct * - * bib and cell offset will be filled in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool BuildingTypeClass::Bib_And_Offset(SmudgeType & bib, CELL & cell) const -{ - bib = SMUDGE_NONE; - - if (IsBibbed && !Special.IsRoad) { - switch (Width()) { - case 2: - bib = SMUDGE_BIB3; - break; - - case 3: - bib = SMUDGE_BIB2; - break; - - case 4: - bib = SMUDGE_BIB1; - break; - } - - /* - ** Adjust the bib position for special buildings that have the bib as part - ** of the building art itself. - */ - if (bib != SMUDGE_NONE) { - cell += ((Height()-1)*MAP_CELL_W); - } - } - return(bib != SMUDGE_NONE); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Max_Pips -- Determines the maximum pips to display. * - * * - * Use this routine to determine the maximum number of pips to display on this building * - * when it is rendered. Typically, this is the tiberium capacity divided by 100. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of pips to display on this building when selected. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/29/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingTypeClass::Max_Pips(void) const -{ - return(Bound(Capacity/100, 0, 10)); -} - - -/*********************************************************************************************** - * BuildingTypeClass::Full_Name -- Fetches the full name text number. * - * * - * This routine will fetch the full name of this building (expressed as a text number). * - * If special civilian names are enabled, then the civilian buildings will show their true * - * name rather than "civilian building". * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the full name of this building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/29/1995 JLB : Created. * - * 07/17/1995 JLB : Village wells will always have their name displayed. * - *=============================================================================================*/ -int BuildingTypeClass::Full_Name(void) const -{ - if (::Scenario == 3 && Type == STRUCT_MISSION) { - return(TXT_PRISON); - } - if (!IsNominal || Special.IsNamed || IsWall || Debug_Map || Type == STRUCT_V23 || Type == STRUCT_V30 || Type == STRUCT_MISSION || Type == STRUCT_BIO_LAB) { - return(TechnoTypeClass::Full_Name()); - } - return(TXT_CIVILIAN_BUILDING); -} - - -int BuildingTypeClass::Raw_Cost(void) const -{ -#ifdef PATCH - /* - ** Forces the turret cost down to original 250 for old - ** version games. - */ - if (IsV107 && Type == STRUCT_TURRET && GameToPlay != GAME_NORMAL) { - return(250); - } -#endif - - int cost = TechnoTypeClass::Raw_Cost(); - - if (Type == STRUCT_HELIPAD) { - cost -= AircraftTypeClass::As_Reference(AIRCRAFT_ORCA).Cost; - } - if (Type == STRUCT_REFINERY) { - cost -= UnitTypeClass::As_Reference(UNIT_HARVESTER).Cost; - } - return(cost); -} - - -int BuildingTypeClass::Cost_Of(void) const -{ - if (Special.IsSeparate && Type == STRUCT_HELIPAD) { - return(Raw_Cost()); - } - -#ifdef PATCH - /* - ** Forces the turret cost down to original 250 for old - ** version games. - */ - if (IsV107 && Type == STRUCT_TURRET && GameToPlay != GAME_NORMAL) { - return(250); - } -#endif - - return(TechnoTypeClass::Cost_Of()); -} diff --git a/code/TIBERIANDAWN/BUILDING.CPP b/code/TIBERIANDAWN/BUILDING.CPP deleted file mode 100644 index 8a19967..0000000 --- a/code/TIBERIANDAWN/BUILDING.CPP +++ /dev/null @@ -1,5471 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\building.cpv 2.13 02 Aug 1995 17:00:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BUILDING.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : August 20, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * BuildingClass::AI -- Handles non-graphic AI processing for buildings. * - * BuildingClass::Active_Click_With -- Handles cell selection for buildings. * - * BuildingClass::As_Target -- Convert the building into a target value. * - * BuildingClass::Assign_Target -- Assigns a target to the building. * - * BuildingClass::Begin_Mode -- Begins an animation mode for the building. * - * BuildingClass::BuildingClass -- Constructor for buildings. * - * BuildingClass::Can_Demolish -- Can the player demolish (sell back) the building? * - * BuildingClass::Can_Enter_Cell -- Determines if building can be placed down. * - * BuildingClass::Can_Fire -- Determines if this building can fire. * - * BuildingClass::Captured -- Captures the building. * - * BuildingClass::Center_Coord -- Fetches the center coordinate for the building. * - * BuildingClass::Click_With -- Handles clicking on the map while the building is selected. * - * BuildingClass::Crew_Type -- This determines the crew that this object generates. * - * BuildingClass::Death_Announcement -- Announce the death of this building. * - * BuildingClass::Debug_Dump -- Displays building status to the monochrome screen. * - * BuildingClass::Detach -- Handles target removal from the game system. * - * BuildingClass::Detach_All -- Possibly abandons production according to factory type. * - * BuildingClass::Draw_It -- Displays the building at the location specified. * - * BuildingClass::Drop_Debris -- Drops rubble when building is destroyed. * - * BuildingClass::Enter_Idle_Mode -- The building will enter its idle mode. * - * BuildingClass::Exit_Object -- Initiates an object to leave the building. * - * BuildingClass::Fire_At -- Fires weapon at specified target. * - * BuildingClass::Fire_Coord -- Calculates the coordinate that projectile would appear. * - * BuildingClass::Fire_Direction -- Fetches the direction of firing. * - * BuildingClass::Fire_Out -- Handles when attached animation expires. * - * BuildingClass::Flush_For_Placement -- Handles clearing a zone for object placement. * - * BuildingClass::Grand_Opening -- Handles construction completed special operations. * - * BuildingClass::Greatest_Threat -- Searches for target that building can fire upon. * - * BuildingClass::Init -- Initialize the building system to an empty null state. * - * BuildingClass::Limbo -- Handles power adjustment as building goes into limbo. * - * BuildingClass::Look -- Reveal map around building. * - * BuildingClass::Mark -- Building interface to map rendering system. * - * BuildingClass::Mission_Attack -- Handles attack mission for building. * - * BuildingClass::Mission_Construction -- Handles mission construction. * - * BuildingClass::Mission_Deconstruction -- Handles building deconstruction. * - * BuildingClass::Mission_Guard -- Handles guard mission for combat buildings. * - * BuildingClass::Mission_Harvest -- Handles refinery unloading harvesters. * - * BuildingClass::Mission_Missile -- State machine for nuclear missile launch. * - * BuildingClass::Mission_Repair -- Handles the repair (active) state for building. * - * BuildingClass::Mission_Unload -- Handles the unload mission for a building. * - * BuildingClass::Pip_Count -- Determines "full" pips to display for building. * - * BuildingClass::Power_Output -- Fetches the current power output from this building. * - * BuildingClass::Read_INI -- Reads buildings from INI file. * - * BuildingClass::Receive_Message -- Handle an incoming message to the building. * - * BuildingClass::Refund_Amount -- Fetches the refund amount if building is sold. * - * BuildingClass::Remap_Table -- Fetches the remap table to use for this building. * - * BuildingClass::Repair -- Initiates or terminates the repair process. * - * BuildingClass::Revealed -- Reveals the building to the specified house. * - * BuildingClass::Sell_Back -- Controls the sell back (demolish) operation. * - * BuildingClass::Sort_Y -- Returns the building coordinate used for sorting. * - * BuildingClass::Take_Damage -- Inflicts damage points upon a building. * - * BuildingClass::Toggle_Primary -- Toggles the primary factory state. * - * BuildingClass::Unlimbo -- Removes a building from limbo state. * - * BuildingClass::Update_Buildables -- Informs sidebar of additional construction options. * - * BuildingClass::Update_Specials -- removes computer specials for lost bld * - * BuildingClass::What_Action -- Determines action to perform if click on specified object. * - * BuildingClass::What_Action -- Determines what action will occur. * - * BuildingClass::Write_INI -- Writes all building data to an INI file. * - * BuildingClass::delete -- Deallocates building object. * - * BuildingClass::new -- Allocates a building object from building pool. * - * BuildingClass::~BuildingClass -- Destructor for building type objects. * - * BuildingClass::Validate -- validates building pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** New sidebar for GlyphX multiplayer. ST - 3/26/2019 12:24PM -*/ -#include "SidebarGlyphx.h" - - -enum SAMState { - SAM_NONE=-1, // Used for non SAM site buildings. - SAM_UNDERGROUND, // Launcher is underground and awaiting orders. - SAM_RISING, // Doors open and launcher rises to normal locked down position. - SAM_READY, // Launcher can be facing any direction tracking targets. - SAM_FIRING, // Stationary while missile is being fired. - SAM_READY2, // Launcher can be facing any direction tracking targets. - SAM_FIRING2, // Stationary while missile is being fired. - SAM_LOCKING, // Rotating to locked position in preparation for lowering. - SAM_LOWERING, // Launcher is lowering into the ground. -}; - - -/*************************************************************************** -** Center of building offset table. -*/ -COORDINATE const BuildingClass::CenterOffset[BSIZE_COUNT] = { - 0x00800080L, - 0x008000FFL, - 0x00FF0080L, - 0x00FF00FFL, - 0x018000FFL, - 0x00FF0180L, - 0x01800180L, - - 0x00FF0200L, - - 0x02800280L, -}; - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * BuildingClass::VTable; - - -/*********************************************************************************************** - * BuildingClass::Validate -- validates building pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int BuildingClass::Validate(void) const -{ - int num; - - num = Buildings.ID(this); - if (num < 0 || num >= BUILDING_MAX) { - Validate_Error("BUILDING"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * BuildingClass::Receive_Message -- Handle an incoming message to the building. * - * * - * This routine handles an incoming message to the building. Messages regulate the * - * various cooperative ventures between buildings and units. This might include such * - * actions as coordinating the construction yard animation with the actual building's * - * construction animation. * - * * - * INPUT: from -- The originator of the message received. * - * * - * message -- The radio message received. * - * * - * param -- Reference to an optional parameter that might be used to return * - * extra information to the message originator. * - * * - * OUTPUT: Returns with the response to the message (typically, this is just RADIO_OK). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/09/1994 JLB : Created. * - * 06/26/1995 JLB : Forces refinery load anim to start immediately. * - * 08/13/1995 JLB : Uses ScenarioInit for special loose "CAN_LOAD" check. * - *=============================================================================================*/ -RadioMessageType BuildingClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - Validate(); - switch (message) { - - /* - ** This message is received as a request to attach/load/dock with this building. - ** Verify that this is allowed and return the appropriate response. - */ - case RADIO_HELLO: - //Refineries can't be interupted while they're processing a harvester - LLL April 22, 2020 - if (Mission == MISSION_HARVEST) { - return(RADIO_NEGATIVE); - } - break; - - case RADIO_CAN_LOAD: - TechnoClass::Receive_Message(from, message, param); - if (BState == BSTATE_CONSTRUCTION || (!ScenarioInit && In_Radio_Contact())) return(RADIO_NEGATIVE); - switch (Class->Type) { - case STRUCT_AIRSTRIP: - if (from->What_Am_I() == RTTI_AIRCRAFT && *((AircraftClass const *)from) == AIRCRAFT_CARGO) { - return(RADIO_ROGER); - } - break; - - case STRUCT_HELIPAD: - if (from->What_Am_I() == RTTI_AIRCRAFT && !((AircraftClass const *)from)->Class->IsFixedWing) { - return(RADIO_ROGER); - } - break; - - case STRUCT_REPAIR: - if (/*from->Health_Ratio() < 0x0100 &&*/ from->What_Am_I() == RTTI_UNIT || from->What_Am_I() == RTTI_AIRCRAFT) { - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - - case STRUCT_REFINERY: - if (from->What_Am_I() == RTTI_UNIT && - *((UnitClass *)from) == UNIT_HARVESTER && - (ScenarioInit || !Is_Something_Attached())) { - - return(RADIO_ROGER); - } - break; - - default: - break; - } - return(RADIO_NEGATIVE); - - /* - ** This message is received when the object has attached itself to this - ** building. - */ - case RADIO_IM_IN: - if (Mission == MISSION_DECONSTRUCTION) { - return(RADIO_NEGATIVE); - } - switch (Class->Type) { - case STRUCT_REPAIR: - IsReadyToCommence = true; - Assign_Mission(MISSION_REPAIR); - from->Assign_Mission(MISSION_SLEEP); - return(RADIO_ROGER); - - case STRUCT_HELIPAD: - Assign_Mission(MISSION_REPAIR); - from->Assign_Mission(MISSION_SLEEP); - return(RADIO_ROGER); - - case STRUCT_REFINERY: - ScenarioInit++; - Begin_Mode(BSTATE_ACTIVE); - ScenarioInit--; - Mark(MARK_CHANGE); - Assign_Mission(MISSION_HARVEST); - return(RADIO_ATTACH); - } - break; - - /* - ** Docking maneuver maintenance message. See if new order should be given to the - ** unit trying to dock. - */ - case RADIO_DOCKING: - TechnoClass::Receive_Message(from, message, param); - - /* - ** When in radio contact for loading, the refinery starts - ** flashing the lights. - */ - //Fix for refinery animation bug when mission is harvest - LLL April 22, 2020 - if (*this == STRUCT_REFINERY && BState != BSTATE_FULL && Mission != MISSION_HARVEST) { - Begin_Mode(BSTATE_FULL); - } - - /* - ** If this building is already in radio contact, then it might - ** be able to satisfy the request to load by bumping off any - ** preoccupying task. - */ - if (*this == STRUCT_REPAIR) { - if (Contact_With_Whom() != from) { - if (Transmit_Message(RADIO_ON_DEPOT) == RADIO_ROGER) { - if (Transmit_Message(RADIO_NEED_REPAIR) == RADIO_NEGATIVE) { - Transmit_Message(RADIO_RUN_AWAY); - Transmit_Message(RADIO_OVER_OUT); - return(RADIO_ROGER); - } - } - } - } - - /* - ** Establish contact with the object if this building isn't already in contact - ** with another. - */ - if (!In_Radio_Contact()) { - Transmit_Message(RADIO_HELLO, from); - } - - if (Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER) { - if (*this == STRUCT_HELIPAD) { - param = As_Target(); - } else { - if (*this == STRUCT_REPAIR) { - Transmit_Message(RADIO_TETHER); - param = ::As_Target(Coord_Cell(Center_Coord())); - } else { - param = ::As_Target(Coord_Cell(Adjacent_Cell(Center_Coord(), DIR_SW))); - } - } - - /* - ** Tell the harvester to move to the docking pad of the refinery. - */ - if (Transmit_Message(RADIO_MOVE_HERE, param) == RADIO_YEA_NOW_WHAT) { - - /* - ** Since the harvester is already there, tell it to begin the backup - ** procedure now. If it can't, then tell it to get outta here. - */ - Transmit_Message(RADIO_TETHER); - if (*this == STRUCT_REFINERY && Transmit_Message(RADIO_BACKUP_NOW, from) != RADIO_ROGER) { - from->Scatter(NULL, true); - } - } - } - return(RADIO_ROGER); - - /* - ** If a transport or harvester is requesting permission to head toward, dock - ** and load/unload, check to make sure that this is allowed given the current - ** state of the building. - */ - case RADIO_ARE_REFINERY: - if (Is_Something_Attached() || In_Radio_Contact() || IsInLimbo || House->Class->House != from->Owner() || (*this != STRUCT_REFINERY/* && *this != STRUCT_REPAIR*/)) { - return(RADIO_NEGATIVE); - } - return(RADIO_ROGER); - - /* - ** Someone is telling us that it is starting construction. This should only - ** occur if this is a construction yard and a building was just placed on - ** the map. - */ - case RADIO_BUILDING: - Assign_Mission(MISSION_REPAIR); - TechnoClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - - /* - ** Someone is telling us that they have finished construction. This should - ** only occur if this is a construction yard and the building that was being - ** constructed has finished. In this case, stop the construction yard - ** animation. - */ - case RADIO_COMPLETE: - if (Mission != MISSION_DECONSTRUCTION) { - Assign_Mission(MISSION_GUARD); - } - TechnoClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - - /* - ** This message may occur unexpectedly if the unit in contact with this - ** building is suddenly destroyed. Handle any cleanup necessary. For example, - ** a construction yard should stop its construction animation in this case. - */ - case RADIO_OVER_OUT: - Begin_Mode(BSTATE_IDLE); - TechnoClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - - /* - ** This message is received when an object has completely left - ** building. Sometimes special cleanup action is required when - ** this event occurs. - */ - case RADIO_UNLOADED: - if (*this == STRUCT_REPAIR) { - if (Distance(from) < 0x0180) { - return(RADIO_ROGER); - } - } - - //Turn off the refinery lights - LLL April 22, 2020 - if (*this == STRUCT_REFINERY) { - Begin_Mode(BSTATE_IDLE); - } - - TechnoClass::Receive_Message(from, message, param); - if (*this == STRUCT_WEAP || *this == STRUCT_AIRSTRIP || *this == STRUCT_REPAIR) return(RADIO_RUN_AWAY); - return(RADIO_ROGER); - } - - /* - ** Pass along the message to the default message handler in the radio itself. - */ - return(TechnoClass::Receive_Message(from, message, param)); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * BuildingClass::Debug_Dump -- Displays building status to the monochrome screen. * - * * - * This utility function will output the current status of the building class to the * - * monochrome screen. It is through this data that bugs may be fixed or detected. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Debug_Dump(MonoClass *mono) const -{ - Validate(); - mono->Set_Cursor(0, 0); - mono->Print( - "ÚName:ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂMission:ÄÄÄÂTarCom:ÂÄÄÄÄÄÄÄÂRadio:ÂCoord:ÄÄÂÄÄÄÄÄÄÄÄÂSt:Ä¿\n" - "³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂNÂYÂHealth:ÄÂÄÄÄÁÄÂTurret:ÂÄÄÄÄÄÁÂÄBuilding:ÄÄÂCargo:ÄÄÄÄÁÄÄÄÄ´\n" - "³Active........³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Limbo.........³ ³ ÃÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n" - "³Owned.........³ ³ ³Last Message: ³\n" - "³Discovered....³ ³ ÃTimer:ÂArm:ÂÄÄÄÄÄÄÂTiberium:ÂFlash:ÂStage:ÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n" - "³Selected......³ ³ ³ ³ ³ ³ ³ ³ ³ \n" - "³Teathered.....³ ³ ÃÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ \n" - "³Locked on Map.³ ³ ³ \n" - "³Is A Loaner...³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³Repairing.....³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³ ³ ³ ³ \n" - "³Recoiling.....³ ³ ³ \n" - "³To Display....³ ³ ³ \n" - "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÙ \n"); - mono->Set_Cursor(1, 1);mono->Printf("%s:%s", House->Class->IniName, Class->IniName); - mono->Set_Cursor(35, 3);mono->Printf("%02X:%02X", PrimaryFacing.Current(), PrimaryFacing.Desired()); - mono->Set_Cursor(50, 3); - if (Factory) { - mono->Printf(Factory->Get_Object()->Class_Of().IniName); - mono->Printf(" "); - mono->Printf("%d%%", Factory->Completion()); - } else { - mono->Printf("(empty)"); - } - - mono->Text_Print("X", 16 + (IsRepairing?2:0), 14); -// mono->Set_Cursor(44, 3);mono->Printf("%d", SAM); - mono->Set_Cursor(34, 1);mono->Printf("%04X", TarCom); - mono->Set_Cursor(28, 7);mono->Printf("%2d", Arm); - - TechnoClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * BuildingClass::Draw_It -- Displays the building at the location specified. * - * * - * This is the low level graphic routine that displays the building at the location * - * specified. * - * * - * INPUT: x,y -- The coordinate to draw the building at. * - * * - * window -- The clipping window to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1994 JLB : Created. * - * 06/27/1994 JLB : Takes a clipping window parameter. * - * 07/06/1995 JLB : Handles damaged silos correctly. * - *=============================================================================================*/ -void BuildingClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - void const * shapefile; // Pointer to loaded shape file. - int shapenum; - - shapenum = Fetch_Stage(); - - /* - ** The shape file to use for rendering depends on whether the building - ** is undergoing construction or not. - */ - if (BState == BSTATE_CONSTRUCTION) { - shapefile = Class->Get_Buildup_Data(); - - /* - ** If the building is deconstructing, then the display frame progresses - ** from the end to the beginning. Reverse the shape number accordingly. - */ - if (Mission == MISSION_DECONSTRUCTION) { - shapenum = (Class->Anims[BState].Start+Class->Anims[BState].Count-1)-shapenum; - } - - } else { - - shapefile = Class->Get_Image_Data(); - - /* - ** The obelisk has a stage value than can be overridden by - ** its current state. - */ - if (*this == STRUCT_OBELISK) { - if (IsCharged) { - shapenum = 3; - } else { - if (IsCharging) { - shapenum = Fetch_Stage(); - } else { - shapenum = 0; - } - } - } - - /* - ** Buildings that contain a turret handle their shape determination - ** differently than normal buildings. They need to take into consideration - ** the direction the turret is facing. - */ - if (Class->IsTurretEquipped) { - shapenum = UnitClass::BodyShape[Facing_To_32(PrimaryFacing.Current())]; - - if (*this == STRUCT_SAM) { - - /* - ** SAM sites that are free to rotate fetch their animation frame - ** from the building's turret facing. All other animation stages - ** fetch their frame from the embedded animation sequencer. - */ - if (Status == SAM_READY || Status == SAM_FIRING || Status == SAM_READY2 || Status == SAM_FIRING2 || Status == SAM_LOCKING) { - shapenum += 16; - } else { - shapenum = Fetch_Stage(); - } - } else { - if (IsInRecoilState) { - shapenum += 32; - } - } - if (Health_Ratio() < 0x0080) { - shapenum += 64; - } - } else { - - /* - ** If it has only one point of strength left, it is shown in the - ** worst state possible. - */ - if (Strength <= 1) { - shapenum = Get_Build_Frame_Count(shapefile)-1; - } else { - - if (*this == STRUCT_WEAP) { - shapenum = 0; - if (Health_Ratio() < 0x0080) { - shapenum = 1; - } - - } else { - - /* - ** Special render stage for silos. The stage is dependant on the current - ** Tiberium collected as it relates to Tiberium capacity. - */ - if (*this == STRUCT_STORAGE) { - int level = 0; - if (House->Capacity) { - level = (House->Tiberium * 5) / House->Capacity; - } -// int level = Fixed_To_Cardinal(4, Cardinal_To_Fixed(House->Capacity, House->Tiberium)); - - shapenum += Bound(level, 0, 4); - if (Health_Ratio() < 0x0080) { - shapenum += 5; - } - - } else { - - if (Health_Ratio() < 0x0080) { - - /* - ** Special damage stage for pump. - */ - if (!Class->IsSimpleDamage) { - int last1 = Class->Anims[BSTATE_IDLE].Start + Class->Anims[BSTATE_IDLE].Count; - int last2 = Class->Anims[BSTATE_ACTIVE].Start + Class->Anims[BSTATE_ACTIVE].Count; - int largest = MAX(last1, last2); - last2 = Class->Anims[BSTATE_AUX1].Start + Class->Anims[BSTATE_AUX1].Count; - largest = MAX(largest, last2); - last2 = Class->Anims[BSTATE_AUX2].Start + Class->Anims[BSTATE_AUX2].Count; - largest = MAX(largest, last2); - - shapenum += largest; - } else { - - /* - ** Presume that the damage stage is the end frame. - */ - shapenum = Get_Build_Frame_Count(shapefile) - 2; - } - } - } - } - } - } - } - - /* - ** Actually draw the building shape. - */ - IsTheaterShape = Class->IsTheater; - Techno_Draw_Object(shapefile, shapenum, x, y, window); - IsTheaterShape = false; - - /* - ** Patch for adding overlay onto weapon factory. Only add the overlay if - ** the building has more than 1 hp. Also, if the building's in radio - ** contact, he must be unloading a constructed vehicle, so draw that - ** vehicle before drawing the overlay. - */ - if (BState != BSTATE_CONSTRUCTION) { - - /* - ** A Tethered object is always rendered AFTER the building. - */ - if (*this == STRUCT_WEAP && IsTethered && In_Radio_Contact() && !Contact_With_Whom()->IsInLimbo) { - TechnoClass * contact = Contact_With_Whom(); - - assert(contact->IsActive); - int xxx = x + ((int)Lepton_To_Pixel((int)Coord_X(contact->Render_Coord())) - (int)Lepton_To_Pixel((int)Coord_X(Render_Coord()))); - int yyy = y + ((int)Lepton_To_Pixel((int)Coord_Y(contact->Render_Coord())) - (int)Lepton_To_Pixel((int)Coord_Y(Render_Coord()))); - contact->Draw_It(xxx, yyy, window); - contact->IsToDisplay = false; - } - - /* - ** Draw the weapon factory custom overlay graphic. - */ - if (*this == STRUCT_WEAP && Strength > 1) { - shapenum = Door_Stage(); - if (Health_Ratio() < 0x0080) shapenum += 10; - // Added override shape file name. ST - 6/20/2019 1:35PM - //Techno_Draw_Object(WarFactoryOverlay, shapenum, x, y, window); - Techno_Draw_Object_Virtual(WarFactoryOverlay, shapenum, x, y, window, "WEAP2"); - } - - /* - ** Draw any repair feedback graphic required. - */ - if (IsRepairing && IsWrenchVisible) { - CC_Draw_Shape(ObjectTypeClass::SelectShapes, SELECT_WRENCH, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL); - } - } - - TechnoClass::Draw_It(x, y, window); -} - - -/*********************************************************************************************** - * BuildingClass::Mark -- Building interface to map rendering system. * - * * - * This routine is used to mark the map cells so that when it renders * - * the underlying icons will also be updated as necessary. * - * * - * INPUT: mark -- Type of image change (MARK_UP, _DOWN, _CHANGE) * - * MARK_UP -- Building is removed. * - * MARK_CHANGE -- Building changes shape. * - * MARK_DOWN -- Building is added. * - * * - * OUTPUT: bool; Did the mark operation succeed? Failure could be the result of marking down * - * when the building is already marked down, or visa versa. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/31/1994 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - * 04/16/1994 JLB : Added health bar tracking. * - * 12/23/1994 JLB : Calls low level check before proceeding. * - * 01/27/1995 JLB : Special road spacer template added. * - *=============================================================================================*/ -bool BuildingClass::Mark(MarkType mark) -{ - Validate(); - if (TechnoClass::Mark(mark)) { - short const *offset = Overlap_List(); - short const *occupy = Occupy_List(); - CELL cell = Coord_Cell(Coord); - SmudgeType bib; - - switch (mark) { - case MARK_UP: - Map.Pick_Up(cell, this); - if (Class->Bib_And_Offset(bib, cell)) { - SmudgeClass * smudge = new SmudgeClass(bib); - if (smudge) { - smudge->Disown(cell); - delete smudge; - } - } - break; - - case MARK_DOWN: - - /* - ** Special wall logic is handled here. A building that is really a wall - ** gets converted into an overlay wall type when it is placed down. The - ** actual building object itself is destroyed. - */ - if (Class->IsWall) { - switch (Class->Type) { - case STRUCT_BRICK_WALL: - new OverlayClass(OVERLAY_BRICK_WALL, cell, House->Class->House); - break; - - case STRUCT_BARBWIRE_WALL: - new OverlayClass(OVERLAY_BARBWIRE_WALL, cell, House->Class->House); - break; - - case STRUCT_SANDBAG_WALL: - new OverlayClass(OVERLAY_SANDBAG_WALL, cell, House->Class->House); - break; - - case STRUCT_WOOD_WALL: - new OverlayClass(OVERLAY_WOOD_WALL, cell, House->Class->House); - break; - - case STRUCT_CYCLONE_WALL: - new OverlayClass(OVERLAY_CYCLONE_WALL, cell, House->Class->House); - break; - } - Transmit_Message(RADIO_OVER_OUT); - Delete_This(); - - } else { - - if (Can_Enter_Cell(cell) == MOVE_OK) { - - /* - ** Determine if a bib is required for this building. If one is, then - ** create and place it. - */ - CELL newcell = cell; - if (Class->Bib_And_Offset(bib, newcell)) { - new SmudgeClass(bib, Cell_Coord(newcell), House->Class->House); - } - - Map.Place_Down(cell, this); - } else { - return(false); - } - } - break; - - default: - Map.Refresh_Cells(cell, offset); - Map.Refresh_Cells(cell, occupy); - break; - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * BuildingClass::Fire_At -- Fires weapon at specified target. * - * * - * This routine does the actual firing of a projectile from the * - * building toward the specified target. Prior to calling this * - * routine, the building must have rotated into position and acquired * - * a suitable target. * - * * - * INPUT: target -- The target to fire upon. * - * * - * which -- Which weapon to use for firing. 0=primary, 1=secondary. * - * * - * OUTPUT: Returns with a pointer to the projectile just launched. This * - * may come in handy if additional adjustments to the projectile * - * are required. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/16/1994 JLB : Created. * - *=============================================================================================*/ -BulletClass * BuildingClass::Fire_At(TARGET target, int which) -{ - Validate(); - BulletClass * bullet; // Projectile. - WeaponTypeClass const * weapon = (which == 0) ? &Weapons[Class->Primary] : &Weapons[Class->Secondary]; - - bullet = TechnoClass::Fire_At(target, which); - if (bullet) { - if (*this == STRUCT_SAM) { - AnimClass *anim = new AnimClass((AnimType)(ANIM_SAM_N + Dir_Facing(PrimaryFacing.Current())), Center_Coord()); - if (anim) { - anim->Attach_To(this); - } - - // MBL 04.17.2020 - Sound_Effect(weapon->Sound, Coord); - - } else { - - /* - ** Flash the muzzle, play sound, and perform any firing animation. - */ - Sound_Effect(weapon->Sound, Coord); - - AnimClass* anim = NULL; - if (weapon->Fires == BULLET_BULLET) { - anim = new AnimClass((AnimType)(ANIM_GUN_N + Dir_Facing(PrimaryFacing.Current())), Fire_Coord(which)); - } else { - switch (weapon->Fires) { - case BULLET_SPREADFIRE: - break; - case BULLET_LASER: - IsCharging = false; - IsCharged = false; - Set_Stage(0); - Set_Rate(0); - break; - default: - anim = new AnimClass(ANIM_MUZZLE_FLASH, Fire_Coord(which)); - break; - } - } - if (anim != NULL) { - anim->Attach_To(this); - } - Mark(MARK_CHANGE); - } - } - - return(bullet); -} - - -/*********************************************************************************************** - * BuildingClass::AI -- Handles non-graphic AI processing for buildings. * - * * - * This function is to handle the AI logic for the building. The graphic logic (facing, * - * firing, and animation) is handled elsewhere. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 12/26/1994 JLB : Handles production. * - * 06/11/1995 JLB : Revamped. * - *=============================================================================================*/ -void BuildingClass::AI(void) -{ - Validate(); - - /* - ** Process building animation state changes. Transition to a following state - ** if there is one specified and the current animation sequence has expired. - ** This process must occur before mission AI since the mission AI relies on - ** the bstate change to occur immediately before the MissionClass::AI. - */ - bool stagechange = Graphic_Logic(); - bool toloop = false; - - /* - ** Always refresh the SAM site if it has an animation change. - */ - if (*this == STRUCT_SAM && stagechange) Mark(MARK_CHANGE); - - if ((!Class->IsTurretEquipped && *this != STRUCT_OBELISK) || Mission == MISSION_CONSTRUCTION || Mission == MISSION_DECONSTRUCTION) { - if (stagechange) { - - /* - ** Check for animation end or if special case of MCV deconstructing when it is allowed - ** to convert back into an MCV. - */ - BuildingTypeClass::AnimControlType const * ctrl = Fetch_Anim_Control(); - - /* - ** When the last frame of the current animation sequence is reached, flag that - ** a new mission may be started. This must occur before the animation actually - ** loops so that if a mission change does occur, it will have a chance to change - ** the building graphic before the last frame is replaced by the first frame of - ** the loop. - */ - if (Fetch_Stage() == ctrl->Start+ctrl->Count-1 || (Special.IsMCVDeploy && *this == STRUCT_CONST && Mission == MISSION_DECONSTRUCTION && Fetch_Stage() == (42-19))) { - IsReadyToCommence = true; - } - - /* - ** If the animation advances beyond the last frame, then start the animation - ** sequence over from the beginning. - */ - if (Fetch_Stage() >= ctrl->Start+ctrl->Count) { - toloop = true; - } - Mark(MARK_CHANGE); - } else { - if (BState == BSTATE_NONE || Fetch_Rate() == 0) { - IsReadyToCommence = true; - } - } - } - - /* - ** If there is a door that is animating, then it might cause this building - ** to be redrawn. Check for and flag to redraw as necessary. - */ - if (Time_To_Redraw()) { - Clear_Redraw_Flag(); - Mark(MARK_CHANGE); - } - - /* - ** The animation sequence has looped. Restart it and flag this loop condition. - ** This is used to tell the mission system that the animation has completed. It - ** also signals that now is a good time to act on any pending mission. - */ - if (toloop) { - BuildingTypeClass::AnimControlType const * ctrl = Fetch_Anim_Control(); - if (BState == BSTATE_CONSTRUCTION || BState == BSTATE_IDLE) { - Set_Rate(Options.Normalize_Delay(ctrl->Rate)); - } else { - Set_Rate(ctrl->Rate); - } - Set_Stage(ctrl->Start); - Mark(MARK_CHANGE); - } - - /* - ** If now is a good time to act on a new mission, then do so. This process occurs - ** here because some outside event may have requested a mission change for the building. - ** Such outside requests (player input) must be initiated BEFORE the normal AI process. - */ - if (IsReadyToCommence && BState != BSTATE_CONSTRUCTION) { - - /* - ** Clear the commencement flag ONLY if something actually occured. By acting - ** this way, a building can set the IsReadyToCommence flag before it goes - ** to "sleep" knowing that it will wake up as soon as a new mission comes - ** along. - */ - if (Commence()) { - IsReadyToCommence = false; - } - } - - /* - ** Proceed with normal logic processing. This is where the mission processing - ** occurs. This call must be located after the animation sequence makes the - ** transition to the next frame (see above) in order for the mission logic to - ** act at the exact moment of graphic transition BEFORE it has a chance to - ** be displayed. - */ - TechnoClass::AI(); - - /* - ** If now is a good time to act on a new mission, then do so. This occurs here because - ** some AI event may have requested a mission change (usually from another mission - ** state machine). This must occur here before it has a chance to render. - */ - if (IsReadyToCommence) { - - /* - ** Clear the commencement flag ONLY if something actually occured. By acting - ** this way, a building can set the IsReadyToCommence flag before it goes - ** to "sleep" knowing that it will wake up as soon as a new mission comes - ** along. - */ - if (Commence()) { - IsReadyToCommence = false; - } - } - - /* - ** If a change of animation was requested, then make the change - ** now. The building animation system acts independantly but subordinate - ** to the mission state machine system. By performing the animation change-up - ** here, the mission AI system is ensured of immediate visual affect when it - ** decides to change the animation state of the building. - */ - if (QueueBState != BSTATE_NONE) { - if (BState != QueueBState) { - BState = QueueBState; - BuildingTypeClass::AnimControlType const * ctrl = Fetch_Anim_Control(); - if (BState == BSTATE_CONSTRUCTION || BState == BSTATE_IDLE) { - Set_Rate(Options.Normalize_Delay(ctrl->Rate)); - } else { - Set_Rate(ctrl->Rate); - } - Set_Stage(ctrl->Start); - } - QueueBState = BSTATE_NONE; - } - - /* - ** If the building's strength has changed, then update the power - ** accordingly. - */ - if (Strength != LastStrength) { - int oldpower = Power_Output(); - LastStrength = Strength; - int newpower = Power_Output(); - House->Adjust_Power(newpower - oldpower); - } - - /* - ** Check to see if the destruction countdown timer is active. If so, then decrement it. - ** When this timer reaches zero, the building is removed from the map. All the explosions - ** are presumed to be in progress at this time. - */ - if (!Strength) { - if (CountDown.Expired()) { - Limbo(); - Drop_Debris(WhomToRepay); - Delete_This(); - } - return; - } - - /* - ** Obelisk charging logic. - */ - if (*this == STRUCT_OBELISK && BState != BSTATE_CONSTRUCTION) { - if (Target_Legal(TarCom) && House->Power_Fraction() >= 0x0100) { - if (!IsCharged) { - if (IsCharging) { - if (stagechange) { - Mark(MARK_CHANGE); - if (Fetch_Stage() >= 4) { - IsCharged = true; - IsCharging = false; - Set_Rate(0); - } - } - } else { - IsCharged = false; - IsCharging = true; - Set_Stage(0); - Set_Rate(OBELISK_ANIMATION_RATE); - Sound_Effect(VOC_LASER_POWER, Coord); - } - } - } else { - if (IsCharging || IsCharged) { - Mark(MARK_CHANGE); - IsCharging = false; - IsCharged = false; - Set_Stage(0); - Set_Rate(0); - } - } - } - - /* - ** Handle any repair process that may be going on. - */ - if (IsRepairing) { - if ((Frame % 15) == 0) { - IsWrenchVisible = (IsWrenchVisible == false); - Mark(MARK_CHANGE); - int cost = Class->Repair_Cost(); - int step = Class->Repair_Step(); - - /* - ** Check for and expend any necessary monies to continue the repair. - */ - if (House->Available_Money() >= cost) { - House->Spend_Money(cost); - Strength += step; - - if (Strength >= Class->MaxStrength) { - Strength = Class->MaxStrength; - IsRepairing = false; - } - } else { - IsRepairing = false; - } - } - } - - /* - ** Handle any production tied to this building. Only computer controlled buildings have - ** production attached to the building itself. The player uses the sidebar interface for - ** all production control. - */ - if (Factory && Factory->Has_Completed() && PlacementDelay.Expired()) { - - switch (Exit_Object(Factory->Get_Object())) { - - /* - ** If the object could not leave the factory, then either request - ** a transport, place the (what must be a) building using another method, or - ** abort the production and refund money. - */ - case 0: - Factory->Abandon(); - delete Factory; - Factory = 0; - break; - - case 1: - PlacementDelay = TICKS_PER_SECOND*3; - break; - - case 2: - Factory->Completed(); - delete Factory; - Factory = 0; - break; - - } - } - - /* - ** For computer controlled buildings, determine what should be produced and start - ** production accordingly. - */ - if (!House->IsHuman && Mission != MISSION_CONSTRUCTION && Mission != MISSION_DECONSTRUCTION) { - - /* - ** Possibly start repair process if the building is below half strength. - */ - int ratio = 0x0040; - if (Scenario > 6) ratio = 0x0080; - if (Scenario > 10) ratio = 0x00C0; - if (Class->IsRepairable && Health_Ratio() <= (unsigned) ratio) { - if (House->Available_Money() >= REPAIR_THRESHHOLD) { - Repair(1); - } else { - if (IsTickedOff && (int)Scenario > 2 && Random_Pick(0, 50) < (int)Scenario && !Trigger) { - Sell_Back(1); - } - } - } - - /* - ** Buildings that produce other objects have special factory logic handled here. - */ - if (Class->ToBuild != RTTI_NONE) { - - if (Factory) { - - /* - ** If production has halted, then just abort production and make the - ** funds available for something else. - */ - if (PlacementDelay.Expired() && !Factory->Is_Building()) { - Factory->Abandon(); - delete Factory; - Factory = 0; - } - - } else { - - /* - ** Only look to start production if there is at least a small amount of - ** money available. In cases where there is no practical money left, then - ** production can never complete -- don't bother starting it. - */ - if (House->IsStarted && House->Available_Money() > 10) { - TechnoTypeClass const * techno = House->Suggest_New_Object(Class->ToBuild); - - /* - ** If a suitable object type was selected for production, then start - ** producing it now. - */ - if (techno) { - Factory = new FactoryClass; - if (Factory) { - if (!Factory->Set(*techno, *House)) { - delete Factory; - Factory = 0; - } else { -#ifdef USE_RA_AI - House->Production_Begun(Factory->Get_Object()); // Added for RA AI in TD. ST - 7/26/2019 9:46AM -#endif - Factory->Start(); - } - } - } - } - } - } - } - - /* - ** Check for demolition timeout. When timeout has expired, the building explodes. - */ - if (IsGoingToBlow && CountDown.Expired()) { - - /* - ** Maybe trigger an achivement. ST - 11/14/2019 1:53PM - */ - TechnoTypeClass const *object_type = Techno_Type_Class(); - if (object_type) { - TechnoClass *saboteur = As_Techno(WhomToRepay); - if (saboteur && saboteur->IsActive && saboteur->House && saboteur->House->IsHuman) { - On_Achievement_Event(saboteur->House, "BUILDING_DESTROYED_C4", object_type->IniName); - } - } - - SabotagedType = Class->Type; - int damage = 5000; - Take_Damage(damage, 0, WARHEAD_FIRE, As_Techno(WhomToRepay)); - Mark(MARK_CHANGE); - } - - /* - ** If the building was in a recoil state (as it would be just as it fires), then - ** restore the building. - */ - if (IsInRecoilState) { - IsInRecoilState = false; - Mark(MARK_CHANGE); - } - - /* - ** Turret equiped buildings must handle turret rotation logic here. This entails - ** rotating the turret to the desired facing as well as figuring out what that - ** desired facing should be. - */ - if (Class->IsTurretEquipped && Mission != MISSION_CONSTRUCTION && Mission != MISSION_DECONSTRUCTION) { - - /* - ** Rotate turret to match desired facing. - */ - if (PrimaryFacing.Is_Rotating()) { - if (*this == STRUCT_SAM) { - if (PrimaryFacing.Rotation_Adjust(15)) { - Mark(MARK_CHANGE); - } - } else { - if (PrimaryFacing.Rotation_Adjust(12)) { - Mark(MARK_CHANGE); - } - } - } - } -} - - -/*********************************************************************************************** - * BuildingClass::Unlimbo -- Removes a building from limbo state. * - * * - * Use this routine to transform a building that has been held in limbo * - * state, into one that really exists on the map. Once a building as * - * been unlimboed, then it becomes a normal object in the game world. * - * * - * INPUT: pos -- The position to place the building on the map. * - * * - * dir (optional) -- not used for this class * - * * - * OUTPUT: bool; Was the unlimbo successful? * - * * - * WARNINGS: The unlimbo operation might not be successful if the * - * building could not be placed at the location specified. * - * * - * HISTORY: * - * 04/16/1994 JLB : Created. * - * 06/07/1994 JLB : Matches virtual function format for base class. * - * 05/09/1995 JLB : Handles wall placement. * - * 06/18/1995 JLB : Checks for wall legality before placing down. * - *=============================================================================================*/ -bool BuildingClass::Unlimbo(COORDINATE coord, DirType dir) -{ - Validate(); -#ifdef OBSOLETE - if (*this == STRUCT_ROAD) { - if (Can_Enter_Cell(Coord_Cell(coord), FACING_NONE) == MOVE_OK) { - ObjectClass * o = OverlayTypeClass::As_Reference(OVERLAY_ROAD).Create_One_Of(House); - if (o && o->Unlimbo(coord)) { - Transmit_Message(RADIO_OVER_OUT); - Delete_This(); - return(true); - } - } - return(false); - } -#endif - - /* - ** If this is a wall type building, then it never gets unlimboed. Instead, it gets - ** converted to an overlay type. - */ - if (Class->IsWall) { - if (Can_Enter_Cell(Coord_Cell(coord), FACING_NONE) == MOVE_OK) { - OverlayType otype = OVERLAY_NONE; - switch (Class->Type) { - case STRUCT_SANDBAG_WALL: - otype = OVERLAY_SANDBAG_WALL; - break; - - case STRUCT_CYCLONE_WALL: - otype = OVERLAY_CYCLONE_WALL; - break; - - case STRUCT_BRICK_WALL: - otype = OVERLAY_BRICK_WALL; - break; - - case STRUCT_BARBWIRE_WALL: - otype = OVERLAY_BARBWIRE_WALL; - break; - - case STRUCT_WOOD_WALL: - otype = OVERLAY_WOOD_WALL; - break; - } - if (otype != OVERLAY_NONE) { - ObjectClass * o = OverlayTypeClass::As_Reference(otype).Create_One_Of(House); - if (o && o->Unlimbo(coord)) { - Map[Coord_Cell(coord)].Owner = House->Class->House; - Transmit_Message(RADIO_OVER_OUT); - Delete_This(); - return(true); - } - } - } - return(false); - } - - /* - ** Normal building unlimbo process. - */ - if (TechnoClass::Unlimbo(coord, dir)) { - - /* - ** Ensure that the owning house knows about the - ** new object. - */ - House->BScan |= (1L << Class->Type); - House->ActiveBScan |= (1L << Class->Type); - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:25AM - // - House->Recalc_Center(); -#endif - - /* - ** Update the total factory type, assuming this building has a factory. - */ - switch (Class->ToBuild) { - case RTTI_AIRCRAFTTYPE: - House->AircraftFactories++; - break; - - case RTTI_INFANTRYTYPE: - House->InfantryFactories++; - break; - - case RTTI_UNITTYPE: - House->UnitFactories++; - break; - - case RTTI_BUILDINGTYPE: - House->BuildingFactories++; - break; - - default: - break; - } - - /* - ** Possibly the sidebar will be affected by this addition. - */ - House->IsRecalcNeeded = true; - LastStrength = 0; - - // Changed for new multiplayer. ST - 4/3/2019 11:20AM - //if ((!IsDiscoveredByPlayer && Map[Coord_Cell(coord)].IsVisible) || GameToPlay != GAME_NORMAL) { - // Revealed(PlayerPtr); - //} - if (!Is_Discovered_By_Player(House) && Map[Coord_Cell(coord)].Is_Visible(House) || GameToPlay != GAME_NORMAL) { - if (House->IsHuman) { - Revealed(House); - } - } - - if (!House->IsHuman) { - Revealed(House); - } - - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Map.PowerClass::IsToRedraw = true; - Map.Flag_To_Redraw(false); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * BuildingClass::Take_Damage -- Inflicts damage points upon a building. * - * * - * This routine will inflict damage points upon the specified building. * - * It will handle the damage animation and building destruction. Use * - * this routine whenever a building is attacked. * - * * - * INPUT: damage -- Amount of damage to inflict. * - * * - * distance -- The distance from the damage center point to the object's center point.* - * * - * warhead -- The kind of damage to inflict. * - * * - * source -- The source of the damage. This is used to change targeting. * - * * - * OUTPUT: true/false; Was the building destroyed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/21/1991 : Created. * - * 04/15/1994 JLB : Converted to member function. * - * 04/16/1994 JLB : Added warhead modifier to damage. * - * 06/03/1994 JLB : Added source of damage as target value. * - * 06/20/1994 JLB : Source is a base class pointer. * - * 11/22/1994 JLB : Shares base damage handler for techno objects. * - * 07/15/1995 JLB : Power ratio gets adjusted. * - *=============================================================================================*/ -ResultType BuildingClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - Validate(); - ResultType res = RESULT_NONE; - int shakes; - - if (this != source) { - if (source) Base_Is_Attacked(source); - - short const *offset = Occupy_List(); - - /* - ** SPECIAL CASE: - ** SAM sites that are closed will take half damage, but never less than one point. - */ - if (*this == STRUCT_SAM && Status == SAM_UNDERGROUND) { - damage /= 2; - damage++; - } - - /* - ** Damage from an ion cannon against the Temple of Nod does more damage than - ** usual. - */ - if (GameToPlay == GAME_NORMAL && *this == STRUCT_TEMPLE && warhead == WARHEAD_PB) { - damage += damage/2; - } - - /* - ** Perform the low level damage assessment. - */ - res = TechnoClass::Take_Damage(damage, distance, warhead, source); - - switch (res) { - case RESULT_DESTROYED: - - /* - ** Destroy all attached objects. - */ - while (Attached_Object()) { - FootClass * obj = Detach_Object(); - - Detach_All(true); - delete obj; - } - - Sound_Effect(VOC_XPLOBIG4, Coord); - while (*offset != REFRESH_EOL) { - CELL cell = Coord_Cell(Coord) + *offset++; - - /* - ** If the building is destroyed, then lots of - ** explosions occur. - */ - new SmudgeClass(Random_Pick(SMUDGE_CRATER1, SMUDGE_CRATER6), Cell_Coord(cell)); - if (Random_Pick(0, 1) == 0) { - new AnimClass(ANIM_FIRE_SMALL, Coord_Scatter(Cell_Coord(cell), 0x0080), Random_Pick(0, 7), Random_Pick(1, 3)); - if (Random_Pick(0, 1) == 0) { - new AnimClass(ANIM_FIRE_MED, Coord_Scatter(Cell_Coord(cell), 0x0040), Random_Pick(0, 7), Random_Pick(1, 3)); - } - } - //Start_Profiler(); - new AnimClass(ANIM_FBALL1, Coord_Scatter(Cell_Coord(cell), 0x0040), Random_Pick(0,3)); - } - - shakes = Class->Cost_Of() / 400; - if (shakes) { - Shake_The_Screen(shakes, Owner()); - if (source && Owner() != source->Owner()) { - Shake_The_Screen(shakes, source->Owner()); - } - } - Sound_Effect(VOC_CRUMBLE, Coord); - if (Mission == MISSION_DECONSTRUCTION) { - CountDown = 0; - Set_Rate(0); - } else { - CountDown = 8; - } - - /* - ** A destuction of the Temple by an ion cannon requires a global - ** remembering of this fact. The finale uses this information to - ** play the correct movie. - */ - if (*this == STRUCT_TEMPLE && warhead == WARHEAD_PB) { - TempleIoned = true; - - /* - ** Maybe trigger an achivement if the structure is owned by an AI house in campaign mode. ST - 11/14/2019 1:53PM - */ - if (GameToPlay == GAME_NORMAL && !House->IsHuman && source && source->House && source->House->IsHuman) { - TechnoTypeClass const *object_type = Techno_Type_Class(); - if (object_type) { - On_Achievement_Event(source->House, "ION_DESTROYS_TEMPLE", object_type->IniName); - } - } - - } else { - TempleIoned = false; - } - - if (House) { - House->Check_Pertinent_Structures(); - } - break; - - case RESULT_HALF: - if (*this == STRUCT_PUMP) { - AnimClass *anim = new AnimClass(ANIM_OILFIELD_BURN, Coord_Add(Coord, 0x00400130L), 1); - if (anim) { - anim->Attach_To(this); - } - } - // Fall into next case. - - case RESULT_MAJOR: - Sound_Effect(VOC_XPLOBIG4, Coord); - while (*offset != REFRESH_EOL) { - CELL cell = Coord_Cell(Coord) + *offset++; - AnimClass * anim = NULL; - - /* - ** Show pieces of fire to indicate that a significant change in - ** damage level has occurred. - */ - if (warhead == WARHEAD_FIRE) { - switch (Random_Pick(0, 13)) { - case 0: - case 1: - case 2: - case 3: - case 4: - anim = new AnimClass(ANIM_ON_FIRE_SMALL, Coord_Scatter(Cell_Coord(cell), 0x0060), 0, Random_Pick(1, 3)); - break; - - case 5: - case 6: - case 7: - anim = new AnimClass(ANIM_ON_FIRE_MED, Coord_Scatter(Cell_Coord(cell), 0x0060), 0, Random_Pick(1, 3)); - break; - - case 8: - anim = new AnimClass(ANIM_ON_FIRE_BIG, Coord_Scatter(Cell_Coord(cell), 0x0060), 0, 1); - break; - - case 9: - case 10: - case 11: - case 12: - case 13: - break; - } - } else { - if (Random_Pick(0, 1) == 0) { - anim = new AnimClass(ANIM_FIRE_SMALL, Coord_Scatter(Cell_Coord(cell), 0x0060), Random_Pick(0, 7), Random_Pick(1, 3)); - } - } - - /* - ** If the animation was created, then attach it to the building. - */ - if (anim) { - anim->Attach_To(this); - } - } - break; - - case RESULT_NONE: - break; - } - - if (source && res != RESULT_NONE) { - - /* - ** If any damage occurred, then inform the house of this fact. If it is the player's - ** house, it might announce this fact. - */ - House->Attacked(this); - - /* - ** Save the type of the house that's doing the damage, so if the building burns - ** to death credit can still be given for the kill - */ - WhoLastHurtMe = source->Owner(); - - /* - ** When certain buildings are hit, they "snap out of it" and - ** return fire if they are able and allowed. - */ - if (*this != STRUCT_SAM && - !House->Is_Ally(source) && - Class->Primary != WEAPON_NONE && - (!Target_Legal(TarCom) || !In_Range(TarCom))) { - - if (source->What_Am_I() != RTTI_AIRCRAFT && (!House->IsHuman || Special.IsSmartDefense)) { - Assign_Target(source->As_Target()); - } else { - - /* - ** Generate a random rotation effect since there is nothing else that this - ** building can do. - */ - if (!PrimaryFacing.Is_Rotating()) { - PrimaryFacing.Set_Desired(Random_Pick(DIR_N, DIR_MAX)); - } - } - } - } - } - - return(res); -} - - -/*********************************************************************************************** - * BuildingClass::Look -- Reveal map around building. * - * * - * Given a building, reveal the cells around the building in accordance * - * with the building's sighting range. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This is a very slow routine. Call only when necessary. * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void BuildingClass::Look(bool) -{ - /* - ** Changed this function to reveal for the appropriate players in GlyphX multiplayer. ST - 4/17/2019 11:50AM - */ - Validate(); - - if (Class->SightRange) { - Map.Sight_From(House, Coord_Cell(Center_Coord()), Class->SightRange, false); - } - -#if (0) - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER) { - - if (Is_Owned_By_Player(PlayerPtr) || Is_Discovered_By_Player(PlayerPtr)) { - Map.Sight_From(PlayerPtr, Coord_Cell(Center_Coord()), Class->SightRange, false); - } - } else { - - for (int i = 0; i < MPlayerCount; i++) { - HousesType house_type = MPlayerHouses[i]; - HouseClass *house = HouseClass::As_Pointer(house_type); - - if (Is_Owned_By_Player(house) || Is_Discovered_By_Player(house)) { - Map.Sight_From(house, Coord_Cell(Center_Coord()), Class->SightRange, false); - } - } - } -#endif -} - - -#if (0) // For reference. ST - 4/17/2019 11:38AM -void BuildingClass::Look(bool) -{ - Validate(); - if (IsOwnedByPlayer || IsDiscoveredByPlayer) { - Map.Sight_From(PlayerPtr, Coord_Cell(Center_Coord()), Class->SightRange, false); - } -} -#endif - - -/*********************************************************************************************** - * BuildingClass::new -- Allocates a building object from building pool. * - * * - * This routine will allocate a building slot from the building alloc * - * system. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the allocated building. If NULL is * - * returned, then this indicates a failure to allocate. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/11/1994 JLB : Created. * - * 04/21/1994 JLB : Converted to operator new. * - * 05/17/1994 JLB : Revamped allocation scheme * - * 07/29/1994 JLB : Simplified. * - *=============================================================================================*/ -void * BuildingClass::operator new(size_t ) -{ - void * ptr = Buildings.Allocate(); - if (ptr) { - ((BuildingClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * BuildingClass::delete -- Deallocates building object. * - * * - * This is the memory deallocation operation for a building object. * - * Since buildings are allocated out of a fixed memory block, all that * - * is needed is to flag the unit as inactive. * - * * - * INPUT: ptr -- Pointer to building to deallocate. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/21/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::operator delete(void *ptr) -{ - if (ptr) { - ((BuildingClass *)ptr)->IsActive = false; - } - Buildings.Free((BuildingClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * BuildingClass::BuildingClass -- Constructor for buildings. * - * * - * This routine inserts a building into the object tracking system. * - * It is placed into a limbo state unless a location is provided for * - * it to unlimbo at. * - * * - * INPUT: type -- The structure type to make this object. * - * * - * house -- The owner of this building. * - * * - * pos -- The position to unlimbo the building. If -1 is * - * specified, then the building remains in a limbo * - * state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/21/1994 JLB : Created. * - * 08/07/1995 JLB : Fixed act like value to match expected value. * - *=============================================================================================*/ -BuildingClass::BuildingClass(StructType type, HousesType house) : - Class(&BuildingTypeClass::As_Reference(type)), - TechnoClass(house) -{ - PlacementDelay = 0; - LastStrength = 0; - ActLike = House->ActLike; - BState = BSTATE_NONE; - CountDown.Set(0); - Factory = 0; -#ifndef USE_RA_AI - House->CurBuildings++; // Removed for RA AI in TD -#endif - WhomToRepay = TARGET_NONE; - IsCaptured = false; - IsCharged = false; - IsCharging = false; - IsSurvivorless = false; - IsGoingToBlow = false; - IsReadyToCommence = false; - IsRepairing = false; - IsSecondShot = !Class->IsTwoShooter; - IsWrenchVisible = false; - QueueBState = BSTATE_NONE; - Strength = Class->MaxStrength; - WhoLastHurtMe = house; - Ammo = Class->MaxAmmo; - - /* - ** Make sure that newly built house specific building types will act like - ** the house they are supposed to act like, regardless of who the current - ** owner may happen to be. - */ - if ((type == STRUCT_AIRSTRIP || type == STRUCT_HAND) && house != HOUSE_BAD) { - ActLike = HOUSE_BAD; - IsCaptured = true; - } - if ((type == STRUCT_WEAP || type == STRUCT_BARRACKS) && house != HOUSE_GOOD) { - ActLike = HOUSE_GOOD; - IsCaptured = true; - } - - if (GameToPlay == GAME_INTERNET){ - House->BuildingTotals->Increment_Unit_Total( (int) type); - } - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Add(this); -#endif // USE_RA_AI -} - - -/*********************************************************************************************** - * BuildingClass::~BuildingClass -- Destructor for building type objects. * - * * - * This destructor for building objects will put the building in limbo if possible. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/18/1995 JLB : Created. * - *=============================================================================================*/ -BuildingClass::~BuildingClass(void) -{ - if (GameActive && Class) { - if (House) { -#ifndef USE_RA_AI - House->CurBuildings--; -#else - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Remove(this); -#endif - } - Limbo(); - } -} - - -/*********************************************************************************************** - * BuildingClass::Drop_Debris -- Drops rubble when building is destroyed. * - * * - * This routine is called when a building is destroyed. It handles * - * placing the rubble down. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - * 06/13/1995 JLB : Added smoke and normal infantry survivor possibility. * - * 07/16/1995 JLB : Survival rate depends on if captured or sabotaged. * - *=============================================================================================*/ -void BuildingClass::Drop_Debris(TARGET source) -{ - Validate(); - CELL const *offset; - CELL cell; - - /* - ** Special case for Chan to run from destroyed technology - ** building. - */ - if (GameToPlay == GAME_NORMAL && *this == STRUCT_MISSION && PlayerPtr->ActLike == HOUSE_BAD && Scenario == 10) { - InfantryClass * i = new InfantryClass(INFANTRY_CHAN, House->Class->House); - - ScenarioInit++; - if (i->Unlimbo(Center_Coord(), DIR_N)) { - i->Trigger = TriggerClass::As_Pointer("win"); - i->Strength = Random_Pick(5, (int)i->Class->MaxStrength); - ScenarioInit--; - i->Scatter(0, true); - ScenarioInit++; - i->Assign_Mission(MISSION_GUARD_AREA); - } else { - delete i; - PlayerPtr->Flag_To_Win(); - } - ScenarioInit--; - } - - - /* - ** Generate random survivors from the destroyed building. - */ - cell = Coord_Cell(Coord); - offset = Occupy_List(); - int odds = 2; - if (Target_Legal(WhomToRepay)) odds -= 1; - if (IsCaptured) odds += 6; - while (*offset != REFRESH_EOL) { - CELL newcell; - - newcell = cell + *offset++; - - /* - ** Infantry could run out of a destroyed building. - */ - if (!House->IsToDie && !IsSurvivorless) { - InfantryClass * i = NULL; - - if (Random_Pick(0, odds) == 1) { - i = new InfantryClass(Crew_Type(), House->Class->House); - if (i) { - if (Class->Get_Buildup_Data() != NULL && i->Class->IsNominal) i->IsTechnician = true; - ScenarioInit++; - if (i->Unlimbo(Cell_Coord(newcell), DIR_N)) { - i->Strength = Random_Pick(5, (int)i->Class->MaxStrength); - i->Scatter(0, true); - if (source != TARGET_NONE && !House->Is_Ally(As_Object(source))) { - i->Assign_Mission(MISSION_ATTACK); - i->Assign_Target(source); - } else { - if (House->IsHuman) { - i->Assign_Mission(MISSION_GUARD); - } else { - i->Assign_Mission(MISSION_HUNT); - } - } - } else { - delete i; - } - ScenarioInit--; - } - } - } - - /* - ** Possibly add some smoke rising from the ashes of the building. - */ - switch (Random_Pick(0, 5)) { - case 0: - case 1: - case 2: - new AnimClass(ANIM_SMOKE_M, Coord_Scatter(Cell_Coord(newcell), 0x0050, false), Random_Pick(0, 5), Random_Pick(1, 2)); - break; - - default: - break; - } - - /* - ** The building always scars the ground in some fashion. - */ - if (Random_Pick(0, 3) == 0) { - new SmudgeClass(Random_Pick(SMUDGE_SCORCH1, SMUDGE_SCORCH6), Cell_Coord(newcell)); - } else { - new SmudgeClass(Random_Pick(SMUDGE_CRATER1, SMUDGE_CRATER6), Coord_Scatter(Cell_Coord(newcell), 0x0080, false)); - } - } -} - - -/*********************************************************************************************** - * BuildingClass::Active_Click_With -- Handles clicking on the map while the building is selected.* - * * - * This interface routine handles when the player clicks on the map while this building * - * is currently selected. This is used to assign an override target to a turret or * - * guard tower. * - * * - * INPUT: target -- The target that was clicked upon. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Active_Click_With(ActionType action, ObjectClass * object) -{ - Validate(); - if (action == ACTION_ATTACK) { - Player_Assign_Mission(MISSION_ATTACK, object->As_Target()); - } - - if (action == ACTION_TOGGLE_PRIMARY && Class->IsFactory) { - OutList.Add(EventClass(EventClass::PRIMARY, As_Target())); - } -} - - -/*********************************************************************************************** - * BuildingClass::Active_Click_With -- Handles cell selection for buildings. * - * * - * This routine really only serves one purpose -- to allow targeting of the ground for * - * buildings that are euipped with weapons. * - * * - * INPUT: action -- The requested action to perform. * - * * - * cell -- The cell location to perform the action upon. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Active_Click_With(ActionType action, CELL cell) -{ - Validate(); - if (action == ACTION_ATTACK) { - Player_Assign_Mission(MISSION_ATTACK, ::As_Target(cell)); - } - - if (action == ACTION_MOVE && *this == STRUCT_CONST) { - OutList.Add(EventClass(EventClass::ARCHIVE, As_Target(), ::As_Target(cell))); - OutList.Add(EventClass(EventClass::SELL, As_Target())); - - COORDINATE coord = Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()); - OutList.Add(EventClass(ANIM_MOVE_FLASH, PlayerPtr->Class->House, coord)); - } -} - - -/*********************************************************************************************** - * BuildingClass::Assign_Target -- Assigns a target to the building. * - * * - * Assigning of a target to a building makes sense if the building is one that can attack. * - * This routine would be used to assign the attack target to a turret or guard tower. * - * * - * INPUT: target -- The target that was clicked on while this building was selected. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - * 11/02/1994 JLB : Checks for range before assigning target. * - *=============================================================================================*/ -void BuildingClass::Assign_Target(TARGET target) -{ - Validate(); - if (*this != STRUCT_SAM && !In_Range(target, 0)) { - target = TARGET_NONE; - } - - TechnoClass::Assign_Target(target); -} - - -/*********************************************************************************************** - * BuildingClass::Init -- Initialize the building system to an empty null state. * - * * - * This routine initializes the building system in preparation for a scenario load. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Init(void) -{ - BuildingClass *ptr; - - Buildings.Free_All(); - - ptr = new BuildingClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * BuildingClass::Exit_Object -- Initiates an object to leave the building. * - * * - * This function is used to cause an object to exit the building. It is called when a * - * factory produces a vehicle or other mobile object and that object needs to exit the * - * building to join the ranks of a regular unit. Typically, the object is placed down on * - * the map such that it overlaps the building and then it is given a movement order so that * - * it will move to an adjacent free cell. * - * * - * INPUT: base -- Pointer to the object that is to exit the building. * - * * - * OUTPUT: Returns the success rating for the exit attempt; * - * 0 = complete failure (refund money please) * - * 1 = temporarily prevented (try again later please) * - * 2 = successful * - * * - * WARNINGS: The building is placed in radio contact with the object. The object is in a * - * teathered condition. This condition will be automatically broken when the * - * object reaches the adjacent square. * - * * - * HISTORY: * - * 11/28/1994 JLB : Created. * - * 04/10/1995 JLB : Handles building production by computer. * - * 06/17/1995 JLB : Handles refinery exit. * - *=============================================================================================*/ -int BuildingClass::Exit_Object(TechnoClass * base) -{ - Validate(); - if (!base) return(0); - - TechnoTypeClass const * ttype = (TechnoTypeClass const *)&base->Class_Of(); - - /* - ** A unit exiting a building is always considered to be "locked". That means, it - ** will be considered as to have legally entered the visible map domain. - */ - base->IsLocked = true; - - /* - ** Find a good cell to unload the object to. The object, probably a vehicle - ** will drive/walk to the adjacent free cell. - */ - switch (base->What_Am_I()) { - CELL cell; - - case RTTI_AIRCRAFT: - if (!In_Radio_Contact()) { - AircraftClass *air = (AircraftClass *)base; - - air->Altitude = 0; - ScenarioInit++; - if (air->Unlimbo(Docking_Coord(), air->Pose_Dir())) { - Transmit_Message(RADIO_HELLO, air); - Transmit_Message(RADIO_TETHER); - ScenarioInit--; - return(2); - } - ScenarioInit--; - } else { - AircraftClass *air = (AircraftClass *)base; - - if (Cell_X(Coord_Cell(Center_Coord())) - Map.MapCellX < Map.MapCellWidth/2) { - cell = XY_Cell(Map.MapCellX-1, Random_Pick(0, Map.MapCellHeight-1)+Map.MapCellY); - } else { - cell = XY_Cell(Map.MapCellX+Map.MapCellWidth, Random_Pick(0, Map.MapCellHeight-1)+Map.MapCellY); - } - ScenarioInit++; - if (air->Unlimbo(Cell_Coord(cell), DIR_N)) { - air->Assign_Destination(::As_Target(Nearby_Location(air))); - air->Assign_Mission(MISSION_MOVE); - ScenarioInit--; - return(2); - } - ScenarioInit--; - } - break; - - case RTTI_INFANTRY: - case RTTI_UNIT: - switch (Class->Type) { - case STRUCT_REFINERY: - if (base->What_Am_I() == RTTI_UNIT) { - CELL cell = Coord_Cell(Center_Coord()); - UnitClass * unit = (UnitClass *)base; - - cell = Adjacent_Cell(cell, FACING_SW); - ScenarioInit++; - if (unit->Unlimbo(Coord_Add(unit->Coord, 0x00550060L), DIR_SW_X2)) { - unit->PrimaryFacing = DIR_SW_X2; - Transmit_Message(RADIO_HELLO, unit); - Transmit_Message(RADIO_TETHER); - unit->Assign_Mission(MISSION_HARVEST); - unit->Force_Track(DriveClass::OUT_OF_REFINERY, Cell_Coord(cell)); - unit->Set_Speed(128); - } - ScenarioInit--; - } else { - base->Scatter(true); - } - break; - - case STRUCT_AIRSTRIP: - if (Create_Special_Reinforcement(House, &AircraftTypeClass::As_Reference(AIRCRAFT_CARGO), ttype, TMISSION_UNLOAD, As_Target())) { - delete base; - return(2); - } - return(0); - - case STRUCT_WEAP: - ScenarioInit++; - if (base->Unlimbo(Coord_Add(Coord, Class->ExitPoint), DIR_SW)) { -// base->Assign_Mission(MISSION_MOVE); -// base->Assign_Destination(::As_Target(As_Cell(Coord)+MAP_CELL_W*2)); - base->Mark(MARK_UP); - base->Coord = Coord_Add(Coord, Class->ExitPoint); - base->Mark(MARK_DOWN); - Transmit_Message(RADIO_HELLO, base); - Transmit_Message(RADIO_TETHER); - Assign_Mission(MISSION_UNLOAD); - ScenarioInit--; - return(2); - } - ScenarioInit--; - break; - - case STRUCT_BARRACKS: - case STRUCT_HAND: - CELL cell; - bool found = false; - - cell = Find_Exit_Cell(base); - if (cell) found = true; - -#ifdef OBSOLETE - CELL const *ptr; - bool found = false; - - ptr = Class->ExitList; - while (*ptr != REFRESH_EOL) { - cell = Coord_Cell(Coord) + *ptr++; - if (base->Can_Enter_Cell(cell) == MOVE_OK) { - found = true; - break; - } - } -#endif - - if (found) { - DirType dir = Direction(cell); - COORDINATE start = Coord_Add(Coord, Class->ExitPoint); - - ScenarioInit++; - if (base->Unlimbo(start, dir)) { - - base->Assign_Mission(MISSION_MOVE); - base->Assign_Destination(::As_Target(cell)); - - /* - ** Establish radio contact so unload coordination can occur. This - ** radio contact should always succeed. - */ - if (Transmit_Message(RADIO_HELLO, base) == RADIO_ROGER) { - Transmit_Message(RADIO_UNLOAD); - } - ScenarioInit--; - return(2); - } - ScenarioInit--; - } - break; - } - break; - - case RTTI_BUILDING: - - if (!House->IsHuman) { - /* - ** Find the next available spot to place this newly created building. If the - ** building could be placed at the desired location, fine. If not, then this - ** routine will return failure. The calling routine will probably abandon this - ** building in preference to building another. - */ - - BaseNodeClass * node = Base.Next_Buildable(((BuildingClass *)base)->Class->Type); - // Replaced with RA AI functioality. ST - 7/25/2019 4:14PM -#ifndef USE_RA_AI - if (node) { - if (Flush_For_Placement(base, Coord_Cell(node->Coord))) { - return(1); - } - if (base->Unlimbo(node->Coord)) { - return(2); - } - } -#else - if (GameToPlay == GAME_NORMAL) { - if (node) { - if (Flush_For_Placement(base, Coord_Cell(node->Coord))) { - return(1); - } - if (base->Unlimbo(node->Coord)) { - return(2); - } - } - } else { - - COORDINATE coord = 0; - if (node) { - coord = node->Coord; - } else { - - /* - ** Find a suitable new spot to place. - */ - coord = House->Find_Build_Location((BuildingClass *)base); - } - - if (coord) { - if (Flush_For_Placement(base, Coord_Cell(coord))) { - return(1); - } - if (base->Unlimbo(coord)) { - if (node && ((BuildingClass *)base)->Class->Type == House->BuildStructure) { - House->BuildStructure = STRUCT_NONE; - } - return(2); - } - } - } -#endif - } - break; - } - - /* - ** Failure to exit the object results in a false return value. - */ - return(0); -} - - - - - -/*********************************************************************************************** - * BuildingClass::Update_Buildables -- Informs sidebar of additional construction options. * - * * - * This routine will tell the sidebar of objects that can be built. The function is called * - * whenever a building matures. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/11/1994 JLB : Created. * - * 12/23/1994 JLB : Only updates for PLAYER buildings. * - *=============================================================================================*/ -void BuildingClass::Update_Buildables(void) -{ - Validate(); - - /* - ** Only do this for real human players. ST - 3/22/2019 1:38PM - */ - if (House != PlayerPtr) { - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER || House->IsHuman == false) { - return; - } - } - - bool buildable_via_capture = (IsCaptured && ActLike != House->ActLike) ? true : false; - - if (!IsInLimbo && Is_Discovered_By_Player()) { - switch (Class->ToBuild) { - StructType i; - UnitType u; - InfantryType f; - AircraftType a; - - case RTTI_BUILDINGTYPE: - for (i = STRUCT_FIRST; i < STRUCT_COUNT; i++) { - if (PlayerPtr->Can_Build(i, ActLike)) { -// if (BuildingTypeClass::As_Reference(i).Who_Can_Build_Me(true, true, ActLike)) { - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - Sidebar_Glyphx_Add(RTTI_BUILDINGTYPE, i, House, buildable_via_capture); - } else { - Map.Add(RTTI_BUILDINGTYPE, i, buildable_via_capture); - } -// } - } - } - break; - - case RTTI_UNITTYPE: - for (u = UNIT_FIRST; u < UNIT_COUNT; u++) { - if (PlayerPtr->Can_Build(u, ActLike)) { -// if (UnitTypeClass::As_Reference(u).Who_Can_Build_Me(true, true, ActLike)) { - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - Sidebar_Glyphx_Add(RTTI_UNITTYPE, u, House, buildable_via_capture); - } else { - Map.Add(RTTI_UNITTYPE, u, buildable_via_capture); - } -// } - } - } - break; - - case RTTI_INFANTRYTYPE: - for (f = INFANTRY_FIRST; f < INFANTRY_COUNT; f++) { - if (PlayerPtr->Can_Build(f, ActLike)) { -// if (InfantryTypeClass::As_Reference(f).Who_Can_Build_Me(true, true, ActLike)) { - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - Sidebar_Glyphx_Add(RTTI_INFANTRYTYPE, f, House, buildable_via_capture); - } else { - Map.Add(RTTI_INFANTRYTYPE, f, buildable_via_capture); - } -// } - } - } - break; - - case RTTI_AIRCRAFTTYPE: - for (a = AIRCRAFT_FIRST; a < AIRCRAFT_COUNT; a++) { - if (PlayerPtr->Can_Build(a, ActLike)) { -// if (AircraftTypeClass::As_Reference(a).Who_Can_Build_Me(true, true, ActLike)) { - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - Sidebar_Glyphx_Add(RTTI_AIRCRAFTTYPE, a, House, buildable_via_capture); - } else { - Map.Add(RTTI_AIRCRAFTTYPE, a, buildable_via_capture); - } -// } - } - } - break; - } - } -} - -#if (0) //ST - 3/22/2019 1:33PM -/*********************************************************************************************** - * BuildingClass::Update_Buildables -- Informs sidebar of additional construction options. * - * * - * This routine will tell the sidebar of objects that can be built. The function is called * - * whenever a building matures. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/11/1994 JLB : Created. * - * 12/23/1994 JLB : Only updates for PLAYER buildings. * - *=============================================================================================*/ -void BuildingClass::Update_Buildables(void) -{ - Validate(); - - if (House == PlayerPtr && !IsInLimbo && IsDiscoveredByPlayer) { - switch (Class->ToBuild) { - StructType i; - UnitType u; - InfantryType f; - AircraftType a; - - case RTTI_BUILDINGTYPE: - for (i = STRUCT_FIRST; i < STRUCT_COUNT; i++) { - if (PlayerPtr->Can_Build(i, ActLike)) { -// if (BuildingTypeClass::As_Reference(i).Who_Can_Build_Me(true, true, ActLike)) { - Map.Add(RTTI_BUILDINGTYPE, i); -// } - } - } - break; - - case RTTI_UNITTYPE: - for (u = UNIT_FIRST; u < UNIT_COUNT; u++) { - if (PlayerPtr->Can_Build(u, ActLike)) { -// if (UnitTypeClass::As_Reference(u).Who_Can_Build_Me(true, true, ActLike)) { - Map.Add(RTTI_UNITTYPE, u); -// } - } - } - break; - - case RTTI_INFANTRYTYPE: - for (f = INFANTRY_FIRST; f < INFANTRY_COUNT; f++) { - if (PlayerPtr->Can_Build(f, ActLike)) { -// if (InfantryTypeClass::As_Reference(f).Who_Can_Build_Me(true, true, ActLike)) { - Map.Add(RTTI_INFANTRYTYPE, f); -// } - } - } - break; - - case RTTI_AIRCRAFTTYPE: - for (a = AIRCRAFT_FIRST; a < AIRCRAFT_COUNT; a++) { - if (PlayerPtr->Can_Build(a, ActLike)) { -// if (AircraftTypeClass::As_Reference(a).Who_Can_Build_Me(true, true, ActLike)) { - Map.Add(RTTI_AIRCRAFTTYPE, a); -// } - } - } - break; - } - } -} -#endif - -/*********************************************************************************************** - * BuildingClass::Fire_Out -- Handles when attached animation expires. * - * * - * This routine is used to perform any fixups necessary when the attached animation has * - * terminated. This occurs when the fire & smoke animation that a SAM site produces stops. * - * At that point, normal reload procedures can commence. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/30/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Fire_Out(void) -{ - Validate(); -// SAM = SAM_READY; -// IsFiring = false; -} - - -/*********************************************************************************************** - * BuildingClass::Limbo -- Handles power adjustment as building goes into limbo. * - * * - * This routine will handle the power adjustments for the associated house when the * - * building goes into limbo. This means that its power drain or production is subtracted * - * from the house accumulated totals. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the building limboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Limbo(void) -{ - Validate(); -// HouseClass *housep; -// RTTIType bld_type; - - if (!IsInLimbo) { - - /* - ** Update the total factory type, assuming this building has a factory. - */ - switch (Class->ToBuild) { - case RTTI_AIRCRAFTTYPE: - House->AircraftFactories--; - break; - - case RTTI_INFANTRYTYPE: - House->InfantryFactories--; - break; - - case RTTI_UNITTYPE: - House->UnitFactories--; - break; - - case RTTI_BUILDINGTYPE: - House->BuildingFactories--; - break; - - default: - break; - } - - House->IsRecalcNeeded = true; - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:25AM - // - House->Recalc_Center(); -#endif - /* - ** Update the power status of the owner's house. - */ - House->Adjust_Power(-Power_Output()); - House->Adjust_Drain(-Class->Drain); - House->Adjust_Capacity(-(int)Class->Capacity, true); - if (House == PlayerPtr) { - Map.PowerClass::IsToRedraw = true; - Map.Flag_To_Redraw(false); - } - -#ifdef OBSOLETE - /* - ** If this building is building something, the FactoryClass doing the - ** building must be deleted, as well as the object being built. - ** - If this building is controlled by Computer AI, this building's Factory - ** pointer will point to the factory doing the building. - ** - Otherwise, the owner House's Factory indices will indicate what's - ** being built. (The player's sidebar also contains indices to indicate - ** what's being built, but those just echo the house's indices.) - */ - if (Factory) { - Factory->Abandon(); - delete Factory; - Factory = 0; - } - - /* - ** If the owner HouseClass is building something, and this building can - ** build that thing, we may be the last building for that house that can - ** build that thing; if so, abandon production of it. - */ - housep = HouseClass::As_Pointer(Owner()); - if (housep) { - FactoryClass * factory = 0; - bld_type = RTTI_NONE; - if (housep->AircraftFactory != -1 && Class->ToBuild == RTTI_AIRCRAFTTYPE) { - bld_type = RTTI_AIRCRAFTTYPE; - factory = Factories.Raw_Ptr(housep->AircraftFactory); - } - if (housep->InfantryFactory != -1 && Class->ToBuild==RTTI_INFANTRYTYPE) { - bld_type = RTTI_INFANTRYTYPE; - factory = Factories.Raw_Ptr(housep->InfantryFactory); - } - if (housep->UnitFactory != -1 && Class->ToBuild==RTTI_UNITTYPE) { - bld_type = RTTI_UNITTYPE; - factory = Factories.Raw_Ptr(housep->UnitFactory); - } - if (housep->BuildingFactory != -1 && Class->ToBuild==RTTI_BUILDINGTYPE) { - bld_type = RTTI_BUILDINGTYPE; - factory = Factories.Raw_Ptr(housep->BuildingFactory); - } - if (housep->SpecialFactory != -1 && Class->ToBuild==RTTI_SPECIAL) { - bld_type = RTTI_SPECIAL; - } - - if (bld_type != RTTI_NONE) { - if (factory) { - TechnoClass * object = factory->Get_Object(); - IsInLimbo = true; - if (object && !object->Techno_Type_Class()->Who_Can_Build_Me(true, false, housep->Class->House)) { - housep->Abandon_Production(bld_type); - } - IsInLimbo = false; - } - } - } -#endif - - /* - ** This could be a building that builds. If so, then the sidebar may need adjustment. - ** Set IsInLimbo to true to "fool" the sidebar into knowing that this building - ** isn't available. Set it back to false so the rest of the Limbo code works. - ** Otherwise, the sidebar won't properly remove non-available buildables. - */ - if (IsOwnedByPlayer && !ScenarioInit) { - IsInLimbo = true; - Map.Recalc(); - IsInLimbo = false; - } -#ifdef NEVER - if (!House->IsHuman) { - Update_Specials(); - } -#endif - - } - return(TechnoClass::Limbo()); -} - - -/*********************************************************************************************** - * BuildingClass::Fire_Coord -- Calculates the coordinate that projectile would appear. * - * * - * This routine is used to determine where a projectile would appear if this building * - * were to fire. The location usually depends on the current rotation setting of the * - * turret or else on the direction of the target that will be fired upon. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with coordinate that the projectile should appear at if the building * - * were to fire. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE BuildingClass::Fire_Coord(int ) const -{ - Validate(); - COORDINATE coord = Center_Coord(); // Center of firing building. - - /* - ** Make adjustments to the firing coordinate to account for turret - ** position. This depends on building type and turret facing. - */ - switch (Class->Type) { - default: - case STRUCT_GTOWER: - case STRUCT_ATOWER: - coord = Coord_Move(coord, DIR_N, 0x0030); - if (Target_Legal(TarCom)) { - coord = Coord_Move(coord, ::Direction(coord, As_Coord(TarCom)), 0x0040); - } - break; - case STRUCT_OBELISK: - coord = Coord_Move(coord, DIR_N, 0x00A8); -// coord = Coord_Move(coord, DIR_N, 0x0058); - coord = Coord_Move(coord, DIR_W, 0x0018); - break; - - case STRUCT_SAM: - case STRUCT_TURRET: - coord = Coord_Move(coord, DIR_N, 0x0030); - coord = Coord_Move(coord, PrimaryFacing.Current(), 0x0080); - break; - } - - return(coord); -} - - -/*********************************************************************************************** - * BuildingClass::Greatest_Threat -- Searches for target that building can fire upon. * - * * - * This routine intercepts the Greatest_Threat function so that it can add the ability * - * to search for ground targets, if this isn't a SAM site. * - * * - * INPUT: threat -- The base threat control value. Typically, it might be THREAT_RANGE * - * or THREAT_NORMAL. * - * * - * OUTPUT: Returns with a suitable target. If none could be found, then TARGET_NONE is * - * returned instead. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - *=============================================================================================*/ -TARGET BuildingClass::Greatest_Threat(ThreatType threat) const -{ - Validate(); - if (*this != STRUCT_SAM) { - threat = threat | (THREAT_INFANTRY|THREAT_BOATS|THREAT_VEHICLES|THREAT_RANGE); - - if (!House->IsHuman) { - threat = threat | THREAT_BUILDINGS; - } -// threat = threat & ~THREAT_AIR; - } else { - threat = threat | THREAT_AREA; - } - - if (Class->Primary != WEAPON_NONE && BulletTypeClass::As_Reference(Weapons[Class->Primary].Fires).IsAntiAircraft) { - threat = threat | THREAT_AIR; - } - return(TechnoClass::Greatest_Threat(threat)); -} - - -/*********************************************************************************************** - * BuildingClass::Grand_Opening -- Handles construction completed special operations. * - * * - * This routine is called when construction has finished. Typically, this enables * - * new production options for factories. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/08/1995 JLB : Created. * - * 06/13/1995 JLB : Added helipad. * - *=============================================================================================*/ -void BuildingClass::Grand_Opening(bool captured) -{ - Validate(); - - /* - ** Adjust the owning house according to the power, drain, and Tiberium capacity that - ** this building has. - */ - House->Adjust_Drain(Class->Drain); - House->Adjust_Capacity(Class->Capacity); - House->IsRecalcNeeded = true; - - /* SPECIAL CASE: - ** Refineries get a free harvester. Add a harvester to the reinforcement list - ** at this time. - */ - if (*this == STRUCT_REFINERY && !ScenarioInit && !captured && !Debug_Map && (!House->IsHuman || PurchasePrice == 0 || PurchasePrice > Class->Raw_Cost())) { - CELL cell = Coord_Cell(Adjacent_Cell(Center_Coord(), DIR_SW)); -// if (!Map[cell].Cell_Unit()) { - UnitClass * unit = new UnitClass(UNIT_HARVESTER, House->Class->House); - if (unit) { - - /* - ** Try to place down the harvesters. If it could not be placed, then try - ** to place it in a nearby location. - */ - if (!unit->Unlimbo(Cell_Coord(cell), DIR_SW)) { - cell = Nearby_Location(unit); - - /* - ** If the harvester could still not be placed, then refund the money - ** to the owner and then bail. - */ - if (!unit->Unlimbo(Cell_Coord(cell), DIR_SW)) { - House->Refund_Money(unit->Class->Cost_Of()); - delete unit; - } - } - } else { - - /* - ** If the harvester could not be created in the first place, then give - ** the full refund price to the owning player. - */ - House->Refund_Money(UnitTypeClass::As_Reference(UNIT_HARVESTER).Cost_Of()); - } - } -// } - - /* - ** Helicopter pads get a free attack helicopter. - */ - if (*this == STRUCT_HELIPAD && !captured && (!House->IsHuman || PurchasePrice == 0 || PurchasePrice > Class->Raw_Cost())) { - ScenarioInit++; - AircraftClass * air = 0; - if (House->ActLike == HOUSE_GOOD) { - air = new AircraftClass(AIRCRAFT_ORCA, House->Class->House); - } else { - air = new AircraftClass(AIRCRAFT_HELICOPTER, House->Class->House); - } - if (air) { - air->Altitude = 0; - if (air->Unlimbo(Docking_Coord(), air->Pose_Dir())) { - air->Assign_Mission(MISSION_GUARD); - air->Transmit_Message(RADIO_HELLO, this); - Transmit_Message(RADIO_TETHER); - } - } - ScenarioInit--; - } -} - - -/*********************************************************************************************** - * BuildingClass::Repair -- Initiates or terminates the repair process. * - * * - * This routine will start, stop, or toggle the repair process. When a building repairs, it * - * occurs incrementally over time. * - * * - * INPUT: control -- Determines how to control the repair process. * - * 0: Turns repair process off (if it was on). * - * 1: Turns repair process on (if it was off). * - * -1:Toggles repair process to other state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/08/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Repair(int control) -{ - Validate(); - switch (control) { - case -1: - IsRepairing = (IsRepairing == false); - break; - - case 1: - if (IsRepairing) return; - IsRepairing = true; - break; - - case 0: - if (!IsRepairing) return; - IsRepairing = false; - break; - } - - /* - ** At this point, we know that the repair state has changed. Perform - ** appropriate action. - */ - VocType sound = VOC_NONE; - if (IsRepairing) { - if (Strength == Class->MaxStrength) { - sound = VOC_SCOLD; - } else { - sound = VOC_BUTTON; - Clicked_As_Target(PlayerPtr->Class->House); // 2019/09/20 JAS - Added record of who clicked on the object - IsWrenchVisible = true; - } - } else { - sound = VOC_BUTTON; - } - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Sound_Effect(sound, Coord); - } -} - - -/*********************************************************************************************** - * BuildingClass::Sell_Back -- Controls the sell back (demolish) operation. * - * * - * This routine will initiate or stop the sell back process for a building. It is called * - * when the player clicks on a building when the sell mode is active. * - * * - * INPUT: control -- The action to perform. 0 = turn deconstruction off, 1 = deconstruct, * - * -1 = toggle deconstruction state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Sell_Back(int control) -{ - Validate(); - if (Class->Get_Buildup_Data()) { - bool decon = false; - switch (control) { - case -1: - decon = (Mission != MISSION_DECONSTRUCTION); - break; - - case 1: - if (Mission == MISSION_DECONSTRUCTION) return; - decon = true; - break; - - case 0: - if (Mission != MISSION_DECONSTRUCTION) return; - decon = false; - break; - } - - /* - ** At this point, we know that the repair state has changed. Perform - ** appropriate action. - */ - if (decon) { -// Transmit_Message(RADIO_RUN_AWAY); -// Transmit_Message(RADIO_OVER_OUT); - Assign_Mission(MISSION_DECONSTRUCTION); - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Clicked_As_Target(PlayerPtr->Class->House); // 2019/09/20 JAS - Added record of who clicked on the object - } - } - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Sound_Effect(VOC_BUTTON); - } - } -} - - -/*********************************************************************************************** - * BuildingClass::What_Action -- Determines action to perform if click on specified object. * - * * - * This routine will determine what action to perform if the mouse was clicked on the * - * object specified. This determination is used to control the mouse imagery and the * - * function process when the mouse button is pressed. * - * * - * INPUT: object -- Pointer to the object that, if clicked on, will control what action * - * is to be performed. * - * * - * OUTPUT: Returns with the ActionType that will occur if the mouse is clicked over the * - * object specified while the building is currently selected. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/18/1995 JLB : Created. * - *=============================================================================================*/ -ActionType BuildingClass::What_Action(ObjectClass * object) const -{ - Validate(); - ActionType action = TechnoClass::What_Action(object); - - if (action == ACTION_SELF) { - if (Class->IsFactory && PlayerPtr == House) { - switch (Class->ToBuild) { - case RTTI_AIRCRAFTTYPE: - if (House->AircraftFactories < 2) { - action = ACTION_NONE; - } - else { - action = ACTION_TOGGLE_PRIMARY; - } - break; - - case RTTI_INFANTRYTYPE: - if (House->InfantryFactories < 2) { - action = ACTION_NONE; - } - else { - action = ACTION_TOGGLE_PRIMARY; - } - break; - - case RTTI_UNITTYPE: - if (House->UnitFactories < 2) { - action = ACTION_NONE; - } - else { - action = ACTION_TOGGLE_PRIMARY; - } - break; - - default: - action = ACTION_NONE; - break; - } - - } else { - action = ACTION_NONE; - } - } - - /* - ** Don't allow targeting of SAM sites, even if the CTRL key - ** is held down. - */ - if (action == ACTION_ATTACK && *this == STRUCT_SAM) { - action = ACTION_NONE; - } - - if (action == ACTION_MOVE) { - action = ACTION_NONE; - } - - return(action); -} - - -/*********************************************************************************************** - * BuildingClass::What_Action -- Determines what action will occur. * - * * - * This routine examines the cell specified and returns with the action that will be * - * performed if that cell were clicked upon while the building is selected. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: Returns the ActionType that indicates what should occur if the mouse is clicked * - * on this cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/18/1995 JLB : Created. * - *=============================================================================================*/ -ActionType BuildingClass::What_Action(CELL cell) const -{ - Validate(); - ActionType action = TechnoClass::What_Action(cell); - - if (action == ACTION_MOVE && (*this != STRUCT_CONST || !Special.IsMCVDeploy)) { - action = ACTION_NONE; - } - - /* - ** Don't allow targeting of SAM sites, even if the CTRL key - ** is held down. - */ - if (action == ACTION_ATTACK && *this == STRUCT_SAM) { - action = ACTION_NONE; - } - - return(action); -} - - -/*********************************************************************************************** - * BuildingClass::Begin_Mode -- Begins an animation mode for the building. * - * * - * This routine will start the building animating. This animation will loop indefinately * - * until explicitly stopped. * - * * - * INPUT: bstate -- The animation state to initiate. * - * * - * OUTPUT: none * - * * - * WARNINGS: The buliding graphic state will reflect the first stage of this animation the * - * very next time it is rendered. * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - * 07/02/1995 JLB : Uses normalize animation rate where applicable. * - *=============================================================================================*/ -void BuildingClass::Begin_Mode(BStateType bstate) -{ - Validate(); - QueueBState = bstate; - if (BState == BSTATE_NONE || bstate == BSTATE_CONSTRUCTION || ScenarioInit) { - BState = bstate; - QueueBState = BSTATE_NONE; - BuildingTypeClass::AnimControlType const * ctrl = Fetch_Anim_Control(); - - int rate = ctrl->Rate; - if (Class->IsRegulated && bstate != BSTATE_CONSTRUCTION) { - rate = Options.Normalize_Delay(rate); - } - Set_Rate(rate); - Set_Stage(ctrl->Start); - } -} - - -/*********************************************************************************************** - * BuildingClass::Read_INI -- Reads buildings from INI file. * - * * - * This is the basic scenario initialization of building function. It * - * is called when reading the scenario startup INI file and it handles * - * creation of all specified buildings. * - * * - * INI entry format: * - * Housename, Typename, Strength, Cell, Facing, Triggername * - * * - * INPUT: buffer -- Pointer to the loaded INI file data. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Read_INI(char *buffer) -{ - BuildingClass *b; // Working unit pointer. - char *tbuffer; // Accumulation buffer of unit IDs. - HousesType bhouse; // Building house. - StructType classid; // Building type. - int len; // Size of data in buffer. - CELL cell; // Cell of building. - char buf[128]; - char *trigname; // building's trigger's name - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - /* - ** Read the entire building INI section into HIDBUF - */ - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - - while (*tbuffer != '\0') { - - /* - ** Get a building entry. - */ - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - - /* - ** 1st token: house name. - */ - bhouse = HouseTypeClass::From_Name(strtok(buf, ",")); - - /* - ** 2nd token: building name. - */ - classid = BuildingTypeClass::From_Name(strtok(NULL, ",")); - - if (bhouse != HOUSE_NONE && classid != STRUCT_NONE) { - int strength; - DirType facing; - - /* - ** 3rd token: strength. - */ - strength = atoi(strtok(NULL, ",")); - - /* - ** 4th token: cell #. - */ - cell = atoi(strtok(NULL, ",")); - - /* - ** 5th token: facing. - */ - facing = (DirType)atoi(strtok(NULL, ",")); - - /* - ** 6th token: triggername (can be NULL). - */ - trigname = strtok(NULL,","); - - if (HouseClass::As_Pointer(bhouse) != NULL) { - b = new BuildingClass(classid, bhouse); - if (b) { - if (b->Unlimbo(Cell_Coord(cell), facing)) { - strength = MIN(strength, 0x100); - strength = Fixed_To_Cardinal(b->Class->MaxStrength, strength); - b->Strength = strength; - b->IsALemon = false; - b->Trigger = TriggerClass::As_Pointer(trigname); - if (b->Trigger) { - b->Trigger->AttachCount++; - } - } else { - - /* - ** If the building could not be unlimboed on the map, then this indicates - ** a serious error. Delete the building. - */ - delete b; - } - } - } - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * BuildingClass::Write_INI -- Writes all building data to an INI file. * - * * - * This routine is used to write the buildings into an INI file. It is necessary for the * - * scenario editor save game option. * - * * - * INI entry format: * - * Housename, Typename, Strength, Cell, Facing, Triggername * - * * - * INPUT: buffer -- The buffer that holds the INI data. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Write_INI(char *buffer) -{ - int index; - char uname[10]; - char buf[127]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing building data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Write the data out. - */ - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass * building; - - building = Buildings.Ptr(index); - if (!building->IsInLimbo) { - - sprintf(uname, "%03d", index); - sprintf(buf, "%s,%s,%d,%u,%d,%s", - building->House->Class->IniName, - building->Class->IniName, - building->Health_Ratio(), - Coord_Cell(building->Coord), - building->PrimaryFacing.Current(), - building->Trigger ? building->Trigger->Get_Name() : "None" - ); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} - - -/*********************************************************************************************** - * BuildingClass::As_Target -- Convert the building into a target value. * - * * - * Use this routine to take the building and convert it into a target number. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the target number for this building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -TARGET BuildingClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_BUILDING, Buildings.ID(this))); -} - - -/*********************************************************************************************** - * BuildingClass::Center_Coord -- Fetches the center coordinate for the building. * - * * - * This routine is used to set the center coordinate for this building. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate for the center location for the building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE BuildingClass::Center_Coord(void) const -{ - Validate(); - return(Coord_Add(Coord, CenterOffset[Class->Size])); -} - -static bool Occupy_List_Contains(const short * list, short cell) -{ - while (*list != REFRESH_EOL) { - if (*list == cell) { - return true; - } - list++; - } - return false; -} - -COORDINATE BuildingClass::Target_Coord(void) const -{ - static constexpr int _num_facings = 3; - static const FacingType _facings[_num_facings] = { FACING_S, FACING_E, FACING_SE }; - static const COORDINATE _offsets[_num_facings] = { 0x00800000, 0x00000080, 0x00800080 }; - - Validate(); - COORDINATE offset = CenterOffset[Class->Size]; - - const short * list = Occupy_List(); - CELL cell = Coord_Cell(offset); - if (!Occupy_List_Contains(list, cell)) { - for (int i = 0; i < _num_facings; ++i) { - CELL adjcell = Adjacent_Cell(cell, _facings[i]); - if (Occupy_List_Contains(list, adjcell)) { - offset = Coord_Add(offset, _offsets[i]) & 0xFF80FF80; - break; - } - } - } - return(Coord_Add(Coord, offset)); -} - - -COORDINATE BuildingClass::Docking_Coord(void) const -{ - Validate(); - if (*this == STRUCT_HELIPAD) { - return(Coord_Add(Coord, XYP_COORD(24, 18))); - } - if (*this == STRUCT_AIRSTRIP) { - return(Coord_Add(Coord, XYP_COORD(18, 30))); - } - return(TechnoClass::Docking_Coord()); -} - - -/*********************************************************************************************** - * BuildingClass::Can_Fire -- Determines if this building can fire. * - * * - * Use this routine to see if the building can fire its weapon. * - * * - * * - * INPUT: target -- The target that firing upon is desired. * - * * - * which -- Which weapon to use when firing. 0=primary, 1=secondary. * - * * - * OUTPUT: Returns with the fire possibility code. If firing is allowed, then FIRE_OK is * - * returned. Other cases will result in appropriate fire code value that indicates * - * why firing is not allowed. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/03/1995 JLB : Created. * - *=============================================================================================*/ -FireErrorType BuildingClass::Can_Fire(TARGET target, int which) const -{ - Validate(); - FireErrorType canfire = TechnoClass::Can_Fire(target, which); - - if (canfire == FIRE_OK) { - - /* - ** Double check to make sure that the facing is roughly toward - ** the target. If the difference is too great, then firing is - ** temporarily postponed. - */ - if (Class->IsTurretEquipped) { - /* - ** If the turret is rotating then firing must be delayed. - */ - if (PrimaryFacing.Is_Rotating()) { - return(FIRE_ROTATING); - } - - int diff = PrimaryFacing.Difference(Direction(TarCom)); - if (ABS(diff) > 8) { - return(FIRE_FACING); - } - } - - /* - ** Advanced guard towers need power to fire. - */ - if (*this == STRUCT_ATOWER && House->Power_Fraction() < 0x0100) { - return(FIRE_BUSY); - } - - /* - ** If an obelisk can fire, check the state of charge. If it isn't charging - ** up, start it charging up and return FIRE_BUSY. If it is charging but - ** isn't done yet, return FIRE_BUSY. If it's done charging, stop the - ** charging process, clear the stage timer, and return FIRE_OK. - */ - if (Class->Primary == WEAPON_OBELISK_LASER && !IsCharged) { - return(FIRE_BUSY); - } - } - return(canfire); -} - - -/*********************************************************************************************** - * BuildingClass::Toggle_Primary -- Toggles the primary factory state. * - * * - * This routine will change the primary factory state of this building. The primary * - * factory is the one that units will be produced from (by default). * - * * - * INPUT: none * - * * - * OUTPUT: Is this building NOW the primary factory? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/03/1995 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Toggle_Primary(void) -{ - Validate(); - if (IsLeader) { - IsLeader = false; - } else { - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (!building->IsInLimbo && building->Owner() == Owner() && building->Class->ToBuild == Class->ToBuild) { - building->IsLeader = false; - } - } - IsLeader = true; - if (House == PlayerPtr) { - Speak(VOX_PRIMARY_SELECTED); - } - } - Mark(MARK_CHANGE); - return(IsLeader); -} - - -/*********************************************************************************************** - * BuildingClass::Captured -- Captures the building. * - * * - * This routine will change the owner of the building. It handles updating any related * - * game systems as a result. Factories are the most prone to have great game related * - * consequences when captured. This could also affect the sidebar and building ownership. * - * * - * INPUT: newowner -- Pointer to the house that is now the new owner. * - * * - * OUTPUT: Was the capture attempt successful? * - * * - * WARNINGS: Capturing could fail if the house is already owned by the one specified or * - * the building isn't allowed to be captured. * - * * - * HISTORY: * - * 05/03/1995 JLB : Created. * - * 07/05/1995 JLB : Fixed production problem with capturing enemy buildings. * - *=============================================================================================*/ -bool BuildingClass::Captured(HouseClass * newowner) -{ - Validate(); - if (Can_Capture() && newowner != House) { - switch (Owner()) { - case HOUSE_GOOD: - Speak(VOX_GDI_CAPTURED); - break; - - case HOUSE_BAD: - Speak(VOX_NOD_CAPTURED); - break; - } - - if (House == PlayerPtr) { - Map.PowerClass::IsToRedraw = true; - Map.Flag_To_Redraw(false); - } - - /* - ** Maybe trigger an achivement. ST - 11/14/2019 1:53PM - */ - if (newowner->IsHuman) { - TechnoTypeClass const *object_type = Techno_Type_Class(); - if (object_type) { - if (newowner->ActLike != House->ActLike) { - On_Achievement_Event(newowner, "OPPOSING_BUILDING_CAPTURED", object_type->IniName); - } else { - On_Achievement_Event(newowner, "BUILDING_CAPTURED", object_type->IniName); - } - } - } - - /* - ** Add this building to the list of buildings captured this game. For internet stats purposes - */ - if (GameToPlay == GAME_INTERNET){ - newowner->CapturedBuildings->Increment_Unit_Total (Class->Type); - } - - House->Adjust_Power(-Power_Output()); - LastStrength = 0; - House->Adjust_Drain(-Class->Drain); - int booty = House->Adjust_Capacity(-(int)Class->Capacity, true); - - /* - ** If there is something loaded, then it gets captured as well. - */ - TechnoClass * tech = Attached_Object(); - if (tech) tech->Captured(newowner); - - /* - ** If something isn't technically attached, but is sitting on this - ** building for another reason (e.g., helicopter on helipad), then it - ** gets captured as well. - */ - tech = Contact_With_Whom(); - if (tech) { - if (Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER && ::Distance(tech->Center_Coord(), Docking_Coord()) < 0x0040) { - tech->Captured(newowner); - } else { - Transmit_Message(RADIO_RUN_AWAY); - Transmit_Message(RADIO_OVER_OUT); - } - } - - /* - ** Decrement the factory counter for the original owner. - */ - switch (Class->ToBuild) { - case RTTI_UNITTYPE: - House->UnitFactories--; - break; - - case RTTI_INFANTRYTYPE: - House->InfantryFactories--; - break; - - case RTTI_BUILDINGTYPE: - House->BuildingFactories--; - break; - - case RTTI_AIRCRAFTTYPE: - House->AircraftFactories--; - break; - - default: - break; - } - -#ifdef NEVER - if (IsOwnedByPlayer && !ScenarioInit) { - Map.Recalc(); - } - if (!House->IsHuman) { - Update_Specials(); - } -#endif - - /* - ** Flag that both owners now need to update their buildable lists. - */ - House->IsRecalcNeeded = true; - newowner->IsRecalcNeeded = true; - - HouseClass * oldowner = House; // Added for RA AI in TD. ST - 7/26/2019 9:25AM - - IsCaptured = true; - TechnoClass::Captured(newowner); - - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:25AM - // - oldowner->Recalc_Center(); - House->Recalc_Center(); -#endif - - SmudgeType bib; - CELL cell = Coord_Cell(Coord); - if (Class->Bib_And_Offset(bib, cell)) { - SmudgeClass * smudge = new SmudgeClass(bib); - if (smudge) { - smudge->Disown(cell); - delete smudge; - } - new SmudgeClass(bib, Cell_Coord(cell), House->Class->House); - } - - /* - ** Increment the factory count for the new owner. - */ - switch (Class->ToBuild) { - case RTTI_UNITTYPE: - House->UnitFactories++; - break; - - case RTTI_INFANTRYTYPE: - House->InfantryFactories++; - break; - - case RTTI_BUILDINGTYPE: - House->BuildingFactories++; - break; - - case RTTI_AIRCRAFTTYPE: - House->AircraftFactories++; - break; - - default: - break; - } - - IsRepairing = false; - Grand_Opening(true); - House->Harvested(booty); - - Mark(MARK_CHANGE); - - /* - ** Perform a look operation when catpured if it was the player - ** that performed the capture. - */ - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER && House->IsHuman) { - Look(false); - } else { - if (House == PlayerPtr) { - Look(false); - } - } - - if (oldowner) { - oldowner->Check_Pertinent_Structures(); - } - - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * BuildingClass::Sort_Y -- Returns the building coordinate used for sorting. * - * * - * The coordinate value returned from this function should be used for sorting purposes. * - * It has special offset adjustment applied so that vehicles don't overlap (as much). * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a coordinate value suitable to be used for sorting. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - * 06/19/1995 JLB : Handles buildings that come with bibs built-in. * - *=============================================================================================*/ -COORDINATE BuildingClass::Sort_Y(void) const -{ - Validate(); - if (*this == STRUCT_REPAIR) { - return(Coord); - } - if (*this == STRUCT_HELIPAD) { - return(Center_Coord()); - } - if (*this == STRUCT_BARRACKS /*|| *this == STRUCT_POWER*/) { - return(Center_Coord()); - } - if (*this == STRUCT_REFINERY) { - return(Center_Coord()); - } - return(Coord_Add(Center_Coord(), XY_Coord(0, (Class->Height()*256)/3))); -} - - -/*********************************************************************************************** - * BuildingClass::Can_Enter_Cell -- Determines if building can be placed down. * - * * - * This routine will determine if the building can be placed down at the location * - * specified. * - * * - * INPUT: cell -- The cell to examine. This is usually the cell of the upper left corner * - * of the building if it were to be placed down. * - * * - * OUTPUT: Returns with the move legality value for placement at the location specified. This * - * will either be MOVE_OK or MOVE_NO. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -MoveType BuildingClass::Can_Enter_Cell(CELL cell, FacingType) const -{ - Validate(); - - if (*this == STRUCT_CONST && IsDown) { - return(Map[cell].Is_Generally_Clear() ? MOVE_OK : MOVE_NO); - } - - return(Class->Legal_Placement(cell) ? MOVE_OK : MOVE_NO); -} - - -/*********************************************************************************************** - * BuildingClass::Can_Demolish -- Can the player demolish (sell back) the building? * - * * - * Determines if the player can sell this building. Selling is possible if the building * - * is not currently in construction or deconstruction animation. * - * * - * INPUT: none * - * * - * OUTPUT: Can the building be demolished at this time? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - * 07/01/1995 JLB : If there is no buildup data, then the building can't be sold. * - * 07/17/1995 JLB : Cannot sell a refinery that has a harvester attached. * - *=============================================================================================*/ -bool BuildingClass::Can_Demolish(void) const -{ - Validate(); - // !Mission != sounds a bit fishy. ST - 2018 - //if (Class->Get_Buildup_Data() && BState != BSTATE_CONSTRUCTION && !Mission != MISSION_DECONSTRUCTION && Mission != MISSION_CONSTRUCTION) { - if (Class->IsUnsellable) return(false); - if (Class->Get_Buildup_Data() && BState != BSTATE_CONSTRUCTION && Mission != MISSION_DECONSTRUCTION && Mission != MISSION_CONSTRUCTION) { - if (*this == STRUCT_REFINERY && Is_Something_Attached()) return(false); - return(true); - } - return(false); -} - - -bool BuildingClass::Can_Demolish_Unit(void) const -{ - return(*this == STRUCT_REPAIR && In_Radio_Contact() && Distance(Contact_With_Whom()) < 0x0080); -} - - -bool BuildingClass::Can_Capture(void) const -{ - bool can_capture = Class->IsCaptureable; - if (*this == STRUCT_EYE) { - // Don't allow the Advanced Comm Center to be capturable in skirmish, MP, or beyond scenario 13 in SP - if (GameToPlay == GAME_NORMAL) { - can_capture &= Scenario < 13; - } else { - can_capture = false; - } - } - return(can_capture); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Guard -- Handles guard mission for combat buildings. * - * * - * Buildings that can attack are given this mission. They will wait until a suitable target * - * comes within range and then launch into the attack mission. Buildings that have no * - * weaponry will just sit in this routine forever. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before this routine will be called * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Mission_Guard(void) -{ - Validate(); - /* - ** If this building has a weapon, then search for a target to attack. When - ** a target is found, switch into attack mode to deal with the threat. - */ - if (Class->Primary != WEAPON_NONE) { - - /* - ** Weapon equipped buildings are ALWAYS ready to launch into another mission if - ** they are sitting around in guard mode. - */ - IsReadyToCommence = true; - - /* - ** If there is no target available, then search for one. - */ - if (!Target_Legal(TarCom)) { - ThreatType threat = THREAT_NORMAL; - Assign_Target(Greatest_Threat(threat)); - } - - /* - ** There is a valid target. Switch into attack mode right away. - */ - if (Target_Legal(TarCom)) { - Assign_Mission(MISSION_ATTACK); - return(1); - } - } else { - - /* - ** This is the very simple state machine that basically does - ** nothing. This is the mode that non weapon equipped buildings - ** are normally in. - */ - enum { - INITIAL_ENTRY, - IDLE - }; - switch (Status) { - case INITIAL_ENTRY: - Begin_Mode(BSTATE_IDLE); - Status = IDLE; - break; - - case IDLE: - /* - ** Special case to break out of guard mode if this is a repair - ** facility and there is a customer waiting at the grease pit. - */ - if (*this == STRUCT_REPAIR && - In_Radio_Contact() && - Contact_With_Whom()->Is_Techno() && - ((TechnoClass *)Contact_With_Whom())->Mission == MISSION_ENTER && - Distance(Contact_With_Whom()) < 0x0040 && - Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER) { - - Assign_Mission(MISSION_REPAIR); - return(1); - } - break; - } - return(TICKS_PER_SECOND*5); - } - return(TICKS_PER_SECOND/2); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Construction -- Handles mission construction. * - * * - * This routine will handle mission construction. When this mission is complete, the * - * building will begin normal operation. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Mission_Construction(void) -{ - Validate(); - enum { - INITIAL, - DURING - }; - switch (Status) { - case INITIAL: - Begin_Mode(BSTATE_CONSTRUCTION); - Transmit_Message(RADIO_BUILDING); - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Sound_Effect(VOC_CONSTRUCTION, Coord); - } - Status = DURING; - break; - - case DURING: - if (IsReadyToCommence) { - - /* - ** When construction is complete, then transmit this - ** to the construction yard so that it can stop its - ** construction animation. - */ - Transmit_Message(RADIO_COMPLETE); // "I'm finished." - Transmit_Message(RADIO_OVER_OUT); // "You're free." - Begin_Mode(BSTATE_IDLE); - // Construction yard already called this on reveal in normal game mode, so don't do twice - if (*this != STRUCT_CONST || GameToPlay != GAME_NORMAL) { - Grand_Opening(); - } - Assign_Mission(MISSION_GUARD); - PrimaryFacing = Class->StartFace; - } - break; - } - return(1); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Deconstruction -- Handles building deconstruction. * - * * - * This state machine is only used when the building is deconstructing as a result of * - * selling. When this mission is finished, the building will no longer exist. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - * 08/13/1995 JLB : Enable selling of units on a repair bay. * - * 08/20/1995 JLB : Scatters infantry from scattered starting points. * - *=============================================================================================*/ -int BuildingClass::Mission_Deconstruction(void) -{ - Validate(); - /* - ** Always force repair off. - */ - Repair(0); - - enum { - INITIAL, - HOLDING, - DURING - }; - switch (Status) { - case INITIAL: - - /* - ** Special check for the repair bay which has the ability to sell - ** whatever is on it. If there is something on the repair bay, then - ** it will be sold. If there is nothing on the repair bay, then - ** the repair bay itself will be sold. - */ - if (Can_Demolish_Unit() && Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER) { - TechnoClass * tech = Contact_With_Whom(); - Transmit_Message(RADIO_OVER_OUT); - tech->Sell_Back(1); -// House->Refund_Money(tech->Refund_Amount()); -// tech->Limbo(); - IsReadyToCommence = true; - Assign_Mission(MISSION_GUARD); - return(1); - } - - IsReadyToCommence = false; - Transmit_Message(RADIO_RUN_AWAY); - Status = HOLDING; - break; - - case HOLDING: - if (!IsTethered) { - - /* - ** The crew will evacuate from the building. The number of crew - ** members leaving is equal to the unrecovered cost of the building - ** divided by 100 (the typical cost of a minigunner infantryman). - */ - if (!Target_Legal(ArchiveTarget) || !Special.IsMCVDeploy || *this != STRUCT_CONST) { - int divisor = 200; - if (IsCaptured) divisor *= 2; - int count = (Class->Raw_Cost()+(divisor-1)) / divisor; - bool engine = false; - count = Bound(count, 1, 5); - - while (count) { - - /* - ** Ensure that the player only gets ONE engineer and not from a captured - ** construction yard. - */ - InfantryType typ = Crew_Type(); - while (typ == INFANTRY_E7 && engine) { - typ = Crew_Type(); - } - if (typ == INFANTRY_E7) engine = true; - - InfantryClass * infantry = new InfantryClass(typ, House->Class->House); - if (infantry) { - ScenarioInit++; - COORDINATE coord = Coord_Add(Center_Coord(), XYP_COORD(0, -12)); - coord = Map[Coord_Cell(coord)].Closest_Free_Spot(coord, false); - - if (infantry->Unlimbo(coord, DIR_N)) { - if (infantry->Class->IsNominal) infantry->IsTechnician = true; - ScenarioInit--; - infantry->Scatter(0, true); - ScenarioInit++; - infantry->Assign_Mission(MISSION_GUARD_AREA); - } else { - delete infantry; - } - ScenarioInit--; - } - count--; - } - } - - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Sound_Effect(VOC_CASHTURN, Coord); - } - - /* - ** Destroy all attached objects. ST - 4/24/2020 9:38PM - */ - while (Attached_Object()) { - FootClass * obj = Detach_Object(); - - Detach_All(true); - delete obj; - } - - Transmit_Message(RADIO_OVER_OUT); - Status = DURING; - Begin_Mode(BSTATE_CONSTRUCTION); - IsReadyToCommence = false; - break; - } - Transmit_Message(RADIO_RUN_AWAY); - break; - - case DURING: - if (IsReadyToCommence) { - - /* - ** Construction yards that deconstruct, really just revert back - ** to an MCV. - */ - if (Target_Legal(ArchiveTarget) && Special.IsMCVDeploy && *this == STRUCT_CONST && House->IsHuman) { - ScenarioInit++; - UnitClass * unit = new UnitClass(UNIT_MCV, House->Class->House); - ScenarioInit--; - if (unit) { - - /* - ** Unlimbo the MCV onto the map. The MCV should start in the same - ** health condition that the construction yard was in. - */ - int ratio = Health_Ratio(); - int money = Refund_Amount(); - TARGET arch = ArchiveTarget; - COORDINATE place = Coord_Snap(Adjacent_Cell(Coord, DIR_SE)); - - Delete_This(); - - if (unit->Unlimbo(place, DIR_SW)) { - unit->Strength = Fixed_To_Cardinal(unit->Class_Of().MaxStrength, ratio); - - /* - ** Lift the move destination from the building and assign - ** it to the unit. - */ - if (Target_Legal(arch)) { - unit->Assign_Destination(arch); - unit->Assign_Mission(MISSION_MOVE); - } - } else { - - /* - ** If, for some strange reason, the MCV could not be placed on the - ** map, then give the player some money to compensate. - */ - House->Refund_Money(money); - } - } else { - House->Refund_Money(Refund_Amount()); - Delete_This(); - } - - } else { - - /* - ** A sold building still counts as a kill, but it just isn't directly - ** attributed to the enemy. - */ - WhoLastHurtMe = HOUSE_NONE; - Record_The_Kill(NULL); - - /* - ** The player gets part of the money back for the sell. - */ - House->Refund_Money(Refund_Amount()); - Limbo(); - - if (House) { - House->Check_Pertinent_Structures(); - } - - /* - ** Finally, delete the building from the game. - */ - Delete_This(); - } - House->IsRecalcNeeded = true; - } - break; - } - return(1); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Attack -- Handles attack mission for building. * - * * - * Buildings that can attack are processed by this attack mission state machine. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Mission_Attack(void) -{ - Validate(); - if (*this == STRUCT_SAM) { - switch (Status) { - - /* - ** The launcher is underground and awaiting the acquisition of - ** a target. - */ - case SAM_UNDERGROUND: - IsReadyToCommence = true; - if (Target_Legal(TarCom)) { - Set_Rate(2); - Set_Stage(0); - Status = SAM_RISING; - return(1); - } else { - Assign_Mission(MISSION_GUARD); - } - break; - - /* - ** The launcher is rising into the ready position so that it - ** may rotate to face the target. - */ - case SAM_RISING: - if (Fetch_Stage() == 15) { - Set_Rate(0); - PrimaryFacing = DIR_N; - if (!Target_Legal(TarCom)) { - Status = SAM_LOWERING; - } else { - Status = SAM_READY; - } - } - return(1); - - /* - ** This is the target tracking state of the launcher. It will rotate - ** to face the current TarCom of the launcher. - */ - case SAM_READY: - if (!Target_Legal(TarCom) || !Is_Target_Aircraft(TarCom) || As_Aircraft(TarCom)->Altitude == 0) { - Assign_Target(TARGET_NONE); - Status = SAM_LOCKING; - return(TICKS_PER_SECOND); - } else { - if (!PrimaryFacing.Is_Rotating()) { - DirType facing = Direction(TarCom); - if (PrimaryFacing.Difference(facing)) { - PrimaryFacing.Set_Desired(facing); - } else { - Status = SAM_FIRING; - } - } - } - return(1); - - /* - ** The launcher is in the process of firing. - */ - case SAM_FIRING: - if (!Target_Legal(TarCom) || !Is_Target_Aircraft(TarCom) || As_Aircraft(TarCom)->Altitude == 0) { - Assign_Target(TARGET_NONE); - Status = SAM_LOCKING; - } else { - FireErrorType error = Can_Fire(TarCom, 0); - if (error == FIRE_ILLEGAL || error == FIRE_CANT || error == FIRE_RANGE) { - Assign_Target(TARGET_NONE); - Status = SAM_LOCKING; - } else { - if (error == FIRE_FACING) { - Status = SAM_READY; - } else { - if (error == FIRE_OK) { - Fire_At(TarCom, 0); - Status = SAM_READY2; - return(1); - } - } - } - } - return(1); - - case SAM_READY2: - if (!Target_Legal(TarCom) || !Is_Target_Aircraft(TarCom) || As_Aircraft(TarCom)->Altitude == 0) { - Assign_Target(TARGET_NONE); - Status = SAM_LOCKING; - return(TICKS_PER_SECOND); - } else { - if (!PrimaryFacing.Is_Rotating()) { - DirType facing = Direction(TarCom); - if (PrimaryFacing.Difference(facing)) { - PrimaryFacing.Set_Desired(facing); - } else { - Status = SAM_FIRING2; - } - } - } - return(1); - - case SAM_FIRING2: - if (!Target_Legal(TarCom) || !Is_Target_Aircraft(TarCom) || As_Aircraft(TarCom)->Altitude == 0) { - Assign_Target(TARGET_NONE); - Status = SAM_LOCKING; - } else { - FireErrorType error = Can_Fire(TarCom, 0); - if (error == FIRE_ILLEGAL || error == FIRE_CANT || error == FIRE_RANGE) { - Assign_Target(TARGET_NONE); - Status = SAM_LOCKING; - } else { - if (error == FIRE_FACING) { - Status = SAM_READY2; - } else { - if (error == FIRE_OK) { - Fire_At(TarCom, 0); - Status = SAM_LOCKING; - return(TICKS_PER_SECOND*3); - } - } - } - } - return(1); - - /* - ** Rotating to face north in preparation for lowering to reload. - */ - case SAM_LOCKING: - if (!PrimaryFacing.Is_Rotating()) { - if (PrimaryFacing == DIR_N) { - Set_Rate(2); - Set_Stage(48); - Status = SAM_LOWERING; - } else { - PrimaryFacing.Set_Desired(DIR_N); - } - } - return(1); - - /* - ** Lowering into the ground in order to reload. - */ - case SAM_LOWERING: - if (Fetch_Stage() >= 63) { - Set_Rate(0); - Set_Stage(0); - Status = SAM_UNDERGROUND; - return(TICKS_PER_SECOND); - } else { - if (Fetch_Rate() == 0) { - Set_Rate(2); - } - } - return(1); - - default: - break; - } - - } else { - IsReadyToCommence = true; - switch (Can_Fire(TarCom, 0)) { - case FIRE_ILLEGAL: - case FIRE_CANT: - case FIRE_RANGE: - case FIRE_AMMO: - Assign_Target(TARGET_NONE); - Assign_Mission(MISSION_GUARD); - Commence(); - break; - - case FIRE_FACING: - PrimaryFacing.Set_Desired(Direction(TarCom)); - return(2); - - case FIRE_REARM: - case FIRE_BUSY: - return(1); - - case FIRE_CLOAKED: - Do_Uncloak(); - break; - - case FIRE_OK: - Fire_At(TarCom, 0); - return(1); - } - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Harvest -- Handles refinery unloading harvesters. * - * * - * This state machine handles the refinery when it unloads the harvester. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Mission_Harvest(void) -{ - Validate(); - enum { - INITIAL, // Dock the Tiberium canister. - WAIT_FOR_DOCK, // Waiting for docking to complete. - MIDDLE, // Offload "bails" of tiberium. - WAIT_FOR_UNDOCK, // Waiting for undocking to complete. - EXITING // Cause the harvester to drive away. - }; - switch (Status) { - case INITIAL: - Begin_Mode(BSTATE_ACTIVE); - Status = WAIT_FOR_DOCK; - break; - - case WAIT_FOR_DOCK: - if (IsReadyToCommence) { - IsReadyToCommence = false; - Status = MIDDLE; - Begin_Mode(BSTATE_AUX1); - } - break; - - case MIDDLE: - if (IsReadyToCommence) { - IsReadyToCommence = false; - - /* - ** Force any bib squaters to scatter. - */ - bool old = Special.IsScatter; - Special.IsScatter = true; - Map[Adjacent_Cell(Coord_Cell(Center_Coord()), DIR_SW)].Incoming(0, true); - Special.IsScatter = old; - - FootClass * techno = Attached_Object(); - if (techno) { - int bail = techno->Offload_Tiberium_Bail(); - - if (bail) { - House->Harvested(bail); - if (techno->Tiberium_Load()) { - return(1); - } - } - } - Begin_Mode(BSTATE_AUX2); - Status = WAIT_FOR_UNDOCK; - } - break; - - case WAIT_FOR_UNDOCK: - if (IsReadyToCommence) { - - /* - ** Detach harvester and go back into idle state. - */ - Exit_Object(Detach_Object()); - Assign_Mission(MISSION_GUARD); - } - break; - } - return(1); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Repair -- Handles the repair (active) state for building. * - * * - * This state machine is used when the building is active in some sort of repair or * - * construction mode. The construction yard will animate. The repair facility will repair * - * anything that it docked on it. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - * 06/25/1995 JLB : Handles repair facility * - * 07/29/1995 JLB : Repair rate is controlled by power rating. * - *=============================================================================================*/ -int BuildingClass::Mission_Repair(void) -{ - Validate(); - if (*this == STRUCT_CONST) { - enum { - INITIAL, - DURING - }; - switch (Status) { - case INITIAL: - Begin_Mode(BSTATE_ACTIVE); - Status = DURING; - break; - - case DURING: - if (!In_Radio_Contact()) { - Assign_Mission(MISSION_GUARD); - } - break; - } - return(1); - } - - if (*this == STRUCT_REPAIR) { - enum { - INITIAL, - IDLE, - DURING - }; - switch (Status) { - case INITIAL: - if (!In_Radio_Contact()) { - Begin_Mode(BSTATE_IDLE); - Assign_Mission(MISSION_GUARD); - return(1); - } - IsReadyToCommence = false; - if (Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER && Distance(Contact_With_Whom()) < 0x0010) { - Status = IDLE; - return(TICKS_PER_SECOND/4); - } - break; - - case IDLE: - if (!In_Radio_Contact()) { - Assign_Mission(MISSION_GUARD); - return(1); - } - - if (Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER) { - if (Contact_With_Whom()->Health_Ratio() < 0x0100 && Transmit_Message(RADIO_REPAIR) == RADIO_ROGER) { - Status = DURING; - Begin_Mode(BSTATE_ACTIVE); - IsReadyToCommence = false; - } else { - if (!House->IsHuman) { - Transmit_Message(RADIO_RUN_AWAY); - } - } -// } else { -// Assign_Mission(MISSION_GUARD); -// return(1); - } - break; - - case DURING: - if (!In_Radio_Contact()) { - Begin_Mode(BSTATE_IDLE); - Status = IDLE; - return(1); - } - if (IsReadyToCommence && Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER) { - IsReadyToCommence = false; - long param = Health_Ratio(); - if (Transmit_Message(RADIO_REPAIR, param) != RADIO_ROGER) { -#ifdef OBSOLETE - if (House->Available_Money() < 10) { - Transmit_Message(RADIO_RUN_AWAY); - } -#endif - Begin_Mode(BSTATE_IDLE); - Status = IDLE; -#ifdef OBSOLETE - } else { - int time = Bound(Fixed_To_Cardinal(TICKS_PER_SECOND, House->Power_Fraction()), 0, TICKS_PER_SECOND); - time = (TICKS_PER_SECOND + (TICKS_PER_SECOND/2)) - time; - return(time); -#endif - } - } - break; - } - return(TICKS_PER_SECOND/2); - } - - if (*this == STRUCT_HELIPAD) { - enum { - INITIAL, - DURING - }; - switch (Status) { - case INITIAL: - if (Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER && Transmit_Message(RADIO_PREPARED) == RADIO_NEGATIVE) { - Begin_Mode(BSTATE_ACTIVE); - Contact_With_Whom()->Assign_Mission(MISSION_SLEEP); - Status = DURING; - return(1); - } - Assign_Mission(MISSION_GUARD); - break; - - case DURING: - if (IsReadyToCommence) { - if (!In_Radio_Contact() || Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_NEGATIVE) { - Assign_Mission(MISSION_GUARD); - return(1); - } - - if (Transmit_Message(RADIO_PREPARED) == RADIO_ROGER) { - Contact_With_Whom()->Assign_Mission(MISSION_GUARD); - Assign_Mission(MISSION_GUARD); - return(1); - } - - if (Transmit_Message(RADIO_RELOAD) != RADIO_ROGER) { - Assign_Mission(MISSION_GUARD); - Contact_With_Whom()->Assign_Mission(MISSION_GUARD); - return(1); - } else { - int time = Bound(Fixed_To_Cardinal(TICKS_PER_SECOND, House->Power_Fraction()), 0, TICKS_PER_SECOND); - time = (TICKS_PER_SECOND*3) - time; - IsReadyToCommence = false; - return(time); - } - } - break; - } - return(3); - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Missile -- State machine for nuclear missile launch. * - * * - * This handles the Temple of Nod launching its nuclear missile. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of frames to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Commented. * - *=============================================================================================*/ -int BuildingClass::Mission_Missile(void) -{ - Validate(); - enum { - INITIAL, - DOOR_OPENING, - LAUNCH_UP, - LAUNCH_DOWN, - DONE_LAUNCH - }; - - if (*this == STRUCT_TEMPLE) { - switch (Status) { - - /* - ** The initial case is responsible for starting the door - ** opening on the building. - */ - case INITIAL: - IsReadyToCommence = false; - Begin_Mode(BSTATE_ACTIVE); - Status = DOOR_OPENING; - return(1); - - /* - ** This polls for the case when the door is actually open and - ** then kicks off the missile smoke. - */ - case DOOR_OPENING: - if (IsReadyToCommence) { - Begin_Mode(BSTATE_IDLE); - new AnimClass(ANIM_ATOM_DOOR, Center_Coord()); - Status = LAUNCH_UP; - return(14); - } - return(1); - - /* - ** Once the smoke has been going for a little while this - ** actually handles launching the missile into the air. - */ - case LAUNCH_UP: - { - BulletClass *bullet = new BulletClass(BULLET_NUKE_UP); - if (bullet) { - COORDINATE launch = Coord_Move(Center_Coord(), (DirType)1, 0x1A0); - bullet->Assign_Target(TARGET_NONE); - bullet->Payback = NULL; - bullet->Strength = 1; - if (!bullet->Unlimbo(launch, DIR_N)) { - delete bullet; - bullet = NULL; - } else { - bullet->PrimaryFacing.Set_Current(DIR_N); - Sound_Effect(VOC_NUKE_FIRE, launch); - - // MBL 03.27.2020 This is never getting triggered for any player in multiplayer, so removing the check (https://jaas.ea.com/browse/TDRA-5458) - // if (House == PlayerPtr) - { - Speak(VOX_NUKE_LAUNCHED); // "NUKLNCH1" - "Nuclear Weapon Launched" - } - } - } - - if (bullet) { - Status = LAUNCH_DOWN; - return(8 * TICKS_PER_SECOND); - } - } - return(1); - - /* - ** Once the missile is in the air, this handles waiting for - ** the missile to be off the screen and then launching one down - ** over the target. - */ - case LAUNCH_DOWN: - { - BulletClass *bullet = new BulletClass(BULLET_NUKE_DOWN); - if (bullet) { -// Theme.Queue_Song(THEME_NONE); - COORDINATE start = Cell_Coord(XY_Cell(Cell_X(House->NukeDest), 1)); - bullet->Assign_Target(::As_Target(House->NukeDest)); - - // MBL 05.20.2020 - // Fix for Nuke or Atom Bomb killing structures and units during animation sequence and not getting kills tracked - // Per https://jaas.ea.com/browse/TDRA-6610 - // - // bullet->Payback = NULL; - bullet->Payback = this; - - bullet->Strength = 1; - if (!bullet->Unlimbo(start, DIR_S)) { - delete bullet; - } else { - bullet->PrimaryFacing.Set_Current(DIR_S); - } - Speak(VOX_INCOMING_NUKE); // "Nuclear Warhead Approaching" - "NUKE1" - Sound_Effect(VOC_NUKE_FIRE, start); - } - if (bullet) { - Status = DONE_LAUNCH; - return(7 * TICKS_PER_SECOND); - } - } - return(1); - - /* - ** Once the missile is done launching this handles allowing - ** the building to sit there with its door open. - */ - case DONE_LAUNCH: - Assign_Mission(MISSION_GUARD); - return(60); - } - } - return(60); -} - - -/*********************************************************************************************** - * BuildingClass::Revealed -- Reveals the building to the specified house. * - * * - * This routine will reveal the building to the specified house. It will handle updating * - * the sidebar for player owned buildings. A player owned building that hasn't been * - * revealed, is in a state of pseudo-limbo. It cannot be used for any of its special * - * abilities even though it exists on the map for all other purposes. * - * * - * INPUT: house -- The house that this building is being revealed to. * - * * - * OUTPUT: Was this building revealed by this procedure? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Revealed(HouseClass * house) -{ - Validate(); - if (TechnoClass::Revealed(house)) { - - if (!ScenarioInit) { - House->JustBuilt = Class->Type; - } - House->IsRecalcNeeded = true; - - /* - ** Perform any grand opening here so that in the scenarios where a player - ** owned house is not yet revealed, it won't be reflected in the sidebar - ** selection icons. - */ - /* - ** Making a change here to avoid Grand_Opening happening multiple times in MP/skirmish. ST - 7/26/2019 11:26AM - */ - //if (!In_Radio_Contact() && (house == House || GameToPlay != GAME_NORMAL) && Mission != MISSION_CONSTRUCTION) { - if (!In_Radio_Contact() && (house == House && GameToPlay == GAME_NORMAL) && Mission != MISSION_CONSTRUCTION) { - Grand_Opening(); - } - - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * BuildingClass::Enter_Idle_Mode -- The building will enter its idle mode. * - * * - * This routine is called when the exact mode of the building isn't known. By examining * - * the building's condition, this routine will assign an appropriate mission. * - * * - * INPUT: initial -- This this being called during scenario init? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Enter_Idle_Mode(bool initial) -{ - Validate(); - /* - ** Assign an appropriate mission for the building. If the ScenarioInit flag is true, then - ** this must be an initial building. Start such buildings in idle state. For other buildings - ** it indicates that it is being placed during game play and thus it must start in - ** the "construction" mission. - */ - MissionType mission = MISSION_GUARD; - if (!initial || ScenarioInit || Debug_Map) { - Begin_Mode(BSTATE_IDLE); - mission = MISSION_GUARD; - } else { - Begin_Mode(BSTATE_CONSTRUCTION); - mission = MISSION_CONSTRUCTION; - } - Assign_Mission(mission); -} - - -/*************************************************************************** - * BuildingClass::Update_Specials -- removes computer specials * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1995 PWG : Created. * - *=========================================================================*/ -void BuildingClass::Update_Specials(void) -{ - Validate(); -} - - -/*********************************************************************************************** - * BuildingClass::Pip_Count -- Determines "full" pips to display for building. * - * * - * This routine will determine the number of pips that should be filled in when rendering * - * the building. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of pips to display as filled in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/28/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Pip_Count(void) const -{ - Validate(); - return(Fixed_To_Cardinal(Class->Max_Pips(), House->Tiberium_Fraction())); -} - - -/*********************************************************************************************** - * BuildingClass::Death_Announcement -- Announce the death of this building. * - * * - * This routine is called when the building is destroyed by "unnatural" means. Typically * - * as a result of combat. If the building is known to the player, then it should be * - * announced. * - * * - * INPUT: source -- The object most directly responsible for the building's death. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Death_Announcement(TechnoClass const * ) const -{ - Validate(); - //Changed for multiplayer ST - 3/13/2019 5:31PM - if (Is_Discovered_By_Player() || Is_Owned_By_Player()) { - //if (IsDiscoveredByPlayer || IsOwnedByPlayer) { - if (House != PlayerPtr && GameToPlay != GAME_NORMAL) { - if (Options.IsDeathAnnounce) Speak(VOX_ENEMY_STRUCTURE); - } else { - if (House == PlayerPtr || Options.IsDeathAnnounce) { - if (!Options.IsDeathAnnounce) { - Speak(VOX_STRUCTURE_LOST); - } else { - switch (House->ActLike) { - case HOUSE_GOOD: - Speak(VOX_GDI_STRUCTURE); - break; - - case HOUSE_BAD: - Speak(VOX_NOD_STRUCTURE); - break; - - default: - break; - } - } - } - } - } -} - - -/*********************************************************************************************** - * BuildingClass::Fire_Direction -- Fetches the direction of firing. * - * * - * This routine will return with the default direction to use when firing from this * - * building. This is the facing of the turret except for the case of non-turret equipped * - * buildings that have a weapon (e.g., guard tower). * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the default firing direction for this building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -DirType BuildingClass::Fire_Direction(void) const -{ - Validate(); - if (Class->IsTurretEquipped) { - return(PrimaryFacing.Current()); - } - return(Direction(TarCom)); -} - - -/*********************************************************************************************** - * BuildingClass::Remap_Table -- Fetches the remap table to use for this building. * - * * - * Use this routine to fetch the remap table to use. This override function is needed * - * because the default remap table for techno objects presumes the object is a unit. * - * Buildings aren't units. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the proper remap table to use for this building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void const * BuildingClass::Remap_Table(void) -{ - Validate(); - return(House->Remap_Table(IsBlushing, false)); -} - - -/*********************************************************************************************** - * BuildingClass::Mission_Unload -- Handles the unload mission for a building. * - * * - * This is the unload mission for a building. This really only applies to the weapon's * - * factory, since it needs the sophistication of an unload mission due to the door * - * animation. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine * - * again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Mission_Unload(void) -{ - Validate(); - if (*this == STRUCT_WEAP) { - COORDINATE coord = Adjacent_Cell(Center_Coord(), FACING_SW); - CELL cell = Coord_Cell(coord); - CellClass * cellptr = &Map[cell]; - enum { - INITIAL, - CLEAR_BIB, - OPEN, - LEAVE, - CLOSE - }; - UnitClass * unit; - switch (Status) { - case INITIAL: - unit = (UnitClass *)Contact_With_Whom(); - if (unit) { - unit->Assign_Mission(MISSION_GUARD); - unit->Commence(); - } - Open_Door(2, 11); - Status = CLEAR_BIB; - break; - - /* - ** Now that the occupants can peek out the door, they will tell - ** everyone that could be blocking the way, that they should - ** scatter away. - */ - case CLEAR_BIB: - unit = (UnitClass *)Contact_With_Whom(); - if (cellptr->Cell_Unit() || cellptr->Cell_Infantry()) { - cellptr->Incoming(0, true, true); - - /* - ** Scatter everything around the weapon's factory door. - */ - for (FacingType f = FACING_FIRST; f < FACING_COUNT; f++) { - CellClass * cptr = cellptr->Adjacent_Cell(f); - if (!cptr) continue; - UnitClass * cellunit = cptr->Cell_Unit(); - if ((cellunit && cellunit != unit) || cptr->Cell_Infantry()) { - cptr->Incoming(coord, true, true); - } - } - } else { - Status = OPEN; - } - break; - - case OPEN: - if (Is_Door_Open()) { - unit = (UnitClass *)Contact_With_Whom(); - if (unit) { - unit->Assign_Mission(MISSION_MOVE); - unit->Force_Track(DriveClass::OUT_OF_WEAPON_FACTORY, Adjacent_Cell(Center_Coord(), FACING_SW)); - unit->Set_Speed(128); - Status = LEAVE; - } else { - Close_Door(2, 11); - Status = CLOSE; - } - } - break; - - case LEAVE: - if (!IsTethered) { - Close_Door(2, 11); - Status = CLOSE; - } - break; - - case CLOSE: - if (Is_Door_Closed()) { - Enter_Idle_Mode(); - } - break; - } - return(TICKS_PER_SECOND/2); - } - Assign_Mission(MISSION_GUARD); - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * BuildingClass::Power_Output -- Fetches the current power output from this building. * - * * - * This routine will return the current power output for this building. The power output * - * is adjusted according to the damage level of the building. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the current power output for this building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Power_Output(void) const -{ - Validate(); - if (Class->Power) { - return(Fixed_To_Cardinal(Class->Power, Cardinal_To_Fixed(Class->MaxStrength, LastStrength))); - } - return(0); -} - - -/*********************************************************************************************** - * BuildingClass::Detach -- Handles target removal from the game system. * - * * - * This routine is called when the specified target is about to be removed from the game * - * system. * - * * - * INPUT: target -- The target to be removed from this building's targeting computer. * - * * - * all -- Is the target about to be completely eliminated? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Detach(TARGET target, bool all) -{ - Validate(); - TechnoClass::Detach(target, all); - if (target == WhomToRepay) { - WhomToRepay = TARGET_NONE; - } -} - - -/*********************************************************************************************** - * BuildingClass::Refund_Amount -- Fetches the refund amount if building is sold. * - * * - * This routine will return the amount of money to be refunded to the building's owner * - * if the building is sold. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the refund amount available for this building. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int BuildingClass::Refund_Amount(void) const -{ - Validate(); - int cost = TechnoClass::Refund_Amount(); - - /* - ** Add in any Tiberium that was stored within the building. - */ - if (IsV107 && Class->Capacity > 0) { - cost += Fixed_To_Cardinal(Class->Capacity, Cardinal_To_Fixed(House->Capacity, House->Tiberium)); - } - return(cost); -} - - -/*********************************************************************************************** - * BuildingClass::Crew_Type -- This determines the crew that this object generates. * - * * - * When selling very cheap buildings (such as the silo), a technician will pop out since * - * generating minigunners would be overkill -- the player could use this loophole to * - * gain an advantage. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the infantry type that this building will generate as a survivor. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/05/1995 JLB : Created. * - *=============================================================================================*/ -InfantryType BuildingClass::Crew_Type(void) const -{ - Validate(); - switch (Class->Type) { - case STRUCT_STORAGE: - if (Random_Pick(0, 1) == 0) { - return(INFANTRY_C1); - } else { - return(INFANTRY_C7); - } - - case STRUCT_CONST: - if (!IsCaptured && House->IsHuman && Random_Pick(0, 3) == 0) { - return(INFANTRY_E7); - } - break; - - default: - break; - } - return(TechnoClass::Crew_Type()); -} - - -/*********************************************************************************************** - * BuildingClass::Detach_All -- Possibly abandons production according to factory type. * - * * - * When this routine is called, it indicates that the building is about to be destroyed * - * or captured. In such a case any production it may be doing, must be abandoned. * - * * - * INPUT: all -- Is the object about the be completely destroyed? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/05/1995 JLB : Created. * - *=============================================================================================*/ -void BuildingClass::Detach_All(bool all) -{ - Validate(); - /* - ** If it is producing something, then it must be abandoned. - */ - if (Factory) { - Factory->Abandon(); - delete Factory; - Factory = 0; - } - - /* - ** If the owner HouseClass is building something, and this building can - ** build that thing, we may be the last building for that house that can - ** build that thing; if so, abandon production of it. - */ - if (House) { - int fnum = -1; - - switch (Class->ToBuild) { - case RTTI_AIRCRAFTTYPE: - fnum = House->AircraftFactory; - break; - - case RTTI_INFANTRYTYPE: - fnum = House->InfantryFactory; - break; - - case RTTI_UNITTYPE: - fnum = House->UnitFactory; - break; - - case RTTI_BUILDINGTYPE: - fnum = House->BuildingFactory; - break; - - case RTTI_SPECIAL: - fnum = House->SpecialFactory; - break; - - } - - /* - ** Convert the factory number into a real factory pointer. - */ - FactoryClass * factory = 0; - if (fnum != -1) { - factory = Factories.Raw_Ptr(fnum); - } - - /* - ** If a factory was found, then temporarily disable this building and then - ** detmermine if any object that is being produced can still be produced. If - ** not, then the object being produced must be abandoned. - */ - if (factory) { - TechnoClass * object = factory->Get_Object(); - IsInLimbo = true; - if (object && !object->Techno_Type_Class()->Who_Can_Build_Me(true, false, House->Class->House)) { - House->Abandon_Production(Class->ToBuild); - } - IsInLimbo = false; - } - } - - TechnoClass::Detach_All(all); -} - - -/*********************************************************************************************** - * BuildingClass::Flush_For_Placement -- Handles clearing a zone for object placement. * - * * - * This routine is used to clear the way for placement of the specified object (usually * - * a building). If there are friendly units blocking the placement area, they are told * - * to scatter. Enemy blocking units are attacked. * - * * - * INPUT: techno -- Pointer to the object that is desired to be placed. * - * * - * cell -- The cell that placement wants to occur at. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/06/1995 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Flush_For_Placement(TechnoClass * techno, CELL cell) -{ - Validate(); - bool again = false; - if (techno && cell > 0) { - short const * list = techno->Class_Of().Occupy_List(true); - - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - - if (Map.In_Radar(newcell)) { - TechnoClass * occupier = Map[newcell].Cell_Techno(); - if (occupier) { - again = true; - if (occupier->House->Is_Ally(this)) { - Map[newcell].Incoming(0, true); - } else { - Base_Is_Attacked(occupier); - } - } - } - } - } - return(again); -} - - -void BuildingClass::Hidden(void) -{ -// if (IsDiscoveredByPlayer && House->IsHuman) { -// House->Adjust_Drain(-Class->Drain); -// } - TechnoClass::Hidden(); -} - - -CELL BuildingClass::Find_Exit_Cell(TechnoClass const * techno) const -{ - CELL const *ptr; - CELL origin = Coord_Cell(Coord); - bool found = false; - - ptr = Class->ExitList; - if (ptr) { - while (*ptr != REFRESH_EOL) { - CELL cell = origin + *ptr++; - if (Map.In_Radar(cell) && techno->Can_Enter_Cell(cell) == MOVE_OK) { - return(cell); - } - } - } - return(0); -} - -/*********************************************************************************************** - * BuildingClass::Can_Player_Move -- Can this building be moved? * - * * - * This routine answers the question 'can this building be moved?' Typically, only the * - * construction yard can be moved and it does this by undeploying back into a MCV. * - * * - * INPUT: none * - * * - * OUTPUT: Can the building move to a new location under player control? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/04/1995 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Can_Player_Move(void) const -{ - Validate(); - return(*this == STRUCT_CONST && (Mission == MISSION_GUARD) && Special.IsMCVDeploy); -} - -/*********************************************************************************************** - * BuildingClass::Passes_Proximity_Check -- Determines if building placement is near friendly sq* - * * - * This routine is used by the building placement cursor logic to determine whether the * - * at the current cursor position if the building would be adjacent to another friendly * - * building. In cases where this is not true, then the building cannot be placed at all. * - * This determination is returned by the function. * - * * - * INPUT: homecell -- The cell that the building would like to be placed down at. * - * * - * OUTPUT: bool; Can the pending building object be placed at the present cursor location * - * checking only for proximity to friendly buildings? If this isn't for a * - * building type object, then this routine always returns true. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/06/1994 JLB : Created. * - * 06/07/1994 JLB : Handles concrete check. * - *=============================================================================================*/ -bool BuildingClass::Passes_Proximity_Check(CELL homecell) -{ - /* - ** In editor mode, the proximity check always passes. - */ - if (Debug_Map || !House->IsHuman) { - return(true); - } - - /* - ** Scan through all cells that the building foundation would cover. If any adjacent - ** cells to these are of friendly persuasion, then consider the proximity check to - ** have been a success. - */ - short const * ptr = Occupy_List(true); - while (*ptr != REFRESH_EOL) { - CELL cell = homecell + *ptr++; - - if (!Map.In_Radar(cell)) return(false); - - for (FacingType facing = FACING_N; facing < FACING_COUNT; facing++) { - CELL newcell = Adjacent_Cell(cell, facing); - - BuildingClass * base = Map[newcell].Cell_Building(); - - /* - ** The special cell ownership flag allows building adjacent - ** to friendly walls and bibs even though there is no official - ** building located there. - */ - if (Map[newcell].Owner == House->Class->House) { - return(true); - } - - if (base && base->House->Class->House == House->Class->House) { - return(true); - } - } - } - return(false); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/BUILDING.H b/code/TIBERIANDAWN/BUILDING.H deleted file mode 100644 index 16c28ac..0000000 --- a/code/TIBERIANDAWN/BUILDING.H +++ /dev/null @@ -1,308 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\building.h_v 2.20 16 Oct 1995 16:47:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BUILDING.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 14, 1994 * - * * - * Last Update : April 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef BUILDING_H -#define BUILDING_H - -#include "tarcom.h" -#include "radio.h" -#include "cargo.h" -#include "mission.h" -#include "bullet.h" -#include "target.h" -#include "factory.h" - -#define MAX_DOOR_STAGE 18 // # of frames of door opening on weapons factory -#define DOOR_OPEN_STAGE 9 // frame on which the door is entirely open -#define MAX_REPAIR_ANIM_STAGE 5 // # of stages of anim for repair center cycling - -/**************************************************************************** -** For each instance of a building in the game, there is one of -** these structures. This structure holds information that is specific -** and dynamic for a particular building. -*/ -class BuildingClass : public TechnoClass -{ - public: - BuildingTypeClass const * const Class; - operator StructType(void) const {return Class->Type;}; - - /* - ** If this building is in the process of producing something, then this - ** will point to the factory manager. - */ - FactoryClass * Factory; - - /* - ** This is the house that originally owned this factory. Objects buildable - ** by this house type will be produced from this factory regardless of who - ** the current owner is. - */ - HousesType ActLike; - - /* - ** If the building is at a good point to change orders, then this - ** flag will be set to true. - */ - unsigned IsReadyToCommence:1; - - /* - ** If this building is currently spending money to repair itself, then - ** this flag is true. It will automatically be set to false when the building - ** has reached full strength, when money is exhausted, or if the player - ** specifically stops the repair process. - */ - unsigned IsRepairing:1; - - /* - ** If repair is currently in progress and this flag is true, then a wrench graphic - ** will be overlaid on the building to give visual feedback for the repair process. - */ - unsigned IsWrenchVisible:1; - - /* - ** This flag is set when a commando has raided the building and planted - ** plastic explosives. When the CommandoCountDown timer expires, the - ** building takes massive damage. - */ - unsigned IsGoingToBlow:1; - - /* - ** If this building was destroyed by some method that would prevent - ** survivors, then this flag will be true. - */ - unsigned IsSurvivorless:1; - - /* - ** These state control variables are used by the oblisk for the charging - ** animation. - */ - unsigned IsCharging:1; - unsigned IsCharged:1; - - /* - ** A building that has been captured will not contain the full compliment - ** of crew. This is true even if it subsiquently gets captured back. - */ - unsigned IsCaptured:1; - - /* - ** Special countdown to destruction value. If the building is destroyed, - ** it won't actually be removed from the map until this value reaches - ** zero. This delay is for cosmetic reasons. - */ - TCountDownTimerClass CountDown; - - /* - ** This is the current animation processing state that the building is - ** in. - */ - BStateType BState; - BStateType QueueBState; - - /* - ** For multiplayer games, this keeps track of the last house to damage - ** this building, so if it burns to death or otherwise gradually dies, - ** proper credit can be given for the kill. - */ - HousesType WhoLastHurtMe; - - /* - ** This is the saboteur responsible for this building's destruction. - */ - TARGET WhomToRepay; - - /* - ** This is a record of the last strength of the building. Every so often, - ** it will compare this strength to the current strength. If there is a - ** discrepency, then the owner power is adjusted accordingly. - */ - int LastStrength; - - /* - ** This is the countdown timer that regulates placement retry logic - ** for factory type buildings. - */ - TCountDownTimerClass PlacementDelay; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - static void * BuildingClass::operator new(size_t size); - static void BuildingClass::operator delete(void *ptr); - BuildingClass(void) : Class(0) {}; - BuildingClass(StructType type, HousesType house); - virtual ~BuildingClass(void); - virtual RTTIType What_Am_I(void) const {return RTTI_BUILDING;}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - static void Init(void); - - TARGET Target_Scan(void); - BuildingTypeClass::AnimControlType const * Fetch_Anim_Control(void) {return (&Class->Anims[BState]);}; - - /* - ** Query functions. - */ - virtual CELL Find_Exit_Cell(TechnoClass const * techno) const; - virtual InfantryType Crew_Type(void) const; - virtual int Pip_Count(void) const; - virtual bool Can_Player_Move(void) const; - virtual ActionType What_Action(ObjectClass * target) const; - virtual ActionType What_Action(CELL cell) const; - virtual bool Can_Demolish(void) const; - virtual bool Can_Demolish_Unit(void) const; - virtual bool Can_Capture(void) const; - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - virtual int Refund_Amount(void) const; - virtual DirType Fire_Direction(void) const; - int Power_Output(void) const; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Docking_Coord(void) const; - virtual COORDINATE Fire_Coord(int which) const; - virtual COORDINATE Center_Coord(void) const; - virtual COORDINATE Sort_Y(void) const; - virtual COORDINATE Target_Coord(void) const; - - /* - ** Object entry and exit from the game system. - */ - virtual void Detach(TARGET target, bool all); - virtual void Detach_All(bool all=true); - virtual void Grand_Opening(bool captured = false); - virtual void Update_Buildables(void); - virtual MoveType Can_Enter_Cell(CELL cell, FacingType = FACING_NONE) const; - virtual bool Unlimbo(COORDINATE , DirType dir = DIR_N); - virtual bool Limbo(void); - bool Passes_Proximity_Check(CELL homecell); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual void const * Remap_Table(void); - virtual int Exit_Object(TechnoClass * base); - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual bool Mark(MarkType mark); - virtual void Look(bool incremental=false); - virtual void Fire_Out(void); - void Begin_Mode(BStateType bstate); - - /* - ** User I/O. - */ - virtual void Active_Click_With(ActionType action, ObjectClass * object); - virtual void Active_Click_With(ActionType action, CELL cell); - - /* - ** Combat related. - */ - virtual void Death_Announcement(TechnoClass const * source=0) const; - virtual FireErrorType Can_Fire(TARGET, int which) const; - virtual TARGET Greatest_Threat(ThreatType threat) const; - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source=0); - virtual TARGET As_Target(void) const; - virtual bool Captured(HouseClass * newowner); - - /* - ** AI. - */ - virtual void Hidden(void); - virtual bool Revealed(HouseClass * house); - virtual void Repair(int control); - virtual void Sell_Back(int control); - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual void AI(void); - virtual void Assign_Target(TARGET target); - virtual bool Toggle_Primary(void); - bool Flush_For_Placement(TechnoClass * techno, CELL cell); - - virtual int Mission_Unload(void); - virtual int Mission_Repair(void); - virtual int Mission_Attack(void); - virtual int Mission_Harvest(void); - virtual int Mission_Guard(void); - virtual int Mission_Construction(void); - virtual int Mission_Deconstruction(void); - virtual int Mission_Missile(void); - virtual void Enter_Idle_Mode(bool initial=false); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static char *INI_Name(void) {return "STRUCTURES";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - void Update_Specials(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - private: - void Drop_Debris(TARGET source = TARGET_NONE); - virtual BulletClass * Fire_At(TARGET target, int which); - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - - static COORDINATE const CenterOffset[BSIZE_COUNT]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/BULLET.CPP b/code/TIBERIANDAWN/BULLET.CPP deleted file mode 100644 index fb09e7b..0000000 --- a/code/TIBERIANDAWN/BULLET.CPP +++ /dev/null @@ -1,795 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\bullet.cpv 2.18 16 Oct 1995 16:50:00 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BULLET.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : March 18, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * BulletClass::AI -- Logic processing for bullet. * - * BulletClass::As_Target -- Converts the bullet into a target value. * - * BulletClass::BulletClass -- Bullet constructor. * - * BulletClass::BulletClass -- Default constructor for bullet objects. * - * BulletClass::Detach -- Removes specified target from this bullet's targeting system. * - * BulletClass::Draw_It -- Displays the bullet at location specified. * - * BulletClass::Init -- Clears the bullets array for scenario preparation. * - * BulletClass::Mark -- Performs related map refreshing under bullet. * - * BulletClass::Occupy_List -- Determines the bullet occupation list. * - * BulletClass::Unlimbo -- Transitions a bullet object into the game render/logic system. * - * BulletClass::delete -- Bullet memory delete. * - * BulletClass::new -- Allocates memory for bullet object. * - * BulletClass::Validate -- validates bullet pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#define GRAVITY 3 - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * BulletClass::VTable; - - -/*********************************************************************************************** - * BulletClass::Validate -- validates bullet pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int BulletClass::Validate(void) const -{ - int num; - - num = Bullets.ID(this); - if (num < 0 || num >= BULLET_MAX) { - Validate_Error("BULLET"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * BulletClass::BulletClass -- Default constructor for bullet objects. * - * * - * This is the default constructor for bullet objects. A bullet constructed by this routine * - * is not in a usable state for game purposes. It must be constructed by the full * - * (parameterized) constructor -- usually called as part of the overloaded "new" operator. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Do not use bullets that were constructed solely by this routine. * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -BulletClass::BulletClass(void) : - Class(0) -{ - Payback = NULL; - IsToAnimate = false; - Altitude = 0; - Riser = 0; - TarCom = TARGET_NONE; - Strength = 0; - IsLocked = true; - IsInaccurate = false; -} - - -/*********************************************************************************************** - * BulletClass::new -- Allocates memory for bullet object. * - * * - * This function will "allocate" a block of memory for a bullet object. * - * This memory block is merely lifted from a fixed pool of blocks. * - * * - * INPUT: size -- The size of the memory block needed. * - * * - * OUTPUT: Returns with a pointer to an available bullet object block. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - *=============================================================================================*/ -void * BulletClass::operator new(size_t ) -{ - void * ptr = Bullets.Allocate(); - if (ptr) { - ((BulletClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * BulletClass::delete -- Bullet memory delete. * - * * - * Since bullets memory is merely "allocated" out of a pool, it never * - * actually gets deleted. * - * * - * INPUT: ptr -- Generic pointer to bullet object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - *=============================================================================================*/ -void BulletClass::operator delete(void *ptr) -{ - if (ptr) { - ((BulletClass *)ptr)->IsActive = false; - } - Bullets.Free((BulletClass *)ptr); -} - - -/*********************************************************************************************** - * BulletClass::BulletClass -- Bullet constructor. * - * * - * This is the constructor for the bullet class. It handles all * - * initialization of the bullet and starting it in motion toward its * - * target. * - * * - * INPUT: id -- The type of bullet this is (could be missile). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - * 06/20/1994 JLB : Firer is a base class pointer. * - * 12/10/1994 JLB : Auto calculate range optional. * - * 12/12/1994 JLB : Handles small arms as an instantaneous effect. * - * 12/23/1994 JLB : Fixed scatter algorithm for non-homing projectiles. * - * 12/31/1994 JLB : Removed range parameter (not needed). * - *=============================================================================================*/ -BulletClass::BulletClass(BulletType id) : - Class(&BulletTypeClass::As_Reference(id)) -{ - Altitude = 0; - IsInaccurate = false; - IsLocked = true; -// IsLocked = false; - IsToAnimate = false; - Payback = 0; - Riser = 0; - Strength = Class->MaxStrength; - TarCom = TARGET_NONE; -} - - -/*********************************************************************************************** - * BulletClass::Occupy_List -- Determines the bullet occupation list. * - * * - * This function will determine the cell occupation list and return a pointer to it. Most * - * bullets are small and the list is usually short, but on occasion, it can be a list that * - * rivals the size of regular vehicles. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the cell offset list that covers all the cells a bullet * - * is over. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1994 JLB : Created. * - * 01/05/1995 JLB : Handles projectiles with altitude. * - *=============================================================================================*/ -short const *BulletClass::Occupy_List(void) const -{ - Validate(); - switch (*this) { - case BULLET_FLAME: - return(Coord_Spillage_List(Coord, 25)); - - case BULLET_NUKE_UP: - case BULLET_NUKE_DOWN: - return(Coord_Spillage_List(Coord, 48)); - - default: - if (Altitude) { - static CELL _list[10]; - const short * ptr = Coord_Spillage_List(Coord, 5); - int index = 0; - CELL cell1 = Coord_Cell(Coord); - - while (ptr[index] != REFRESH_EOL) { - _list[index] = ptr[index]; - index++; - } - - COORDINATE coord = XY_Coord(0, Altitude); - coord = Coord_Sub(Coord, coord); - CELL cell2 = Coord_Cell(coord); - ptr = Coord_Spillage_List(coord, 5); - while (*ptr != REFRESH_EOL) { - _list[index++] = (*ptr++) + (cell2 - cell1); - } - _list[index] = REFRESH_EOL; - return(_list); - } - } - return(Coord_Spillage_List(Coord, 10)); -} - - -/*********************************************************************************************** - * BulletClass::Mark -- Performs related map refreshing under bullet. * - * * - * This routine marks the objects under the bullet so that they will * - * be redrawn. This is necessary as the bullet moves -- objects under * - * its path need to be restored. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - *=============================================================================================*/ -bool BulletClass::Mark(MarkType mark) -{ - Validate(); - if (ObjectClass::Mark(mark)) { - if (!Class->IsInvisible) { - Map.Refresh_Cells(Coord_Cell(Coord), Occupy_List()); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * BulletClass::AI -- Logic processing for bullet. * - * * - * This routine will perform all logic (flight) logic on the bullet. * - * Primarily this is motion, fuse tracking, and detonation logic. Call * - * this routine no more than once per bullet per game tick. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - *=============================================================================================*/ -void BulletClass::AI(void) -{ - Validate(); - COORDINATE coord; - - ObjectClass::AI(); - - /* - ** Balistic objects are handled here. - */ - bool forced = false; // Forced explosion. - if (Class->IsArcing) { - Altitude += Riser; - - if (Altitude <= 0) { - forced = true; - } - if (Riser > -100) { - Riser -= GRAVITY; - } - } - if (Class->IsDropping) { - Altitude += Riser; - - if (Altitude <= 0) { - forced = true; - } - if (Riser > -100) { - Riser -= 1; - } - } - - /* - ** Homing projectiles constantly change facing to face toward the target but - ** they only do so every other game frame (improves game speed and makes - ** missiles not so deadly). - */ - if ((Frame & 0x01) && Class->IsHoming && Target_Legal(TarCom)) { - PrimaryFacing.Set_Desired(Direction256(Coord, ::As_Coord(TarCom))); - } - - /* - ** Move the projectile forward according to its speed - ** and direction. - */ - coord = Coord; - if (Class->IsFlameEquipped) { - if (IsToAnimate) { - new AnimClass(ANIM_SMOKE_PUFF, coord, 1); - } - IsToAnimate = !IsToAnimate; - } - - /* - ** Handle any body rotation at this time. This process must - ** occur every game fame in order to achieve smooth rotation. - */ - if (PrimaryFacing.Is_Rotating()) { - PrimaryFacing.Rotation_Adjust(Class->ROT); - } - - switch (Physics(coord, PrimaryFacing)) { - - /* - ** When a projectile reaches the edge of the world, it - ** vanishes from existence -- presumed to explode off - ** map. - */ - case IMPACT_EDGE: -// if (IsLocked) { - Mark(); - Delete_This(); -// } - break; - - default: - case IMPACT_NONE: - - /* - ** The projectile has moved. Check its fuse. If detonation - ** is signaled, then do so. Otherwise, just move. - */ - case IMPACT_NORMAL: - Mark(); -// IsLocked = true; - if (!Class->IsHigh) { - CellClass * cellptr = &Map[Coord_Cell(coord)]; - if (cellptr->Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(cellptr->Overlay).IsHigh) { - forced = true; - Coord = coord = Cell_Coord(Coord_Cell(coord)); - } - } - - /* - ** Bullets are generaly more effective when they are fired at aircraft. - */ - if (Class->IsAntiAircraft && As_Aircraft(TarCom) && Distance(TarCom) < 0x0080) { - forced = true; - - if (*this == BULLET_TOW) { - Strength += Strength/3; - } else { - Strength += Strength/2; - } - } - - if (!forced && (Class->IsDropping || !Fuse_Checkup(coord))) { - Coord = coord; - Mark(); - - /* - ** Certain projectiles loose strength when they travel. - */ - if (*this == BULLET_BULLET) { - if (Strength > 5) Strength--; - } - - } else { - - /* - ** When the target is reached, explode and do the damage - ** required of it. For homing objects, don't force the explosion to - ** match the target position. Non-homing projectiles adjust position so - ** that they hit the target. This compensates for the error in line of - ** flight logic. - */ - Mark(); - if (!forced && !Class->IsArcing && !Class->IsHoming && Fuse_Target()) { - Coord = Fuse_Target(); - } - - /* - ** Non-aircraft targets apply damage to the ground. - */ - if (!Is_Target_Aircraft(TarCom) || As_Aircraft(TarCom)->In_Which_Layer() == LAYER_GROUND) { - Explosion_Damage(Coord, Strength, Payback, Class->Warhead); - } else { - - /* - ** Special damage apply for SAM missiles. This is the only way that missile - ** damage affects the aircraft target. - */ - if (Distance(TarCom) < 0x0080) { - AircraftClass * object = As_Aircraft(TarCom); - - int str = Strength; - if (object) object->Take_Damage(str, 0, Class->Warhead, Payback); - } - } - - /* - ** For projectiles that are invisible while travelling toward the target, - ** allow scatter effect for the impact animation. - */ - if (Class->IsInvisible) { - Coord = Coord_Scatter(Coord, 0x0020); - } - if (Class->Explosion != ANIM_NONE) { - AnimClass * newanim = new AnimClass(Class->Explosion, Coord); - if (newanim) { - newanim->Sort_Above(TarCom); - } - - // MBL 05.20.2020 - // Fix for Nuke or Atom Bomb killing structures and units during animation sequence and not getting kills tracked - // Per https://jaas.ea.com/browse/TDRA-6610 - // - if (newanim && Class->Explosion == ANIM_ATOM_BLAST && newanim->OwnerHouse == HOUSE_NONE) { - if (Payback && Payback->House && Payback->House->Class) { - newanim->OwnerHouse = Payback->House->Class->House; - } - } - } - Delete_This(); - return; - } - break; - } -} - - -/*********************************************************************************************** - * BulletClass::Draw_It -- Displays the bullet at location specified. * - * * - * This routine displays the bullet visual at the location specified. * - * * - * INPUT: x,y -- The center coordinate to render the bullet at. * - * * - * window -- The window to clip to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1994 JLB : Created. * - * 06/27/1994 JLB : Takes a window clipping parameter. * - * 01/08/1995 JLB : Handles translucent colors if necessary. * - *=============================================================================================*/ -void BulletClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - int facing = Facing_To_32(PrimaryFacing); - - /* - ** Certain projectiles aren't visible. This includes small bullets (which are actually - ** invisible) and flame thrower flames (which are rendered as an animation instead of a projectile). - */ - if (Class->IsInvisible) return; - - /* - ** If there is no shape loaded for this object, then - ** it obviously can't be rendered -- just bail. - */ - void const * shapeptr = Class->Get_Image_Data(); - if (!shapeptr) return; - - /* - ** Get the basic shape number for this projectile. - */ - int shapenum = 0; - if (!Class->IsFaceless) { - shapenum = UnitClass::BodyShape[facing]; - } - - /* - ** For tumbling projectiles, fetch offset stage. - */ - if (*this == BULLET_NAPALM) { - shapenum += Frame % 6; - } - - if (*this == BULLET_GRENADE) { - shapenum += Frame % 8; -// Timer++; - } - - /* - ** For flying projectiles, draw the shadow and adjust the actual projectile body - ** render position. - */ - if (Altitude) { - CC_Draw_Shape(shapeptr, shapenum, x, y, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, NULL, Map.FadingShade); - y -= Lepton_To_Pixel(Altitude); - } - - /* - ** Draw the main body of the projectile. - */ - ShapeFlags_Type flags = SHAPE_NORMAL; - if (Class->IsTranslucent) { - flags = SHAPE_GHOST; - } - CC_Draw_Shape(this, shapeptr, shapenum, x, y, window, flags|SHAPE_CENTER|SHAPE_WIN_REL, NULL, Map.UnitShadow); -} - - -/*********************************************************************************************** - * BulletClass::Init -- Clears the bullets array for scenario preparation. * - * * - * This routine will zero out the bullet tracking list and object array in preparation for * - * the start of a new scenario. All bullets cease to exists after this function is * - * called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/15/1994 JLB : Created. * - *=============================================================================================*/ -void BulletClass::Init(void) -{ - BulletClass *ptr; - - Bullets.Free_All(); - - ptr = new BulletClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * BulletClass::Detach -- Removes specified target from this bullet's targeting system. * - * * - * When an object is removed from the game system, it must be removed all targeting and * - * tracking systems as well. This routine is used to remove the specified object from the * - * bullet. If the object isn't part of this bullet's tracking system, then no action is * - * performed. * - * * - * INPUT: target -- The target to remove from this tracking system. * - * * - * all -- Is the target going away for good as opposed to just cloaking/hiding? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void BulletClass::Detach(TARGET target, bool all) -{ - Validate(); - ObjectClass * obj = As_Object(target); - - if (obj == Payback) { - Payback = 0; - } - - if (all && target == TarCom) { - TarCom = TARGET_NONE; - } -} - - -/*********************************************************************************************** - * BulletClass::Unlimbo -- Transitions a bullet object into the game render/logic system. * - * * - * This routine is used to take a bullet object that is in limbo and transition it to the * - * game system. A bullet object so transitioned, will be drawn and logic processing * - * performed. In effect, it comes into existance. * - * * - * INPUT: coord -- The location where the bullet object is to appear. * - * * - * dir -- The initial facing for the bullet object. * - * * - * OUTPUT: bool; Was the unlimbo successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/10/1995 JLB : Created. * - *=============================================================================================*/ -bool BulletClass::Unlimbo(COORDINATE coord, DirType dir) -{ - Validate(); - /* - ** Try to unlimbo the bullet as far as the base class is concerned. Use the already - ** set direction and strength if the "punt" values were passed in. This allows a bullet - ** to be setup prior to being launched. - */ - if (ObjectClass::Unlimbo(coord)) { - COORDINATE tcoord = As_Coord(TarCom); - - /* - ** Homing projectiles (missiles) do NOT override facing. They just fire in the - ** direction specified and let the chips fall where they may. - */ - if (!Class->IsHoming && !Class->IsDropping) { - dir = Direction(tcoord); - } - - /* - ** Possibly adjust the target if this projectile is inaccurate. This occurs whenever - ** certain weapons are trained upon targets they were never designed to attack. Example: when - ** turrets or anti-tank missiles are fired at infantry. Indirect - ** fire is inherently inaccurate. - */ - if (IsInaccurate || Class->IsInaccurate || - ((Is_Target_Cell(TarCom) || Is_Target_Infantry(TarCom)) && (Class->Warhead == WARHEAD_AP || Class->IsFueled))) { - - /* - ** Inaccuracy for low velocity or homing projectiles manifests itself as a standard - ** Cicular Error of Probability (CEP) algorithm. High speed projectiles usually - ** just overshoot the target by extending the straight line flight. - */ - if (Class->IsHoming || Class->IsArcing) { - int scatterdist = ::Distance(coord, tcoord)/3; - scatterdist = MIN(scatterdist, 0x0200); - - if (*this == BULLET_GRENADE) { - scatterdist = ::Distance(coord, tcoord)/4; - scatterdist = MIN(scatterdist, 0x0080); - } - - dir = (DirType)((dir + (Random_Pick(0, 10)-5)) & 0x00FF); - tcoord = Coord_Scatter(tcoord, Random_Pick(0, scatterdist)); - } else { - tcoord = Coord_Move(tcoord, dir, Random_Pick(0, 0x0100)); - } - - /* - ** Limit scatter to the weapon range of the firer. - */ - if (Payback) { - if (!Payback->In_Range(tcoord, 0) && !Payback->In_Range(tcoord, 1)) { - tcoord = Coord_Move(tcoord, ::Direction(tcoord, Coord), Distance(tcoord) - MAX(Payback->Weapon_Range(0), Payback->Weapon_Range(1))); - } - } - } - - /* - ** For very fast and invisible projectiles, just make the projectile exist at the target - ** location and dispense with the actual flight. - */ - if (Class->MaxSpeed == MPH_LIGHT_SPEED && Class->IsInvisible) { - Coord = tcoord; - } - - /* - ** Set the range equal to either the class defined range or the calculated - ** number of game frames it would take for the projectile to reach the target. - */ - int range = 0xFF; - if (!Class->Range) { - if (!Class->IsDropping) { - range = (::Distance(tcoord, Coord) / Class->MaxSpeed) + 4; - } - } else { - range = Class->Range; - } - - /* - ** Projectile speed is usually the default value for that projectile, but - ** certian projectiles alter speed according to the distance to the - ** target. - */ - int speed = Class->MaxSpeed; - if (speed == MPH_LIGHT_SPEED) speed = MPH_IMMOBILE; - if (Class->IsArcing) { - speed = Class->MaxSpeed + (Distance(tcoord)>>5); - - /* - ** Set minimum speed (i.e., distance) for arcing projectiles. - */ - speed = MAX(speed, 25); - } - if (!Class->IsDropping) { - Fly_Speed(255, (MPHType)speed); - } - - /* - ** Arm the fuse. - */ - Arm_Fuse(Coord, tcoord, range, ((As_Aircraft(TarCom)!=0) ? 0 : Class->Arming)); - - /* - ** Projectiles that make a ballistic flight to impact point must determine a - ** vertical component for the projectile launch. This is crudely simulated - ** by biasing ground speed according to target distance and then giving - ** enough vertical velocity to keep the projectile airborne for the - ** desired amount of time. The mathematically correct solution would be to - ** calculate launch angle (given fixed projectile velocity) and then derive - ** the vertical and horizontal components. This solution would require a - ** of square root and an arcsine lookup table. OUCH! - */ - Altitude = 0; - Riser = 0; - if (Class->IsArcing) { - Altitude = 1; - Riser = ((Distance(tcoord)/2) / (speed+1))*GRAVITY; - Riser = MAX(Riser, (signed char)10); - } - if (Class->IsDropping) { - Altitude = Pixel_To_Lepton(24); - Riser = 0; - } - - PrimaryFacing = dir; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * BulletClass::As_Target -- Converts the bullet into a target value. * - * * - * This support routine is used to convert the bullet (as a pointer) into a target * - * value (which is a number). * - * * - * INPUT: none * - * * - * OUTPUT: Returns the bullet as a target value. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -TARGET BulletClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_BULLET, Bullets.ID(this))); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/BULLET.H b/code/TIBERIANDAWN/BULLET.H deleted file mode 100644 index 3273b1d..0000000 --- a/code/TIBERIANDAWN/BULLET.H +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\bullet.h_v 2.18 16 Oct 1995 16:47:40 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BULLET.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef BULLET_H -#define BULLET_H - -#include "object.h" -#include "fly.h" -#include "fuse.h" - - -class BulletClass : public ObjectClass, - public FlyClass, - public FuseClass -{ - public: - - /* - ** This specifies exactly what kind of bullet this is. All of the static attributes - ** for this bullet is located in the BulletTypeClass pointed to by this variable. - */ - BulletTypeClass const * const Class; - operator BulletType(void) const {return Class->Type;}; - - /* - ** Records who sent this "present" so that an appropriate "thank you" can - ** be returned. - */ - TechnoClass * Payback; - - /* - ** This is the facing that the projectile is travelling. - */ - FacingClass PrimaryFacing; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - static void * BulletClass::operator new(size_t size); - static void BulletClass::operator delete(void *ptr); - BulletClass(void); - BulletClass(BulletType id); - virtual ~BulletClass(void) {if (GameActive) BulletClass::Limbo();}; - virtual RTTIType What_Am_I(void) const {return RTTI_BULLET;}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - static void Init(void); - - virtual void Assign_Target(TARGET target) {TarCom = target;}; - virtual bool Unlimbo(COORDINATE , DirType facing = DIR_N); - virtual LayerType In_Which_Layer(void) const {return LAYER_TOP;}; - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - virtual void Detach(TARGET target, bool all); - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual bool Mark(MarkType mark=MARK_CHANGE); - virtual void AI(void); - virtual short const * Occupy_List(void) const; - virtual short const * Overlap_List(void) const {return Occupy_List();}; - virtual TARGET As_Target(void) const; - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** If this bullet is forced to be inaccurate because of some outside means. A tank - ** firing while moving is a good example. - */ - unsigned IsInaccurate:1; - - private: - - // Crude animation flag. - unsigned IsToAnimate:1; - - /* - ** This is the height of the projectile. It starts at a low height, rises to an - ** apogee and then drops to explode upon impact. The height is used to render - ** the bullet's vertical offset. - */ - int Altitude; - - /* - ** This is a modifier for the altitude that rises and falls in order to simulate - ** the arc of the projectile. This value is added to the height every game tick - ** while simultaneously being reduced itself. The net effect, is a rising - ** projectile that slows and then eventually drops. - */ - signed char Riser; - - /* - ** This is the target of the projectile. It is especially significant for those projectiles - ** that home in on a target. - */ - TARGET TarCom; - - /* - ** Is this missle allowed to come in from out of bounds? - */ - unsigned IsLocked:1; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/CARGO.CPP b/code/TIBERIANDAWN/CARGO.CPP deleted file mode 100644 index e6620fb..0000000 --- a/code/TIBERIANDAWN/CARGO.CPP +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cargo.cpv 2.18 16 Oct 1995 16:49:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CARGO.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : 10/31/94 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CargoClass::Attach -- Add unit to cargo hold. * - * CargoClass::Attached_Object -- Determine attached unit pointer. * - * CargoClass::Detach_Object -- Removes a unit from the cargo hold. * - * CargoClass::Debug_Dump -- Displays the cargo value to the monochrome screen. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * CargoClass::Debug_Dump -- Displays the cargo value to the monochrome screen. * - * * - * This routine is used to dump the current cargo value to the monochrome monitor. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void CargoClass::Debug_Dump(MonoClass * mono) const -{ - if (How_Many()) { - mono->Set_Cursor(63, 3); - mono->Printf("(%d)%04X", How_Many(), Attached_Object()); - } -} -#endif - - -/*********************************************************************************************** - * CargoClass::Attach -- Add unit to cargo hold. * - * * - * This routine will add the specified unit to the cargo hold. The * - * unit will chain to any existing units in the hold. The chaining is * - * in a LIFO order. * - * * - * INPUT: object-- Pointer to the object to attach to the cargo hold. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/23/1994 JLB : Created. * - * 10/31/94 JLB : Handles chained objects. * - *=============================================================================================*/ -void CargoClass::Attach(FootClass * object) -{ - /* - ** If there is no object, then no action is necessary. - */ - if (!object) return; - - object->Limbo(); - - /* - ** Attach any existing cargo hold object to the end of the list as indicated by the - ** object pointer passed into this routine. This is necessary because several objects may - ** be attached at one time or several objects may be attached as a result of several calls - ** to this routine. Either case must be handled properly. - */ - ObjectClass * o = object->Next; - while (o) { - if (!o->Next) break; - o = o->Next; - } - if (o) { - o->Next = CargoHold; - } else { - object->Next = CargoHold; - } - - /* - ** Finally, assign the object pointer as the first object attached to this cargo hold. - */ - CargoHold = object; - Quantity = 0; - object = CargoHold; - while (object) { - Quantity++; - object = (FootClass *)object->Next; - } -} - - -/*********************************************************************************************** - * CargoClass::Detach_Object -- Removes a unit from the cargo hold. * - * * - * This routine will take a unit from the cargo hold and extract it. * - * The unit extracted is the last unit added to the hold. If there * - * is no unit in the hold or the occupant is not a unit, then NULL is * - * returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the unit that has been extracted. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/23/1994 JLB : Created. * - * 06/07/1994 JLB : Handles generic object types. * - *=============================================================================================*/ -FootClass * CargoClass::Detach_Object(void) -{ - FootClass * unit = Attached_Object(); - - if (unit) { - CargoHold = (FootClass *)unit->Next; - unit->Next = 0; - Quantity--; - } - return(unit); -} - - -/*********************************************************************************************** - * CargoClass::Attached_Object -- Determine attached unit pointer. * - * * - * This routine will return with a pointer to the attached unit if one * - * is present. One would need to know this if this is a transport * - * unit and it needs to unload. * - * * - * INPUT: none * - * * - * OUTPUT: Returns a pointer to the attached unit. If there is no * - * attached unit, then return NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/07/1992 JLB : Created. * - * 06/07/1994 JLB : Handles generic object types. * - *=============================================================================================*/ -FootClass * CargoClass::Attached_Object(void) const -{ - if (Is_Something_Attached()) { - return(CargoHold); - } - return(NULL); -} - - diff --git a/code/TIBERIANDAWN/CARGO.H b/code/TIBERIANDAWN/CARGO.H deleted file mode 100644 index dd4f968..0000000 --- a/code/TIBERIANDAWN/CARGO.H +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cargo.h_v 2.20 16 Oct 1995 16:45:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CARGO.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CARGO_H -#define CARGO_H - -class FootClass; - -/**************************************************************************** -** This class handles the basic cargo logic. -*/ -class CargoClass { - public: - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - CargoClass(void) {Quantity = 0;CargoHold = 0;}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - - #ifdef CHEAT_KEYS - void Debug_Dump(MonoClass *mono) const; - #endif - void AI(void) {}; - - int How_Many(void) const {return Quantity;}; - bool Is_Something_Attached(void) const {return (CargoHold != 0);}; - FootClass * Attached_Object(void) const; - FootClass * Detach_Object(void); - void Attach(FootClass * object); - - /* - ** File I/O. - */ - void Code_Pointers(void); - void Decode_Pointers(void); - - private: - - /* - ** This is the number of objects attached to this cargo hold. For transporter - ** objects, they might contain more than one object. - */ - unsigned char Quantity; - - /* - ** This is the target value of any attached object. A value of zero indicates - ** that no object is attached. - */ - FootClass * CargoHold; -}; - -#endif - diff --git a/code/TIBERIANDAWN/CCDDE.CPP b/code/TIBERIANDAWN/CCDDE.CPP deleted file mode 100644 index 3202c7f..0000000 --- a/code/TIBERIANDAWN/CCDDE.CPP +++ /dev/null @@ -1,419 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer - Red Alert * - * * - * File Name : CCDDE.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : 10/04/95 * - * * - * Last Update : August 5th, 1996 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * C&C's interface to the DDE class * - * * - *---------------------------------------------------------------------------------------------* - * * - * Functions: * - * DDE_Callback -- DDE server callback function * - * DDEServerClass::DDEServerClass -- class constructor * - * DDEServerClass::Enable -- Enables the DDE callback * - * DDEServerClass::Disable -- Disables the DDE callback * - * DDEServerClass::~DDEServerClass -- class destructor * - * DDESC::Callback -- callback function. Called from the DDE_Callback wrapper function * - * DDESC::Get_MPlayer_Game_Info -- returns a pointer to the multiplayer setup info from wchat * - * DDESC::Delete_MPlayer_Game_Info -- clears out multi player game setup info * - * DDESC::Time_Since_Heartbeat -- returns the time in ticks since the last heartbeat from wchat* - * * - * Send_Data_To_DDE_Server -- sends a packet to WChat * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include -#include "ccdde.h" -#include -#include - -DDEServerClass DDEServer; //Instance of the DDE Server class - -Instance_Class *DDE_Class = NULL; // pointer for client callback - // this *must* be called DDE_Class - -BOOL CC95AlreadyRunning = FALSE; //Was there an instance of C&C 95 already running when we started? - -extern HWND MainWindow; -extern TimerClass GameTimer; -extern bool GameTimerInUse; -extern void CCDebugString (char *string); - - -/*********************************************************************************************** - * DDE_Callback -- DDE server callback function * - * * - * Just acts as a wrapper for the DDEServerClass callback function * - * * - * INPUT: ptr to data from client * - * length of data * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 3:19PM ST : Created * - *=============================================================================================*/ -BOOL CALLBACK DDE_Callback (unsigned char *data, long length) -{ - return (DDEServer.Callback(data, length)); -} - - - - -/*********************************************************************************************** - * DDEServerClass::DDEServerClass -- class constructor * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 3:20PM ST : Created * - *=============================================================================================*/ -DDEServerClass::DDEServerClass(void) -{ - MPlayerGameInfo = NULL; //Flag that we havnt received a start game info packet yet - - DDE_Class = new Instance_Class ("CONQUER", "WCHAT"); - - DDE_Class->Enable_Callback( TRUE ); - IsEnabled = TRUE; - - if (DDE_Class->Test_Server_Running(DDE_Class->local_name)){ - CC95AlreadyRunning = TRUE; - }else{ - - //ST - 12/20/2018 2:27PM - //DDE_Class->Register_Server( DDE_Callback ); - } -} - - - -void DDEServerClass::Enable(void) -{ - if (!IsEnabled){ - DDE_Class->Enable_Callback( TRUE ); - IsEnabled = TRUE; - } -} - - - -/*********************************************************************************************** - * DDEServerClass::Disable -- Disables the DDE callback * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/5/96 9:44PM ST : Created * - *=============================================================================================*/ -void DDEServerClass::Disable(void) -{ - if (IsEnabled){ - DDE_Class->Enable_Callback( FALSE ); - IsEnabled = FALSE; - } -} - - - - - - -/*********************************************************************************************** - * DDEServerClass::~DDEServerClass -- class destructor * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 3:20PM ST : Created * - *=============================================================================================*/ -DDEServerClass::~DDEServerClass(void) -{ - Delete_MPlayer_Game_Info(); - delete( DDE_Class ); -} - - - -/*********************************************************************************************** - * DDESC::Callback -- callback function. Called from the DDE_Callback wrapper function * - * * - * * - * * - * INPUT: data from DDE client * - * length of data * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: Data has length and type as first 2 ints * - * * - * HISTORY: * - * 6/8/96 3:21PM ST : Created * - *=============================================================================================*/ -BOOL DDEServerClass::Callback(unsigned char *data, long length) -{ - - /* - ** If the packet length < 0 then this is a special advisory packet - */ - if ( length<0 ) { - - switch( length ) { - - case DDE_ADVISE_CONNECT: - CCDebugString("C&C95 - DDE advisory: client connect detected."); - return TRUE; - - case DDE_ADVISE_DISCONNECT: - CCDebugString("C&C95 - DDE advisory: client disconnect detected."); - return TRUE; - - default: - CCDebugString("C&C95 - DDE advisory: Unknown DDE advise type."); - return FALSE; - } - - }else{ - - /* - ** Packet must be at least the length of the packet type & size fields to be valid - */ - if (length < 2*sizeof(int)) { - CCDebugString ("C&C95 - Received invalid packet."); - return (FALSE); - } - - /* - ** Find out what kind of packet this is and its length. - */ - int *packet_pointer = (int *)data; - int actual_length = ntohl(*packet_pointer++); - int packet_type = ntohl(*packet_pointer++); - - /* - ** Strip the ID int from the start of the packet - */ - data += 2*sizeof (int); - length -= 2*sizeof (int); - actual_length -= 2*sizeof (int); - - /* - ** Take the appropriate action for the packet type - */ - switch ( packet_type ){ - - /* - ** This is a packet with the info required for starting a new internet game. This is really - * just C&CSPAWN.INI sent from WChat instead of read from disk. - */ - case DDE_PACKET_START_MPLAYER_GAME: - CCDebugString("C&C95 - Received start game packet."); - Delete_MPlayer_Game_Info(); - MPlayerGameInfo = new char [actual_length + 1]; - memcpy (MPlayerGameInfo, data, actual_length); - *(MPlayerGameInfo + actual_length) = 0; //Terminator in case we treat it as a string - MPlayerGameInfoLength = actual_length; - LastHeartbeat = 0; - break; - - case DDE_TICKLE: - CCDebugString("C&C95 - Received 'tickle' packet."); - //SetForegroundWindow ( MainWindow ); - //ShowWindow ( MainWindow, SW_SHOWMAXIMIZED ); - break; - - case DDE_PACKET_HEART_BEAT: - CCDebugString("C&C95 - Received heart beat packet."); - if (GameTimerInUse){ - LastHeartbeat = GameTimer.Time(); - }else{ - LastHeartbeat = 0; - } - break; - - default: - CCDebugString("C&C95 - Received unrecognised packet."); - break; - - } - } - - return (TRUE); - -} - - - -/*********************************************************************************************** - * DDESC::Get_MPlayer_Game_Info -- returns a pointer to the multiplayer setup info from wchat * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: ptr to data in .INI file format * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 3:23PM ST : Created * - *=============================================================================================*/ -char *DDEServerClass::Get_MPlayer_Game_Info (void) -{ - return (MPlayerGameInfo); -} - - - -/*********************************************************************************************** - * DDESC::Delete_MPlayer_Game_Info -- clears out multi player game setup info * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 3:24PM ST : Created * - *=============================================================================================*/ -void DDEServerClass::Delete_MPlayer_Game_Info(void) -{ - if (MPlayerGameInfo){ - delete [] MPlayerGameInfo; - MPlayerGameInfo = NULL; - } -} - - - -/*********************************************************************************************** - * DDESC::Time_Since_Heartbeat -- returns the time in ticks since the last heartbeat from wchat* - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: time since heartbeat * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/9/96 11:05PM ST : Created * - *=============================================================================================*/ -int DDEServerClass::Time_Since_Heartbeat(void) -{ - return (GameTimer.Time() - LastHeartbeat); -} - - - - -/*********************************************************************************************** - * Send_Data_To_DDE_Server -- sends a packet to WChat * - * * - * * - * * - * INPUT: ptr to the data to send * - * length of data * - * packet type identifier * - * * - * OUTPUT: true if packet successfully sent * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/9/96 11:07PM ST : Created * - *=============================================================================================*/ -BOOL Send_Data_To_DDE_Server (char *data, int length, int packet_type) -{ -#if (0) - BOOL app_exists; - - app_exists = DDE_Class->Test_Server_Running(DDE_Class->remote_name); - - if (app_exists != TRUE) { - CCDebugString("Connection to server failed!"); - return(FALSE); - } -#endif //(0) - - if( DDE_Class->Open_Poke_Connection(DDE_Class->remote_name) == FALSE) { - CCDebugString("C&C95 - Failed to connect for POKE!"); - return (FALSE); - } - - char *poke_data = new char [length + 2*sizeof(int)]; - - int *poke_data_int = (int*)poke_data; - - *poke_data_int = htonl (length + 2*sizeof(int)); - *(poke_data_int+1)= htonl (packet_type); - - memcpy (poke_data + 8, data, length); - - - if(DDE_Class->Poke_Server( (LPBYTE) poke_data, ntohl(*poke_data_int) ) == FALSE) { - CCDebugString("C&C95 - POKE failed!\n"); - DDE_Class->Close_Poke_Connection(); // close down the link - delete poke_data; - return (FALSE); - } - - DDE_Class->Close_Poke_Connection(); // close down the link - - delete poke_data; - - return (TRUE); -} diff --git a/code/TIBERIANDAWN/CCDDE.H b/code/TIBERIANDAWN/CCDDE.H deleted file mode 100644 index fc8dd5f..0000000 --- a/code/TIBERIANDAWN/CCDDE.H +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer - Red Alert * - * * - * File Name : CCDDE.H * - * * - * Programmer : Steve Tall * - * * - * Start Date : 10/04/95 * - * * - * Last Update : August 5th, 1996 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * C&C's interface to the DDE class * - * * - *---------------------------------------------------------------------------------------------* - * * - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifdef WIN32 - -#include "dde.h" - -class DDEServerClass { - - public: - - DDEServerClass (void); - ~DDEServerClass (void); - - - char *Get_MPlayer_Game_Info (void); //Returns pointer to game info - int Get_MPlayer_Game_Info_Length(){return(MPlayerGameInfoLength);}; //Len of game info - BOOL Callback(unsigned char *data, long length); //DDE callback function - void Delete_MPlayer_Game_Info(void); //release the game info memory - void Enable(void); //Enable the DDE callback - void Disable(void); //Disable the DDE callback - int Time_Since_Heartbeat(void); //Returns the time since the last hearbeat from WChat - - /* - ** Enumeration for DDE packet types from WChat - */ - enum { - DDE_PACKET_START_MPLAYER_GAME, //Start game packet. This includes game options - DDE_PACKET_GAME_RESULTS, //Game results packet. The game statistics. - DDE_PACKET_HEART_BEAT, //Heart beat packet so we know WChat is still there. - DDE_TICKLE, //Message to prompt other app to take focus. - DDE_CONNECTION_FAILED - }; - - - private: - - char *MPlayerGameInfo; //Pointer to game start packet - int MPlayerGameInfoLength; //Length of game start packet. - BOOL IsEnabled; //Flag for DDE callback enable - int LastHeartbeat; // Time since last heartbeat packet was received from WChat - -}; - - -extern DDEServerClass DDEServer; -extern BOOL Send_Data_To_DDE_Server (char *data, int length, int packet_type); - - -#endif //WIN32 diff --git a/code/TIBERIANDAWN/CCFILE.CPP b/code/TIBERIANDAWN/CCFILE.CPP deleted file mode 100644 index d4b86eb..0000000 --- a/code/TIBERIANDAWN/CCFILE.CPP +++ /dev/null @@ -1,626 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CCFILE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : March 20, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CCFileClass::CCFileClass -- Default constructor for file object. * - * CCFileClass::CCFileClass -- Filename based constructor for C&C file. * - * CCFileClass::Close -- Closes the file. * - * CCFileClass::Is_Available -- Checks for existence of file on disk or in mixfile. * - * CCFileClass::Is_Open -- Determines if the file is open. * - * CCFileClass::Open -- Opens a file from either the mixfile system or the rawfile system. * - * CCFileClass::Read -- Reads data from the file. * - * CCFileClass::Seek -- Moves the current file pointer in the file. * - * CCFileClass::Size -- Determines the size of the file. * - * CCFileClass::Write -- Writes data to the file (non mixfile files only). * - * CCFileClass::Error -- Handles displaying a file error message. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" -//#include -//#include -//#include -//#include -//#include -//#include -//#include "ccfile.h" - - -/*********************************************************************************************** - * CCFileClass::Error -- Handles displaying a file error message. * - * * - * Display an error message as indicated. If it is allowed to retry, then pressing a key * - * will return from this function. Otherwise, it will exit the program with "exit()". * - * * - * INPUT: error -- The error number (same as the DOSERR.H error numbers). * - * * - * canretry -- Can this routine exit normally so that retrying can occur? If this is * - * false, then the program WILL exit in this routine. * - * * - * filename -- Optional filename to report with this error. If no filename is * - * supplied, then no filename is listed in the error message. * - * * - * OUTPUT: none, but this routine might not return at all if the "canretry" parameter is * - * false or the player pressed ESC. * - * * - * WARNINGS: This routine may not return at all. It handles being in text mode as well as * - * if in a graphic mode. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void CCFileClass::Error(int , int , char const * ) -{ -#ifdef DEMO - if (strstr(File_Name(), "\\")) { - if (!Force_CD_Available(-1)) { - Prog_End(); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } - } - } - -#else - - if (!Force_CD_Available(RequiredCD)) { - Prog_End("CCFileClass::Error CD not found", true); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } - } - -#endif -} - - -/*********************************************************************************************** - * CCFileClass::CCFileClass -- Filename based constructor for C&C file. * - * * - * Use this constructor for a file when the filename is known at construction time. * - * * - * INPUT: filename -- Pointer to the filename to use for this file object. * - * * - * OUTPUT: none * - * * - * WARNINGS: The filename pointer is presumed to be inviolate throughout the duration of * - * the file object. If this is not guaranteed, then use the default constructor * - * and then set the name manually. * - * * - * HISTORY: * - * 03/20/1995 JLB : Created. * - *=============================================================================================*/ -CCFileClass::CCFileClass(char const *filename) : - CDFileClass(), - FromDisk(false), - Pointer(0), - Position(0), - Length(0), - Start(0) -{ - Set_Name(filename); -} - - -/*********************************************************************************************** - * CCFileClass::CCFileClass -- Default constructor for file object. * - * * - * This is the default constructor for a C&C file object. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/20/1995 JLB : Created. * - *=============================================================================================*/ -CCFileClass::CCFileClass(void) -{ - FromDisk = false; - Pointer = 0; - Position = 0; - Length = 0; - Start = 0; -} - - -/*********************************************************************************************** - * CCFileClass::Write -- Writes data to the file (non mixfile files only). * - * * - * This routine will write data to the file, but NOT to a file that is part of a mixfile. * - * * - * INPUT: buffer -- Pointer to the buffer that holds the data to be written. * - * * - * size -- The number of bytes to write. * - * * - * OUTPUT: Returns the number of bytes actually written. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -long CCFileClass::Write(void const *buffer, long size) -{ - - /* - ** If this is part of a mixfile, then writing is not allowed. Error out with a fatal - ** message. - */ - if (Pointer || FromDisk) { - Error(EACCES, false, File_Name()); - } - - return(CDFileClass::Write(buffer, size)); -} - - -/*********************************************************************************************** - * CCFileClass::Read -- Reads data from the file. * - * * - * This routine determines if the file is part of the mixfile system. If it is, then * - * the file is copied from RAM if it is located there. Otherwise it is read from disk * - * according to the correct position of the file within the parent mixfile. * - * * - * INPUT: buffer -- Pointer to the buffer to place the read data. * - * * - * size -- The number of bytes to read. * - * * - * OUTPUT: Returns the actual number of bytes read (this could be less than requested). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -long CCFileClass::Read(void *buffer, long size) -{ - int opened = false; - - if (!Is_Open()) { - if (Open()) { - opened = true; - } - } - - /* - ** If the file is part of a loaded mixfile, then a mere copy is - ** all that is required for the read. - */ - if (Pointer) { - long maximum = Length - Position; - - size = MIN(maximum, size); - if (size) { - Mem_Copy(Add_Long_To_Pointer(Pointer, Position), buffer, size); - Position += size; - } - if (opened) Close(); - return(size); - } - - /* - ** If the file is part of a mixfile, but the mixfile is located - ** on disk, then a special read operation is necessary. - */ - if (FromDisk) { - long maximum = Length - Position; - - size = MIN(maximum, size); - if (size > 0) { - CDFileClass::Seek(Start + Position, SEEK_SET); - size = CDFileClass::Read(buffer, size); - Position += size; - } - if (opened) Close(); - return(size); - } - - long s = CDFileClass::Read(buffer, size); - if (opened) Close(); - return(s); -} - - -/*********************************************************************************************** - * CCFileClass::Seek -- Moves the current file pointer in the file. * - * * - * This routine will change the current file pointer to the position specified. It follows * - * the same rules the a normal Seek() does, but if the file is part of the mixfile system, * - * then only the position value needs to be updated. * - * * - * INPUT: pos -- The position to move the file to relative to the position indicated * - * by the "dir" parameter. * - * * - * dir -- The direction to affect the position change against. This can be * - * either SEEK_CUR, SEEK_END, or SEEK_SET. * - * * - * OUTPUT: Returns with the position of the new location. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -long CCFileClass::Seek(long pos, int dir) -{ - if (Pointer || FromDisk) { - switch (dir) { - case SEEK_END: - Position = Length; - break; - - case SEEK_SET: - Position = 0; - break; - - case SEEK_CUR: - default: - break; - } - Position += pos; - if (Position < 0) Position = 0; - if (Position > Length) Position = Length; - return(Position); - } - return(CDFileClass::Seek(pos, dir)); -} - - -/*********************************************************************************************** - * CCFileClass::Size -- Determines the size of the file. * - * * - * If the file is part of the mixfile system, then the size of the file is already * - * determined and available. Otherwise, go to the low level system to find the file * - * size. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the size of the file in bytes. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -long CCFileClass::Size(void) -{ - if (Pointer || FromDisk) return(Length); - - return(CDFileClass::Size()); -} - - -/*********************************************************************************************** - * CCFileClass::Is_Available -- Checks for existence of file on disk or in mixfile. * - * * - * This routine will examine the mixfile system looking for the file. If the file could * - * not be found there, then the disk is examined directly. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the file available for opening? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -int CCFileClass::Is_Available(int ) -{ - if (MixFileClass::Offset(File_Name())) { - return(true); - } - return(CDFileClass::Is_Available()); -} - - -/*********************************************************************************************** - * CCFileClass::Is_Open -- Determines if the file is open. * - * * - * A mixfile is open if there is a pointer to the mixfile data. In absence of this, * - * the the file is open if the file handle is valid. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the file open? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -int CCFileClass::Is_Open(void) const -{ - - /* - ** If the file is part of a cached file, then return that it is opened. A closed file - ** doesn't have a valid pointer. - */ - if (Pointer) return(true); - return(CDFileClass::Is_Open()); -} - - -/*********************************************************************************************** - * CCFileClass::Close -- Closes the file. * - * * - * If this is a mixfile file, then only the pointers need to be adjusted. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -void CCFileClass::Close(void) -{ - FromDisk = false; - Pointer = 0; - Position = 0; // Starts at beginning offset. - Start = 0; - Length = 0; - CDFileClass::Close(); -} - - -/*********************************************************************************************** - * CCFileClass::Open -- Opens a file from either the mixfile system or the rawfile system. * - * * - * This routine will open the specified file. It examines the mixfile system to find a * - * match. If one is found then the file is "opened" in a special cached way. Otherwise * - * it is opened as a standard DOS file. * - * * - * INPUT: rights -- The access rights desired. * - * * - * OUTPUT: bool; Was the file opened successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -int CCFileClass::Open(int rights) -{ - /* - ** Always close the file if it was open. - */ - Close(); - - /* - ** Perform a preliminary check to see if the specified file - ** exists on the disk. If it does, then open this file regardless - ** of whether it also exists in RAM. This is slower, but allows - ** upgrade files to work. - */ - if ((rights & WRITE) || CDFileClass::Is_Available()) { - return(CDFileClass::Open(rights)); - } - - /* - ** Check to see if file is part of a mixfile and that mixfile is currently loaded - ** into RAM. - */ - MixFileClass *mixfile = 0; - if (MixFileClass::Offset(File_Name(), &Pointer, &mixfile, &Start, &Length)) { - - /* - ** If the mixfile is located on disk, then fake out the file system to read from - ** the mixfile, but think it is reading from a solitary file. - */ - if (!Pointer) { - long start = Start; - long length = Length; - - /* - ** This is a legitimate open to the file. All access to the file through this - ** file object will be appropriately adjusted for mixfile support however. Also - ** note that the filename attached to this object is NOT the same as the file - ** attached to the file handle. - */ - char const * dupfile = strdup(File_Name()); - Open(mixfile->Filename, READ); - Searching(false); // Disable multi-drive search. - Set_Name(dupfile); - Searching(true); - if (dupfile) free((void *)dupfile); - Start = start; - Length = length; - FromDisk = true; - } - - } else { - - /* - ** The file cannot be found in any mixfile, so it must reside as - ** an individual file on the disk. Or else it is just plain missing. - */ - return(CDFileClass::Open(rights)); - } - return(true); -} - - -/*********************************************************************************** -** Backward compatibility section. -*/ -//extern "C" { - -static CCFileClass Handles[10]; - -#ifdef NEVER -bool __cdecl Set_Search_Drives(char const *) -{ - CCFileClass::Set_Search_Path(path); - return(true); -} -#endif - -int __cdecl Open_File(char const *file_name, int mode) -{ - for (int index = 0; index < sizeof(Handles)/sizeof(Handles[0]); index++) { - if (!Handles[index].Is_Open()) { - Handles[index].Set_Name(file_name); - if (Handles[index].Open(mode)) { -// if (Handles[index].Open(file_name, mode)) { - return(index); - } - break; - } - } - return(WW_ERROR); -} - -VOID __cdecl Close_File(int handle) -{ - if (handle != WW_ERROR && Handles[handle].Is_Open()) { - Handles[handle].Close(); - } -} - -LONG __cdecl Read_File(int handle, VOID *buf, ULONG bytes) -{ - if (handle != WW_ERROR && Handles[handle].Is_Open()) { - return(Handles[handle].Read(buf, bytes)); - } - return(0); -} - -LONG __cdecl Write_File(int handle, VOID const *buf, ULONG bytes) -{ - if (handle != WW_ERROR && Handles[handle].Is_Open()) { - return(Handles[handle].Write(buf, bytes)); - } - return(0); -} - -int __cdecl Find_File(char const *file_name) -{ - CCFileClass file(file_name); - return(file.Is_Available()); -} - -#ifdef NEVER -int __cdecl Delete_File(char const *file_name) -{ - return(CCFileClass(file_name).Delete()); -} - -int __cdecl Create_File(char const *file_name) -{ - return(CCFileClass(file_name).Create()); -} - -ULONG __cdecl Load_Data(char const *name, VOID *ptr, ULONG size) -{ - return(CCFileClass(name).Read(ptr, size)); -} -#endif - -VOID * __cdecl Load_Alloc_Data(char const *name, int ) -{ - CCFileClass file(name); - - return(Load_Alloc_Data(file)); -} - -ULONG __cdecl File_Size(int handle) -{ - if (handle != WW_ERROR && Handles[handle].Is_Open()) { - return(Handles[handle].Size()); - } - return(0); -} - -#ifdef NEVER -ULONG __cdecl Write_Data(char const *name, VOID const *ptr, ULONG size) -{ - return(CCFileClass(name).Write(ptr, size)); -} -#endif - -ULONG __cdecl Seek_File(int handle, LONG offset, int starting) -{ - if (handle != WW_ERROR && Handles[handle].Is_Open()) { - return(Handles[handle].Seek(offset, starting)); - } - return(0); -} - -void WWDOS_Shutdown(void) -{ - for (int index = 0; index < 10; index++) { - Handles[index].Set_Name(NULL); - } -} - -#ifdef NEVER -bool __cdecl Multi_Drive_Search(bool on) -{ -// return(CCFileClass::Multi_Drive_Search(on)); - return(on); -} - -VOID __cdecl WWDOS_Init(VOID) -{ -} - -VOID __cdecl WWDOS_Shutdown(VOID) -{ -} - -int __cdecl Find_Disk_Number(char const *) -{ - return(0); -} -#endif - -//ULONG cdecl Load_Uncompress(BYTE const *file, BuffType uncomp_buff, BuffType dest_buff, VOID *reserved_data) -//{ -// return(Load_Uncompress(CCFileClass(file), uncomp_buff, dest_buff, reserved_data)); -// return(CCFileClass(file).Load_Uncompress(uncomp_buff, dest_buff, reserved_data)); -//} - -//extern "C" { -//int MaxDevice; -//int DefaultDrive; -//char CallingDOSInt; - -//} - - -void Unfragment_File_Cache(void) -{ -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/CCFILE.H b/code/TIBERIANDAWN/CCFILE.H deleted file mode 100644 index 070dd32..0000000 --- a/code/TIBERIANDAWN/CCFILE.H +++ /dev/null @@ -1,111 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ccfile.h_v 2.18 16 Oct 1995 16:45:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CCFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 17, 1994 * - * * - * Last Update : October 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CCFILE_H -#define CCFILE_H - -#include -#include -#include "mixfile.h" -#include "cdfile.h" - - -/* -** This derived class for file access knows about mixfiles (packed files). It can handle opening -** a file that is embedded within a mixfile. This is true if the mixfile is cached or resides on -** disk. It is functionally similar to pakfiles, except much faster and less RAM intensive. -*/ -class CCFileClass : public CDFileClass -{ - public: - CCFileClass(char const *filename); - CCFileClass(void); - virtual ~CCFileClass(void) {}; - - // Delete should be overloaded here as well. Don't allow deletes of mixfiles. - - virtual int Open(char const *filename, int rights=READ) {Set_Name(filename);return Open(rights);}; - virtual int Open(int rights=READ); - virtual int Is_Open(void) const; - virtual int Is_Available(int forced=false); - virtual long Read(void *buffer, long size); - virtual long Seek(long pos, int dir=SEEK_CUR); - virtual long Size(void); - virtual long Write(void const *buffer, long size); - virtual void Close(void); - virtual void Error(int error, int canretry = false, char const * filename=NULL); - - private: - - /* - ** This flag indicates that the file is part of a mixfile and the mixfile resides on - ** disk. The file handle for this file is a legitimate DOS handle, although special - ** handling is necessary that takes into account the embedded nature of the file. - */ - bool FromDisk; - - /* - ** This indicates the file is actually part of a resident image of the mixfile - ** itself. In this case, the embedded file handle is invalid. All file access actually - ** gets routed through the cached version of the file. This is a pointer to the start - ** of the RAM image of the file. - */ - void * Pointer; - - /* - ** This is the starting offset of the beginning of the file. This value is only valid - ** if the file is part of a mixfile that resides on disk. It serves as the counterpart - ** to the "Pointer" variable. - */ - long Start; - - /* - ** This is the current seek position of the file. It is duplicated here if the file is - ** part of a mixfile since the DOS seek position is not accurate. This value will - ** range from zero to the size of the file in bytes. - */ - long Position; - - /* - ** This is the size of the file if it was embedded in a mixfile. The size must be manually - ** kept track of because the DOS file size is invalid. - */ - long Length; - - // Force these to never be invoked. - CCFileClass const operator = (CCFileClass const & c); - CCFileClass (CCFileClass const & ) {}; -}; - -#endif diff --git a/code/TIBERIANDAWN/CC_ICON.RC b/code/TIBERIANDAWN/CC_ICON.RC deleted file mode 100644 index a2324fa..0000000 --- a/code/TIBERIANDAWN/CC_ICON.RC +++ /dev/null @@ -1,16 +0,0 @@ -/**************************************************************************** - - -CC_ICON.RC - -produced by Borland Resource Workshop - - -*****************************************************************************/ - -#include "cc_icon.rh" - - - -ICON_1 ICON "conquer.ico" - diff --git a/code/TIBERIANDAWN/CDATA.CPP b/code/TIBERIANDAWN/CDATA.CPP deleted file mode 100644 index 26175ed..0000000 --- a/code/TIBERIANDAWN/CDATA.CPP +++ /dev/null @@ -1,2770 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cdata.cpv 2.18 16 Oct 1995 16:50:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CDATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 16, 1994 * - * * - * Last Update : July 29, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TemplateTypeClass::Create_And_Place -- Creates and places a template object on the map. * - * TemplateTypeClass::Create_One_Of -- Creates an object of this template type. * - * TemplateTypeClass::Display -- Displays a generic representation of template. * - * TemplateTypeClass::From_Name -- Determine template from ASCII name. * - * TemplateTypeClass::Init -- Loads graphic data for templates. * - * TemplateTypeClass::Occupy_List -- Determines occupation list. * - * TemplateTypeClass::One_Time -- Performs one-time initialization * - * TemplateTypeClass::Prep_For_Add -- Prepares to add template to scenario. * - * TemplateTypeClass::TemplateTypeClass -- Constructor for template type objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -static char const _slope00000001[] = {7,-1}; -static char const _slope000000101[] = {6,8,-1}; -static char const _slope00000011[] = {6,7,-1}; -static char const _slope0000001[] = {6,-1}; -static char const _slope000001001[] = {5,8,-1}; -static char const _slope000001[] = {5,-1}; -static char const _slope000101[] = {3,5,-1}; -static char const _slope00011010000100000001000011[] = {3,4,6,11,19,25,25,-1}; -static char const _slope00011010010100100001000011[] = {3,4,6,9,11,14,19,24,25,-1}; -static char const _slope0001[] = {3,-1}; -static char const _slope001001001[] = {2,5,8,-1}; -static char const _slope00110000000011[] = {2,3,12,13,-1}; -static char const _slope00110010010011[] = {2,3,6,9,12,13,-1}; -static char const _slope001111001[] = {2,3,4,5,8,-1}; -static char const _slope0011[] = {2,3,-1}; -static char const _slope001[] = {2,-1}; -static char const _slope01000000000000000000001[] = {1,22,-1}; -static char const _slope01000000100000010000001[] = {1,8,15,22,-1}; -static char const _slope0111[] = {1,2,3,-1}; -static char const _slope01[] = {1,-1}; -static char const _slope1001001[] = {0,3,6,-1}; -static char const _slope1001[] = {0,3,-1}; -static char const _slope1100000000000000001100011[] = {0,1,18,19,23,24,-1}; -static char const _slope1100001000001000001100011[] = {0,1,6,12,18,19,23,24,-1}; -static char const _slope1101101[] = {0,1,3,4,6,-1}; -static char const _slope1101[] = {0,1,3,-1}; -static char const _slope111[] = {0,1,2,-1}; -static char const _slope111010011[] = {0,1,2,4,7,8,-1}; -static char const _slope11101[] = {0,1,2,4,-1}; -static char const _slope111111011[] = {0,1,2,3,4,5,7,8,-1}; -static char const _slope11111111[] = {0,1,2,3,4,5,6,7,-1}; -static char const _slope111111[] = {0,1,2,3,4,5,-1}; -static char const _slope1[] = {0,-1}; - -static TemplateTypeClass const Empty( - TEMPLATE_CLEAR1, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE|THEATERF_JUNGLE, - "CLEAR1", - TXT_CLEAR, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Clear( - TEMPLATE_CLEAR1, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE|THEATERF_JUNGLE, - "CLEAR1", - TXT_CLEAR, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road1( - TEMPLATE_ROAD1, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D01", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road2( - TEMPLATE_ROAD2, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D02", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road3( - TEMPLATE_ROAD3, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D03", - TXT_ROAD, - LAND_CLEAR, - 1,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road4( - TEMPLATE_ROAD4, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D04", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road5( - TEMPLATE_ROAD5, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D05", - TXT_ROAD, - LAND_CLEAR, - 3,4, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road6( - TEMPLATE_ROAD6, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D06", - TXT_ROAD, - LAND_CLEAR, - 2,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road7( - TEMPLATE_ROAD7, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D07", - TXT_ROAD, - LAND_CLEAR, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road8( - TEMPLATE_ROAD8, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D08", - TXT_ROAD, - LAND_CLEAR, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road9( - TEMPLATE_ROAD9, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D09", - TXT_ROAD, - LAND_CLEAR, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road10( - TEMPLATE_ROAD10, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D10", - TXT_ROAD, - LAND_CLEAR, - 4,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road11( - TEMPLATE_ROAD11, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D11", - TXT_ROAD, - LAND_CLEAR, - 2,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road12( - TEMPLATE_ROAD12, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D12", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road13( - TEMPLATE_ROAD13, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D13", - TXT_ROAD, - LAND_CLEAR, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road14( - TEMPLATE_ROAD14, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D14", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road15( - TEMPLATE_ROAD15, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D15", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road16( - TEMPLATE_ROAD16, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D16", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road17( - TEMPLATE_ROAD17, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D17", - TXT_ROAD, - LAND_CLEAR, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road18( - TEMPLATE_ROAD18, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D18", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road19( - TEMPLATE_ROAD19, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D19", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road20( - TEMPLATE_ROAD20, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D20", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road21( - TEMPLATE_ROAD21, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D21", - TXT_ROAD, - LAND_CLEAR, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road22( - TEMPLATE_ROAD22, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D22", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road23( - TEMPLATE_ROAD23, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D23", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road24( - TEMPLATE_ROAD24, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D24", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road25( - TEMPLATE_ROAD25, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D25", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road26( - TEMPLATE_ROAD26, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D26", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road27( - TEMPLATE_ROAD27, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D27", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road28( - TEMPLATE_ROAD28, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D28", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road29( - TEMPLATE_ROAD29, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D29", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road30( - TEMPLATE_ROAD30, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D30", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road31( - TEMPLATE_ROAD31, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D31", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road32( - TEMPLATE_ROAD32, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D32", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road33( - TEMPLATE_ROAD33, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D33", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road34( - TEMPLATE_ROAD34, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D34", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road35( - TEMPLATE_ROAD35, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D35", - TXT_ROAD, - LAND_CLEAR, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road36( - TEMPLATE_ROAD36, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D36", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road37( - TEMPLATE_ROAD37, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D37", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road38( - TEMPLATE_ROAD38, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D38", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road39( - TEMPLATE_ROAD39, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D39", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road40( - TEMPLATE_ROAD40, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D40", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road41( - TEMPLATE_ROAD41, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D41", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road42( - TEMPLATE_ROAD42, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D42", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Road43( - TEMPLATE_ROAD43, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "D43", - TXT_ROAD, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Water( - TEMPLATE_WATER, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "W1", - TXT_WATER, - LAND_WATER, - 1,1, - LAND_WATER, - NULL -); -static TemplateTypeClass const Water2( - TEMPLATE_WATER2, - THEATERF_WINTER|THEATERF_TEMPERATE, - "W2", - TXT_WATER, - LAND_WATER, - 2,2, - LAND_WATER, - NULL -); -static TemplateTypeClass const Shore1( - TEMPLATE_SHORE1, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH1", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope111111 -); -static TemplateTypeClass const Shore2( - TEMPLATE_SHORE2, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH2", - TXT_WATER, - LAND_ROCK, - 3,3, - LAND_BEACH, - (char const *)_slope111 -); -static TemplateTypeClass const Shore3( - TEMPLATE_SHORE3, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH3", - TXT_WATER, - LAND_ROCK, - 1,1, - LAND_WATER, - NULL -); -static TemplateTypeClass const Shore4( - TEMPLATE_SHORE4, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH4", - TXT_WATER, - LAND_ROCK, - 2,1, - LAND_WATER, - NULL -); -static TemplateTypeClass const Shore5( - TEMPLATE_SHORE5, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH5", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope111111 -); -static TemplateTypeClass const Shore6( - TEMPLATE_SHORE6, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH6", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope111111 -); -static TemplateTypeClass const Shore7( - TEMPLATE_SHORE7, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH7", - TXT_WATER, - LAND_WATER, - 2,2, - LAND_BEACH, - (char const *)_slope1 -); -static TemplateTypeClass const Shore8( - TEMPLATE_SHORE8, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH8", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope11111111 -); -static TemplateTypeClass const Shore9( - TEMPLATE_SHORE9, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH9", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope111111011 -); -static TemplateTypeClass const Shore10( - TEMPLATE_SHORE10, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH10", - TXT_WATER, - LAND_WATER, - 2,2, - LAND_BEACH, - (char const *)_slope01 -); -static TemplateTypeClass const Shore11( - TEMPLATE_SHORE11, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH11", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope1001 -); -static TemplateTypeClass const Shore12( - TEMPLATE_SHORE12, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH12", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope000001001 -); -static TemplateTypeClass const Shore13( - TEMPLATE_SHORE13, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH13", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_BEACH, - (char const *)_slope0000001 -); -static TemplateTypeClass const Shore14( - TEMPLATE_SHORE14, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH14", - TXT_WATER, - LAND_ROCK, - 3,3, - LAND_BEACH, - (char const *)_slope00000011 -); -static TemplateTypeClass const Shore15( - TEMPLATE_SHORE15, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH15", - TXT_WATER, - LAND_ROCK, - 3,3, - LAND_BEACH, - (char const *)_slope000000101 -); -static TemplateTypeClass const Shore16( - TEMPLATE_SHORE16, - THEATERF_WINTER|THEATERF_TEMPERATE, - "SH16", - TXT_WATER, - LAND_ROCK, - 3,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Shore17( - TEMPLATE_SHORE17, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "SH17", - TXT_WATER, - LAND_WATER, - 2,2, - LAND_WATER, - NULL -); -static TemplateTypeClass const Shore18( - TEMPLATE_SHORE18, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "SH18", - TXT_WATER, - LAND_WATER, - 2,2, - LAND_WATER, - NULL -); -static TemplateTypeClass const Shore19( - TEMPLATE_SHORE19, - THEATERF_DESERT, - "SH19", - TXT_WATER, - LAND_ROCK, - 3,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Shore20( - TEMPLATE_SHORE20, - THEATERF_DESERT, - "SH20", - TXT_WATER, - LAND_ROCK, - 4,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Shore21( - TEMPLATE_SHORE21, - THEATERF_DESERT, - "SH21", - TXT_WATER, - LAND_ROCK, - 3,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Shore22( - TEMPLATE_SHORE22, - THEATERF_DESERT, - "SH22", - TXT_WATER, - LAND_ROCK, - 6,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Shore23( - TEMPLATE_SHORE23, - THEATERF_DESERT, - "SH23", - TXT_WATER, - LAND_ROCK, - 2,2, - LAND_CLEAR, - (char const *)_slope01 -); -static TemplateTypeClass const Shore24( - TEMPLATE_SHORE24, - THEATERF_DESERT, - "SH24", - TXT_WATER, - LAND_ROCK, - 3,3, - LAND_CLEAR, - (char const *)_slope000001 -); -static TemplateTypeClass const Shore25( - TEMPLATE_SHORE25, - THEATERF_DESERT, - "SH25", - TXT_WATER, - LAND_ROCK, - 3,2, - LAND_CLEAR, - (char const *)_slope0001 -); -static TemplateTypeClass const Shore26( - TEMPLATE_SHORE26, - THEATERF_DESERT, - "SH26", - TXT_WATER, - LAND_ROCK, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore27( - TEMPLATE_SHORE27, - THEATERF_DESERT, - "SH27", - TXT_WATER, - LAND_ROCK, - 4,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore28( - TEMPLATE_SHORE28, - THEATERF_DESERT, - "SH28", - TXT_WATER, - LAND_ROCK, - 3,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore29( - TEMPLATE_SHORE29, - THEATERF_DESERT, - "SH29", - TXT_WATER, - LAND_ROCK, - 6,2, - LAND_CLEAR, - (char const *)_slope00000001 -); -static TemplateTypeClass const Shore30( - TEMPLATE_SHORE30, - THEATERF_DESERT, - "SH30", - TXT_WATER, - LAND_ROCK, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore31( - TEMPLATE_SHORE31, - THEATERF_DESERT, - "SH31", - TXT_WATER, - LAND_ROCK, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore32( - TEMPLATE_SHORE32, - THEATERF_TEMPERATE|THEATERF_WINTER, - "SH32", - TXT_WATER, - LAND_CLEAR, - 3,3, - LAND_WATER, - (char const *)_slope1 -); -static TemplateTypeClass const Shore33( - TEMPLATE_SHORE33, - THEATERF_TEMPERATE|THEATERF_WINTER, - "SH33", - TXT_WATER, - LAND_CLEAR, - 3,3, - LAND_WATER, - (char const *)_slope001 -); -static TemplateTypeClass const Shore34( - TEMPLATE_SHORE34, - THEATERF_TEMPERATE|THEATERF_WINTER, - "SH34", - TXT_WATER, - LAND_CLEAR, - 3,3, - LAND_WATER, - (char const *)_slope001001001 -); -static TemplateTypeClass const Shore35( - TEMPLATE_SHORE35, - THEATERF_TEMPERATE|THEATERF_WINTER, - "SH35", - TXT_WATER, - LAND_CLEAR, - 3,3, - LAND_WATER, - (char const *)_slope1001001 -); -static TemplateTypeClass const Shore36( - TEMPLATE_SHORE36, - THEATERF_DESERT, - "SH36", - TXT_WATER, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore37( - TEMPLATE_SHORE37, - THEATERF_DESERT, - "SH37", - TXT_WATER, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore38( - TEMPLATE_SHORE38, - THEATERF_DESERT, - "SH38", - TXT_WATER, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore39( - TEMPLATE_SHORE39, - THEATERF_DESERT, - "SH39", - TXT_WATER, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore40( - TEMPLATE_SHORE40, - THEATERF_DESERT, - "SH40", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_CLEAR, - (char const *)_slope1 -); -static TemplateTypeClass const Shore41( - TEMPLATE_SHORE41, - THEATERF_DESERT, - "SH41", - TXT_WATER, - LAND_CLEAR, - 3,3, - LAND_WATER, - (char const *)_slope1101101 -); -static TemplateTypeClass const Shore42( - TEMPLATE_SHORE42, - THEATERF_DESERT, - "SH42", - TXT_WATER, - LAND_WATER, - 1,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore43( - TEMPLATE_SHORE43, - THEATERF_DESERT, - "SH43", - TXT_WATER, - LAND_WATER, - 1,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore44( - TEMPLATE_SHORE44, - THEATERF_DESERT, - "SH44", - TXT_WATER, - LAND_WATER, - 1,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore45( - TEMPLATE_SHORE45, - THEATERF_DESERT, - "SH45", - TXT_WATER, - LAND_WATER, - 1,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore46( - TEMPLATE_SHORE46, - THEATERF_DESERT, - "SH46", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_CLEAR, - (char const *)_slope1101 -); -static TemplateTypeClass const Shore47( - TEMPLATE_SHORE47, - THEATERF_DESERT, - "SH47", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore48( - TEMPLATE_SHORE48, - THEATERF_DESERT, - "SH48", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore49( - TEMPLATE_SHORE49, - THEATERF_DESERT, - "SH49", - TXT_WATER, - LAND_WATER, - 3,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore50( - TEMPLATE_SHORE50, - THEATERF_DESERT, - "SH50", - TXT_WATER, - LAND_WATER, - 4,3, - LAND_CLEAR, - (char const *)_slope00000001 -); -static TemplateTypeClass const Shore51( - TEMPLATE_SHORE51, - THEATERF_DESERT, - "SH51", - TXT_WATER, - LAND_WATER, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore52( - TEMPLATE_SHORE52, - THEATERF_DESERT, - "SH52", - TXT_WATER, - LAND_WATER, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore53( - TEMPLATE_SHORE53, - THEATERF_DESERT, - "SH53", - TXT_WATER, - LAND_WATER, - 4,3, - LAND_CLEAR, - (char const *)_slope11101 -); -static TemplateTypeClass const Shore54( - TEMPLATE_SHORE54, - THEATERF_DESERT, - "SH54", - TXT_WATER, - LAND_WATER, - 3,2, - LAND_CLEAR, - (char const *)_slope1 -); -static TemplateTypeClass const Shore55( - TEMPLATE_SHORE55, - THEATERF_DESERT, - "SH55", - TXT_WATER, - LAND_WATER, - 3,2, - LAND_CLEAR, - (char const *)_slope001 -); -static TemplateTypeClass const Shore56( - TEMPLATE_SHORE56, - THEATERF_DESERT, - "SH56", - TXT_WATER, - LAND_WATER, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore57( - TEMPLATE_SHORE57, - THEATERF_DESERT, - "SH57", - TXT_WATER, - LAND_WATER, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore58( - TEMPLATE_SHORE58, - THEATERF_DESERT, - "SH58", - TXT_WATER, - LAND_WATER, - 2,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore59( - TEMPLATE_SHORE59, - THEATERF_DESERT, - "SH59", - TXT_WATER, - LAND_WATER, - 2,3, - LAND_CLEAR, - (char const *)_slope1 -); -static TemplateTypeClass const Shore60( - TEMPLATE_SHORE60, - THEATERF_DESERT, - "SH60", - TXT_WATER, - LAND_WATER, - 2,3, - LAND_CLEAR, - (char const *)_slope000101 -); -static TemplateTypeClass const Shore61( - TEMPLATE_SHORE61, - THEATERF_DESERT, - "SH61", - TXT_WATER, - LAND_WATER, - 2,3, - LAND_CLEAR, - (char const *)_slope01 -); -static TemplateTypeClass const Shore62( - TEMPLATE_SHORE62, - THEATERF_DESERT, - "SH62", - TXT_WATER, - LAND_WATER, - 6,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Shore63( - TEMPLATE_SHORE63, - THEATERF_DESERT, - "SH63", - TXT_WATER, - LAND_WATER, - 4,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Boulder1( - TEMPLATE_BOULDER1, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "B1", - TXT_SLOPE, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Boulder2( - TEMPLATE_BOULDER2, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "B2", - TXT_SLOPE, - LAND_ROCK, - 2,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Boulder3( - TEMPLATE_BOULDER3, - THEATERF_WINTER|THEATERF_TEMPERATE, - "B3", - TXT_SLOPE, - LAND_ROCK, - 3,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Boulder4( - TEMPLATE_BOULDER4, - THEATERF_TEMPERATE, - "B4", - TXT_SLOPE, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Boulder5( - TEMPLATE_BOULDER5, - THEATERF_TEMPERATE, - "B5", - TXT_SLOPE, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Boulder6( - TEMPLATE_BOULDER6, - THEATERF_TEMPERATE, - "B6", - TXT_SLOPE, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope1( - TEMPLATE_SLOPE1, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S01", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_CLEAR, - (char const *)_slope001 -); -static TemplateTypeClass const Slope2( - TEMPLATE_SLOPE2, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S02", - TXT_SLOPE, - LAND_ROCK, - 2,3, - LAND_CLEAR, - (char const *)_slope01 -); -static TemplateTypeClass const Slope3( - TEMPLATE_SLOPE3, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S03", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope4( - TEMPLATE_SLOPE4, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S04", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope5( - TEMPLATE_SLOPE5, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S05", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope6( - TEMPLATE_SLOPE6, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S06", - TXT_SLOPE, - LAND_ROCK, - 2,3, - LAND_CLEAR, - (char const *)_slope1 -); -static TemplateTypeClass const Slope7( - TEMPLATE_SLOPE7, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S07", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope8( - TEMPLATE_SLOPE8, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S08", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_CLEAR, - (char const *)_slope01 -); -static TemplateTypeClass const Slope9( - TEMPLATE_SLOPE9, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S09", - TXT_SLOPE, - LAND_ROCK, - 3,2, - LAND_CLEAR, - (char const *)_slope0001 -); -static TemplateTypeClass const Slope10( - TEMPLATE_SLOPE10, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S10", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope11( - TEMPLATE_SLOPE11, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S11", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope12( - TEMPLATE_SLOPE12, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S12", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope13( - TEMPLATE_SLOPE13, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S13", - TXT_SLOPE, - LAND_ROCK, - 3,2, - LAND_CLEAR, - (char const *)_slope000001 -); -static TemplateTypeClass const Slope14( - TEMPLATE_SLOPE14, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S14", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_CLEAR, - (char const *)_slope0111 -); -static TemplateTypeClass const Slope15( - TEMPLATE_SLOPE15, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S15", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_CLEAR, - (char const *)_slope01 -); -static TemplateTypeClass const Slope16( - TEMPLATE_SLOPE16, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S16", - TXT_SLOPE, - LAND_ROCK, - 2,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope17( - TEMPLATE_SLOPE17, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S17", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope18( - TEMPLATE_SLOPE18, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S18", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope19( - TEMPLATE_SLOPE19, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S19", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope20( - TEMPLATE_SLOPE20, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S20", - TXT_SLOPE, - LAND_ROCK, - 2,3, - LAND_CLEAR, - (char const *)_slope000001 -); -static TemplateTypeClass const Slope21( - TEMPLATE_SLOPE21, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S21", - TXT_SLOPE, - LAND_ROCK, - 1,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope22( - TEMPLATE_SLOPE22, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S22", - TXT_SLOPE, - LAND_ROCK, - 2,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope23( - TEMPLATE_SLOPE23, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S23", - TXT_SLOPE, - LAND_ROCK, - 3,2, - LAND_CLEAR, - (char const *)_slope000001 -); -static TemplateTypeClass const Slope24( - TEMPLATE_SLOPE24, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S24", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope25( - TEMPLATE_SLOPE25, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S25", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope26( - TEMPLATE_SLOPE26, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S26", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope27( - TEMPLATE_SLOPE27, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S27", - TXT_SLOPE, - LAND_ROCK, - 3,2, - LAND_CLEAR, - (char const *)_slope0011 -); -static TemplateTypeClass const Slope28( - TEMPLATE_SLOPE28, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S28", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope29( - TEMPLATE_SLOPE29, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S29", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope30( - TEMPLATE_SLOPE30, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S30", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope31( - TEMPLATE_SLOPE31, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S31", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope32( - TEMPLATE_SLOPE32, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S32", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope33( - TEMPLATE_SLOPE33, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S33", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope34( - TEMPLATE_SLOPE34, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S34", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope35( - TEMPLATE_SLOPE35, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S35", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope36( - TEMPLATE_SLOPE36, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S36", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope37( - TEMPLATE_SLOPE37, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S37", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Slope38( - TEMPLATE_SLOPE38, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "S38", - TXT_SLOPE, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush1( - TEMPLATE_BRUSH1, - THEATERF_DESERT, - "BR1", - TXT_BRUSH, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush2( - TEMPLATE_BRUSH2, - THEATERF_DESERT, - "BR2", - TXT_BRUSH, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush3( - TEMPLATE_BRUSH3, - THEATERF_DESERT, - "BR3", - TXT_BRUSH, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush4( - TEMPLATE_BRUSH4, - THEATERF_DESERT, - "BR4", - TXT_BRUSH, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush5( - TEMPLATE_BRUSH5, - THEATERF_DESERT, - "BR5", - TXT_BRUSH, - LAND_ROCK, - 1,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush6( - TEMPLATE_BRUSH6, - THEATERF_DESERT, - "BR6", - TXT_BRUSH, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush7( - TEMPLATE_BRUSH7, - THEATERF_DESERT, - "BR7", - TXT_BRUSH, - LAND_ROCK, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush8( - TEMPLATE_BRUSH8, - THEATERF_DESERT, - "BR8", - TXT_BRUSH, - LAND_ROCK, - 3,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush9( - TEMPLATE_BRUSH9, - THEATERF_DESERT, - "BR9", - TXT_BRUSH, - LAND_ROCK, - 3,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Brush10( - TEMPLATE_BRUSH10, - THEATERF_DESERT, - "BR10", - TXT_BRUSH, - LAND_ROCK, - 2,1, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Patch1( - TEMPLATE_PATCH1, - THEATERF_TEMPERATE|THEATERF_DESERT, - "P01", - TXT_PATCH, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch2( - TEMPLATE_PATCH2, - THEATERF_TEMPERATE|THEATERF_DESERT, - "P02", - TXT_PATCH, - LAND_ROCK, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch3( - TEMPLATE_PATCH3, - THEATERF_TEMPERATE|THEATERF_DESERT, - "P03", - TXT_PATCH, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch4( - TEMPLATE_PATCH4, - THEATERF_TEMPERATE|THEATERF_DESERT, - "P04", - TXT_PATCH, - LAND_ROCK, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch5( - TEMPLATE_PATCH5, - THEATERF_DESERT, - "P05", - TXT_PATCH, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch6( - TEMPLATE_PATCH6, - THEATERF_DESERT, - "P06", - TXT_PATCH, - LAND_CLEAR, - 6,4, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch7( - TEMPLATE_PATCH7, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "P07", - TXT_PATCH, - LAND_CLEAR, - 4,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch8( - TEMPLATE_PATCH8, - THEATERF_WINTER|THEATERF_TEMPERATE|THEATERF_DESERT, - "P08", - TXT_PATCH, - LAND_CLEAR, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch13( - TEMPLATE_PATCH13, - THEATERF_WINTER|THEATERF_TEMPERATE, - "P13", - TXT_PATCH, - LAND_CLEAR, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch14( - TEMPLATE_PATCH14, - THEATERF_WINTER|THEATERF_TEMPERATE, - "P14", - TXT_PATCH, - LAND_CLEAR, - 2,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch15( - TEMPLATE_PATCH15, - THEATERF_WINTER|THEATERF_TEMPERATE, - "P15", - TXT_PATCH, - LAND_CLEAR, - 1,1, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch16( - TEMPLATE_PATCH16, - THEATERF_WINTER, - "P16", - TXT_PATCH, - LAND_CLEAR, - 2,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch17( - TEMPLATE_PATCH17, - THEATERF_WINTER, - "P17", - TXT_PATCH, - LAND_CLEAR, - 4,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch18( - TEMPLATE_PATCH18, - THEATERF_WINTER, - "P18", - TXT_PATCH, - LAND_CLEAR, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch19( - TEMPLATE_PATCH19, - THEATERF_WINTER, - "P19", - TXT_PATCH, - LAND_CLEAR, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Patch20( - TEMPLATE_PATCH20, - THEATERF_WINTER, - "P20", - TXT_PATCH, - LAND_CLEAR, - 4,3, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const River1( - TEMPLATE_RIVER1, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV01", - TXT_RIVER, - LAND_WATER, - 5,4, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const River2( - TEMPLATE_RIVER2, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV02", - TXT_RIVER, - LAND_WATER, - 5,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River3( - TEMPLATE_RIVER3, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV03", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_CLEAR, - (char const *)_slope00000001 -); -static TemplateTypeClass const River4( - TEMPLATE_RIVER4, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV04", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River5( - TEMPLATE_RIVER5, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV05", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River6( - TEMPLATE_RIVER6, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV06", - TXT_RIVER, - LAND_WATER, - 3,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River7( - TEMPLATE_RIVER7, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV07", - TXT_RIVER, - LAND_WATER, - 3,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River8( - TEMPLATE_RIVER8, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV08", - TXT_RIVER, - LAND_WATER, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River9( - TEMPLATE_RIVER9, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV09", - TXT_RIVER, - LAND_WATER, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River10( - TEMPLATE_RIVER10, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV10", - TXT_RIVER, - LAND_WATER, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River11( - TEMPLATE_RIVER11, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV11", - TXT_RIVER, - LAND_WATER, - 2,2, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River12( - TEMPLATE_RIVER12, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV12", - TXT_RIVER, - LAND_WATER, - 3,4, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River13( - TEMPLATE_RIVER13, - THEATERF_WINTER|THEATERF_TEMPERATE, - "RV13", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River14( - TEMPLATE_RIVER14, - THEATERF_DESERT, - "RV14", - TXT_RIVER, - LAND_WATER, - 4,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River15( - TEMPLATE_RIVER15, - THEATERF_DESERT, - "RV15", - TXT_RIVER, - LAND_WATER, - 4,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River16( - TEMPLATE_RIVER16, - THEATERF_DESERT, - "RV16", - TXT_RIVER, - LAND_WATER, - 6,4, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River17( - TEMPLATE_RIVER17, - THEATERF_DESERT, - "RV17", - TXT_RIVER, - LAND_WATER, - 6,5, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River18( - TEMPLATE_RIVER18, - THEATERF_DESERT, - "RV18", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River19( - TEMPLATE_RIVER19, - THEATERF_DESERT, - "RV19", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River20( - TEMPLATE_RIVER20, - THEATERF_DESERT, - "RV20", - TXT_RIVER, - LAND_WATER, - 6,8, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River21( - TEMPLATE_RIVER21, - THEATERF_DESERT, - "RV21", - TXT_RIVER, - LAND_WATER, - 5,8, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River22( - TEMPLATE_RIVER22, - THEATERF_DESERT, - "RV22", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River23( - TEMPLATE_RIVER23, - THEATERF_DESERT, - "RV23", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River24( - TEMPLATE_RIVER24, - THEATERF_DESERT, - "RV24", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const River25( - TEMPLATE_RIVER25, - THEATERF_DESERT, - "RV25", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_ROCK, - NULL -); -static TemplateTypeClass const Ford1( - TEMPLATE_FORD1, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "FORD1", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_CLEAR, - (char const *)_slope001111001 -); -static TemplateTypeClass const Ford2( - TEMPLATE_FORD2, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "FORD2", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_CLEAR, - (char const *)_slope111010011 -); -static TemplateTypeClass const Falls1( - TEMPLATE_FALLS1, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "FALLS1", - TXT_RIVER, - LAND_WATER, - 3,3, - LAND_CLEAR, - (char const *)_slope1 -); -static TemplateTypeClass const Falls2( - TEMPLATE_FALLS2, - THEATERF_WINTER|THEATERF_DESERT|THEATERF_TEMPERATE, - "FALLS2", - TXT_RIVER, - LAND_WATER, - 3,2, - LAND_CLEAR, - NULL -); -static TemplateTypeClass const Bridge1( - TEMPLATE_BRIDGE1, - THEATERF_WINTER|THEATERF_TEMPERATE, - "BRIDGE1", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_CLEAR, - (char const *)_slope00110010010011 -); -static TemplateTypeClass const Bridge1d( - TEMPLATE_BRIDGE1D, - THEATERF_WINTER|THEATERF_TEMPERATE, - "BRIDGE1D", - TXT_RIVER, - LAND_WATER, - 4,4, - LAND_CLEAR, - (char const *)_slope00110000000011 -); -static TemplateTypeClass const Bridge2( - TEMPLATE_BRIDGE2, - THEATERF_WINTER|THEATERF_TEMPERATE, - "BRIDGE2", - TXT_RIVER, - LAND_WATER, - 5,5, - LAND_CLEAR, - (char const *)_slope1100001000001000001100011 -); -static TemplateTypeClass const Bridge2d( - TEMPLATE_BRIDGE2D, - THEATERF_WINTER|THEATERF_TEMPERATE, - "BRIDGE2D", - TXT_RIVER, - LAND_WATER, - 5,5, - LAND_CLEAR, - (char const *)_slope1100000000000000001100011 -); -static TemplateTypeClass const Bridge3( - TEMPLATE_BRIDGE3, - THEATERF_DESERT, - "BRIDGE3", - TXT_RIVER, - LAND_WATER, - 6,5, - LAND_CLEAR, - (char const *)_slope00011010010100100001000011 -); -static TemplateTypeClass const Bridge3d( - TEMPLATE_BRIDGE3D, - THEATERF_DESERT, - "BRIDGE3D", - TXT_RIVER, - LAND_WATER, - 6,5, - LAND_CLEAR, - (char const *)_slope00011010000100000001000011 -); -static TemplateTypeClass const Bridge4( - TEMPLATE_BRIDGE4, - THEATERF_DESERT, - "BRIDGE4", - TXT_RIVER, - LAND_WATER, - 6,4, - LAND_CLEAR, - (char const *)_slope01000000100000010000001 -); -static TemplateTypeClass const Bridge4d( - TEMPLATE_BRIDGE4D, - THEATERF_DESERT, - "BRIDGE4D", - TXT_RIVER, - LAND_WATER, - 6,4, - LAND_CLEAR, - (char const *)_slope01000000000000000000001 -); - -TemplateTypeClass const * const TemplateTypeClass::Pointers[TEMPLATE_COUNT] = { - &Clear, // TEMPLATE_CLEAR1 - &Water, // TEMPLATE_WATER - &Water2, // TEMPLATE_WATER2 - &Shore1, // TEMPLATE_SHORE1 - &Shore2, // TEMPLATE_SHORE2 - &Shore3, // TEMPLATE_SHORE3 - &Shore4, // TEMPLATE_SHORE4 - &Shore5, // TEMPLATE_SHORE5 - &Shore11, // TEMPLATE_SHORE11 - &Shore12, // TEMPLATE_SHORE12 - &Shore13, // TEMPLATE_SHORE13 - &Shore14, // TEMPLATE_SHORE14 - &Shore15, // TEMPLATE_SHORE15 - &Slope1, // TEMPLATE_SLOPE1 - &Slope2, // TEMPLATE_SLOPE2 - &Slope3, // TEMPLATE_SLOPE3 - &Slope4, // TEMPLATE_SLOPE4 - &Slope5, // TEMPLATE_SLOPE5 - &Slope6, // TEMPLATE_SLOPE6 - &Slope7, // TEMPLATE_SLOPE7 - &Slope8, // TEMPLATE_SLOPE8 - &Slope9, // TEMPLATE_SLOPE9 - &Slope10, // TEMPLATE_SLOPE10 - &Slope11, // TEMPLATE_SLOPE11 - &Slope12, // TEMPLATE_SLOPE12 - &Slope13, // TEMPLATE_SLOPE13 - &Slope14, // TEMPLATE_SLOPE14 - &Slope15, // TEMPLATE_SLOPE15 - &Slope16, // TEMPLATE_SLOPE16 - &Slope17, // TEMPLATE_SLOPE17 - &Slope18, // TEMPLATE_SLOPE18 - &Slope19, // TEMPLATE_SLOPE19 - &Slope20, // TEMPLATE_SLOPE20 - &Slope21, // TEMPLATE_SLOPE21 - &Slope22, // TEMPLATE_SLOPE22 - &Slope23, // TEMPLATE_SLOPE23 - &Slope24, // TEMPLATE_SLOPE24 - &Slope25, // TEMPLATE_SLOPE25 - &Slope26, // TEMPLATE_SLOPE26 - &Slope27, // TEMPLATE_SLOPE27 - &Slope28, // TEMPLATE_SLOPE28 - &Slope29, // TEMPLATE_SLOPE29 - &Slope30, // TEMPLATE_SLOPE30 - &Slope31, // TEMPLATE_SLOPE31 - &Slope32, // TEMPLATE_SLOPE32 - &Slope33, // TEMPLATE_SLOPE33 - &Slope34, // TEMPLATE_SLOPE34 - &Slope35, // TEMPLATE_SLOPE35 - &Slope36, // TEMPLATE_SLOPE36 - &Slope37, // TEMPLATE_SLOPE37 - &Slope38, // TEMPLATE_SLOPE38 - &Shore32, // TEMPLATE_SHORE32 - &Shore33, // TEMPLATE_SHORE33 - &Shore20, // TEMPLATE_SHORE20 - &Shore21, // TEMPLATE_SHORE21 - &Shore22, // TEMPLATE_SHORE22 - &Shore23, // TEMPLATE_SHORE23 - &Brush1, // TEMPLATE_BRUSH1 - &Brush2, // TEMPLATE_BRUSH2 - &Brush3, // TEMPLATE_BRUSH3 - &Brush4, // TEMPLATE_BRUSH4 - &Brush5, // TEMPLATE_BRUSH5 - &Brush6, // TEMPLATE_BRUSH6 - &Brush7, // TEMPLATE_BRUSH7 - &Brush8, // TEMPLATE_BRUSH8 - &Brush9, // TEMPLATE_BRUSH9 - &Brush10, // TEMPLATE_BRUSH10 - &Patch1, // TEMPLATE_PATCH1 - &Patch2, // TEMPLATE_PATCH2 - &Patch3, // TEMPLATE_PATCH3 - &Patch4, // TEMPLATE_PATCH4 - &Patch5, // TEMPLATE_PATCH5 - &Patch6, // TEMPLATE_PATCH6 - &Patch7, // TEMPLATE_PATCH7 - &Patch8, // TEMPLATE_PATCH8 - &Shore16, // TEMPLATE_SHORE16 - &Shore17, // TEMPLATE_SHORE17 - &Shore18, // TEMPLATE_SHORE18 - &Shore19, // TEMPLATE_SHORE19 - &Patch13, // TEMPLATE_PATCH13 - &Patch14, // TEMPLATE_PATCH14 - &Patch15, // TEMPLATE_PATCH15 - &Boulder1, // TEMPLATE_BOULDER1 - &Boulder2, // TEMPLATE_BOULDER2 - &Boulder3, // TEMPLATE_BOULDER3 - &Boulder4, // TEMPLATE_BOULDER4 - &Boulder5, // TEMPLATE_BOULDER5 - &Boulder6, // TEMPLATE_BOULDER6 - &Shore6, // TEMPLATE_SHORE6 - &Shore7, // TEMPLATE_SHORE7 - &Shore8, // TEMPLATE_SHORE8 - &Shore9, // TEMPLATE_SHORE9 - &Shore10, // TEMPLATE_SHORE10 - - &Road1, // TEMPLATE_ROAD1 - &Road2, // TEMPLATE_ROAD2 - &Road3, // TEMPLATE_ROAD3 - &Road4, // TEMPLATE_ROAD4 - &Road5, // TEMPLATE_ROAD5 - &Road6, // TEMPLATE_ROAD6 - &Road7, // TEMPLATE_ROAD7 - &Road8, // TEMPLATE_ROAD8 - &Road9, // TEMPLATE_ROAD9 - &Road10, // TEMPLATE_ROAD10 - &Road11, // TEMPLATE_ROAD11 - &Road12, // TEMPLATE_ROAD12 - &Road13, // TEMPLATE_ROAD13 - &Road14, // TEMPLATE_ROAD14 - &Road15, // TEMPLATE_ROAD15 - &Road16, // TEMPLATE_ROAD16 - &Road17, // TEMPLATE_ROAD17 - &Road18, // TEMPLATE_ROAD18 - &Road19, // TEMPLATE_ROAD19 - &Road20, // TEMPLATE_ROAD20 - &Road21, // TEMPLATE_ROAD21 - &Road22, // TEMPLATE_ROAD22 - &Road23, // TEMPLATE_ROAD23 - &Road24, // TEMPLATE_ROAD24 - &Road25, // TEMPLATE_ROAD25 - &Road26, // TEMPLATE_ROAD26 - &Road27, // TEMPLATE_ROAD27 - &Road28, // TEMPLATE_ROAD28 - &Road29, // TEMPLATE_ROAD29 - &Road30, // TEMPLATE_ROAD30 - &Road31, // TEMPLATE_ROAD31 - &Road32, // TEMPLATE_ROAD32 - &Road33, // TEMPLATE_ROAD33 - &Road34, // TEMPLATE_ROAD34 - &Road35, // TEMPLATE_ROAD35 - &Road36, // TEMPLATE_ROAD36 - &Road37, // TEMPLATE_ROAD37 - &Road38, // TEMPLATE_ROAD38 - &Road39, // TEMPLATE_ROAD39 - &Road40, // TEMPLATE_ROAD40 - &Road41, // TEMPLATE_ROAD41 - &Road42, // TEMPLATE_ROAD42 - &Road43, // TEMPLATE_ROAD43 - - &River1, // TEMPLATE_RIVER1 - &River2, // TEMPLATE_RIVER2 - &River3, // TEMPLATE_RIVER3 - &River4, // TEMPLATE_RIVER4 - &River5, // TEMPLATE_RIVER5 - &River6, // TEMPLATE_RIVER6 - &River7, // TEMPLATE_RIVER7 - &River8, // TEMPLATE_RIVER8 - &River9, // TEMPLATE_RIVER9 - &River10, // TEMPLATE_RIVER10 - &River11, // TEMPLATE_RIVER11 - &River12, // TEMPLATE_RIVER12 - &River13, // TEMPLATE_RIVER13 - &River14, // TEMPLATE_RIVER14 - &River15, // TEMPLATE_RIVER15 - &River16, // TEMPLATE_RIVER16 - &River17, // TEMPLATE_RIVER17 - &River18, // TEMPLATE_RIVER18 - &River19, // TEMPLATE_RIVER19 - &River20, // TEMPLATE_RIVER20 - &River21, // TEMPLATE_RIVER21 - &River22, // TEMPLATE_RIVER22 - &River23, // TEMPLATE_RIVER23 - &River24, // TEMPLATE_RIVER24 - &River25, // TEMPLATE_RIVER25 - &Ford1, // TEMPLATE_FORD1 - &Ford2, // TEMPLATE_FORD2 - &Falls1, // TEMPLATE_FALLS1 - &Falls2, // TEMPLATE_FALLS2 - &Bridge1, // TEMPLATE_BRIDGE1 - &Bridge1d, // TEMPLATE_BRIDGE1D - &Bridge2, // TEMPLATE_BRIDGE2 - &Bridge2d, // TEMPLATE_BRIDGE2D - &Bridge3, // TEMPLATE_BRIDGE3 - &Bridge3d, // TEMPLATE_BRIDGE3D - &Bridge4, // TEMPLATE_BRIDGE4 - &Bridge4d, // TEMPLATE_BRIDGE4D - - &Shore24, // TEMPLATE_SHORE24 - &Shore25, // TEMPLATE_SHORE25 - &Shore26, // TEMPLATE_SHORE26 - &Shore27, // TEMPLATE_SHORE27 - &Shore28, // TEMPLATE_SHORE28 - &Shore29, // TEMPLATE_SHORE29 - &Shore30, // TEMPLATE_SHORE30 - &Shore31, // TEMPLATE_SHORE31 - - &Patch16, // TEMPLATE_PATCH16 - &Patch17, // TEMPLATE_PATCH17 - &Patch18, // TEMPLATE_PATCH18 - &Patch19, // TEMPLATE_PATCH19 - &Patch20, // TEMPLATE_PATCH20 - - &Shore34, // TEMPLATE_SHORE34 - &Shore35, // TEMPLATE_SHORE35 - &Shore36, // TEMPLATE_SHORE36 - &Shore37, // TEMPLATE_SHORE37 - &Shore38, // TEMPLATE_SHORE38 - &Shore39, // TEMPLATE_SHORE39 - &Shore40, // TEMPLATE_SHORE40 - &Shore41, // TEMPLATE_SHORE41 - &Shore42, // TEMPLATE_SHORE42 - &Shore43, // TEMPLATE_SHORE43 - &Shore44, // TEMPLATE_SHORE44 - &Shore45, // TEMPLATE_SHORE45 - - &Shore46, // TEMPLATE_SHORE46 - &Shore47, // TEMPLATE_SHORE47 - &Shore48, // TEMPLATE_SHORE48 - &Shore49, // TEMPLATE_SHORE49 - &Shore50, // TEMPLATE_SHORE50 - &Shore51, // TEMPLATE_SHORE51 - &Shore52, // TEMPLATE_SHORE52 - &Shore53, // TEMPLATE_SHORE53 - &Shore54, // TEMPLATE_SHORE54 - &Shore55, // TEMPLATE_SHORE55 - &Shore56, // TEMPLATE_SHORE56 - &Shore57, // TEMPLATE_SHORE57 - &Shore58, // TEMPLATE_SHORE58 - &Shore59, // TEMPLATE_SHORE59 - &Shore60, // TEMPLATE_SHORE60 - &Shore61, // TEMPLATE_SHORE61 - - &Shore62, // TEMPLATE_SHORE62 - &Shore63, // TEMPLATE_SHORE63 -}; - - -/*********************************************************************************************** - * TemplateTypeClass::TemplateTypeClass -- Constructor for template type objects. * - * * - * This is the constructor for the template types. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1994 JLB : Created. * - *=============================================================================================*/ -TemplateTypeClass::TemplateTypeClass(TemplateType iconset, int theater, - char const *ininame, int fullname, LandType land, - int width, int height, LandType altland, char const *alticons ) : - ObjectTypeClass(false, false, false, true, false, false, true, true, fullname, ininame, ARMOR_NONE, 0) -{ - Theater = theater; - AltIcons = alticons; - AltLand = altland; - Type = iconset; - Land = land; - Width = width; - Height = height; -} - - -/*********************************************************************************************** - * TemplateTypeClass::From_Name -- Determine template from ASCII name. * - * * - * This routine is used to determine the template number given only * - * an ASCII representation. The scenario loader uses this routine * - * to construct the map from the INI control file. * - * * - * INPUT: name -- Pointer to the ASCII name of the template. * - * * - * OUTPUT: Returns with the template number. If the name had no match, * - * then returns with TEMPLATE_NONE. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -TemplateType TemplateTypeClass::From_Name(char const *name) -{ - if (name) { - for (TemplateType index = TEMPLATE_FIRST; index < TEMPLATE_COUNT; index++) { - if (stricmp(As_Reference(index).IniName, name) == 0) { - return(index); - } - } - } - return(TEMPLATE_NONE); -} - - -/*********************************************************************************************** - * TemplateTypeClass::Occupy_List -- Determines occupation list. * - * * - * This routine is used to examine the template map and build an * - * occupation list. This list is used to render a template cursor as * - * well as placement of icon numbers. * - * * - * INPUT: placement -- Is this for placement legality checking only? The normal condition * - * is for marking occupation flags. * - * * - * OUTPUT: Returns with a pointer to the template occupation list. * - * * - * WARNINGS: The return pointer is valid only until the next time that * - * this routine is called. * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -short const * TemplateTypeClass::Occupy_List(bool) const -{ - static short _occupy[13*8+5]; - unsigned char map[13*8]; - short *ptr; - int index; - - Mem_Copy(Get_Icon_Set_Map(Get_Image_Data()), map, Width*Height); - - ptr = &_occupy[0]; - for (index = 0; index < Width*Height; index++) { - if (map[index] != 0xFF) { - *ptr++ = (index % Width) + ((index / Width)*MAP_CELL_W); - } - } - *ptr = REFRESH_EOL; - - return((short const *)&_occupy[0]); -} - - -/*********************************************************************************************** - * TemplateTypeClass::Init -- Loads graphic data for templates. * - * * - * This routine loads the template graphic data for all the template * - * type supported for the specified theater. This routine is called * - * whenever the theater for the scenario is first determined. * - * * - * INPUT: theater -- The theater that the template data is to be * - * loaded for. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine goes to disk! * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - * 06/02/1994 JLB : Only handles iconset loading now (as it should). * - *=============================================================================================*/ -void TemplateTypeClass::Init(TheaterType theater) -{ - //if (theater != LastTheater){ - char fullname[_MAX_FNAME+_MAX_EXT]; // Fully constructed iconset name. - void const * ptr; // Working loaded iconset pointer. - - for (TemplateType index = TEMPLATE_FIRST; index < TEMPLATE_COUNT; index++) { - TemplateTypeClass const & tplate = As_Reference(index); - - ((void const *&)tplate.ImageData) = NULL; - if (tplate.Theater & (1< 3 || h > 3); - if (scale) { - x -= (w/2) * (ICON_PIXEL_W/2); - y -= (h/2) * (ICON_PIXEL_H/2); - } else { - x -= (w/2) * ICON_PIXEL_W; - y -= (h/2) * ICON_PIXEL_H; - } - x += WindowList[window][WINDOWX]<<3; - y += WindowList[window][WINDOWY]; - - Mem_Copy(Get_Icon_Set_Map(Get_Image_Data()), map, Width*Height); - - for (index = 0; index < w*h; index++) { - if (map[index] != 0xFF) { - HidPage.Draw_Stamp(Get_Image_Data(), index, 0, 0, NULL, WINDOW_MAIN); - if (scale) { - - HidPage.Scale((*LogicPage), 0, 0, - x + ((index % w)*(ICON_PIXEL_W/2)), - y + ((index / w)*(ICON_PIXEL_H/2)), - ICON_PIXEL_W, ICON_PIXEL_H, - ICON_PIXEL_W/2, ICON_PIXEL_H/2, (char *)NULL); - - } else { - HidPage.Blit((*LogicPage), 0, 0, x + ((index % w)*(ICON_PIXEL_W)), - y + ((index / w)*(ICON_PIXEL_H)), ICON_PIXEL_W, ICON_PIXEL_H); - } - } - } -} - - -/*********************************************************************************************** - * TemplateTypeClass::Prep_For_Add -- Prepares to add template to scenario. * - * * - * This routine prepares a list of template objects so that the * - * scenario editor can use this list to display a dialog box. The * - * selection of a template object will allow its placement upon the * - * map. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - * 05/28/1994 JLB : Only handles real templates now. * - * 06/04/1994 JLB : Uses map editing interface functions. * - *=============================================================================================*/ -void TemplateTypeClass::Prep_For_Add(void) -{ - for (TemplateType index = TEMPLATE_CLEAR1; index < TEMPLATE_COUNT; index++) { - if (As_Reference(index).Get_Image_Data()) { - Map.Add_To_List(&As_Reference(index)); - } - } -} -#endif - - -/*********************************************************************************************** - * TemplateTypeClass::Create_And_Place -- Creates and places a template object on the map. * - * * - * This support routine is used by the scenario editor to add a template object to the map * - * and to the game. * - * * - * INPUT: cell -- The cell to place the template object. * - * * - * OUTPUT: bool; Was the template object placed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -bool TemplateTypeClass::Create_And_Place(CELL cell, HousesType ) const -{ - if (new TemplateClass(Type, cell)) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TemplateTypeClass::Create_One_Of -- Creates an object of this template type. * - * * - * This routine will create an object of this type. For certain template objects, such * - * as walls, it is actually created as a building. The "building" wall is converted into * - * a template at the moment of placing down on the map. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the appropriate object for this template type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/18/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * TemplateTypeClass::Create_One_Of(HouseClass *) const -{ - return(new TemplateClass(Type, -1)); -} - - -/*********************************************************************************************** - * TemplateTypeClass::One_Time -- Performs one-time initialization * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -void TemplateTypeClass::One_Time(void) -{ -} - - - diff --git a/code/TIBERIANDAWN/CDFILE.CPP b/code/TIBERIANDAWN/CDFILE.CPP deleted file mode 100644 index 1468c79..0000000 --- a/code/TIBERIANDAWN/CDFILE.CPP +++ /dev/null @@ -1,534 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cdfile.cpv 2.18 16 Oct 1995 16:48:10 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : CDFILE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 18, 1994 * - * * - * Last Update : October 18, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CDFileClass::Clear_Search_Drives -- Removes all record of a search path. * - * CDFileClass::Open -- Opens the file object -- with path search. * - * CDFileClass::Open -- Opens the file wherever it can be found. * - * CDFileClass::Set_Name -- Performs a multiple directory scan to set the filename. * - * CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -//#include "cdfile.h" - -/* -** Pointer to the first search path record. -*/ -CDFileClass::SearchDriveType * CDFileClass::First = 0; - -int CDFileClass::CurrentCDDrive = 0; -int CDFileClass::LastCDDrive = 0; -char CDFileClass::RawPath[512]; - - - -int __cdecl Is_Disk_Inserted(int disk) -{ - return true; - -#if (0) // ST - 12/17/2018 5:31PM - struct find_t fb; - char scan[] = "?:\\*.*"; - - scan[0] = 'A' + disk; - return(_dos_findfirst(scan, _A_SUBDIR, &fb) == 0); -#endif -} - - -CDFileClass::CDFileClass(char const *filename) : - IsDisabled(false) -{ - Set_Name(filename); - memset (RawPath, 0, sizeof(RawPath)); -} - - -CDFileClass::CDFileClass(void) : - IsDisabled(false) -{ -} - - -/*********************************************************************************************** - * CDFileClass::Open -- Opens the file object -- with path search. * - * * - * This will open the file object, but since the file object could have been constructed * - * with a pathname, this routine will try to find the file first. For files opened for * - * writing, then use the existing filename without performing a path search. * - * * - * INPUT: rights -- The access rights to use when opening the file * - * * - * OUTPUT: bool; Was the open successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -int CDFileClass::Open(int rights) -{ - return(RawFileClass::Open(rights)); -} - - -/*********************************************************************************************** - * CDFC::Refresh_Search_Drives -- Updates the search path when a CD changes or is added * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/22/96 9:01AM ST : Created * - *=============================================================================================*/ -void CDFileClass::Refresh_Search_Drives (void) -{ - Clear_Search_Drives(); - Set_Search_Drives(RawPath); -} - - - - - -/*********************************************************************************************** - * CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. * - * * - * This routine sets up a list of search paths to use when accessing files. The path list * - * is scanned if the file could not be found in the current directory. This is the primary * - * method of supporting CD-ROM drives, but is also useful for scanning network and other * - * directories. The pathlist as passed to this routine is of the same format as the path * - * list used by DOS -- paths are separated by semicolons and need not end in an antivirgule.* - * * - * If a path entry begins with "?:" then the question mark will be replaced with the first * - * CD-ROM drive letter available. If there is no CD-ROM driver detected, then this path * - * entry will be ignored. By using this feature, you can always pass the CD-ROM path * - * specification to this routine and it will not break if the CD-ROM is not loaded (as in * - * the case during development). * - * * - * Here is an example path specification: * - * * - * Set_Search_Drives("DATA;?:\DATA;F:\PROJECT\DATA"); * - * * - * In this example, the current directory will be searched first, followed by a the * - * subdirectory "DATA" located off of the current directory. If not found, then the CD-ROM * - * will be searched in a directory called "\DATA". If not found or the CD-ROM is not * - * present, then it will look to the hard coded path of "F:\PROJECTS\DATA" (maybe a * - * network?). If all of these searches fail, the file system will default to the current * - * directory and let the normal file error system take over. * - * * - * INPUT: pathlist -- Pointer to string of path specifications (separated by semicolons) * - * that will be used to search for files. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - * 05/21/1996 ST : Modified to recognise multiple CD drives * - *=============================================================================================*/ -int CDFileClass::Set_Search_Drives(char * pathlist) -{ - int found = FALSE; - int empty = FALSE; - /* - ** If there is no pathlist to add, then just return. - */ - if (!pathlist) return(0); - - /* - ** Save the path as it was passed in so we can parse it again later. - ** Check for the case where RawPath was passed in. - */ - if (pathlist != RawPath){ - strcat (RawPath, ";"); - strcat (RawPath, pathlist); - } - - char const * ptr = strtok(pathlist, ";"); - while (ptr) { - if (strlen(ptr)){ - - char path[MAX_PATH]; // Working path buffer. - - /* - ** Fixup the path to be legal. Legal is defined as all that is necessary to - ** create a pathname is to append the actual filename submitted to the - ** file system. This means that it must have either a trailing ':' or '\' - ** character. - */ - strcpy(path, ptr); - switch (path[strlen(path)-1]) { - case ':': - case '\\': - break; - - default: - strcat(path, "\\"); - break; - } - - /* - ** If there is a drive letter specified, and this drive letter is '?', then it should - ** be substituted with the CD-ROM drive letter. In the case of no CD-ROM attached, then - ** merely ignore this path entry. - */ - if (strncmp(path, "?:", 2) == 0) { - if (CurrentCDDrive){ - found = TRUE; - /* - ** If the drive has a C&C CD in it then add it to the path - */ - if (Get_CD_Index(CurrentCDDrive, 2*60) >= 0){ - path[0] = CurrentCDDrive + 'A'; - Add_Search_Drive(path); - } - } - /* - ** Find the next path string and resubmit. - */ - ptr = strtok(NULL, ";"); - continue; - } - - found = TRUE; - Add_Search_Drive(path); - } - - /* - ** Find the next path string and resubmit. - */ - ptr = strtok(NULL, ";"); - } - if (!found) return(1); - if (empty) return(2); - return(0); -} - - - -/*********************************************************************************************** - * CDFC::Set_CD_Drive -- sets the current CD drive letter * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/22/96 9:39AM ST : Created * - *=============================================================================================*/ - -void CDFileClass::Set_CD_Drive (int drive) -{ - LastCDDrive = CurrentCDDrive; - CurrentCDDrive = drive; -} - - - -/*********************************************************************************************** - * CDFC::Add_Search_Drive -- Add a new path to the search path list * - * * - * * - * * - * INPUT: path * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/22/96 10:12AM ST : Created * - *=============================================================================================*/ - -void CDFileClass::Add_Search_Drive(char *path) -{ - SearchDriveType *srch; // Working pointer to path object. - /* - ** Allocate a record structure. - */ - srch = new SearchDriveType; - - /* - ** Attach the path to this structure. - */ - srch->Path = strdup(path); - srch->Next = NULL; - - /* - ** Attach this path record to the end of the path chain. - */ - if (!First) { - First = srch; - } else { - SearchDriveType * chain = First; - - while (chain->Next) { - chain = (SearchDriveType *)chain->Next; - } - chain->Next = srch; - } -} - - - - -/*********************************************************************************************** - * CDFileClass::Clear_Search_Drives -- Removes all record of a search path. * - * * - * Use this routine to clear out any previous path(s) set with Set_Search_Drives() * - * function. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -void CDFileClass::Clear_Search_Drives(void) -{ - SearchDriveType * chain; // Working pointer to path chain. - - chain = First; - while (chain) { - SearchDriveType *next; - - next = (SearchDriveType *)chain->Next; - if (chain->Path) { - free((char *)chain->Path); - } - delete chain; - - chain = next; - } - First = 0; -} - - -/*********************************************************************************************** - * CDFileClass::Set_Name -- Performs a multiple directory scan to set the filename. * - * * - * This routine will scan all the directories specified in the path list and if the file * - * was found in one of the directories, it will set the filename to a composite of the * - * correct directory and the filename. It is used to allow path searching when searching * - * for files. Typical use is to support CD-ROM drives. This routine examines the current * - * directory first before scanning through the path list. If after scanning the entire * - * path list, the file still could not be found, then the file object's name is set with * - * just the raw filename as passed to this routine. * - * * - * INPUT: filename -- Pointer to the filename to set as the name of this file object. * - * * - * OUTPUT: Returns a pointer to the final and complete filename of this file object. This * - * may have a path attached to the file. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -char const * CDFileClass::Set_Name(char const *filename) -{ - /* - ** Try to find the file in the current directory first. If it can be found, then - ** just return with the normal file name setting process. Do the same if there is - ** no multi-drive search path. - */ - RawFileClass::Set_Name(filename); - if (IsDisabled || !First || RawFileClass::Is_Available()) { - return(File_Name()); - } - - /* - ** Attempt to find the file first. Check the current directory. If not found there, then - ** search all the path specifications available. If it still can't be found, then just - ** fall into the normal raw file filename setting system. - */ - SearchDriveType * srch = First; - - while (srch) { - char path[_MAX_PATH]; - - /* - ** Build a pathname to search for. - */ - strcpy(path, srch->Path); - strcat(path, filename); - - /* - ** Check to see if the file could be found. The low level Is_Available logic will - ** prompt if necessary when the CD-ROM drive has been removed. In all other cases, - ** it will return false and the search process will continue. - */ - RawFileClass::Set_Name(path); - if (RawFileClass::Is_Available()) { - return(File_Name()); - } - - /* - ** It wasn't found, so try the next path entry. - */ - srch = (SearchDriveType *)srch->Next; - } - - /* - ** At this point, all path searching has failed. Just set the file name to the - ** plain text passed to this routine and be done with it. - */ - RawFileClass::Set_Name(filename); - return(File_Name()); -} - - -/*********************************************************************************************** - * CDFileClass::Open -- Opens the file wherever it can be found. * - * * - * This routine is similar to the RawFileClass open except that if the file is being * - * opened only for READ access, it will search all specified directories looking for the * - * file. If after a complete search the file still couldn't be found, then it is opened * - * using the normal RawFileClass system -- resulting in normal error procedures. * - * * - * INPUT: filename -- Pointer to the override filename to supply for this file object. It * - * would be the base filename (sans any directory specification). * - * * - * rights -- The access rights to use when opening the file. * - * * - * OUTPUT: bool; Was the file opened successfully? If so then the filename may be different * - * than requested. The location of the file can be determined by examining the * - * filename of this file object. The filename will contain the complete * - * pathname used to open the file. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -int CDFileClass::Open(char const *filename, int rights) -{ - Close(); - - /* - ** Verify that there is a filename associated with this file object. If not, then this is a - ** big error condition. - */ - if (!filename) { - Error(ENOENT, false); - } - - /* - ** If writing is requested, then multiple drive searching is not performed. - */ - if (IsDisabled || rights == WRITE) { - return(RawFileClass::Open(filename, rights)); - } - - /* - ** Perform normal multiple drive searching for the filename and open - ** using the normal procedure. - */ - Set_Name(filename); - return(RawFileClass::Open(rights)); -} - - -#ifdef NEVER -/* Get the drive letters if the CD's online */ -WORD __cdecl GetCDDrive(VOID) -{ - _ES = FP_SEG(&cdDrive[0]); - _BX = FP_OFF(&cdDrive[0]); - _AX = 0x150d; - geninterrupt(0x2F); - return((WORD)(*cdDrive)); -} -#endif - -int Get_CD_Drive(void) -{ -#ifdef NEVER - for (int index = 0; index < 26; index++) { - union REGS regs; - - regs.w.ax = 0x150B; - regs.w.bx = 0; - regs.w.cx = index; - int386(0x2F, ®s, ®s); - if (regs.w.bx == 0xADAD) { - return(index); - } - } - return(0); -#else - -// GetCDClass temp; -// return(temp.GetCDDrive()); - return (0); -#endif - -} - - - -const char *CDFileClass::Get_Search_Path(int index) -{ - if (First == NULL) { - return NULL; - } - - SearchDriveType *sd = First; - - for (int i=0 ; i <= index ; i++) { // We want to loop once, even if index==0 - - if (i == index) { - return sd->Path; - } - - sd = (SearchDriveType *) sd->Next; - if (sd == NULL) { - return NULL; - } - } - - return NULL; -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/CDFILE.H b/code/TIBERIANDAWN/CDFILE.H deleted file mode 100644 index c8b0f13..0000000 --- a/code/TIBERIANDAWN/CDFILE.H +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cdfile.h_v 2.20 16 Oct 1995 16:45:58 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood LIbrary * - * * - * File Name : CDFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 18, 1994 * - * * - * Last Update : October 18, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CDFILE_H -#define CDFILE_H - -#include -#include "rawfile.h" - -/* -** This class is derived from the raw file class. This class adds the functionality of searching -** across multiple directories or drives. It is designed for the typical case of a CD-ROM game -** were some data exists in the current directory (hard drive) and the rest exists on the CD-ROM. -** Searching for the file occurs by first examining the current directory. If the file does not -** exist there, then all the paths available are examined in turn until the file can be found. -** For opening files to write, only the current directory is examined. The directory search order -** is controlled by the path list as submitted to Set_Search_Drives(). The format of the path -** string is the same as the DOS path string. -*/ -class CDFileClass : public RawFileClass -{ - public: - CDFileClass(char const *filename); - CDFileClass(void); - virtual ~CDFileClass(void) {}; - - virtual char const * Set_Name(char const *filename); - virtual int Open(char const *filename, int rights=READ); - virtual int Open(int rights=READ); - - void Searching(int on) {IsDisabled = !on;}; - - static bool Is_There_Search_Drives(void) {return(First != NULL);}; - static int Set_Search_Drives(char * pathlist); - static void Add_Search_Drive(char *path); - static void Clear_Search_Drives(void); - static void Refresh_Search_Drives(void); - static void Set_CD_Drive(int drive); - static int Get_CD_Drive(void) {return(CurrentCDDrive);}; - static int Get_Last_CD_Drive(void) {return(LastCDDrive);}; - - // RawPath will overflow if we keep setting the path. ST - 1/23/2019 11:12AM - static void Reset_Raw_Path(void) {RawPath[0] = 0;} - - // Need to access the paths. ST - 3/15/2019 2:14PM - static const char *Get_Search_Path(int index); - - private: - - /* - ** Is multi-drive searching disabled for this file object? - */ - unsigned IsDisabled:1; - - /* - ** This is the control record for each of the drives specified in the search - ** path. There can be many such search paths available. - */ - typedef struct { - void * Next; // Pointer to next search record. - char const * Path; // Pointer to path string. - } SearchDriveType; - - /* - ** This points to the first path record. - */ - static SearchDriveType * First; - - /* - ** This is a copy of the unparsed search path list - */ - static char RawPath[512]; - - /* - ** The drive letter of the current cd drive - */ - static int CurrentCDDrive; - - /* - ** The drive letter of the last used CD drive - */ - static int LastCDDrive; -}; - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/CELL.CPP b/code/TIBERIANDAWN/CELL.CPP deleted file mode 100644 index 22274fa..0000000 --- a/code/TIBERIANDAWN/CELL.CPP +++ /dev/null @@ -1,2757 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cell.cpv 2.18 16 Oct 1995 16:49:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CELL.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : August 17, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CellClass::Adjacent_Cell -- Determines the adjacent cell according to facing. * - * CellClass::Adjust_Threat -- Allows adjustment of threat at cell level * - * CellClass::CellClass -- Constructor for cell objects. * - * CellClass::Cell_Building -- Return with building at specified cell. * - * CellClass::Cell_Color -- Determine what radar color to use for this cell. * - * CellClass::Cell_Coord -- Returns the coordinate of this cell. * - * CellClass::Cell_Find_Object -- Returns ptr to RTTI type occupying cell * - * CellClass::Cell_Infantry -- Returns with pointer of first infantry unit. * - * CellClass::Cell_Object -- Returns with clickable object in cell. * - * CellClass::Cell_Techno -- Return with the unit/building at specified cell. * - * CellClass::Cell_Terrain -- Determines terrain object in cell. * - * CellClass::Cell_Unit -- Returns with pointer to unit occupying cell. * - * CellClass::Clear_Icon -- Calculates what the clear icon number should be. * - * CellClass::Closest_Free_Spot -- returns free spot closest to given coord * - * CellClass::Concrete_Calc -- Calculates the concrete icon to use for the cell. * - * CellClass::Draw_It -- Draws the cell imagery at the location specified. * - * CellClass::Flag_Place -- Places a house flag down on the cell. * - * CellClass::Flag_Remove -- Removes the house flag from the cell. * - * CellClass::Cell_Occupier -- Fetches the occupier for the cell. * - * CellClass::Get_Trigger -- retrieves reference to the cell's trigger * - * CellClass::Goodie_Check -- Performs crate discovery logic. * - * CellClass::Incoming -- Causes objects in cell to "run for cover". * - * CellClass::Is_Generally_Clear -- Determines if cell can be built upon. * - * CellClass::Occupy_Down -- Flag occupation of specified cell. * - * CellClass::Occupy_Unit -- Marks cell as unit occupied. * - * CellClass::Occupy_Up -- Removes occupation flag from the specified cell. * - * CellClass::Overlap_Down -- This routine is used to mark a cell as being spilled over (overla* - * CellClass::Overlap_Unit -- Marks cell as being overlapped by unit. * - * CellClass::Overlap_Up -- Removes overlap flag for the cell. * - * CellClass::Read -- Reads a particular cell value from a save game file. * - * CellClass::Recalc_Attributes -- Recalculates the ground type attributes for the cell. * - * CellClass::Redraw_Objects -- Redraws all objects overlapping this cell. * - * CellClass::Reduce_Tiberium -- Reduces the tiberium in the cell by the amount specified. * - * CellClass::Reduce_Wall -- Damages a wall, if damage is high enough. * - * CellClass::Reserve_Cell -- Marks a cell as being occupied by the specified unit ID. * - * CellClass::Shimmer -- Causes all objects in the cell to shimmer. * - * CellClass::Spot_Index -- returns cell sub-coord index for given COORD * - * CellClass::Tiberium_Adjust -- Adjust the look of the Tiberium for smooth. * - * CellClass::Validate -- validates cell's number * - * CellClass::Wall_Update -- Updates the imagery for wall objects in cell. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** New sidebar for GlyphX multiplayer. ST - 3/26/2019 12:24PM -*/ -#include "SidebarGlyphx.h" - -#define FIXUP 0 - - -/*********************************************************************************************** - * CellClass::Validate -- validates cell's number * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int CellClass::Validate(void) const -{ - int num; - - num = Cell_Number(); - if (num < 0 || num > 4095) { - Validate_Error("CELL"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * CellClass::CellClass -- Constructor for cell objects. * - * * - * A cell object is constructed into an empty state. It contains no specific objects, * - * templates, or overlays. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/09/1994 JLB : Created. * - *=============================================================================================*/ -CellClass::CellClass(void) -{ - memset(this, 0, sizeof(CellClass)); - Overlay = OVERLAY_NONE; - Smudge = SMUDGE_NONE; - TType = TEMPLATE_NONE; - Owner = HOUSE_NONE; - InfType = HOUSE_NONE; - OverrideLand = LAND_COUNT; -} - - -/*********************************************************************************************** - * CellClass::Cell_Color -- Determine what radar color to use for this cell. * - * * - * Use this routine to determine what radar color to render a radar * - * pixel with. This routine is called many many times to render the * - * radar map, so it must be fast. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the color to display the radar pixel with. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/01/1994 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - * 05/31/1994 JLB : Takes into account any stealth characteristics of object. * - *=============================================================================================*/ -int CellClass::Cell_Color(bool override) const -{ - Validate(); - BuildingClass * object = Cell_Building(); - if (object) { - return(object->House->Class->Color); - } - - if (override) { - return(TBLACK); - } - return(::Ground[Land_Type()].Color); -} - - -/*********************************************************************************************** - * CellClass::Cell_Techno -- Return with the unit/building at specified cell. * - * * - * Returns an object located in the cell. If there is a * - * building present, it returns a pointer to that, otherwise it returns * - * a pointer to one of the units there. If nothing is present in the * - * specified cell, then it returns NULL. * - * * - * INPUT: x,y -- Coordinate offset (from upper left corner) to use as an aid in selecting * - * the desired object within the cell. * - * * - * OUTPUT: Returns a pointer to a building or unit located in cell. If * - * nothing present, just returns NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - *=============================================================================================*/ -TechnoClass * CellClass::Cell_Techno(int x, int y) const -{ - Validate(); - ObjectClass * object; - COORDINATE click; // Coordinate of click relative to cell corner. - TechnoClass * close = NULL; - long distance = 0; // Recorded closest distance. - - /* - ** Create a coordinate value that represent the pixel location within the cell. This is - ** actually the lower significant bits (leptons) of a regular coordinate value. - */ - click = XY_Coord(Pixel_To_Lepton(x), Pixel_To_Lepton(y)); - - if (Cell_Occupier()) { - object = Cell_Occupier(); - while (object && object->IsActive) { - if (object->Is_Techno()) { - COORDINATE coord; // Coordinate relative to cell corner. - long dist; - - coord = object->Center_Coord() & 0x00FF00FFL; - dist = Distance(coord, click); - if (!close || dist < distance) { - close = (TechnoClass *)object; - distance = dist; - } - } - object = object->Next; - } - } - return(close); -} - - -/*************************************************************************** - * CellClass::Cell_Find_Object -- Returns ptr to RTTI type occupying cell * - * * - * INPUT: RTTIType the RTTI type we are searching for * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/17/1995 PWG : Created. * - * 06/12/1995 JLB : Returns object class pointer. * - *=========================================================================*/ -ObjectClass * CellClass::Cell_Find_Object(RTTIType rtti) const -{ - Validate(); - ObjectClass * object = Cell_Occupier(); - - while (object && object->IsActive) { - if (object->What_Am_I() == rtti) { - return(object); - } - object = object->Next; - } - return(NULL); -} - - -/*********************************************************************************************** - * CellClass::Cell_Building -- Return with building at specified cell. * - * * - * Given a cell, determine if there is a building associated * - * and return with a pointer to this building. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the building associated with the * - * cell. If there is no building associated, then NULL is * - * returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - *=============================================================================================*/ -BuildingClass * CellClass::Cell_Building(void) const -{ - Validate(); - return((BuildingClass *)Cell_Find_Object(RTTI_BUILDING)); -} - - -/*********************************************************************************************** - * CellClass::Cell_Terrain -- Determines terrain object in cell. * - * * - * This routine is used to determine the terrain object (if any) that * - * overlaps this cell. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the terrain object that overlaps * - * this cell. If there is no terrain object present, then NULL * - * is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1994 JLB : Created. * - *=============================================================================================*/ -TerrainClass * CellClass::Cell_Terrain(void) const -{ - Validate(); - return((TerrainClass *)Cell_Find_Object(RTTI_TERRAIN)); -} - - -/*********************************************************************************************** - * CellClass::Cell_Object -- Returns with clickable object in cell. * - * * - * This routine is used to determine which object is to be selected * - * by a player click upon the cell. Not all objects that overlap the * - * cell are selectable by the player. This routine sorts out which * - * is which and returns with the appropriate object pointer. * - * * - * INPUT: x,y -- Coordinate (from upper left corner of cell) to use as a guide when * - * selecting the object within the cell. This plays a role in those cases * - * where several objects (such as infantry) exist within the same cell. * - * * - * OUTPUT: Returns with pointer to the object clickable within the * - * cell. NULL is returned if there is no clickable object * - * present. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/13/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * CellClass::Cell_Object(int x, int y) const -{ - Validate(); - ObjectClass * ptr; - - /* - ** Hack so that aircraft landed on helipads can still be selected if directly - ** clicked on. - */ - ptr = (ObjectClass *)Cell_Find_Object(RTTI_AIRCRAFT); - if (ptr) { - return(ptr); - } - - ptr = Cell_Techno(x, y); - if (ptr) { - return(ptr); - } - ptr = Cell_Terrain(); - if (ptr) return(ptr); - return(ptr); -} - - -/*********************************************************************************************** - * CellClass::Redraw_Objects -- Redraws all objects overlapping this cell. * - * * - * This is a low level routine that marks all objects that overlap this * - * cell to be redrawn. It is necessary to call this routine whenever * - * the underlying icon has to be redrawn. * - * * - * INPUT: forced -- Should this redraw be forced even if flags * - * indicate that it would be redundant? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1994 JLB : Created. * - * 06/20/1994 JLB : Simplified to use object pointers. * - * 12/24/1994 JLB : Only checks if cell is in view and not flagged already. * - *=============================================================================================*/ -void CellClass::Redraw_Objects(bool forced) -{ - Validate(); - CELL cell = Cell_Number(); - - if (Map.In_View(cell) && (forced || !Map.Is_Cell_Flagged(cell))) { - - /* - ** Flag the icon to be redrawn. - */ - Map.Flag_Cell(cell); - - /* - ** Flag the main object in the cell to be redrawn. - */ - if (Cell_Occupier()) { - ObjectClass * optr = Cell_Occupier(); - while (optr) { - optr->Mark(MARK_CHANGE); - optr = optr->Next; - } - } - - /* - ** Flag any overlapping object in this cell to be redrawn. - */ - for (int index = 0; index < sizeof(Overlapper)/sizeof(Overlapper[0]); index++) { - if (Overlapper[index]) { - if (!Overlapper[index]->IsActive) { - Overlapper[index] = 0; - } else { - Overlapper[index]->Mark(MARK_CHANGE); - } - } - } - } -} - - -/*********************************************************************************************** - * CellClass::Is_Generally_Clear -- Determines if cell can be built upon. * - * * - * This determines if the cell can become a proper foundation for * - * building placement. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Can the cell be built upon? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1994 JLB : Created. * - *=============================================================================================*/ -bool CellClass::Is_Generally_Clear(bool ignore_cloaked) const -{ - Validate(); - if (ScenarioInit) return(true); - if (Flag.Composite || IsFlagged || Cell_Occupier()) { - if (!ignore_cloaked || (Cell_Occupier() && Cell_Occupier()->Is_Techno() && ((TechnoClass *)Cell_Occupier())->Cloak != CLOAKED)) { - return(false); - } - } - if (Smudge != SMUDGE_NONE && SmudgeTypeClass::As_Reference(Smudge).IsBib && Owner != HOUSE_NONE) { - return(false); - } - if (Overlay != OVERLAY_NONE && (Overlay == OVERLAY_FLAG_SPOT || OverlayTypeClass::As_Reference(Overlay).IsWall)) { - return(false); - } - -#ifdef ADVANCED - /* - ** Building certain kinds of terrain is prohibited -- bridges in particular. - */ - switch (TType) { - case TEMPLATE_BRIDGE1: - case TEMPLATE_BRIDGE1D: - case TEMPLATE_BRIDGE2: - case TEMPLATE_BRIDGE2D: - case TEMPLATE_BRIDGE3: - case TEMPLATE_BRIDGE3D: - case TEMPLATE_BRIDGE4: - case TEMPLATE_BRIDGE4D: - case TEMPLATE_FORD1: - case TEMPLATE_FORD2: - return(false); - - default: - break; - } -#endif - - return(::Ground[Land_Type()].Build); -} - - -/*********************************************************************************************** - * CellClass::Recalc_Attributes -- Recalculates the ground type attributes for the cell. * - * * - * This routine recalculates the ground type in the cell. The speeds the find path * - * algorithm and other determinations of the cell type. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/29/1994 JLB : Created. * - * 06/20/1994 JLB : Knows about template pointer in cell object. * - *=============================================================================================*/ -void CellClass::Recalc_Attributes(void) -{ - Validate(); - /* - ** Check for wall effects. - */ - if (Overlay != OVERLAY_NONE) { - Land = OverlayTypeClass::As_Reference(Overlay).Land; - if (Land != LAND_CLEAR) return; - } - - /* - ** If there is a template associated with this cell, then scan - ** through the template exception list checking to see if this cell - ** is one of the exception types. If it is, then return that ground type, - ** otherwise return the template's default type. - */ - if (TType != TEMPLATE_NONE) { - TemplateTypeClass const *ttype = &TemplateTypeClass::As_Reference(TType); - - /* - ** If there is an exception type list for the icons of this template, then - ** find out if the current icon is one of them. If so, apply the exception - ** ground type to the cell. - */ - char const *ptr = ttype->AltIcons; - if (ptr) { - int icon = TIcon; - - while (*ptr != -1) { - if (icon == *ptr++) { - Land = ttype->AltLand; - return; - } - } - } - - /* - ** No exception found, so just return the default ground type for this template. - */ - Land = ttype->Land; - return; - } - - /* - ** No template is the same as clear terrain. - */ - Land = TemplateTypeClass::As_Reference(TEMPLATE_CLEAR1).Land; -} - - -/*********************************************************************************************** - * CellClass::Occupy_Down -- Flag occupation of specified cell. * - * * - * This routine is used to mark the cell as being occupied by the specified object. * - * * - * INPUT: object -- The object that is to occupy the cell * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - * 11/29/1994 JLB : Simplified. * - *=============================================================================================*/ -void CellClass::Occupy_Down(ObjectClass * object) -{ - Validate(); - ObjectClass * optr; - - /* - ** If the specified object is already part of the occupation list, then don't add - ** it again -- bail instead. - */ - if (Cell_Occupier()) { - optr = Cell_Occupier(); - while (optr) { - if (optr == object) { - return; - } - if (!optr->Next) break; - optr = optr->Next; - } - } - optr = Cell_Occupier(); - object->Next = optr; - - OccupierPtr = object; - Map.Radar_Pixel(Cell_Number()); - - /* - ** If being placed down on a visible square, then flag this - ** techno object as being revealed to the player. - */ - // Changes for GlyphX multiplayer. ST - 4/17/2019 3:02PM - //if (IsVisible || GameToPlay != GAME_NORMAL) { - // object->Revealed(PlayerPtr); - //} - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER) { - if (IsVisible || GameToPlay != GAME_NORMAL) { - object->Revealed(PlayerPtr); - } - } else { - - for (int i = 0; i < MPlayerCount; i++) { - HousesType house_type = MPlayerHouses[i]; - if (Is_Visible(house_type)) { - HouseClass *house = HouseClass::As_Pointer(house_type); - object->Revealed(house); - } - } - } - - /* - ** Special occupy bit set. - */ - switch (object->What_Am_I()) { - case RTTI_BUILDING: - Flag.Occupy.Building = true; - break; - - case RTTI_AIRCRAFT: - case RTTI_UNIT: - Flag.Occupy.Vehicle = true; - break; - - case RTTI_TERRAIN: - Flag.Occupy.Monolith = true; - break; - - default: - break; - } -} - - -/*********************************************************************************************** - * CellClass::Occupy_Up -- Removes occupation flag from the specified cell. * - * * - * This routine will lift the object from the cell and free the cell to be occupied by * - * another object. Only if the cell was previously marked with the object specified, will * - * the object be lifted off. This routine is the counterpart to Occupy_Down(). * - * * - * INPUT: object -- The object that is being lifted off. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - * 11/29/1994 JLB : Fixed to handle next pointer in previous object. * - *=============================================================================================*/ -void CellClass::Occupy_Up(ObjectClass * object) -{ - Validate(); - ObjectClass * optr = NULL; // Working pointer to the objects in the chain. - - if (Cell_Occupier()) { - optr = Cell_Occupier(); - } - if (optr == object) { - OccupierPtr = object->Next; - object->Next = 0; - } else { - while (optr) { - if (optr->Next == object) { - optr->Next = object->Next; - object->Next = 0; - break; - } - if (!optr->Next) break; - optr = optr->Next; - } - } - Map.Radar_Pixel(Cell_Number()); - - /* - ** Special occupy bit clear. - */ - switch (object->What_Am_I()) { - case RTTI_BUILDING: - Flag.Occupy.Building = false; - break; - - case RTTI_AIRCRAFT: - case RTTI_UNIT: - Flag.Occupy.Vehicle = false; -#ifdef NEVER - int x,y; - if (Map.Coord_To_Pixel(Cell_Coord(), x, y)) { - SeenBuff.Put_Pixel(x, y, BLUE); - } -#endif - break; - - case RTTI_TERRAIN: - Flag.Occupy.Monolith = false; - break; - - default: - break; - } -} - - -/*********************************************************************************************** - * CellClass::Overlap_Down -- This routine is used to mark a cell as being spilled over (overla* - * * - * Most game objects can often have their graphic imagery spill into more than one cell * - * even though they are considered to "occupy" only one cell. All cells overlapped are * - * flagged by this routine. Using this information it is possible to keep the tactical map * - * display correct. * - * * - * INPUT: object -- The object to mark as overlapping this cell. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - * 07/04/1995 JLB : Ensures that buildings are always marked down. * - *=============================================================================================*/ -void CellClass::Overlap_Down(ObjectClass * object) -{ - Validate(); - ObjectClass **ptr = 0; - - if (!object) return; - int index; - for (index = 0; index < sizeof(Overlapper)/sizeof(Overlapper[0]); index++) { - if (Overlapper[index] == object) return; - if (!Overlapper[index]) ptr = &Overlapper[index]; - } - - /* - ** Buildings must ALWAYS succeed in marking the cell as overlapped. Bump somebody - ** else out in this case. - */ - if (!ptr && object->What_Am_I() == RTTI_BUILDING) { - for (index = 0; index < sizeof(Overlapper)/sizeof(Overlapper[0]); index++) { - switch (Overlapper[index]->What_Am_I()) { - case RTTI_BUILDING: - case RTTI_TERRAIN: - break; - - default: - Overlapper[index] = object; - index = sizeof(Overlapper)/sizeof(Overlapper[0]); - break; - } - } - } - if (ptr) *ptr = object; - - /* - ** If being placed down on a visible square, then flag this - ** techno object as being revealed to the player. - */ - // Changes for GlyphX multiplayer. ST - 4/18/2019 9:50AM - //if (IsVisible) { - // object->Revealed(PlayerPtr); - //} - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER) { - if (IsVisible) { - object->Revealed(PlayerPtr); - } - } else { - - if (object->Is_Techno()) { - TechnoClass *tech = static_cast(object); - object->Revealed(tech->House); - } else { - - for (int i = 0; i < MPlayerCount; i++) { - HousesType house_type = MPlayerHouses[i]; - HouseClass *house = HouseClass::As_Pointer(house_type); - object->Revealed(house); - } - } - } -} - - -/*********************************************************************************************** - * CellClass::Overlap_Up -- Removes overlap flag for the cell. * - * * - * This is the counterpart to Overlap_Down and is used to remove the overlap flag for the * - * specified unit on the cell. * - * * - * INPUT: object -- The object to remove the overlap flag for. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -void CellClass::Overlap_Up(ObjectClass *object) -{ - Validate(); - for (int index = 0; index < sizeof(Overlapper)/sizeof(Overlapper[0]); index++) { - if (Overlapper[index] == object) { - Overlapper[index] = 0; - break; - } - } - - //Map.Validate(); -} - - -/*********************************************************************************************** - * CellClass::Cell_Unit -- Returns with pointer to unit occupying cell. * - * * - * This routine will determine if a unit is occupying the cell and if so, return a pointer * - * to it. If there is no unit occupying the cell, then NULL is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with pointer to unit occupying cell, else NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -UnitClass * CellClass::Cell_Unit(void) const -{ - Validate(); - return((UnitClass*)Cell_Find_Object(RTTI_UNIT)); -} - - -/*********************************************************************************************** - * CellClass::Cell_Infantry -- Returns with pointer of first infantry unit occupying the cell. * - * * - * This routine examines the cell and returns a pointer to the first infantry unit * - * that occupies it. If there is no infantry unit in the cell, then NULL is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with pointer to infantry unit occupying the cell or NULL if none are * - * present. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/21/1994 JLB : Created. * - *=============================================================================================*/ -InfantryClass * CellClass::Cell_Infantry(void) const -{ - Validate(); - return((InfantryClass*)Cell_Find_Object(RTTI_INFANTRY)); -} - - - -/*********************************************************************************************** - * CellClass::Get_Template_Info -- Get some info about a template for external use * - * * - * * - * * - * * - * INPUT: Ref to info required * - * * - * OUTPUT: True if image info available * - * * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 1/10/2019 5:57PM ST : Created. * - *=============================================================================================*/ -bool CellClass::Get_Template_Info(char *template_name, int &icon, void *&image_data) -{ - TemplateTypeClass const *ttype = NULL; - - if (TType != TEMPLATE_NONE) { - ttype = &TemplateTypeClass::As_Reference(TType); - icon = TIcon; - } else { - ttype = &TemplateTypeClass::As_Reference(TEMPLATE_CLEAR1); - icon = Clear_Icon(); - } - - if (ttype) { - - strcpy(template_name, ttype->IniName); - image_data = (void*) ttype->ImageData; - - return true; - } - - return false; -} - - - - -/*********************************************************************************************** - * CellClass::Draw_It -- Draws the cell imagery at the location specified. * - * * - * This is the gruntwork cell rendering code. It draws the cell at the screen location * - * specified. This routine doesn't draw any overlapping or occupying units. It only * - * deals with the ground (cell) layer -- icon level. * - * * - * INPUT: x,y -- The screen coordinates to render the cell imagery at. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - * 08/21/1994 JLB : Revised for simple template objects. * - * 11/01/1994 BRR : Updated placement cursor; draws actual object * - * 11/14/1994 BRR : Added remapping code to show passable areas * - * 12/02/1994 BRR : Added trigger display * - * 12/11/1994 JLB : Mixes up clear terrain through pseudo-random table. * - * 04/25/1995 JLB : Smudges drawn BELOW overlays. * - *=============================================================================================*/ -void CellClass::Draw_It(int x, int y, int draw_type) const -{ - Validate(); - TemplateTypeClass const *ttype = 0; - int icon; // The icon number to use from the template set. - CELL cell = Cell_Number(); - void * remap = NULL; -#ifdef SCENARIO_EDITOR - TemplateTypeClass * tptr; - TriggerClass * trig; - int i; - char waypt[2]; -#endif - - /* - ** Fetch a pointer to the template type associated with this cell. - */ - if (TType != TEMPLATE_NONE) { - ttype = &TemplateTypeClass::As_Reference(TType); - icon = TIcon; - } else { - ttype = &TemplateTypeClass::As_Reference(TEMPLATE_CLEAR1); - icon = Clear_Icon(); - } - - - /* - ** Draw the stamp of the template. - */ - if (Debug_Icon) { - LogicPage->Fill_Rect(Map.TacPixelX+x, Map.TacPixelY+y, Map.TacPixelX+x+ICON_PIXEL_W-1, Map.TacPixelY+y+ICON_PIXEL_H-1, Sim_Random_Pick(1, 254)); - FontXSpacing -= 2; - Fancy_Text_Print("%d\r%2X%c\r%02X.%02X", Map.TacPixelX+x+(ICON_PIXEL_W>>1), Map.TacPixelY+y, WHITE, TBLACK, TPF_6POINT|TPF_NOSHADOW|TPF_CENTER, cell, Flag.Composite, (Cell_Occupier() ? '*' : ' '), Overlay, OverlayData); - FontXSpacing += 2; - } else { - - - if (!draw_type || draw_type == CELL_BLIT_ONLY){ - - -#ifdef SCENARIO_EDITOR - /* - ** Set up the remap table for this icon. - */ - if (Debug_Map && Debug_Passable) { - if (::Ground[Land].Cost[0] == 0 || (Cell_Occupier() != NULL && - Cell_Occupier()->What_Am_I() != RTTI_INFANTRY)) { // impassable - remap = Map.FadingRed; - } else { - if (::Ground[Land].Cost[0] > 0x70) { // pretty passable - remap = Map.FadingGreen; - } else { - remap = Map.FadingYellow; // moderately passable - } - } - } -#endif - - // ****** maybe this icon shouldn't be drawn if it is known that the cell will be covered - // with shadow. - /* - ** This is the underlying terrain icon. - */ - if (ttype->Get_Image_Data()) { - LogicPage->Draw_Stamp(ttype->Get_Image_Data(), icon, x, y, NULL, WINDOW_TACTICAL); - if (remap) { - LogicPage->Remap(x+Map.TacPixelX, y+Map.TacPixelY, ICON_PIXEL_W, ICON_PIXEL_H, remap); - } - } - - -#ifdef SCENARIO_EDITOR - /* - ** Draw the map editor's "current" cell. This is the cell that can be - ** assigned attributes such as tag labels. - ** This must be draw before the placement cursor, but after drawing the - ** objects in the cell. - */ - if (Debug_Map && CurrentCell == Cell_Number()) { - LogicPage->Draw_Rect(x+Map.TacPixelX, y+Map.TacPixelY, Map.TacPixelX + x + CELL_PIXEL_W - 1, Map.TacPixelY + y + CELL_PIXEL_H - 1, YELLOW); - } -#endif - -#ifdef NEVER - /* - ** Special concrete render. It always renders over the underlying - ** terrain unless this concrete piece will cover the entire terrain - ** piece. - */ - if (Concrete) { - LogicPage->Draw_Stamp(TemplateTypeClass::As_Pointer(TEMPLATE_CONCRETE_GDI)->Get_Image_Data(), Concrete-1, x, y, NULL, WINDOW_TACTICAL); - } -#endif - } - - /* - ** Redraw any smudge. - */ - if (Smudge != SMUDGE_NONE) { -#ifdef NEVER - switch (Smudge) { - case SMUDGE_BIB1: - CC_Draw_Shape(Bib1, SmudgeData, x, y, WINDOW_TACTICAL, SHAPE_WIN_REL); - break; - - case SMUDGE_BIB2: - CC_Draw_Shape(Bib2, SmudgeData, x, y, WINDOW_TACTICAL, SHAPE_WIN_REL); - break; - - case SMUDGE_BIB3: - CC_Draw_Shape(Bib3, SmudgeData, x, y, WINDOW_TACTICAL, SHAPE_WIN_REL); - break; - } -#endif - SmudgeTypeClass::As_Reference(Smudge).Draw_It(x, y, SmudgeData); - } - - - if (!draw_type || draw_type == CELL_DRAW_ONLY){ - - /* - ** Draw the overlay object. - */ - if (Overlay != OVERLAY_NONE) { - OverlayTypeClass const & otype = OverlayTypeClass::As_Reference(Overlay); - IsTheaterShape = (bool)otype.IsTheater; - CC_Draw_Shape(otype.Get_Image_Data(), OverlayData, (x+(CELL_PIXEL_W>>1)), (y+(CELL_PIXEL_H>>1)), WINDOW_TACTICAL, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST, NULL, Map.UnitShadow); - IsTheaterShape = false; - } - - #ifdef SCENARIO_EDITOR - if (Debug_Map) { - /* - ** Draw the cell's Trigger mnemonic, if it has a trigger - */ - if (IsTrigger) { - trig = Get_Trigger(); - Fancy_Text_Print(trig->Get_Name(), x+Map.TacPixelX, y+Map.TacPixelY, PINK, TBLACK, TPF_NOSHADOW|TPF_6POINT); - } - - /* - ** Draw the cell's Waypoint designation if there is one. - */ - if (IsWaypoint) { - for (i = 0; i < 26; i++) { - if (Waypoint[i]==Cell_Number()) { - waypt[0] = 'A' + i; - waypt[1] = 0; - Fancy_Text_Print(waypt, Map.TacPixelX + x + CELL_PIXEL_W / 2, - Map.TacPixelY + y + (CELL_PIXEL_H / 2) - 3, YELLOW, TBLACK, - TPF_NOSHADOW | TPF_6POINT | TPF_CENTER); - break; - } - } - if (Waypoint[WAYPT_HOME] == Cell_Number()) { - Fancy_Text_Print("Home", Map.TacPixelX + x, Map.TacPixelY + y + (CELL_PIXEL_H) - 7, - WHITE, TBLACK, TPF_NOSHADOW | TPF_6POINT); - } - if (Waypoint[WAYPT_REINF] == Cell_Number()) { - Fancy_Text_Print("Reinf", Map.TacPixelX + x, Map.TacPixelY + y + (CELL_PIXEL_H) - 7, - WHITE, TBLACK, TPF_NOSHADOW | TPF_6POINT); - } - } - } - #endif - - /* - ** Draw the placement cursor: - ** - First, draw the hash-mark cursor, so it will appear underneath - ** any cursor being drawn - ** - If the PendingObject is a template, overlay, or smudge, draw it - ** - Otherwise, it's up to the Display.Refresh_Map() routine to draw it - */ - if (IsCursorHere) { - - /* - ** Draw the hash-mark cursor: - */ - if (Map.ProximityCheck && Is_Generally_Clear()) { - LogicPage->Draw_Stamp(Map.TransIconset, 0, x, y, NULL, WINDOW_TACTICAL); - } else { - LogicPage->Draw_Stamp(Map.TransIconset, 2, x, y, NULL, WINDOW_TACTICAL); - } - - #ifdef SCENARIO_EDITOR - if (Debug_Map && Map.PendingObject) { - - switch (Map.PendingObject->What_Am_I()) { - - /* - ** Draw a template: - ** - Compute the icon offset of this cell for this template, using - ** ZoneCell+ZoneOffset to get the upper-left corner of the placement - ** cursor - ** - Draw the icon - */ - case RTTI_TEMPLATETYPE: - tptr = (TemplateTypeClass *)Map.PendingObject; - if (tptr->Get_Image_Data()) { - icon = (Cell_X(cell) - Cell_X(Map.ZoneCell + Map.ZoneOffset)) + - (Cell_Y(cell) - Cell_Y(Map.ZoneCell + Map.ZoneOffset)) * - tptr->Width; - LogicPage->Draw_Stamp(tptr->Get_Image_Data(), icon, x, y, NULL, WINDOW_TACTICAL); - } - break; - - /* - ** Draw an overlay; just use the existing 'OverlayData' even though - ** it means nothing. - */ - case RTTI_OVERLAYTYPE: - OverlayTypeClass::As_Reference(((OverlayTypeClass *)Map.PendingObject)->Type).Draw_It(x, y, OverlayData); - break; - - /* - ** Draw a smudge - */ - case RTTI_SMUDGETYPE: - SmudgeTypeClass::As_Reference(((SmudgeTypeClass *)Map.PendingObject)->Type).Draw_It(x, y, 0); - break; - } - } - #endif - } - } - } -} - - -/*********************************************************************************************** - * CellClass::Concrete_Calc -- Calculates the concrete icon to use for the cell. * - * * - * This routine examines the cells around the current one and from this, determines what * - * concrete icon shape to use (if any). The cell data is adjusted and the cell is marked * - * for redraw if the icon changed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/01/1994 JLB : Created. * - *=============================================================================================*/ -void CellClass::Concrete_Calc(void) -{ - Validate(); - static FacingType _even[5] = {FACING_N, FACING_S, FACING_SW, FACING_W, FACING_NW}; - static FacingType _odd[5] = {FACING_N, FACING_NE, FACING_E, FACING_SE, FACING_S}; - FacingType *ptr; // Working pointer into adjacent cell list. - int index; // Constructed bit index. - int icon; // Icon number. - bool isodd; // Is this for the odd column? - -#define OF_N 0x01 -#define OF_NE 0x02 -#define OF_E 0x04 -#define OF_SE 0x08 -#define OF_S 0x10 - -#define EF_N 0x01 -#define EF_NW 0x10 -#define EF_W 0x08 -#define EF_SW 0x04 -#define EF_S 0x02 - - /* - ** Determine if the even or odd row logic is necessary. - */ - isodd = ((Cell_Number() & 0x01) != 0); - - /* - ** Fetch correct pointer depending on whether this is for an - ** odd or even row. - */ - ptr = (isodd) ? _odd : _even; - - /* - ** Build an index according to the presence of concrete in the special - ** adjacent cells. This is a short list of adjacent cell flags since - ** only 5 adjacent cells need to be examined. The choice of which 5 - ** depends on whether this is for an even or odd column. - */ - index = 0; - for (int i = 0; i < (sizeof(_even)/sizeof(_even[0])); i++) { - CellClass * cellptr = Adjacent_Cell(*ptr++); - -// if ((cellptr->IsConcrete) || -// cellptr->Concrete == C_UPDOWN_RIGHT || -// cellptr->Concrete == C_UPDOWN_LEFT) { - - if (cellptr && cellptr->Overlay == OVERLAY_CONCRETE) { - index |= (1<Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(newcell->Overlay).IsWall) { - int icon = 0; - - /* - ** Build the icon number according to walls located in the adjacent - ** cells. - */ - for (unsigned i = 0; i < 4; i++) { - CellClass * adjcell = newcell->Adjacent_Cell(_offsets[i]); - if (adjcell && adjcell->Overlay == newcell->Overlay) { - icon |= 1 << i; - } - } - newcell->OverlayData = (newcell->OverlayData & 0xFFF0) | icon; -// newcell->OverlayData = icon; - - /* - ** Handle special cases for the incomplete damaged wall sets. If a damage stage - ** is calculated, but there is no artwork for it, then consider the wall to be - ** completely destroyed. - */ - if (newcell->Overlay == OVERLAY_BRICK_WALL && newcell->OverlayData == 48) { - newcell->Overlay = OVERLAY_NONE; - newcell->OverlayData = 0; - ObjectClass::Detach_This_From_All(::As_Target(newcell->Cell_Number()), true); - } - if (newcell->Overlay == OVERLAY_SANDBAG_WALL && newcell->OverlayData == 16) { - newcell->Overlay = OVERLAY_NONE; - newcell->OverlayData = 0; - ObjectClass::Detach_This_From_All(::As_Target(newcell->Cell_Number()), true); - } - if (newcell->Overlay == OVERLAY_CYCLONE_WALL && newcell->OverlayData == 32) { - newcell->Overlay = OVERLAY_NONE; - newcell->OverlayData = 0; - ObjectClass::Detach_This_From_All(::As_Target(newcell->Cell_Number()), true); - } - if (newcell->Overlay == OVERLAY_BARBWIRE_WALL && newcell->OverlayData == 16) { - newcell->Overlay = OVERLAY_NONE; - newcell->OverlayData = 0; - ObjectClass::Detach_This_From_All(::As_Target(newcell->Cell_Number()), true); - } - - newcell->Recalc_Attributes(); - newcell->Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * CellClass::Cell_Coord -- Returns the coordinate of this cell. * - * * - * This support function will determine the coordinate of this cell and return it. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with coordinate value of cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE CellClass::Cell_Coord(void) const -{ - Validate(); - return(::Cell_Coord(Cell_Number())); -} - - -/*********************************************************************************************** - * CellClass::Reduce_Tiberium -- Reduces the tiberium in the cell by the amount specified. * - * * - * This routine will lower the tiberium level in the cell. It is used by the harvesting * - * process as well as by combat damage to the tiberium fields. * - * * - * INPUT: levels -- The number of levels to reduce the tiberium. * - * * - * OUTPUT: bool; Was the tiberium level reduced by at least one level? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -int CellClass::Reduce_Tiberium(int levels) -{ - Validate(); - int reducer = 0; - - if (levels && Land == LAND_TIBERIUM) { - if (OverlayData > levels) { - OverlayData -= levels; - reducer = levels; - } else { - Overlay = OVERLAY_NONE; - reducer = OverlayData; - OverlayData = 0; - Recalc_Attributes(); - } - } - return(reducer); -} - - -/*********************************************************************************************** - * CellClass::Reduce_Wall -- Damages a wall, if damage is high enough. * - * * - * This routine will change the wall shape used for a wall if it's damaged. * - * * - * * - * INPUT: damage -- The number of damage points the wall was hit with. * - * * - * OUTPUT: bool; Was the wall destroyed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BWG : Created. * - * 03/19/1995 JLB : Updates cell information if wall was destroyed. * - *=============================================================================================*/ -int CellClass::Reduce_Wall(int damage) -{ - Validate(); - if (Overlay != OVERLAY_NONE) { - bool destroyed = false; - OverlayTypeClass const & wall = OverlayTypeClass::As_Reference(Overlay); - - if (wall.IsWall) { - - /* - ** If the damage was great enough to ensure wall destruction, reduce the wall by one - ** level (no more). Otherwise determine wall reduction based on a percentage chance - ** proportional to the damage received and the wall's strength. - */ - if (damage >= wall.DamagePoints) { - destroyed = true; - } else { - destroyed = Random_Pick(0, wall.DamagePoints) < damage; - } - - if (destroyed) { - OverlayData+=16; - if ((OverlayData>>4) >= wall.DamageLevels) { - ObjectClass::Detach_This_From_All(As_Target()); - Owner = HOUSE_NONE; - Overlay = OVERLAY_NONE; - OverlayData = 0; - Recalc_Attributes(); - Redraw_Objects(); - CellClass * ncell = Adjacent_Cell(FACING_N); - if (ncell) ncell->Wall_Update(); - CellClass * wcell = Adjacent_Cell(FACING_W); - if (wcell) wcell->Wall_Update(); - CellClass * scell = Adjacent_Cell(FACING_S); - if (scell) scell->Wall_Update(); - CellClass * ecell = Adjacent_Cell(FACING_E); - if (ecell) ecell->Wall_Update(); - return(true); - } - } - } - } - return(false); -} - - -/*********************************************************************************************** - * CellClass::Get_Trigger -- retrieves reference to the cell's trigger * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * TriggerClass reference * - * * - * WARNINGS: * - * Never call this function unless the IsTrigger flag is set for the cell! * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=============================================================================================*/ -TriggerClass * CellClass::Get_Trigger(void) const -{ - Validate(); - if (IsTrigger) { - return(CellTriggers[Cell_Number()]); - } - return(NULL); -} - - -/*********************************************************************************************** - * CellClass::Spot_Index -- returns cell sub-coord index for given COORD * - * * - * INPUT: * - * coord COORD to compute index for * - * * - * OUTPUT: * - * index into StoppingCoord that's closest to this coord * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1994 BR : Created. * - * 12/10/1994 JLB : Uses alternate sub-position algorithm. * - *=============================================================================================*/ -int CellClass::Spot_Index(COORDINATE coord) -{ - COORDINATE rel = coord & 0x00FF00FFL; // Sub coordinate value within cell. - - /* - ** If the coordinate is close enough to the center of the cell, then return - ** the center position index. - */ - if (Distance(rel, 0x00800080L) < 60) { - return(0); - } - - /* - ** Since the center cell position has been eliminated, a simple comparison - ** as related to the center of the cell can be used to determine the sub - ** position. Take advantage of the fact that the sub positions are organized - ** from left to right, top to bottom. - */ - int index = 0; - if (Coord_X(rel) > 0x80) index |= 0x01; - if (Coord_Y(rel) > 0x80) index |= 0x02; - return(index+1); -} - - -/*********************************************************************************************** - * CellClass::Closest_Free_Spot -- returns free spot closest to given coord * - * * - * Similar to the CellClass::Free_Spot; this routine finds the spot in * - * the cell closest to the given coordinate, and returns the COORD of * - * that spot if it's available, NULL if it's not. * - * * - * INPUT: * - * coord coordinate to check (only sub cell position examined) * - * * - * any -- If only the closest spot is desired regardless of whether it is free or * - * not, then this parameter will be true. * - * * - * OUTPUT: * - * COORD of free spot, NULL if none. The coordinate return value does not alter the cell * - * coordinate data portions of the coordinate passed in. Only the lower sub-cell * - * data is altered. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/08/1994 BR : Created. * - * 12/10/1994 JLB : Picks best of closest stopping positions. * - * 12/21/1994 JLB : Adds a mix-up factor if center location is occupied. * - *=============================================================================================*/ -COORDINATE CellClass::Closest_Free_Spot(COORDINATE coord, bool any) const -{ - Validate(); - int spot_index = Spot_Index(coord); - - /* - ** This precalculated sequence table records the closest spots to any given spot. Sequential - ** examination of these spots for availability ensures that the closes available one is - ** discovered first. - */ - static unsigned char _sequence[5][4] = { - {1,2,3,4}, - {0,2,3,4}, - {0,1,4,3}, - {0,1,4,2}, - {0,2,3,1} - }; - - /* - ** In the case of the center coordinate being requested, but is occupied, then all other - ** sublocations are equidistant. Instead of picking a static sequence of examination, the - ** order is mixed up by way of this table. - */ - static unsigned char _alternate[4][4] = { - {1,2,3,4}, - {2,3,4,1}, - {3,4,1,2}, - {4,1,2,3}, - }; - coord &= 0xFF00FF00L; - - /* - ** Cells occupied by buildings or vehicles don't have any free spots. - */ - if (!any && (Flag.Occupy.Vehicle || Flag.Occupy.Monolith)) { - return(NULL); - } - - /* - ** If just the nearest position is desired regardless of whether occupied or not, - ** then just return with the stopping coordinate value. - */ - if (any || Is_Spot_Free(spot_index)) { - return(Coord_Add(coord, StoppingCoordAbs[spot_index])); - } - - /* - ** Scan through all available sub-locations in the cell in order to determine - ** the closest one to the coordinate requested. Use precalculated table so that - ** when the first free position is found, bail. - */ - unsigned char *sequence; - if (spot_index == 0) { - sequence = &_alternate[Random_Pick(0,3)][0]; - } else { - sequence = &_sequence[spot_index][0]; - } - for (int index = 0; index < 4; index++) { - int pos = *sequence++; - - if (Is_Spot_Free(pos)) { - return(Coord_Add(coord, StoppingCoordAbs[pos])); - } - } - - /* - ** No free spot could be found so return a NULL coordinate. - */ - return(0x00000000L); -} - - -/*********************************************************************************************** - * CellClass::Clear_Icon -- Calculates what the clear icon number should be. * - * * - * This support routine will determine what the clear icon number would be for the cell. * - * The icon number is determined by converting the cell number into an index into a * - * lookup table. This yields what appears to be a randomized map without the necessity of * - * generating and recording randomized map numbers. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the icon number for clear terrain if it were displayed at the * - * cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - * 06/09/1995 JLB : Uses 16 entry scramble algorithm. * - *=============================================================================================*/ -int CellClass::Clear_Icon(void) const -{ - Validate(); - CELL cell = Cell_Number(); - return((cell & 0x03) | ((cell>>4) & 0x0C)); -} - - -/*********************************************************************************************** - * CellClass::Incoming -- Causes objects in cell to "run for cover". * - * * - * This routine is called whenever a great, but slow moving, threat is presented to the * - * occupants of a cell. The occupants will, in most cases, stop what they are doing and * - * try to get out of the way. * - * * - * INPUT: threat -- The coordinate source of the threat. * - * * - * forced -- If this threat is so major that the occupants should stop what * - * they are doing, then this parameter should be set to true. * - * * - * nokidding -- Override the scatter to also affect human controlled objects. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/10/1995 JLB : Created. * - *=============================================================================================*/ -void CellClass::Incoming(COORDINATE threat, bool forced, bool nokidding) -{ - Validate(); - ObjectClass * object = NULL; - - object = Cell_Occupier(); - while (object) { - - /* - ** Special check to make sure that friendly units never scatter. - */ - if (nokidding || Special.IsScatter || (object->Is_Techno() && !((TechnoClass *)object)->House->IsHuman)) { - if (object->What_Am_I() == RTTI_INFANTRY) { - object->Scatter(threat, forced, nokidding); - } else { - object->Scatter(threat, forced, nokidding); -// object->Scatter(threat, false); - } - } - object = object->Next; - } -} - - -/*********************************************************************************************** - * CellClass::Adjacent_Cell -- Determines the adjacent cell according to facing. * - * * - * Use this routine to return a reference to the adjacent cell in the direction specified. * - * * - * INPUT: face -- The direction to use when determining the adjacent cell. * - * * - * OUTPUT: Returns with a reference to the adjacent cell. * - * * - * WARNINGS: If the facing value is invalid, then a reference to the same cell is returned. * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -CellClass const * CellClass::Adjacent_Cell(FacingType face) const -{ - Validate(); - if (face == FACING_NONE) { - return(this); - } - - if ((unsigned)face >= FACING_COUNT) { - return(NULL); - } - - CELL newcell = ::Adjacent_Cell(Cell_Number(), face); - if ((unsigned)newcell >= MAP_CELL_TOTAL) { - return(NULL); - } - - return &Map[newcell]; -} - - -/*************************************************************************** - * CellClass::Adjust_Threat -- Allows adjustment of threat at cell level * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/24/1995 PWG : Created. * - *=========================================================================*/ -void CellClass::Adjust_Threat(HousesType house, int threat_value) -{ - Validate(); - int region = Map.Cell_Region(Cell_Number()); - - for (HousesType lp = HOUSE_FIRST; lp < HOUSE_COUNT; lp ++) { - if (lp == house) continue; - - HouseClass *house_ptr = HouseClass::As_Pointer(lp); - if (house_ptr && (!house_ptr->IsHuman || !house_ptr->Is_Ally(house))) { - house_ptr->Adjust_Threat(region, threat_value); - } - } - if (Debug_Threat) { - Map.Flag_To_Redraw(true); - } -} - - -/*********************************************************************************************** - * CellClass::Tiberium_Adjust -- Adjust the look of the Tiberium for smoothing purposes. * - * * - * This routine will adjust the level of the Tiberium in the cell so that it will * - * smoothly blend with the adjacent Tiberium. This routine should only be called for * - * new Tiberium cells. Existing cells that contain Tiberium follow a different growth * - * pattern. * - * * - * INPUT: pregame -- Is this a pregame call? Such a call will mixup the Tiberium overlay * - * used. * - * * - * OUTPUT: Returns with the added Tiberium value that is now available for harvesting. * - * * - * WARNINGS: The return value is only valid for the initial placement. Tiberium growth will * - * increase the net worth of the existing Tiberium. * - * * - * HISTORY: * - * 05/16/1995 JLB : Created. * - *=============================================================================================*/ -long CellClass::Tiberium_Adjust(bool pregame) -{ - Validate(); - if (Overlay != OVERLAY_NONE) { - if (OverlayTypeClass::As_Reference(Overlay).Land == LAND_TIBERIUM) { - static int _adj[9] = {0,1,3,4,6,7,8,10,11}; - int count = 0; - - /* - ** Mixup the Tiberium overlays so that they don't look the same. - */ - if (pregame) { - Overlay = Random_Pick(OVERLAY_TIBERIUM1, OVERLAY_TIBERIUM12); - } - - /* - ** Add up all adjacent cells that contain tiberium. - ** (Skip those cells which aren't on the map) - */ - for (FacingType face = FACING_FIRST; face < FACING_COUNT; face++) { - CELL cell = Cell_Number() + AdjacentCell[face]; - if ((unsigned)cell >= MAP_CELL_TOTAL) continue; - - CellClass * adj = Adjacent_Cell(face); - - if (adj && adj->Overlay != OVERLAY_NONE && - OverlayTypeClass::As_Reference(adj->Overlay).Land == LAND_TIBERIUM) { - count++; - } - } - - OverlayData = _adj[count]; - return((OverlayData+1) * UnitTypeClass::TIBERIUM_STEP); - } - } - return(0); -} - - -/*********************************************************************************************** - * CellClass::Goodie_Check -- Performs crate discovery logic. * - * * - * Call this routine whenever an object enters a cell. It will check for the existance * - * of a crate and generate any "goodie" it might contain. * - * * - * INPUT: object -- Pointer to the object that is triggering this crate. * - * * - * OUTPUT: Can the object continue to enter this cell? A false return value means that the * - * cell is now occupied and must not be entered. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - * 07/08/1995 JLB : Added a bunch of goodies to the crates. * - *=============================================================================================*/ -bool CellClass::Goodie_Check(FootClass * object) -{ - Validate(); - enum { - MONEY, // Cash award. - UNIT, // A free unit. - NUKE, // A nuclear device that explodes. - ION, // Calls forth an ion blast on discoverer. - NUKE_MISSILE, // Gets a one time nuclear missile options. - ION_BLAST, // Gets a one time ion blast option. - AIR_STRIKE, // Gets a one time air strike option. - HEAL_BASE, // Heals the player's entire base. - CLOAK, // Units in region gain cloak ability. - EXPLOSION, // Conventional explosion. - NAPALM, // A napalm explosion. - SQUAD, // A mixed squad of friendly infantry appear. - VISCEROID, // A visceroid appears! - DARKNESS, // Shroud the entire map. - REVEAL, // Reveal the entire map. - TOTAL_CRATES, - }; - static int _what[] = { - DARKNESS,DARKNESS, - REVEAL,REVEAL, - NUKE, -// ION,ION, - NUKE_MISSILE, - ION_BLAST,ION_BLAST, - AIR_STRIKE,AIR_STRIKE,AIR_STRIKE,AIR_STRIKE, - HEAL_BASE,HEAL_BASE, - CLOAK,CLOAK, - EXPLOSION,EXPLOSION,EXPLOSION,EXPLOSION, - NAPALM,NAPALM,NAPALM, - SQUAD,SQUAD,SQUAD,SQUAD,SQUAD, - UNIT,UNIT,UNIT,UNIT,UNIT, - VISCEROID - }; - - - /* - ** Crate types are only defined here so it needs to match my new global crate total ST - 6/4/96 2:16PM - */ -#if (TOTAL_CRATES) == (TOTAL_CRATE_TYPES) - -#else - //Huge_Errrrror..... Oh NO! - -#endif - - - if (object && Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(Overlay).IsCrate) { - bool steel = (Overlay == OVERLAY_STEEL_CRATE); - COORDINATE coord; // Temporary working coordinate value. - - /* - ** A triggered crate is automatically destroyed regardless of who or how - ** it was triggered. - */ - Redraw_Objects(); - Overlay = OVERLAY_NONE; - OverlayData = 0; - - if (steel) { - if (object->Owner() == HOUSE_BAD) { - object->House->Add_Nuke_Piece(); - new AnimClass(ANIM_CRATE_EMPULSE, Cell_Coord()); - } - - } else { - - int index; - UnitClass * unit = 0; - unsigned damage = 0; - int what = MONEY; - - if (GameToPlay != GAME_NORMAL && (Random_Pick(1, 2) == 1 || !object->House->BScan)) { - what = -1; - - /* - ** If the player has a construction yeard and practically no money and no legitmate means - ** to make any more money, then give money to build a refinery. - */ - if ((object->House->BScan & (STRUCTF_CONST|STRUCTF_REFINERY)) == STRUCTF_CONST && - object->House->Available_Money() < BuildingTypeClass::As_Reference(STRUCT_REFINERY).Cost) { - - what = MONEY; - } - - /* - ** If the player should get an MCV replacement, then give it now (probably). - */ - if (Random_Pick(0, 1) == 0 && - MPlayerBases && - !(object->House->UScan & UNITF_MCV) && - object->House->BScan == 0 && - object->House->Available_Money() > ((BuildingTypeClass::As_Reference(STRUCT_REFINERY).Cost + BuildingTypeClass::As_Reference(STRUCT_POWER).Cost) * object->House->CostBias)) { - - what = UNIT; - } - - bool allow_super = true; - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER && !Rule.AllowSuperWeapons) { - allow_super = false; - } - - while (what == -1) { - what = _what[Random_Pick((unsigned)0, sizeof(_what)/sizeof(_what[0])-1)]; - - if (what == REVEAL && object->House->IsVisionary) what = -1; - if (what == AIR_STRIKE && (!allow_super || object->House->AirStrike.Is_Present())) what = -1; - if (what == NUKE_MISSILE && (!allow_super || object->House->NukeStrike.Is_Present())) what = -1; - if (what == ION_BLAST && (!allow_super || object->House->IonCannon.Is_Present())) what = -1; - if (what == CLOAK && object->IsCloakable) what = -1; - } - } - - /* - ** Keep track of the number of each type of crate found - */ - if (GameToPlay == GAME_INTERNET){ - object->House->TotalCrates->Increment_Unit_Total(what); - } - - /* - ** Update the crate count and when all the crates have been discovered, flag - ** to generate a new one. - */ - CrateCount--; - if (!CrateMaker && CrateCount <= 0 && GameToPlay != GAME_NORMAL) { - CrateMaker = true; - CrateTimer = 1; - } - - /* - ** Create the effect requested. - */ - switch (what) { - default: - - /* - ** Give the player money. - */ - case MONEY: - new AnimClass(ANIM_CRATE_DOLLAR, Cell_Coord()); - if (GameToPlay == GAME_NORMAL) { - HouseClass::As_Pointer(object->Owner())->Refund_Money(2000); - } else { - HouseClass::As_Pointer(object->Owner())->Refund_Money(100 + (Random_Pick(0,19)*100)); - } - break; - - /* - ** Shroud the world in blackness. - */ - case DARKNESS: - { - new AnimClass(ANIM_CRATE_EMPULSE, Cell_Coord()); - bool shroud = false; - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER) { - if (object->House == PlayerPtr) { - shroud = true; - } - } else { - if (object->House->IsHuman) { - shroud = true; - } - } - if (shroud) { - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { - CellClass * cellptr = &Map[cell]; - if (cellptr->Is_Mapped(object->House) || cellptr->Is_Visible(object->House)) { - cellptr->Redraw_Objects(); - cellptr->Set_Mapped(object->House, false); - cellptr->Set_Visible(object->House, false); - } - } - HouseClass *find_house = object->House; - for (int index = 0; index < Map.Layer[LAYER_GROUND].Count(); index++) { - ObjectClass * object = Map.Layer[LAYER_GROUND][index]; - if (object && object->Is_Techno() && ((TechnoClass *)object)->House == find_house) { - object->Look(); - } - } - Map.Flag_To_Redraw(true); - } - break; - } - /* - ** Reveal the entire map. - */ - case REVEAL: - { - bool reveal = false; - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER) { - if (object->House == PlayerPtr) { - reveal = true; - } - } else { - if (object->House->IsHuman) { - reveal = true; - } - } - - new AnimClass(ANIM_CRATE_EMPULSE, Cell_Coord()); - object->House->IsVisionary = true; - if (reveal) { - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { - Map.Map_Cell(cell, object->House, true); - } - } - break; - } - /* - ** Try to create a unit where the crate was. - */ - case UNIT: { - UnitTypeClass const * utp = NULL; - - /* - ** Give the player an MCV if he has no base left but does have more than enough - ** money to rebuild a new base. Of course, if he already has an MCV, then don't - ** give him another one. - */ - if (MPlayerBases && - !(object->House->UScan & UNITF_MCV) && - object->House->BScan == 0 && - object->House->Available_Money() > (BuildingTypeClass::As_Reference(STRUCT_REFINERY).Cost + BuildingTypeClass::As_Reference(STRUCT_POWER).Cost)) { - - utp = &UnitTypeClass::As_Reference(UNIT_MCV); - } - - /* - ** If the player has a base and a refinery, but no harvester, then give him - ** a free one. - */ - if (!utp && (object->House->BScan & STRUCTF_REFINERY) && !(object->House->UScan & UNITF_HARVESTER)) { - utp = &UnitTypeClass::As_Reference(UNIT_HARVESTER); - } - - while (!utp) { - UnitType utype = Random_Pick(UNIT_FIRST, (UnitType)(UNIT_COUNT-1)); - if (utype != UNIT_MCV || MPlayerBases) { - utp = &UnitTypeClass::As_Reference(utype); - if (utp->IsCrateGoodie && (utp->Ownable & (1 << object->Owner())) && utp->Level <= BuildLevel+2) break; - utp = NULL; - } - } - - UnitClass * unit = (UnitClass *)utp->Create_One_Of(object->House); - if (unit) { - if (unit->Unlimbo(Cell_Coord())) { - return(false); - } - delete unit; - } - } - break; - - /* - ** Create a squad of miscellanous composition. - */ - case SQUAD: - for (index = 0; index < 5; index++) { - static InfantryType _inf[] = { - INFANTRY_E1,INFANTRY_E1,INFANTRY_E1,INFANTRY_E1,INFANTRY_E1,INFANTRY_E1, - INFANTRY_E2, - INFANTRY_E3, - INFANTRY_E4, - INFANTRY_E5, - INFANTRY_E7, - INFANTRY_RAMBO - }; - InfantryTypeClass::As_Reference(_inf[Random_Pick((unsigned)0, sizeof(_inf)/sizeof(_inf[0])-1)]).Create_And_Place(Cell_Number(), object->Owner()); - } - return(false); - - /* - ** Sometimes an explosion of great magnitude occurs. - */ - case NUKE: - new AnimClass(ANIM_ATOM_BLAST, Cell_Coord()); - break; - - /* - ** Sometimes an explosion of great magnitude occurs. - */ - case ION: - new AnimClass(ANIM_ION_CANNON, Cell_Coord()); - break; - - /* - ** A nuclear missile was discovered. Add it to the sidebar. - */ - case NUKE_MISSILE: - new AnimClass(ANIM_CRATE_MISSILE, Cell_Coord()); - if (object->House->NukeStrike.Enable(true)) { - // Add to Glyphx multiplayer sidebar. ST - 3/22/2019 1:50PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (object->House->IsHuman) { - Sidebar_Glyphx_Add(RTTI_SPECIAL, SPC_NUCLEAR_BOMB, object->House); - } - } else { - if (object->IsOwnedByPlayer) { - Map.Add(RTTI_SPECIAL, SPC_NUCLEAR_BOMB); - Map.Column[1].Flag_To_Redraw(); - } - } - } - break; - - /* - ** A one time ion blast was discovered. Add it to the sidebar. - */ - case ION_BLAST: - new AnimClass(ANIM_CRATE_EARTH, Cell_Coord()); - if (object->House->IonCannon.Enable(true)) { - // Add to Glyphx multiplayer sidebar. ST - 3/22/2019 1:50PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (object->House->IsHuman) { - Sidebar_Glyphx_Add(RTTI_SPECIAL, SPC_ION_CANNON, object->House); - } - } else { - if (object->IsOwnedByPlayer) { - Map.Add(RTTI_SPECIAL, SPC_ION_CANNON); - Map.Column[1].Flag_To_Redraw(); - } - } - } - break; - - /* - ** A one time air strike can be called int. Add it to the sidebar. - */ - case AIR_STRIKE: - new AnimClass(ANIM_CRATE_DEVIATOR, Cell_Coord()); - if (object->House->AirStrike.Enable(true)) { - // Add to Glyphx multiplayer sidebar. ST - 3/22/2019 1:50PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (object->House->IsHuman) { - Sidebar_Glyphx_Add(RTTI_SPECIAL, SPC_AIR_STRIKE, object->House); - } - } else { - if (object->IsOwnedByPlayer) { - Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE); - Map.Column[1].Flag_To_Redraw(); - } - } - } - break; - - /* - ** A group of explosions are triggered around the crate. - */ - case EXPLOSION: - damage = 400; - object->Take_Damage((int&)damage, 0, WARHEAD_HE); - for (index = 0; index < 5; index++) { - COORDINATE coord = Coord_Scatter(Cell_Coord(), Random_Pick(0, 0x0200)); - new AnimClass(ANIM_FBALL1, coord); - damage = 400; - Explosion_Damage(coord, damage, NULL, WARHEAD_HE); - } - break; - - /* - ** A napalm blast is triggered. - */ - case NAPALM: - coord = Coord_Mid(Cell_Coord(), object->Center_Coord()); - new AnimClass(ANIM_NAPALM3, coord); - damage = 600; - Explosion_Damage(coord, damage, NULL, WARHEAD_FIRE); - break; - - /* - ** A visceroid appears and, boy, he's angry! - */ - case VISCEROID: - unit = new UnitClass(UNIT_VICE, HOUSE_JP); - if (unit) { - if (unit->Unlimbo(Cell_Coord())) { - return(false); - } - delete unit; - } - break; - - /* - ** All objects within a certain range will gain the ability to cloak. - */ - case CLOAK: - new AnimClass(ANIM_CRATE_STEALTH, Cell_Coord()); - for (index = 0; index < Map.Layer[LAYER_GROUND].Count(); index++) { - ObjectClass * obj = Map.Layer[LAYER_GROUND][index]; - - if (obj && obj->Is_Techno() && Distance(Cell_Coord(), obj->Center_Coord()) < 0x0300) { - ((TechnoClass *)obj)->IsCloakable = true; - } - } - break; - - /* - ** All of the player's objects heal up. - */ - case HEAL_BASE: - new AnimClass(ANIM_CRATE_INVUN, Cell_Coord()); - for (index = 0; index < Logic.Count(); index++) { - ObjectClass * obj = Logic[index]; - - if (obj && object->Is_Techno() && object->House->Class->House == obj->Owner()) { - obj->Strength = obj->Class_Of().MaxStrength; - } - } - break; - - } - } - } - return(true); -} - - -/*********************************************************************************************** - * CellClass::Flag_Place -- Places a house flag down on the cell. * - * * - * This routine will place the house flag at this cell location. * - * * - * INPUT: house -- The house that is having its flag placed here. * - * * - * OUTPUT: Was the flag successfully placed here? * - * * - * WARNINGS: Failure to place means that the cell is impassable for some reason. * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool CellClass::Flag_Place(HousesType house) -{ - Validate(); - if (!IsFlagged && Is_Generally_Clear()) { - IsFlagged = true; - Owner = house; - Flag_Update(); - Redraw_Objects(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * CellClass::Flag_Remove -- Removes the house flag from the cell. * - * * - * This routine will free the cell of any house flag that may be located there. * - * * - * INPUT: none * - * * - * OUTPUT: Was there a flag here that was removed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool CellClass::Flag_Remove(void) -{ - Validate(); - if (IsFlagged) { - IsFlagged = false; - Owner = HOUSE_NONE; - Flag_Update(); - Redraw_Objects(); - return(true); - } - return(false); -} - - -void CellClass::Flag_Update(void) -{ - if (IsFlagged && !CTFFlag) { - Flag_Create(); - } else if (!IsFlagged && CTFFlag) { - Flag_Destroy(); - } -} - - -void CellClass::Flag_Create(void) -{ - if (!CTFFlag) { - CTFFlag = new AnimClass(ANIM_FLAG, Cell_Coord(), 0, 1, true); - if (CTFFlag) { - CTFFlag->OwnerHouse = Owner; - } - } -} - - -void CellClass::Flag_Destroy(void) -{ - delete CTFFlag; - CTFFlag = NULL; -} - - -/*********************************************************************************************** - * CellClass::Shimmer -- Causes all objects in the cell to shimmer. * - * * - * This routine is called when some event would cause a momentary disruption in the * - * cloaking device. All objects that are cloaked in the cell will have their cloaking * - * device shimmer. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void CellClass::Shimmer(void) -{ - Validate(); - ObjectClass * object = Cell_Occupier(); - - while (object) { - object->Do_Shimmer(); - object = object->Next; - } -} - - -/*********************************************************************************************** - * CellClass::Cell_Occupier -- Fetches the occupier for the cell. * - * * - * This routine returns with the first recorded occupier of this cell. A special validity * - * check is performed to ensure that there are no dead objects still marked on the * - * map. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the first occupier object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/17/1995 JLB : Created. * - *=============================================================================================*/ -ObjectClass * CellClass::Cell_Occupier(void) const -{ - ObjectClass * ptr = OccupierPtr; - - while (ptr && !ptr->IsActive) { - ptr = ptr->Next; - ((ObjectClass *&)OccupierPtr) = 0; - } - - return(ptr); -} - - - - - - - - - -/* -** Additions to CellClass to track visibility per-player. ST - 3/5/2019 3:08PM -** -** -** -** -** -*/ - -/*********************************************************************************************** - * CellClass::Set_Mapped -- Set the cell mapped for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:09PM - ST * - *=============================================================================================*/ -void CellClass::Set_Mapped(HousesType house, bool set) -{ - int shift = (int) house; - if (set) { - IsMappedByPlayerMask |= (1 << shift); - } else { - IsMappedByPlayerMask &= ~(1 << shift); - } -} - - -/*********************************************************************************************** - * CellClass::Set_Mapped -- Set the cell mapped for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:09PM - ST * - *=============================================================================================*/ -void CellClass::Set_Mapped(HouseClass *player, bool set) -{ - if (player && player->Class) { - Set_Mapped(player->Class->House, set); - if (GameToPlay == GAME_NORMAL && player->IsHuman) { - IsMapped = set; // Also set the regular flag in single player - } - } -} - -/*********************************************************************************************** - * CellClass::Is_Mapped -- Is the cell mapped for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:13PM - ST * - *=============================================================================================*/ -bool CellClass::Is_Mapped(HousesType house) const -{ - int shift = (int) house; - return (IsMappedByPlayerMask & (1 << shift)) ? true : false; -} - -/*********************************************************************************************** - * CellClass::Is_Mapped -- Is the cell mapped for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:13PM - ST * - *=============================================================================================*/ -bool CellClass::Is_Mapped(HouseClass *player) const -{ - if (player && player->Class) { - return Is_Mapped(player->Class->House); - } - return false; -} - -/*********************************************************************************************** - * CellClass::Set_Visible -- Set the cell visible for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:16PM - ST * - *=============================================================================================*/ -void CellClass::Set_Visible(HousesType house, bool set) -{ - int shift = (int) house; - if (set) { - IsVisibleByPlayerMask |= (1 << shift); - } else { - IsVisibleByPlayerMask &= ~(1 << shift); - } -} - - -/*********************************************************************************************** - * CellClass::Set_Visible -- Set the cell visible for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:16PM - ST * - *=============================================================================================*/ -void CellClass::Set_Visible(HouseClass *player, bool set) -{ - if (player && player->Class) { - Set_Visible(player->Class->House, set); - if (GameToPlay == GAME_NORMAL && player->IsHuman) { - IsVisible = set; // Also set the regular flag in single player. This is needed for rendering - } - } -} - -/*********************************************************************************************** - * CellClass::Is_Visible -- Is the cell visible for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:16PM - ST * - *=============================================================================================*/ -bool CellClass::Is_Visible(HousesType house) const -{ - int shift = (int) house; - return (IsVisibleByPlayerMask & (1 << shift)) ? true : false; -} - -/*********************************************************************************************** - * CellClass::Is_Visible -- Is the cell visible for the given player * - * * - * * - * HISTORY: * - * 3/5/2019 3:16PM - ST * - *=============================================================================================*/ -bool CellClass::Is_Visible(HouseClass *player) const -{ - if (player && player->Class) { - return Is_Visible(player->Class->House); - } - return false; -} - -void CellClass::Override_Land_Type(LandType type) -{ - OverrideLand = type; -} - -#ifdef USE_RA_AI - -/* -** Addition from Red Alert for AI. ST - 7/24/2019 5:33PM -*/ -/*********************************************************************************************** - * CellClass::Is_Clear_To_Move -- Determines if the cell is generally clear for travel * - * * - * This routine is called when determining general passability for purposes of zone * - * calculation. Only blockages that cannot be circumvented are considered to make a cell * - * impassable. All other obstructions can either be destroyed or are temporary. * - * * - * INPUT: loco -- The locomotion type to use when determining passablility. * - * * - * ignoreinfantry -- Should infantry in the cell be ignored for movement purposes? * - * * - * ignorevehicles -- If vehicles should be ignored, then this flag will be true. * - * * - * zone -- If specified, the zone must match this value or else movement is * - * presumed disallowed. * - * * - * check -- This specifies the zone type that this check applies to. * - * * - * OUTPUT: Is the cell generally passable to ground targeting? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/25/1995 JLB : Created. * - * 06/25/1996 JLB : Uses tracked vehicles as a basis for zone check. * - * 10/05/1996 JLB : Allows checking for crushable blockages. * - *=============================================================================================*/ -bool CellClass::Is_Clear_To_Move(bool ignoreinfantry, bool ignorevehicles) const -{ - //assert((unsigned)Cell_Number() <= MAP_CELL_TOTAL); - - /* - ** Flying objects always consider every cell passable since they can fly over everything. - */ - //if (loco == SPEED_WINGED) { - // return(true); - //} - - /* - ** If a zone was specified, then see if the cell is in a legal - ** zone to allow movement. - */ - //if (zone != -1) { - // if (zone != Zones[check]) { - // return(false); - // } - //} - - /* - ** Check the occupy bits for passable legality. If ignore infantry is true, then - ** don't consider infnatry. - */ - int composite = Flag.Composite; - if (ignoreinfantry) { - composite &= 0xE0; // Drop the infantry occupation bits. - } - if (ignorevehicles) { - composite &= 0x5F; // Drop the vehicle/building bit. - } - if (composite != 0) { - return(false); - } - - /* - ** Fetch the land type of the cell -- to be modified and used later. - */ - //LandType land = Land_Type(); - - /* - ** Walls are always considered to block the terrain for general passability - ** purposes unless this is a wall crushing check or if the checking object - ** can destroy walls. - */ - OverlayTypeClass const * overlay = NULL; - if (Overlay != OVERLAY_NONE) { - overlay = &OverlayTypeClass::As_Reference(Overlay); - } - if (overlay != NULL && overlay->IsWall) { - //if (check != MZONE_DESTROYER && (check != MZONE_CRUSHER || !overlay->IsCrushable)) { - return(false); - //} - - /* - ** Crushing objects consider crushable walls as clear rather than the - ** typical LAND_WALL setting. - */ - //land = LAND_CLEAR; - } - - /* - ** See if the ground type is impassable to this locomotion type and if - ** so, return the error condition. - */ - //if (::Ground[land].Cost[loco] == 0) { - // return(false); - //} - - /* - ** All checks passed, so this cell must be passable. - */ - return(true); -} - -#endif //USE_RA_AI \ No newline at end of file diff --git a/code/TIBERIANDAWN/CELL.H b/code/TIBERIANDAWN/CELL.H deleted file mode 100644 index 963897a..0000000 --- a/code/TIBERIANDAWN/CELL.H +++ /dev/null @@ -1,303 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cell.h_v 2.20 16 Oct 1995 16:45:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CELL.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : April 29, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CELL_H -#define CELL_H - -#include "building.h" -#include "unit.h" -#include "template.h" - - -/**************************************************************************** -** Each cell on the map is controlled by the following structure. -*/ -class CellClass -{ - public: - /* - ** Does this cell need to be updated on the radar map? If something changes in the cell - ** that might change the radar map imagery, then this flag will be set. It gets cleared - ** when the cell graphic is updated to the radar map. - */ - unsigned IsPlot:1; - - /* - ** Does this cell contain the special placement cursor graphic? This graphic is - ** present when selecting a site for building placement. - */ - unsigned IsCursorHere:1; - - /* - ** Is this cell mapped by the player? A mapped cell is visible. An unmapped cell - ** is covered in a dark shroud. In addition to visibility, mapped cells are the only - ** legal place for transports to land. - */ - unsigned IsMapped:1; - - /* - ** If any part of this cell is visible (even just peeking out from under the shadow), - ** this this flag will be true. Mapped cells always have this flag set, but unmapped - ** cells might not -- it depends on where the shadow edge is located. - */ - unsigned IsVisible:1; - - /* - ** Every cell can be assigned a trigger. The same trigger can be assigned to - ** multiple cells. This bitflag indicates whether this cell has a trigger. - ** The trigger pointers for all cells must be stored elsewhere. - */ - unsigned IsTrigger:1; - - /* - ** Every cell can be assigned a waypoint. A waypoint can only be assigned - ** to one cell, and vice-versa. This bit simply indicates whether this - ** cell is assigned a waypoint or not. - */ - unsigned IsWaypoint:1; - - /* - ** Is this cell currently under the radar map cursor? If so then it - ** needs to be updated whenever the map is updated. - */ - unsigned IsRadarCursor:1; - - /* - ** If this cell contains a house flag, then this will be true. The actual house - ** flag it contains is specified by the Owner field. - */ - unsigned IsFlagged:1; - - /* - ** This contains the icon number and set to use for the base - ** of the terrain. All rendering on an icon occurs AFTER the icon - ** specified by this element is rendered. It is the lowest of the low. - */ - TemplateType TType; - unsigned char TIcon; - - /* - ** The second layer of 'terrain' icons is represented by a simple - ** type number and a value byte. This is sufficient for handling - ** concrete and walls. - */ - OverlayType Overlay; - unsigned char OverlayData; - - /* - ** This is used to specify any special 'stain' overlay icon. This - ** typically includes infantry bodies or other temporary marks. - */ - SmudgeType Smudge; - unsigned char SmudgeData; - - /* - ** Smudges and walls need to record ownership values. For walls, this - ** allows adjacent building placement logic to work. For smudges, it - ** allows building over smudges that are no longer attached to buildings - ** in addition to fixing the adjacent placement logic. - */ - HousesType Owner; - - /* - ** This flag tells you what type of infantry currently occupy the - ** cell or are moving into it. - */ - HousesType InfType; - - /* - ** These point to the object(s) that are located in this cell or overlap - ** this cell. - */ - ObjectClass *OccupierPtr; - ObjectClass *Overlapper[3]; - - - /* - ** Per-player view of whether a cell is mapped. One bit for each house type. ST - 3/5/2019 3:00PM - */ - unsigned int IsMappedByPlayerMask; - - /* - ** Per-player view of whether a cell is visible. One bit for each house type. ST - 3/5/2019 3:00PM - */ - unsigned int IsVisibleByPlayerMask; - - - /* - ** This array of bit flags is used to indicate which sub positions - ** within the cell are either occupied or are soon going to be - ** occupied. For vehicles, the cells that the vehicle is passing over - ** will be flagged with the vehicle bit. For infantry, the the sub - ** position the infantry is stopped at or headed toward will be marked. - ** The sub positions it passes over will NOT be marked. - */ - union { - struct { - unsigned Center:1; - unsigned NW:1; - unsigned NE:1; - unsigned SW:1; - unsigned SE:1; - unsigned Vehicle:1; // Reserved for vehicle occupation. - unsigned Monolith:1; // Some immovable blockage is in cell. - unsigned Building:1; // A building of some time (usually blocks movement). - } Occupy; - unsigned char Composite; - } Flag; - - //---------------------------------------------------------------- - CellClass(void); - ~CellClass(void) {}; - - int operator == (CellClass const & cell) const {return &cell == this;}; - - /* - ** Query functions. - */ - ObjectClass * Cell_Occupier(void) const; - static int Spot_Index(COORDINATE coord); - bool Is_Spot_Free(int spot_index) const {return (! (Flag.Composite & (1 << spot_index)) ); } - COORDINATE Closest_Free_Spot(COORDINATE coord, bool any=false) const; - COORDINATE Free_Spot(void) const {return Closest_Free_Spot(Cell_Coord());}; - bool Is_Generally_Clear(bool ignore_cloaked = false) const; - TARGET As_Target(void) const {return ::As_Target(Cell_Number());}; - BuildingClass * Cell_Building(void) const; - CellClass const * Adjacent_Cell(FacingType face) const; - CellClass * Adjacent_Cell(FacingType face) {return (CellClass *)((*((CellClass const *)this)).Adjacent_Cell(face));}; - COORDINATE Cell_Coord(void) const; - int Cell_Color(bool override=false) const; - CELL Cell_Number(void) const; - LandType Land_Type(void) const {return((OverrideLand != LAND_COUNT) ? OverrideLand : Land);}; - ObjectClass * Cell_Find_Object(RTTIType rtti) const; - ObjectClass * Cell_Object(int x=0, int y=0) const; - TechnoClass * Cell_Techno(int x=0, int y=0) const; - TerrainClass * Cell_Terrain(void) const; - UnitClass * Cell_Unit(void) const; - InfantryClass * Cell_Infantry(void) const; - TriggerClass * Get_Trigger(void) const; - int Clear_Icon(void) const; - bool Goodie_Check(FootClass * object); - ObjectClass * Fetch_Occupier(void) const; - bool Get_Template_Info(char *template_name, int &icon, void *&image_data); - - /* - ** Object placement and removal flag operations. - */ - void Occupy_Down(ObjectClass * object); - void Occupy_Up(ObjectClass * object); - void Overlap_Down(ObjectClass * object); - void Overlap_Up(ObjectClass * object); - bool Flag_Place(HousesType house); - bool Flag_Remove(void); - void Flag_Update(void); - void Flag_Create(void); - void Flag_Destroy(void); - - /* - ** File I/O. - */ - bool Should_Save(void) const; - bool Save(FileClass & file); - bool Load(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - /* - ** Display and rendering controls. - */ - void Draw_It(int x, int y, int draw_flags = 0) const; - void Redraw_Objects(bool forced=false); - void Shimmer(void); - - /* - ** Maintenance calculation support. - */ - long Tiberium_Adjust(bool pregame=false); - void Wall_Update(void); - void Concrete_Calc(void); - void Recalc_Attributes(void); - int Reduce_Tiberium(int levels); - int Reduce_Wall(int damage); - void Incoming(COORDINATE threat=0, bool forced = false, bool nokidding = false); - void Adjust_Threat(HousesType house, int threat_value); - - int operator != (CellClass const &) const {return 0;}; - - int Validate(void) const; - - - /* - ** Additional per-player functionality is needed for multiplayer. ST - 3/5/2019 3:03PM - */ - void Set_Mapped(HousesType house, bool set = true); - void Set_Mapped(HouseClass *player, bool set = true); - bool Is_Mapped(HousesType house) const; - bool Is_Mapped(HouseClass *player) const; - void Set_Visible(HousesType house, bool set = true); - void Set_Visible(HouseClass *player, bool set = true); - bool Is_Visible(HousesType house) const; - bool Is_Visible(HouseClass *player) const; - - /* - ** Override land type to fix passability issues on some maps - */ - void Override_Land_Type(LandType type); - -#ifdef USE_RA_AI - /* - ** Imported from RA for AI. ST - 7/24/2019 5:36PM - */ - bool Is_Clear_To_Move(bool ignoreinfantry, bool ignorevehicles) const; -#endif - - private: - CellClass (CellClass const &) {}; - - LandType Land; // The land type of this cell. - - LandType OverrideLand; // The overriden land type of this cell. - - /* - ** Points to the flag animation on this cell in CTF games. - */ - AnimClass* CTFFlag; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[28]; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/CHECKBOX.CPP b/code/TIBERIANDAWN/CHECKBOX.CPP deleted file mode 100644 index 923edea..0000000 --- a/code/TIBERIANDAWN/CHECKBOX.CPP +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\checkbox.cpv 1.6 16 Oct 1995 16:49:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CHECKBOX.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 05/26/95 * - * * - * Last Update : July 1, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CheckBoxClass::Draw_Me -- Draws the checkbox imagery. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "checkbox.h" - - -/*********************************************************************************************** - * CheckBoxClass::Draw_Me -- Draws the checkbox imagery. * - * * - * This routine will draw the checkbox either filled or empty as necessary. * - * * - * INPUT: forced -- Should the check box be drawn even if it doesn't think it needs to? * - * * - * OUTPUT: Was the check box rendered? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/01/1995 JLB : Created. * - *=============================================================================================*/ -int CheckBoxClass::Draw_Me(int forced) -{ - if (ToggleClass::Draw_Me(forced)) { - - Hide_Mouse(); - Draw_Box(X, Y, Width, Height, BOXSTYLE_GREEN_DOWN, false); - LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, Y+Height-2, DKGREY); - if (IsOn) { - LogicPage->Draw_Line(X+1, Y+1, X+Width-2, Y+Height-2, BLACK); - LogicPage->Draw_Line(X+Width-2, Y+1, X+1, Y+Height-2, BLACK); - } - Show_Mouse(); - return(true); - } - return(false); -} diff --git a/code/TIBERIANDAWN/CHECKBOX.H b/code/TIBERIANDAWN/CHECKBOX.H deleted file mode 100644 index 9c5fa3f..0000000 --- a/code/TIBERIANDAWN/CHECKBOX.H +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\checkbox.h_v 1.6 16 Oct 1995 16:46:00 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CHECKBOX.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 05/26/95 * - * * - * Last Update : May 26, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CHECKBOX_H -#define CHECKBOX_H - -#include "toggle.h" - -class CheckBoxClass : public ToggleClass -{ - public: - CheckBoxClass(unsigned id, int x, int y) : - ToggleClass(id, x, y, 7, 7) - {}; - - virtual int Draw_Me(int forced=false); - - protected: -}; - -#endif diff --git a/code/TIBERIANDAWN/CHEKLIST.CPP b/code/TIBERIANDAWN/CHEKLIST.CPP deleted file mode 100644 index 956b93a..0000000 --- a/code/TIBERIANDAWN/CHEKLIST.CPP +++ /dev/null @@ -1,165 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cheklist.cpv 2.18 16 Oct 1995 16:48:36 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CHEKLIST.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : February 16, 1995 * - * * - * Last Update : February 16, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * CheckListClass::Action -- action function for this class * - * CheckListClass::CheckListClass -- constructor * - * CheckListClass::Check_Item -- [un]checks an items * - * CheckListClass::~CheckListClass -- destructor * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * CheckListClass::CheckListClass -- constructor * - * * - * INPUT: * - * id control ID for this list box * - * x x-coord * - * y y-coord * - * w width * - * h height * - * flags mouse event flags * - * up ptr to Up-arrow shape * - * down ptr to Down-arrow shape * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/16/1995 BR : Created. * - *=========================================================================*/ -CheckListClass::CheckListClass(int id, int x, int y, int w, int h, TextPrintType flags, - void const * up, void const * down) : - ListClass (id, x, y, w, h, flags, up, down) -{ - IsReadOnly = false; -} - - -/*************************************************************************** - * CheckListClass::Check_Item -- [un]checks an items * - * * - * INPUT: * - * index index of item to check or uncheck * - * checked 0 = uncheck, non-zero = check * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/16/1995 BR : Created. * - *=========================================================================*/ -void CheckListClass::Check_Item(int index, int checked) -{ - if (List[index]) { - ((char &)List[index][0]) = checked ? CHECK_CHAR : UNCHECK_CHAR; - } -} - - -/*************************************************************************** - * CheckListClass::Is_Checked -- returns checked state of an item * - * * - * INPUT: * - * index index of item to query * - * * - * OUTPUT: * - * 0 = item is unchecked, 1 = item is checked * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/16/1995 BR : Created. * - *=========================================================================*/ -int CheckListClass::Is_Checked(int index) const -{ - if (List[index]) { - return(List[index][0] == CHECK_CHAR); - } - return(false); -} - - -/*************************************************************************** - * CheckListClass::Action -- action function for this class * - * * - * INPUT: * - * flags the reason we're being called * - * key the KN_number that was pressed * - * * - * OUTPUT: * - * true = event was processed, false = event not processed * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/16/1995 BR : Created. * - *=========================================================================*/ -int CheckListClass::Action(unsigned flags, KeyNumType &key) -{ - int rc; - - /* - ** If this is a read-only list, it's a display-only device - */ - if (IsReadOnly) { - return(false); - } - - /* - ** Invoke parents Action first, so it can set the SelectedIndex if needed. - */ - rc = ListClass::Action(flags, key); - - /* - ** Now, if this event was a left-press, toggle the checked state of the - ** current item. - */ - if (flags & LEFTPRESS) { - if (Is_Checked(SelectedIndex)) { - Check_Item(SelectedIndex,0); - } else { - Check_Item(SelectedIndex,1); - } - } - - return(rc); -} diff --git a/code/TIBERIANDAWN/CHEKLIST.H b/code/TIBERIANDAWN/CHEKLIST.H deleted file mode 100644 index 603ffcd..0000000 --- a/code/TIBERIANDAWN/CHEKLIST.H +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\cheklist.h_v 2.19 16 Oct 1995 16:46:20 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CHEKLIST.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : February 16, 1995 * - * * - * Last Update : February 16, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * This class behaves just like the standard list box, except that if the * - * first character of a list entry is a space, clicking on it toggles the * - * space with a check-mark ('\3'). This makes each entry in the list box * - * "toggle-able". * - *-------------------------------------------------------------------------* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CHEKLIST_H -#define CHEKLIST_H - -#include "list.h" - - -class CheckListClass : public ListClass -{ - public: - /*--------------------------------------------------------------------- - Constructor/Destructor - ---------------------------------------------------------------------*/ - CheckListClass(int id, int x, int y, int w, int h, TextPrintType flags, - void const * up, void const * down); - ~CheckListClass(void) {}; - - /*--------------------------------------------------------------------- - Checkmark utility functions - ---------------------------------------------------------------------*/ - void Check_Item(int index, int checked); // sets checked state of item - int Is_Checked(int index) const; // gets checked state of item - - /*--------------------------------------------------------------------- - This defines the ASCII value of the checkmark character & non-checkmark - character. - ---------------------------------------------------------------------*/ - enum CheckListClassEnum { - CHECK_CHAR = '\3', - UNCHECK_CHAR = ' ', - }; - - void Set_Read_Only(int rdonly) {IsReadOnly = rdonly ? true : false;} - - protected: - virtual int Action(unsigned flags, KeyNumType &key); - - private: - bool IsReadOnly; - -}; - - - -#endif -/************************** end of cheklist.h ******************************/ \ No newline at end of file diff --git a/code/TIBERIANDAWN/COLRLIST.CPP b/code/TIBERIANDAWN/COLRLIST.CPP deleted file mode 100644 index eb19e8f..0000000 --- a/code/TIBERIANDAWN/COLRLIST.CPP +++ /dev/null @@ -1,280 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\colrlist.cpv 1.9 16 Oct 1995 16:50:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LIST.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : April 19, 1995 [BRR] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ColorListClass::Add_Item -- Adds an item to the list * - * ColorListClass::ColorListClass -- Class constructor * - * ColorListClass::Draw_Entry -- Draws one text line * - * ColorListClass::Remove_Item -- Removes an item from the list * - * ColorListClass::Set_Selected_Style -- tells how to draw selected item * - * ColorListClass::~ColorListClass -- Class destructor * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * ColorListClass::ColorListClass -- class constructor * - * * - * INPUT: * - * id button ID * - * x,y upper-left corner, in pixels * - * w,h width, height, in pixels * - * list ptr to array of char strings to list * - * flags flags for mouse, style of listbox * - * up,down pointers to shapes for up/down buttons * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: 01/05/1995 MML : Created. * - *=========================================================================*/ -ColorListClass::ColorListClass (int id, int x, int y, int w, int h, - TextPrintType flags, void const * up, void const * down) : - ListClass (id, x, y, w, h, flags, up, down) -{ - Style = SELECT_HIGHLIGHT; - SelectColor = -1; -} - - -/*************************************************************************** - * ColorListClass::~ColorListClass -- Class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/19/1995 BRR : Created. * - *=========================================================================*/ -ColorListClass::~ColorListClass(void) -{ - Colors.Clear(); -} - - -/*************************************************************************** - * ColorListClass::Add_Item -- Adds an item to the list * - * * - * INPUT: * - * text text to add to list * - * color color for item * - * * - * OUTPUT: * - * position of item in the list * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/19/1995 BRR : Created. * - *=========================================================================*/ -int ColorListClass::Add_Item(char const * text, char color) -{ - Colors.Add(color); - return(ListClass::Add_Item(text)); -} - - -/*************************************************************************** - * ColorListClass::Add_Item -- Adds an item to the list * - * * - * INPUT: * - * text text to add to list * - * color color for item * - * * - * OUTPUT: * - * position of item in the list * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/19/1995 BRR : Created. * - *=========================================================================*/ -int ColorListClass::Add_Item(int text, char color) -{ - Colors.Add(color); - return(ListClass::Add_Item(text)); -} - - -/*************************************************************************** - * ColorListClass::Remove_Item -- Removes an item from the list * - * * - * INPUT: * - * text ptr to item to remove * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/19/1995 BRR : Created. * - *=========================================================================*/ -void ColorListClass::Remove_Item(char const * text) -{ - int index = List.ID(text); - if (index != -1) { - Colors.Delete(index); - ListClass::Remove_Item(text); - } -} - - -/*************************************************************************** - * ColorListClass::Set_Selected_Style -- tells how to draw selected item * - * * - * INPUT: * - * style style to draw * - * color color to draw the special style in; -1 = use item's color* - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/19/1995 BRR : Created. * - *=========================================================================*/ -void ColorListClass::Set_Selected_Style(SelectStyleType style, int color) -{ - Style = style; - SelectColor = color; -} - - -/*************************************************************************** - * ColorListClass::Draw_Entry -- Draws one text line * - * * - * INPUT: * - * index index into List of item to draw * - * x,y x,y coords to draw at * - * width maximum width allowed for text * - * selected true = this item is selected * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/19/1995 BRR : Created. * - *=========================================================================*/ -void ColorListClass::Draw_Entry(int index, int x, int y, int width, int selected) -{ - int color; - - /* - ** Draw a non-selected item in its color - */ - if (!selected) { - Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs); - return; - } - - /* - ** For selected items, choose the right color & style: - */ - if (SelectColor==-1) { - color = Colors[index]; - } else { - color = SelectColor; - } - - switch (Style) { - /* - ** NONE: Just print the string in its native color - */ - case SELECT_NONE: - Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs); - break; - - /* - ** HIGHLIGHT: Draw the string in the highlight color (SelectColor must - ** be set) - */ - case SELECT_HIGHLIGHT: - if (TextFlags & TPF_6PT_GRAD) { - Conquer_Clip_Text_Print(List[index], x, y, color, TBLACK, TextFlags | TPF_BRIGHT_COLOR, width, Tabs); - } else { - Conquer_Clip_Text_Print(List[index], x, y, color, TBLACK, TextFlags, width, Tabs); - } - break; - - /* - ** BOX: Draw a box around the item in the current select color - */ - case SELECT_BOX: - LogicPage->Draw_Rect (x, y, x + width - 2, y + LineHeight - 2, color); - Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs); - break; - - /* - ** BAR: draw a color bar under the text - */ - case SELECT_BAR: - if (TextFlags & TPF_6PT_GRAD) { - LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, SelectColor); - Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags | TPF_BRIGHT_COLOR, width, Tabs); - } else { - LogicPage->Fill_Rect (x, y, x + width - 2, y + LineHeight - 2, SelectColor); - Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs); - } - break; - - /* - ** INVERT: Draw text as the background color on foreground color - */ - case SELECT_INVERT: - if (TextFlags & TPF_6PT_GRAD) { - LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, Colors[index]); - Conquer_Clip_Text_Print(List[index], x, y, BLACK, TBLACK, TextFlags, width, Tabs); - } else { - LogicPage->Fill_Rect (x, y, x + width - 2, y + LineHeight - 2, Colors[index]); - Conquer_Clip_Text_Print(List[index], x, y, LTGREY, TBLACK, TextFlags, width, Tabs); - } - break; - - } -} diff --git a/code/TIBERIANDAWN/COLRLIST.H b/code/TIBERIANDAWN/COLRLIST.H deleted file mode 100644 index 710346f..0000000 --- a/code/TIBERIANDAWN/COLRLIST.H +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\colrlist.h_v 1.10 16 Oct 1995 16:47:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COLRLIST.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef COLORLIST_H -#define COLORLIST_H - -#include "list.h" - - -/*************************************************************************** -** This class adds the ability for every list item to have a different color. -*/ -class ColorListClass : public ListClass -{ - public: - /********************************************************************* - ** These enums are the ways a selected item can be drawn - */ - typedef enum SelectEnum { - SELECT_NONE, // selected items aren't drawn differently - SELECT_HIGHLIGHT, // item is highlighted - SELECT_BOX, // draw a box around the item - SELECT_BAR, // draw a bar behind the item - SELECT_INVERT, // draw the string inverted - } SelectStyleType; - - ColorListClass(int id, int x, int y, int w, int h, TextPrintType flags, - void const * up, void const * down); - virtual ~ColorListClass(void); - - virtual int Add_Item(char const * text, char color = WHITE); - virtual int Add_Item(int text, char color = WHITE); - virtual void Remove_Item(char const * text); - - virtual void Set_Selected_Style(SelectStyleType style, int color = -1); - - /* - ** This is the list of colors for each item. - */ - DynamicVectorClass Colors; - - protected: - virtual void Draw_Entry(int index, int x, int y, int width, int selected); - - /* - ** This tells how to draw the selected item. - */ - SelectStyleType Style; - int SelectColor; - -}; - -#endif diff --git a/code/TIBERIANDAWN/COMBAT.CPP b/code/TIBERIANDAWN/COMBAT.CPP deleted file mode 100644 index fc1cb2f..0000000 --- a/code/TIBERIANDAWN/COMBAT.CPP +++ /dev/null @@ -1,233 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\combat.cpv 2.17 16 Oct 1995 16:48:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COMBAT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 19, 1994 * - * * - * Last Update : January 1, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Explosion_Damage -- Inflict an explosion damage affect. * - * Modify_Damage -- Adjusts damage to reflect the nature of the target. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -int Modify_Damage(int damage, WarheadType warhead, ArmorType armor); -void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass *source, WarheadType warhead); - - -/*********************************************************************************************** - * Modify_Damage -- Adjusts damage to reflect the nature of the target. * - * * - * This routine is the core of combat tactics. It implements the * - * affect various armor types have against various weapon types. By * - * careful exploitation of this table, tactical advantage can be * - * obtained. * - * * - * INPUT: damage -- The damage points to process. * - * * - * warhead -- The source of the damage points. * - * * - * armor -- The type of armor defending against the damage. * - * * - * distance -- The distance (in leptons) from the source of the damage. * - * * - * OUTPUT: Returns with the adjusted damage points to inflict upon the * - * target. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/16/1994 JLB : Created. * - * 04/17/1994 JLB : Always does a minimum of damage. * - * 01/01/1995 JLB : Takes into account distance from damage source. * - *=============================================================================================*/ -int Modify_Damage(int damage, WarheadType warhead, ArmorType armor, int distance) -{ - /* - ** If there is no raw damage value to start with, then - ** there can be no modified damage either. - */ - if (Special.IsInert || !damage || warhead == WARHEAD_NONE) return(0); - - WarheadTypeClass const * whead = &Warheads[warhead]; - - damage = Fixed_To_Cardinal(damage, whead->Modifier[armor]); - - /* - ** Reduce damage according to the distance from the impact point. - */ - if (damage) { -// if (distance < 0x0010) damage *= 2; // Double damage for direct hits. - distance >>= whead->SpreadFactor; - distance = Bound(distance, 0, 16); - damage >>= distance; - } - - /* - ** If damage was indicated, then it should never drop below one damage point regardless - ** of modifiers. This allows a very weak attacker to eventually destroy anything it - ** fires upon, given enough time. - */ - return(damage); -} - - -/*********************************************************************************************** - * Explosion_Damage -- Inflict an explosion damage affect. * - * * - * Processes the collateral damage affects typically caused by an * - * explosion. * - * * - * INPUT: coord -- The coordinate of ground zero. * - * * - * strength -- Raw damage points at ground zero. * - * * - * source -- Source of the explosion (who is responsible). * - * * - * warhead -- The kind of explosion to process. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine can consume some time and will affect the AI * - * of nearby enemy units (possibly). * - * * - * HISTORY: * - * 08/16/1991 JLB : Created. * - * 11/30/1991 JLB : Uses coordinate system. * - * 12/27/1991 JLB : Radius of explosion damage effect. * - * 04/13/1994 JLB : Streamlined. * - * 04/16/1994 JLB : Warhead damage type modifier. * - * 04/17/1994 JLB : Cleaned up. * - * 06/20/1994 JLB : Uses object pointers to distribute damage. * - * 06/20/1994 JLB : Source is a pointer. * - *=============================================================================================*/ -void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass * source, WarheadType warhead) -{ - CELL cell; // Cell number under explosion. - ObjectClass * object; // Working object pointer. - ObjectClass * objects[32]; // Maximum number of objects that can be damaged. - int distance; // Distance to unit. - int range; // Damage effect radius. - int index; - int count; // Number of vehicle IDs in list. - - if (!strength || Special.IsInert || warhead == WARHEAD_NONE) return; - - WarheadTypeClass const * whead = &Warheads[warhead]; - range = ICON_LEPTON_W + (ICON_LEPTON_W >> 1); - cell = Coord_Cell(coord); - if ((unsigned)cell >= MAP_CELL_TOTAL) return; -// if (!Map.In_Radar(cell)) return; - - CellClass * cellptr = &Map[cell]; - ObjectClass * impacto = cellptr->Cell_Occupier(); - - /* - ** Fill the list of unit IDs that will have damage - ** assessed upon them. The units can be lifted from - ** the cell data directly. - */ - count = 0; - for (FacingType i = FACING_NONE; i < FACING_COUNT; i++) { - /* - ** Fetch a pointer to the cell to examine. This is either - ** an adjacent cell or the center cell. Damage never spills - ** further than one cell away. - */ - if (i != FACING_NONE) { - cellptr = Map[cell].Adjacent_Cell(i); - if (!cellptr) continue; - } - - /* - ** Add all objects in this cell to the list of objects to possibly apply - ** damage to. The list stops building when the object pointer list becomes - ** full. Do not include overlapping objects; selection state can affect - ** the overlappers, and this causes multiplayer games to go out of sync. - */ - object = cellptr->Cell_Occupier(); - while (object) { - if (!object->IsToDamage && object != source) { - object->IsToDamage = true; - objects[count++] = object; - if (count >= (sizeof(objects)/sizeof(objects[0]))) break; - } - object = object->Next; - } - if (count >= (sizeof(objects)/sizeof(objects[0]))) break; - } - - /* - ** Sweep through the units to be damaged and damage them. When damaging - ** buildings, consider a hit on any cell the building occupies as if it - ** were a direct hit on the building's center. - */ - for (index = 0; index < count; index++) { - object = objects[index]; - - object->IsToDamage = false; - if (object->What_Am_I() == RTTI_BUILDING && impacto == object) { - distance = 0; - } else { - distance = Distance(coord, object->Center_Coord()); - } - if (object->IsDown && !object->IsInLimbo && distance < range) { - int damage = strength; - - /* - ** High explosive does double damage against aircraft. - */ - if (warhead == WARHEAD_HE && object->What_Am_I() == RTTI_AIRCRAFT) { - damage *= 2; - } - - /* - ** Apply the damage to the object. - */ - if (damage) { - object->Take_Damage(damage, distance, warhead, source); - } - } - } - - /* - ** If there is a wall present at this location, it may be destroyed. Check to - ** make sure that the warhead is of the kind that can destroy walls. - */ - cellptr = &Map[cell]; - cellptr->Reduce_Tiberium(strength / 10); - if (cellptr->Overlay != OVERLAY_NONE) { - OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay); - - if (optr->IsWall) { - if (whead->IsWallDestroyer || (whead->IsWoodDestroyer && optr->IsWooden)) { - Map[cell].Reduce_Wall(strength); - } - } - } -} diff --git a/code/TIBERIANDAWN/COMBUF.CPP b/code/TIBERIANDAWN/COMBUF.CPP deleted file mode 100644 index 04dedba..0000000 --- a/code/TIBERIANDAWN/COMBUF.CPP +++ /dev/null @@ -1,1036 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\combuf.cpv 1.4 16 Oct 1995 16:50:16 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COMBUF.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : May 2, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * CommBufferClass::CommBufferClass -- class constructor * - * CommBufferClass::~CommBufferClass -- class destructor * - * CommBufferClass::Init -- initializes this queue * - * CommBufferClass::Queue_Send -- queues a message for sending * - * CommBufferClass::UnQueue_Send -- removes next entry from send queue * - * CommBufferClass::Get_Send -- gets ptr to queue entry * - * CommBufferClass::Queue_Receive -- queues a received message * - * CommBufferClass::UnQueue_Receive -- removes next entry from send queue* - * CommBufferClass::Get_Receive -- gets ptr to queue entry * - * CommBufferClass::Add_Delay -- adds a new delay value for response time* - * CommBufferClass::Avg_Response_Time -- returns average response time * - * CommBufferClass::Max_Response_Time -- returns max response time * - * CommBufferClass::Reset_Response_Time -- resets computations * - * Mono_Debug_Print -- Debug output routine * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * CommBufferClass::CommBufferClass -- class constructor * - * * - * INPUT: * - * numsend # queue entries for sending * - * numreceive # queue entries for receiving * - * maxlen maximum desired packet length, in bytes * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -CommBufferClass::CommBufferClass(int numsend, int numreceive, int maxlen) -{ - int i; - - /* - ----------------------------- Init variables ----------------------------- - */ - MaxSend = numsend; - MaxReceive = numreceive; - MaxPacketSize = maxlen; - - /* - ----------------------- Allocate the queue entries ----------------------- - */ - SendQueue = new SendQueueType[numsend]; - ReceiveQueue = new ReceiveQueueType[numreceive]; - - SendIndex = new int[numsend]; - ReceiveIndex = new int[numreceive]; - - /* - ---------------------- Allocate queue entry buffers ---------------------- - */ - for (i = 0; i < MaxSend; i++) { - SendQueue[i].Buffer = new char[maxlen]; - } - - for (i = 0; i < MaxReceive; i++) { - ReceiveQueue[i].Buffer = new char[maxlen]; - } - - Init(); - -} /* end of CommBufferClass */ - - -/*************************************************************************** - * CommBufferClass::~CommBufferClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -CommBufferClass::~CommBufferClass() -{ - int i; - - /* - ------------------------ Free queue entry buffers ------------------------ - */ - for (i = 0; i < MaxSend; i++) { - delete [] SendQueue[i].Buffer; - } - - for (i = 0; i < MaxReceive; i++) { - delete [] ReceiveQueue[i].Buffer; - } - - delete [] SendQueue; - delete [] ReceiveQueue; - - delete [] SendIndex; - delete [] ReceiveIndex; - -} /* end of ~CommBufferClass */ - - -/*************************************************************************** - * CommBufferClass::Init -- initializes this queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/20/1995 BR : Created. * - *=========================================================================*/ -void CommBufferClass::Init(void) -{ - int i; - - /*------------------------------------------------------------------------ - Init data members - ------------------------------------------------------------------------*/ - SendTotal = 0L; - ReceiveTotal = 0L; - - DelaySum = 0L; - NumDelay = 0L; - MeanDelay = 0L; - MaxDelay = 0L; - - SendCount = 0; - - ReceiveCount = 0; - - /*------------------------------------------------------------------------ - Init the queue entries - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxSend; i++) { - SendQueue[i].IsActive = 0; - SendQueue[i].IsACK = 0; - SendQueue[i].FirstTime = 0L; - SendQueue[i].LastTime = 0L; - SendQueue[i].SendCount = 0L; - SendQueue[i].BufLen = 0; - - SendIndex[i] = 0; - } - - for (i = 0; i < MaxReceive; i++) { - ReceiveQueue[i].IsActive = 0; - ReceiveQueue[i].IsRead = 0; - ReceiveQueue[i].IsACK = 0; - ReceiveQueue[i].BufLen = 0; - - ReceiveIndex[i] = 0; - } - - /*------------------------------------------------------------------------ - Init debug values - ------------------------------------------------------------------------*/ - DebugOffset = 0; - DebugSize = 0; - DebugNames = NULL; - DebugMaxNames = 0; - -} /* end of Init */ - - -void CommBufferClass::Init_Send_Queue(void) -{ - int i; - - /*------------------------------------------------------------------------ - Init data members - ------------------------------------------------------------------------*/ - SendCount = 0; - - /*------------------------------------------------------------------------ - Init the queue entries - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxSend; i++) { - SendQueue[i].IsActive = 0; - SendQueue[i].IsACK = 0; - SendQueue[i].FirstTime = 0L; - SendQueue[i].LastTime = 0L; - SendQueue[i].SendCount = 0L; - - SendIndex[i] = 0; - } - -} /* end of Init_Send_Queue */ - - -/*************************************************************************** - * CommBufferClass::Queue_Send -- queues a message for sending * - * * - * INPUT: * - * buf buffer containing the message * - * buflen length of 'buf' * - * * - * OUTPUT: * - * 1 = OK, 0 = no room in the queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommBufferClass::Queue_Send(void *buf, int buflen) -{ - int i; - int index; - - /* - --------------------- Error if no room in the queue ---------------------- - */ - if (SendCount==MaxSend) - return(0); - - /* - -------------------------- Find an empty slot ---------------------------- - */ - index = -1; - for (i = 0; i < MaxSend; i++) { - if (SendQueue[i].IsActive==0) { - index = i; - break; - } - } - - /* - ---------------------------- Set entry flags ----------------------------- - */ - SendQueue[index].IsActive = 1; // entry is now active - SendQueue[index].IsACK = 0; // entry hasn't been ACK'd - SendQueue[index].FirstTime = 0L; // filled in by Manager when sent - SendQueue[index].LastTime = 0L; // filled in by Manager when sent - SendQueue[index].SendCount = 0L; // filled in by Manager when sent - SendQueue[index].BufLen = buflen; // save buffer size - - /* - ------------------------- Copy the packet data --------------------------- - */ - memcpy(SendQueue[index].Buffer,buf,buflen); - - /* - ----------------------- Save this entry's index -------------------------- - */ - SendIndex[SendCount] = index; - - /* - -------------------- Increment counters & entry ptr ---------------------- - */ - SendCount++; - SendTotal++; - - return(1); - -} /* end of Queue_Send */ - - -/*************************************************************************** - * CommBufferClass::UnQueue_Send -- removes next entry from send queue * - * * - * Frees the given entry; the index given by the caller is the "active" * - * index value (ie the "nth" active entry), not the actual index in the * - * array. * - * * - * INPUT: * - * buf buffer to store entry's data in; if NULL, it's discarded * - * buflen filled in with length of entry retrieved * - * index "index" of entry to un-queue * - * * - * OUTPUT: * - * 1 = OK, 0 = no entry to retreive * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommBufferClass::UnQueue_Send(void *buf, int *buflen, int index) -{ - int i; - - /* - --------------------- Error if no entry to retrieve ---------------------- - */ - if (SendCount==0 || SendQueue[SendIndex[index]].IsActive==0) - return(0); - - /* - ---------------------- Copy the data from the entry ---------------------- - */ - if (buf!=NULL) { - memcpy(buf,SendQueue[SendIndex[index]].Buffer, - SendQueue[SendIndex[index]].BufLen); - (*buflen) = SendQueue[SendIndex[index]].BufLen; - } - - /* - ---------------------------- Set entry flags ----------------------------- - */ - SendQueue[SendIndex[index]].IsActive = 0; - SendQueue[SendIndex[index]].IsACK = 0; - SendQueue[SendIndex[index]].FirstTime = 0L; - SendQueue[SendIndex[index]].LastTime = 0L; - SendQueue[SendIndex[index]].SendCount = 0L; - SendQueue[SendIndex[index]].BufLen = 0; - - /* - ------------------------- Move Indices back one -------------------------- - */ - for (i = index; i < SendCount - 1; i++) { - SendIndex[i] = SendIndex[i + 1]; - } - SendIndex[SendCount - 1] = 0; - SendCount--; - - return(1); - -} /* end of UnQueue_Send */ - - -/*************************************************************************** - * CommBufferClass::Get_Send -- gets ptr to queue entry * - * * - * This routine gets a pointer to the indicated queue entry. The index * - * value is relative to the next-accessable queue entry; 0 = get the * - * next available queue entry, 1 = get the one behind that, etc. * - * * - * INPUT: * - * index index of entry to get (0 = 1st available) * - * * - * OUTPUT: * - * ptr to entry * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/21/1994 BR : Created. * - *=========================================================================*/ -SendQueueType * CommBufferClass::Get_Send(int index) -{ - if (SendQueue[SendIndex[index]].IsActive==0) { - return(NULL); - } else { - return(&SendQueue[SendIndex[index]]); - } - -} /* end of Get_Send */ - - -/*************************************************************************** - * CommBufferClass::Queue_Receive -- queues a received message * - * * - * INPUT: * - * buf buffer containing the message * - * buflen length of 'buf' * - * * - * OUTPUT: * - * 1 = OK, 0 = no room in the queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommBufferClass::Queue_Receive(void *buf, int buflen) -{ - int i; - int index; - -//CCDebugString ("C&C95 - Queueing a receive packet\n"); - - /* - --------------------- Error if no room in the queue ---------------------- - */ - if (ReceiveCount==MaxReceive) { -CCDebugString ("C&C95 - Error - Receive queue full!\n"); - return(0); - } - - /* - -------------------------- Find an empty slot ---------------------------- - */ - index = -1; - for (i = 0; i < MaxReceive; i++) { - if (ReceiveQueue[i].IsActive==0) { - index = i; - break; - } - } - -if (index == -1){ -CCDebugString ("C&C95 - Error - Receive queue full too!\n"); -} - - - /* - ---------------------------- Set entry flags ----------------------------- - */ - ReceiveQueue[index].IsActive = 1; - ReceiveQueue[index].IsRead = 0; - ReceiveQueue[index].IsACK = 0; - ReceiveQueue[index].BufLen = buflen; - - /* - ------------------------- Copy the packet data --------------------------- - */ - memcpy(ReceiveQueue[index].Buffer,buf,buflen); - - /* - ----------------------- Save this entry's index -------------------------- - */ - ReceiveIndex[ReceiveCount] = index; - - /* - -------------------- Increment counters & entry ptr ---------------------- - */ - ReceiveCount++; - ReceiveTotal++; - - return(1); - -} /* end of Queue_Receive */ - - -/*************************************************************************** - * CommBufferClass::UnQueue_Receive -- removes next entry from send queue * - * * - * Frees the given entry; the index given by the caller is the "active" * - * index value (ie the "nth" active entry), not the actual index in the * - * array. * - * * - * INPUT: * - * buf buffer to store entry's data in; if NULL, it's discarded * - * buflen filled in with length of entry retrieved * - * index index of entry to un-queue * - * * - * OUTPUT: * - * 1 = OK, 0 = no entry to retreive * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommBufferClass::UnQueue_Receive(void *buf, int *buflen, int index) -{ - int i; - - /* - --------------------- Error if no entry to retrieve ---------------------- - */ - if (ReceiveCount==0 || ReceiveQueue[ReceiveIndex[index]].IsActive==0) { - return(0); - } - - /* - ---------------------- Copy the data from the entry ---------------------- - */ - if (buf!=NULL) { - memcpy(buf,ReceiveQueue[ReceiveIndex[index]].Buffer, - ReceiveQueue[ReceiveIndex[index]].BufLen); - (*buflen) = ReceiveQueue[ReceiveIndex[index]].BufLen; - } - - /* - ---------------------------- Set entry flags ----------------------------- - */ - ReceiveQueue[ReceiveIndex[index]].IsActive = 0; - ReceiveQueue[ReceiveIndex[index]].IsRead = 0; - ReceiveQueue[ReceiveIndex[index]].IsACK = 0; - ReceiveQueue[ReceiveIndex[index]].BufLen = 0; - - /* - ------------------------- Move Indices back one -------------------------- - */ - for (i = index; i < ReceiveCount - 1; i++) { - ReceiveIndex[i] = ReceiveIndex[i + 1]; - } - ReceiveIndex[ReceiveCount - 1] = 0; - ReceiveCount--; - - return(1); - -} /* end of UnQueue_Receive */ - - -/*************************************************************************** - * CommBufferClass::Get_Receive -- gets ptr to queue entry * - * * - * This routine gets a pointer to the indicated queue entry. The index * - * value is relative to the next-accessable queue entry; 0 = get the * - * next available queue entry, 1 = get the one behind that, etc. * - * * - * INPUT: * - * index index of entry to get (0 = 1st available) * - * * - * OUTPUT: * - * ptr to entry * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/21/1994 BR : Created. * - *=========================================================================*/ -ReceiveQueueType * CommBufferClass::Get_Receive(int index) -{ - if (ReceiveQueue[ReceiveIndex[index]].IsActive==0) { - return(NULL); - } else { - return(&ReceiveQueue[ReceiveIndex[index]]); - } - -} /* end of Get_Receive */ - - -/*************************************************************************** - * CommBufferClass::Add_Delay -- adds a new delay value for response time * - * * - * This routine updates the average response time for this queue. The * - * computation is based on the average of the last 'n' delay values given, * - * It computes a running total of the last n delay values, then divides * - * that by n to compute the average. * - * * - * When the number of values given exceeds the max, the mean is subtracted * - * off the total, then the new value is added in. Thus, any single delay * - * value will have an effect on the total that approaches 0 over time, and * - * the new delay value contributes to 1/n of the mean. * - * * - * INPUT: * - * delay value to add into the response time computation * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -void CommBufferClass::Add_Delay(unsigned long delay) -{ - int roundoff = 0; - - if (NumDelay==256) { - DelaySum -= MeanDelay; - DelaySum += delay; - if ( (DelaySum & 0x00ff) > 127) - roundoff = 1; - MeanDelay = (DelaySum >> 8) + roundoff; - } else { - NumDelay++; - DelaySum += delay; - MeanDelay = DelaySum / NumDelay; - } - - if (delay > MaxDelay) - MaxDelay = delay; - -} /* end of Add_Delay */ - - -/*************************************************************************** - * CommBufferClass::Avg_Response_Time -- returns average response time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * latest computed average response time * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -unsigned long CommBufferClass::Avg_Response_Time(void) -{ - return(MeanDelay); - -} /* end of Avg_Response_Time */ - - -/*************************************************************************** - * CommBufferClass::Max_Response_Time -- returns max response time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * latest computed average response time * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -unsigned long CommBufferClass::Max_Response_Time(void) -{ - return(MaxDelay); - -} /* end of Max_Response_Time */ - - -/*************************************************************************** - * CommBufferClass::Reset_Response_Time -- resets computations * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -void CommBufferClass::Reset_Response_Time(void) -{ - DelaySum = 0L; - NumDelay = 0L; - MeanDelay = 0L; - MaxDelay = 0L; - -} /* end of Reset_Response_Time */ - - -/*************************************************************************** - * CommBufferClass::Configure_Debug -- sets up special debug values * - * * - * Mono_Debug_Print2() can look into a packet to pull out a particular * - * ID, and can print both that ID and a string corresponding to * - * that ID. This routine configures these values so it can find * - * and decode the ID. This ID is used in addition to the normal * - * CommHeaderType values. * - * * - * INPUT: * - * offset ID's byte offset into packet * - * size size of ID, in bytes; 0 if none * - * names ptr to array of names; use ID as an index into this * - * maxnames max # in the names array; 0 if none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * Names shouldn't be longer than 12 characters. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -void CommBufferClass::Configure_Debug(int offset, int size, char **names, - int maxnames) -{ - DebugOffset = offset; - DebugSize = size; - DebugNames = names; - DebugMaxNames = maxnames; - -} /* end of Configure_Debug */ - - -/*************************************************************************** - * Mono_Debug_Print -- Debug output routine * - * * - * This routine leaves 5 lines at the top for the caller's use. * - * * - * INPUT: * - * refresh 1 = clear screen & completely refresh * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/02/1995 BRR : Created. * - *=========================================================================*/ -void CommBufferClass::Mono_Debug_Print(int refresh) -{ -#ifdef WWLIB32_H - int i; // loop counter - static int send_col[] = {1,14,28}; // coords of send queue columns - static int receive_col[] = {40,54,68}; // coords of recv queue columns - int row,col; // current row,col for printing - int num; // max # items to print - - struct CommHdr { // this mirrors the CommHeaderType - unsigned short MagicNumber; - unsigned char Code; - unsigned long PacketID; - } *hdr; - - /*------------------------------------------------------------------------ - If few enough entries, call the verbose debug version - ------------------------------------------------------------------------*/ - if (MaxSend <= 16) { - Mono_Debug_Print2(refresh); - return; - } - - /*------------------------------------------------------------------------ - Refresh the screen - ------------------------------------------------------------------------*/ - if (refresh) { - Mono_Clear_Screen (); - Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"); - Mono_Printf("³ Send Queue ³ Receive Queue ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ID Ct ACK ID Ct ACK ID Ct ACK³ ID Rd ACK ID Rd ACK ID Rd ACK³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); - } - - /*------------------------------------------------------------------------ - Print Send Queue items - ------------------------------------------------------------------------*/ - if (MaxSend <= 48) { - num = MaxSend; - } else { - num = 48; - } - col = 0; - row = 0; - for (i = 0; i < MaxSend; i++) { - Mono_Set_Cursor (send_col[col],row + 8); - if (SendQueue[i].IsActive) { - hdr = (CommHdr *)SendQueue[i].Buffer; - hdr->MagicNumber = hdr->MagicNumber; - hdr->Code = hdr->Code; - Mono_Printf ("%4d %2d %d",hdr->PacketID, SendQueue[i].SendCount, - SendQueue[i].IsACK); - } else { - Mono_Printf ("____ __ _ "); - } - - row++; - if (row > 15) { - row = 0; - col++; - } - } - - /*------------------------------------------------------------------------ - Print Receive Queue items - ------------------------------------------------------------------------*/ - if (MaxReceive <= 48) { - num = MaxSend; - } else { - num = 48; - } - col = 0; - row = 0; - for (i = 0; i < MaxReceive; i++) { - Mono_Set_Cursor (receive_col[col],row + 8); - if (ReceiveQueue[i].IsActive) { - hdr = (CommHdr *)ReceiveQueue[i].Buffer; - Mono_Printf ("%4d %d %d",hdr->PacketID, ReceiveQueue[i].IsRead, - ReceiveQueue[i].IsACK); - } else { - Mono_Printf ("____ _ _ "); - } - - row++; - if (row > 15) { - row = 0; - col++; - } - } - -#else - refresh = refresh; -#endif -} /* end of Mono_Debug_Print */ - - -/*************************************************************************** - * CommBufferClass::Mono_Debug_Print2 -- Debug output; alternate format * - * * - * This routine prints more information than the other version; it's * - * called only if the number of queue entries is small enough to support * - * this format. * - * * - * INPUT: * - * refresh 1 = clear screen & completely refresh * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -void CommBufferClass::Mono_Debug_Print2(int refresh) -{ -#ifdef WWLIB32_H - int i; // loop counter - char txt[80]; - int val; - - struct CommHdr { // this mirrors the CommHeaderType - unsigned short MagicNumber; - unsigned char Code; - unsigned long PacketID; - } *hdr; - - /*------------------------------------------------------------------------ - Refresh the screen - ------------------------------------------------------------------------*/ - if (refresh) { - Mono_Clear_Screen (); - Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"); - Mono_Printf("³ Send Queue ³ Receive Queue ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ID Ct Type Data Name ACK ³ ID Rd Type Data Name ACK ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); - } - - /*------------------------------------------------------------------------ - Print Send Queue items - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxSend; i++) { - Mono_Set_Cursor (1,8 + i); - /*..................................................................... - Print an active entry - .....................................................................*/ - if (SendQueue[i].IsActive) { - /*.................................................................. - Get header info - ..................................................................*/ - hdr = (CommHdr *)SendQueue[i].Buffer; - hdr->MagicNumber = hdr->MagicNumber; - hdr->Code = hdr->Code; - sprintf(txt,"%4d %2d %-5s ", - hdr->PacketID, - SendQueue[i].SendCount, - ConnectionClass::Command_Name(hdr->Code)); - - /*.................................................................. - Decode app's ID & its name - ..................................................................*/ - if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) { - if (DebugSize==1) { - val = *(SendQueue[i].Buffer + DebugOffset); - } else { - if (DebugSize==2) { - val = *((short *)(SendQueue[i].Buffer + DebugOffset)); - } else { - if (DebugSize==4) { - val = *((int *)(SendQueue[i].Buffer + DebugOffset)); - } - } - } - sprintf(txt + strlen(txt),"%4d ",val); - - if (DebugMaxNames > 0 && val >= 0 && val < DebugMaxNames) { - sprintf(txt + strlen(txt),"%-12s %x", DebugNames[val], SendQueue[i].IsACK); - } else { - sprintf(txt + strlen(txt)," %x",SendQueue[i].IsACK); - } - } else { - sprintf(txt + strlen(txt)," %x",SendQueue[i].IsACK); - } - - Mono_Printf("%s",txt); - } else { - - /*..................................................................... - Entry isn't active; print blanks - .....................................................................*/ - Mono_Printf("____ __ _"); - } - } - - /*------------------------------------------------------------------------ - Print Receive Queue items - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxReceive; i++) { - Mono_Set_Cursor (40,8 + i); - /*..................................................................... - Print an active entry - .....................................................................*/ - if (ReceiveQueue[i].IsActive) { - /*.................................................................. - Get header info - ..................................................................*/ - hdr = (CommHdr *)ReceiveQueue[i].Buffer; - hdr->MagicNumber = hdr->MagicNumber; - hdr->Code = hdr->Code; - sprintf(txt,"%4d %2d %-5s ", - hdr->PacketID, - ReceiveQueue[i].IsRead, - ConnectionClass::Command_Name(hdr->Code)); - /*.................................................................. - Decode app's ID & its name - ..................................................................*/ - if (DebugSize && (DebugOffset + DebugSize) <= ReceiveQueue[i].BufLen) { - if (DebugSize==1) { - val = *(ReceiveQueue[i].Buffer + DebugOffset); - } else { - if (DebugSize==2) { - val = *((short *)(ReceiveQueue[i].Buffer + DebugOffset)); - } else { - if (DebugSize==4) { - val = *((int *)(ReceiveQueue[i].Buffer + DebugOffset)); - } - } - } - sprintf(txt + strlen(txt),"%4d ",val); - - if (DebugMaxNames > 0 && val >= 0 && val < DebugMaxNames) { - sprintf(txt + strlen(txt),"%-12s %x", - DebugNames[val], - ReceiveQueue[i].IsACK); - } else { - sprintf(txt + strlen(txt)," %x",ReceiveQueue[i].IsACK); - } - } else { - sprintf(txt + strlen(txt)," %x",ReceiveQueue[i].IsACK); - } - - Mono_Printf("%s",txt); - } else { - - /*..................................................................... - Entry isn't active; print blanks - .....................................................................*/ - Mono_Printf("____ __ _"); - } - } - -#else - refresh = refresh; -#endif -} /* end of Mono_Debug_Print2 */ - - diff --git a/code/TIBERIANDAWN/COMBUF.H b/code/TIBERIANDAWN/COMBUF.H deleted file mode 100644 index 8c3a147..0000000 --- a/code/TIBERIANDAWN/COMBUF.H +++ /dev/null @@ -1,178 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\combuf.h_v 1.6 16 Oct 1995 16:46:00 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COMBUF.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 1, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This class's job is to store outgoing messages & incoming messages, * - * and serves as a storage area for various flags for ACK & Retry logic. * - * * - * This class stores buffers in a non-sequenced order; it allows freeing * - * any entry, so the buffers can be kept clear, even if packets come in * - * out of order. * - * * - * The class also contains routines to maintain a cumulative response time * - * for this queue. It's up to the caller to call Add_Delay() whenever * - * it detects that an outgoing message has been ACK'd; this class adds * - * that delay into a computed average delay over the last few message * - * delays. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef COMBUF_H -#define COMBUF_H - - -/* -********************************** Defines ********************************** -*/ -/*--------------------------------------------------------------------------- -This is one output queue entry ----------------------------------------------------------------------------*/ -typedef struct { - unsigned int IsActive : 1; // 1 = this entry is ready to be processed - unsigned int IsACK : 1; // 1 = ACK received for this packet - unsigned long FirstTime; // time this packet was first sent - unsigned long LastTime; // time this packet was last sent - unsigned long SendCount; // # of times this packet has been sent - int BufLen; // size of the packet stored in this entry - char *Buffer; // the data packet -} SendQueueType; - -/*--------------------------------------------------------------------------- -This is one input queue entry ----------------------------------------------------------------------------*/ -typedef struct { - unsigned int IsActive : 1; // 1 = this entry is ready to be processed - unsigned int IsRead : 1; // 1 = caller has read this entry - unsigned int IsACK : 1; // 1 = ACK sent for this packet - int BufLen; // size of the packet stored in this entry - char *Buffer; // the data packet -} ReceiveQueueType; - -/* -***************************** Class Declaration ***************************** -*/ -class CommBufferClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /* - ....................... Constructor/Destructor ........................ - */ - CommBufferClass(int numsend, int numrecieve, int maxlen); - virtual ~CommBufferClass(); - void Init(void); - void Init_Send_Queue(void); - - /* - ......................... Send Queue routines ......................... - */ - int Queue_Send(void *buf, int buflen); // add to Send queue - int UnQueue_Send(void *buf, int *buflen, int index); // remove from Send queue - int Num_Send(void) {return (SendCount);} // # entries in queue - int Max_Send(void) { return (MaxSend);} // max # send queue entries - SendQueueType * Get_Send(int index); // random access to queue - unsigned long Send_Total(void) {return (SendTotal);} - - /* - ....................... Receive Queue routines ........................ - */ - int Queue_Receive(void *buf, int buflen); // add to Receive queue - int UnQueue_Receive(void *buf, int *buflen, int index); // remove from Receive queue - int Num_Receive(void) {return (ReceiveCount);} // # entries in queue - int Max_Receive(void) { return (MaxReceive); } // max # recv queue entries - ReceiveQueueType * Get_Receive(int index); // random access to queue - unsigned long Receive_Total(void) {return (ReceiveTotal);} - - /* - ....................... Response time routines ........................ - */ - void Add_Delay(unsigned long delay); // accumulates response time - unsigned long Avg_Response_Time(void); // gets mean response time - unsigned long Max_Response_Time(void); // gets max response time - void Reset_Response_Time(void); // resets computations - - /* - ........................ Debug output routines ........................ - */ - void Configure_Debug(int offset, int size, char **names, int maxnames); - void Mono_Debug_Print(int refresh = 0); - void Mono_Debug_Print2(int refresh = 0); - - /* - --------------------------- Private Interface ---------------------------- - */ - private: - /* - .......................... Limiting variables ......................... - */ - int MaxSend; // max # send queue entries - int MaxReceive; // max # receive queue entries - int MaxPacketSize; // max size of a packet, in bytes - - /* - ....................... Response time variables ....................... - */ - unsigned long DelaySum; // sum of last 4 delay times - unsigned long NumDelay; // current # delay times summed - unsigned long MeanDelay; // current average delay time - unsigned long MaxDelay; // max delay ever for this queue - - /* - ........................ Send Queue variables ......................... - */ - SendQueueType * SendQueue; // incoming packets - int SendCount; // # packets in the queue - unsigned long SendTotal; // total # added to send queue - int *SendIndex; // array of Send entry indices - - /* - ....................... Receive Queue variables ....................... - */ - ReceiveQueueType * ReceiveQueue; // outgoing packets - int ReceiveCount; // # packets in the queue - unsigned long ReceiveTotal; // total # added to receive queue - int *ReceiveIndex; // array of Receive entry indices - - /* - ......................... Debugging Variables ......................... - */ - int DebugOffset; // offset into app's packet for ID - int DebugSize; // size of app's ID - char **DebugNames; // ptr to array of app-specific names - int DebugMaxNames; // max # of names in array -}; - -#endif - -/**************************** end of combuf.h ******************************/ - diff --git a/code/TIBERIANDAWN/COMPAT.H b/code/TIBERIANDAWN/COMPAT.H deleted file mode 100644 index 69d128e..0000000 --- a/code/TIBERIANDAWN/COMPAT.H +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\compat.h_v 2.19 16 Oct 1995 16:46:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COMPAT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/02/95 * - * * - * Last Update : March 2, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef COMPAT_H -#define COMPAT_H - - -//#include "i86.h" - -#define KeyNumType int -#define KeyASCIIType int - - - -#define BuffType BufferClass -#define movmem(a,b,c) memmove(b,a,c) -#define ShapeBufferSize _ShapeBufferSize -extern "C" { - extern long ShapeBufferSize; - extern char *ShapeBuffer; -} - -/*=========================================================================*/ -/* Define some equates for the different graphic routines we will install */ -/* later. */ -/*=========================================================================*/ -#define HIDBUFF ((void *)(0xA0000)) -//#define Size_Of_Region(a, b) a*b - -/*=========================================================================*/ -/* Define some Graphic Routines which will only be fixed by these defines */ -/*=========================================================================*/ -#define Set_Font_Palette(a) Set_Font_Palette_Range(a, 0, 15) - -/* -** These are the Open_File, Read_File, and Seek_File constants. -*/ -#define READ 1 // Read access. -#define WRITE 2 // Write access. - -#ifndef SEEK_SET -#define SEEK_SET 0 // Seek from start of file. -#define SEEK_CUR 1 // Seek relative from current location. -#define SEEK_END 2 // Seek from end of file. -#endif - -#define ERROR_WINDOW 1 -#define ErrorWindow 1 - - -extern unsigned char *Palette; -extern unsigned char MDisabled; // Is mouse disabled? -extern WORD Hard_Error_Occured; - -/* -** This is the menu control structures. -*/ -typedef enum MenuIndexType { - MENUX, - MENUY, - ITEMWIDTH, - ITEMSHIGH, - MSELECTED, - NORMCOL, - HILITE, - MENUPADDING=0x1000 -} MenuIndexType; - - -#define BITSPERBYTE 8 -#define MAXSHORT 0x7fff -#define HIBITS 0x8000 -//#define MAXLONG 0x7fffffffL -#define HIBITL 0x80000000 - -//PG_TO_FIX -#ifndef MAXINT -#define MAXINT MAXLONG -#endif -#define HIBITI HIBITL - -#define DMAXEXP 308 -#define FMAXEXP 38 -#define DMINEXP -307 -#define FMINEXP -37 - -#define MAXDOUBLE 1.797693E+308 -#define MAXFLOAT 3.37E+38F -#define MINDOUBLE 2.225074E-308 -#define MINFLOAT 8.43E-37F - -#define DSIGNIF 53 -#define FSIGNIF 24 - -#define DMAXPOWTWO 0x3FF -#define FMAXPOWTWO 0x7F -#define DEXPLEN 11 -#define FEXPLEN 8 -#define EXPBASE 2 -#define IEEE 1 -#define LENBASE 1 -#define HIDDENBIT 1 -#define LN_MAXDOUBLE 7.0978E+2 -#define LN_MINDOUBLE -7.0840E+2 - -/* These defines handle the various names given to the same color. */ -#define DKGREEN GREEN -#define DKBLUE BLUE -#define GRAY GREY -#define DKGREY GREY -#define DKGRAY GREY -#define LTGRAY LTGREY - -#if 0 -typedef struct { - short Width; // Width of icons (pixels). - short Height; // Height of icons (pixels). - short Count; // Number of (logical) icons in this set. - short Allocated; // Was this iconset allocated? - long Size; // Size of entire iconset memory block. - unsigned char * Icons; // Offset from buffer start to icon data. - long Palettes; // Offset from buffer start to palette data. - long Remaps; // Offset from buffer start to remap index data. - long TransFlag; // Offset for transparency flag table. - unsigned char * Map; // Icon map offset (if present). -} IControl_Type; -#endif - - - -void Stuff_Key_Num ( int ); - - -extern "C"{ -extern int MouseQX; -extern int MouseQY; -} - -#endif diff --git a/code/TIBERIANDAWN/COMQUEUE.CPP b/code/TIBERIANDAWN/COMQUEUE.CPP deleted file mode 100644 index c5df96e..0000000 --- a/code/TIBERIANDAWN/COMQUEUE.CPP +++ /dev/null @@ -1,1009 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\comqueue.cpv 1.10 16 Oct 1995 16:49:14 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COMQUEUE.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : May 31, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * CommQueueClass::CommQueueClass -- class constructor * - * CommQueueClass::~CommQueueClass -- class destructor * - * CommQueueClass::Init -- initializes this queue * - * CommQueueClass::Queue_Send -- queues a message for sending * - * CommQueueClass::UnQueue_Send -- removes next entry from send queue * - * CommQueueClass::Next_Send -- gets ptr to next entry in send queue * - * CommQueueClass::Get_Send -- gets ptr to queue entry * - * CommQueueClass::Queue_Receive -- queues a received message * - * CommQueueClass::UnQueue_Receive -- removes next entry from send queue * - * CommQueueClass::Next_Receive -- gets ptr to next entry in send queue * - * CommQueueClass::Get_Receive -- gets ptr to queue entry * - * CommQueueClass::Add_Delay -- adds a new delay value for response time * - * CommQueueClass::Avg_Response_Time -- returns average response time * - * CommQueueClass::Max_Response_Time -- returns max response time * - * CommQueueClass::Reset_Response_Time -- resets computations * - * CommQueueClass::Configure_Debug -- sets up special debug values * - * CommQueueClass::Mono_Debug_Print -- Debug output routine * - * CommQueueClass::Mono_Debug_Print2 -- Debug output; alternate format * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#if (0) - - -#include "function.h" - -#ifndef DEMO - -/*************************************************************************** - * CommQueueClass::CommQueueClass -- class constructor * - * * - * INPUT: * - * numsend # queue entries for sending * - * numreceive # queue entries for receiving * - * maxlen maximum desired packet length, in bytes * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -CommQueueClass::CommQueueClass(int numsend, int numreceive, int maxlen) -{ - int i; - - /* - ----------------------------- Init variables ----------------------------- - */ - MaxSend = numsend; - MaxReceive = numreceive; - MaxPacketSize = maxlen; - - /* - ----------------------- Allocate the queue entries ----------------------- - */ - SendQueue = new SendQueueType[numsend]; - ReceiveQueue = new ReceiveQueueType[numreceive]; - - /* - ---------------------- Allocate queue entry buffers ---------------------- - */ - for (i = 0; i < MaxSend; i++) { - SendQueue[i].Buffer = new char[maxlen]; - } - - for (i = 0; i < MaxReceive; i++) { - ReceiveQueue[i].Buffer = new char[maxlen]; - } - - Init(); - -} /* end of CommQueueClass */ - - -/*************************************************************************** - * CommQueueClass::~CommQueueClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -CommQueueClass::~CommQueueClass() -{ - int i; - - /* - ------------------------ Free queue entry buffers ------------------------ - */ - for (i = 0; i < MaxSend; i++) { - delete [] SendQueue[i].Buffer; - } - - for (i = 0; i < MaxReceive; i++) { - delete [] ReceiveQueue[i].Buffer; - } - - delete [] SendQueue; - delete [] ReceiveQueue; - -} /* end of ~CommQueueClass */ - - -/*************************************************************************** - * CommQueueClass::Init -- initializes this queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/20/1995 BR : Created. * - *=========================================================================*/ -void CommQueueClass::Init(void) -{ - int i; - - /*------------------------------------------------------------------------ - Init data members - ------------------------------------------------------------------------*/ - SendTotal = 0L; - ReceiveTotal = 0L; - - DelaySum = 0L; - NumDelay = 0L; - MeanDelay = 0L; - MaxDelay = 0L; - - SendCount = 0; - SendNext = 0; - SendEmpty = 0; - - ReceiveCount = 0; - ReceiveNext = 0; - ReceiveEmpty = 0; - - /*------------------------------------------------------------------------ - Init the queue entries - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxSend; i++) { - SendQueue[i].IsActive = 0; - SendQueue[i].IsACK = 0; - SendQueue[i].FirstTime = 0L; - SendQueue[i].LastTime = 0L; - SendQueue[i].SendCount = 0L; - ReceiveQueue[i].BufLen = 0; - } - for (i = 0; i < MaxReceive; i++) { - ReceiveQueue[i].IsActive = 0; - ReceiveQueue[i].IsRead = 0; - ReceiveQueue[i].IsACK = 0; - ReceiveQueue[i].BufLen = 0; - } - - /*------------------------------------------------------------------------ - Init debug values - ------------------------------------------------------------------------*/ - DebugOffset = 0; - DebugSize = 0; - DebugNames = NULL; - DebugMaxNames = 0; - -} /* end of Init */ - - -/*************************************************************************** - * CommQueueClass::Queue_Send -- queues a message for sending * - * * - * INPUT: * - * buf buffer containing the message * - * buflen length of 'buf' * - * * - * OUTPUT: * - * 1 = OK, 0 = no room in the queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommQueueClass::Queue_Send(void *buf, int buflen) -{ - /* - --------------------- Error if no room in the queue ---------------------- - */ - if (SendCount==MaxSend || SendQueue[SendEmpty].IsActive!=0) - return(0); - - /* - ---------------------------- Set entry flags ----------------------------- - */ - SendQueue[SendEmpty].IsActive = 1; // entry is now active - SendQueue[SendEmpty].IsACK = 0; // entry hasn't been ACK'd - SendQueue[SendEmpty].FirstTime = 0L; // filled in by Manager when sent - SendQueue[SendEmpty].LastTime = 0L; // filled in by Manager when sent - SendQueue[SendEmpty].SendCount = 0L; // filled in by Manager when sent - SendQueue[SendEmpty].BufLen = buflen; // save buffer size - - /* - ------------------------- Copy the packet data --------------------------- - */ - memcpy(SendQueue[SendEmpty].Buffer,buf,buflen); - - /* - -------------------- Increment counters & entry ptr ---------------------- - */ - SendCount++; - SendEmpty++; - if (SendEmpty==MaxSend) - SendEmpty = 0; - - SendTotal++; - - return(1); - -} /* end of Queue_Send */ - - -/*************************************************************************** - * CommQueueClass::UnQueue_Send -- removes next entry from send queue * - * * - * INPUT: * - * buf buffer to store entry's data in; if NULL, it's discarded * - * buflen filled in with length of entry retrieved * - * * - * OUTPUT: * - * 1 = OK, 0 = no entry to retreive * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommQueueClass::UnQueue_Send(void *buf, int *buflen) -{ - /* - --------------------- Error if no entry to retrieve ---------------------- - */ - if (SendCount==0 || SendQueue[SendNext].IsActive==0) - return(0); - - /* - ---------------------- Copy the data from the entry ---------------------- - */ - if (buf!=NULL) { - memcpy(buf,SendQueue[SendNext].Buffer,SendQueue[SendNext].BufLen); - (*buflen) = SendQueue[SendNext].BufLen; - } - - /* - ---------------------------- Set entry flags ----------------------------- - */ - SendQueue[SendNext].IsActive = 0; - SendQueue[SendNext].IsACK = 0; - SendQueue[SendNext].FirstTime = 0L; - SendQueue[SendNext].LastTime = 0L; - SendQueue[SendNext].SendCount = 0L; - SendQueue[SendNext].BufLen = 0; - SendCount--; - SendNext++; - if (SendNext==MaxSend) - SendNext = 0; - - return(1); - -} /* end of UnQueue_Send */ - - -/*************************************************************************** - * CommQueueClass::Next_Send -- gets ptr to next entry in send queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * ptr to entry, NULL if there is none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -SendQueueType * CommQueueClass::Next_Send(void) -{ - if (SendCount==0) { - return(NULL); - } else { - return(&SendQueue[SendNext]); - } -} - - -/*************************************************************************** - * CommQueueClass::Get_Send -- gets ptr to queue entry * - * * - * This routine gets a pointer to the indicated queue entry. The index * - * value is relative to the next-accessable queue entry; 0 = get the * - * next available queue entry, 1 = get the one behind that, etc. * - * * - * INPUT: * - * index index of entry to get (0 = 1st available) * - * * - * OUTPUT: * - * ptr to entry * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/21/1994 BR : Created. * - *=========================================================================*/ -SendQueueType * CommQueueClass::Get_Send(int index) -{ - int i; - - i = SendNext + index; - if (i >= MaxSend) - i -= MaxSend; - - if (SendQueue[i].IsActive==0) { - return(NULL); - } else { - return(&SendQueue[i]); - } -} - - -/*************************************************************************** - * CommQueueClass::Queue_Receive -- queues a received message * - * * - * INPUT: * - * buf buffer containing the message * - * buflen length of 'buf' * - * * - * OUTPUT: * - * 1 = OK, 0 = no room in the queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommQueueClass::Queue_Receive(void *buf, int buflen) -{ - /* - --------------------- Error if no room in the queue ---------------------- - */ - if (ReceiveCount==MaxReceive || ReceiveQueue[ReceiveEmpty].IsActive!=0) { - return(0); - } - - /* - ---------------------------- Set entry flags ----------------------------- - */ - ReceiveQueue[ReceiveEmpty].IsActive = 1; - ReceiveQueue[ReceiveEmpty].IsRead = 0; - ReceiveQueue[ReceiveEmpty].IsACK = 0; - ReceiveQueue[ReceiveEmpty].BufLen = buflen; - - /* - ------------------------- Copy the packet data --------------------------- - */ - if (buflen > MaxPacketLen){ - CCDebugString ("C&C95 - Error. Incoming packet too large"); - } - memcpy(ReceiveQueue[ReceiveEmpty].Buffer,buf,buflen); - - /* - -------------------- Increment counters & entry ptr ---------------------- - */ - ReceiveCount++; - ReceiveEmpty++; - if (ReceiveEmpty==MaxReceive) - ReceiveEmpty = 0; - - ReceiveTotal++; - - return(1); - -} /* end of Queue_Receive */ - - -/*************************************************************************** - * CommQueueClass::UnQueue_Receive -- removes next entry from send queue * - * * - * INPUT: * - * buf buffer to store entry's data in; if NULL, it's discarded * - * buflen filled in with length of entry retrieved * - * * - * OUTPUT: * - * 1 = OK, 0 = no entry to retreive * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int CommQueueClass::UnQueue_Receive(void *buf, int *buflen) -{ - /* - --------------------- Error if no entry to retrieve ---------------------- - */ - if (ReceiveCount==0 || ReceiveQueue[ReceiveNext].IsActive==0) { - return(0); - } - - /* - ---------------------- Copy the data from the entry ---------------------- - */ - if (buf!=NULL) { - memcpy(buf,ReceiveQueue[ReceiveNext].Buffer, - ReceiveQueue[ReceiveNext].BufLen); - (*buflen) = ReceiveQueue[ReceiveNext].BufLen; - } - - /* - ---------------------------- Set entry flags ----------------------------- - */ - ReceiveQueue[ReceiveNext].IsActive = 0; - ReceiveQueue[ReceiveNext].IsRead = 0; - ReceiveQueue[ReceiveNext].IsACK = 0; - ReceiveQueue[ReceiveNext].BufLen = 0; - ReceiveCount--; - ReceiveNext++; - if (ReceiveNext==MaxReceive) - ReceiveNext = 0; - - return(1); - -} /* end of UnQueue_Receive */ - - -/*************************************************************************** - * CommQueueClass::Next_Receive -- gets ptr to next entry in send queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * ptr to entry, NULL if there is none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -ReceiveQueueType * CommQueueClass::Next_Receive(void) -{ - if (ReceiveCount==0) { - return(NULL); - } else { - return(&ReceiveQueue[ReceiveNext]); - } -} - - -/*************************************************************************** - * CommQueueClass::Get_Receive -- gets ptr to queue entry * - * * - * This routine gets a pointer to the indicated queue entry. The index * - * value is relative to the next-accessable queue entry; 0 = get the * - * next available queue entry, 1 = get the one behind that, etc. * - * * - * INPUT: * - * index index of entry to get (0 = 1st available) * - * * - * OUTPUT: * - * ptr to entry * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/21/1994 BR : Created. * - *=========================================================================*/ -ReceiveQueueType * CommQueueClass::Get_Receive(int index) -{ - int i; - - i = ReceiveNext + index; - if (i >= MaxReceive) - i -= MaxReceive; - - if (ReceiveQueue[i].IsActive==0) { - return(NULL); - } else { - return(&ReceiveQueue[i]); - } -} - - -/*************************************************************************** - * CommQueueClass::Add_Delay -- adds a new delay value for response time * - * * - * This routine updates the average response time for this queue. The * - * computation is based on the average of the last 'n' delay values given, * - * It computes a running total of the last n delay values, then divides * - * that by n to compute the average. * - * * - * When the number of values given exceeds the max, the mean is subtracted * - * off the total, then the new value is added in. Thus, any single delay * - * value will have an effect on the total that approaches 0 over time, and * - * the new delay value contributes to 1/n of the mean. * - * * - * INPUT: * - * delay value to add into the response time computation * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -void CommQueueClass::Add_Delay(unsigned long delay) -{ - int roundoff = 0; - - if (NumDelay==256) { - DelaySum -= MeanDelay; - DelaySum += delay; - if ( (DelaySum & 0x00ff) > 127) - roundoff = 1; - MeanDelay = (DelaySum >> 8) + roundoff; - } else { - NumDelay++; - DelaySum += delay; - MeanDelay = DelaySum / NumDelay; - } - - if (delay > MaxDelay) { - MaxDelay = delay; - } - -} /* end of Add_Delay */ - - -/*************************************************************************** - * CommQueueClass::Avg_Response_Time -- returns average response time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * latest computed average response time * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -unsigned long CommQueueClass::Avg_Response_Time(void) -{ - return(MeanDelay); - -} /* end of Avg_Response_Time */ - - -/*************************************************************************** - * CommQueueClass::Max_Response_Time -- returns max response time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * latest computed average response time * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -unsigned long CommQueueClass::Max_Response_Time(void) -{ - return(MaxDelay); - -} /* end of Max_Response_Time */ - - -/*************************************************************************** - * CommQueueClass::Reset_Response_Time -- resets computations * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -void CommQueueClass::Reset_Response_Time(void) -{ - DelaySum = 0L; - NumDelay = 0L; - MeanDelay = 0L; - MaxDelay = 0L; - -} /* end of Reset_Response_Time */ - - -/*************************************************************************** - * CommQueueClass::Configure_Debug -- sets up special debug values * - * * - * Mono_Debug_Print2() can look into a packet to pull out a particular * - * ID, and can print both that ID and a string corresponding to * - * that ID. This routine configures these values so it can find * - * and decode the ID. This ID is used in addition to the normal * - * CommHeaderType values. * - * * - * INPUT: * - * offset ID's byte offset into packet * - * size size of ID, in bytes; 0 if none * - * names ptr to array of names; use ID as an index into this * - * maxnames max # in the names array; 0 if none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * Names shouldn't be longer than 12 characters. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -void CommQueueClass::Configure_Debug(int offset, int size, char **names, - int maxnames) -{ - DebugOffset = offset; - DebugSize = size; - DebugNames = names; - DebugMaxNames = maxnames; - -} /* end of Configure_Debug */ - - -/*************************************************************************** - * Mono_Debug_Print -- Debug output routine * - * * - * This routine leaves 5 lines at the top for the caller's use. * - * * - * INPUT: * - * refresh 1 = clear screen & completely refresh * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/02/1995 BRR : Created. * - *=========================================================================*/ -void CommQueueClass::Mono_Debug_Print(int refresh) -{ -#ifdef WWLIB32_H - int i; // loop counter - static int send_col[] = {1,14,28}; // coords of send queue columns - static int receive_col[] = {40,54,68}; // coords of recv queue columns - int row,col; // current row,col for printing - int num; // max # items to print - - struct CommHdr { // this mirrors the CommHeaderType - unsigned short MagicNumber; - unsigned char Code; - unsigned long PacketID; - } *hdr; - - /*------------------------------------------------------------------------ - If few enough entries, call the verbose debug version - ------------------------------------------------------------------------*/ - if (MaxSend <= 16) { - Mono_Debug_Print2(refresh); - return; - } - - /*------------------------------------------------------------------------ - Refresh the screen - ------------------------------------------------------------------------*/ - if (refresh) { - Mono_Clear_Screen (); - Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"); - Mono_Printf("³ Send Queue ³ Receive Queue ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ID Ct ACK ID Ct ACK ID Ct ACK³ ID Rd ACK ID Rd ACK ID Rd ACK³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); - } - - /*------------------------------------------------------------------------ - Print Send Queue items - ------------------------------------------------------------------------*/ - if (MaxSend <= 48) { - num = MaxSend; - } else { - num = 48; - } - col = 0; - row = 0; - for (i = 0; i < MaxSend; i++) { - Mono_Set_Cursor (send_col[col],row + 8); - if (SendQueue[i].IsActive) { - hdr = (CommHdr *)SendQueue[i].Buffer; - hdr->MagicNumber = hdr->MagicNumber; - hdr->Code = hdr->Code; - Mono_Printf ("%4d %2d %d",hdr->PacketID, SendQueue[i].SendCount, - SendQueue[i].IsACK); - } else { - Mono_Printf ("____ __ _ "); - } - - row++; - if (row > 15) { - row = 0; - col++; - } - } - - /*------------------------------------------------------------------------ - Print Receive Queue items - ------------------------------------------------------------------------*/ - if (MaxReceive <= 48) { - num = MaxSend; - } else { - num = 48; - } - col = 0; - row = 0; - for (i = 0; i < MaxReceive; i++) { - Mono_Set_Cursor (receive_col[col],row + 8); - if (ReceiveQueue[i].IsActive) { - hdr = (CommHdr *)ReceiveQueue[i].Buffer; - Mono_Printf ("%4d %d %d",hdr->PacketID, ReceiveQueue[i].IsRead, - ReceiveQueue[i].IsACK); - } else { - Mono_Printf ("____ _ _ "); - } - - row++; - if (row > 15) { - row = 0; - col++; - } - } - -#else - refresh = refresh; -#endif -} /* end of Mono_Debug_Print */ - - -/*************************************************************************** - * CommQueueClass::Mono_Debug_Print2 -- Debug output; alternate format * - * * - * This routine prints more information than the other version; it's * - * called only if the number of queue entries is small enough to support * - * this format. * - * * - * INPUT: * - * refresh 1 = clear screen & completely refresh * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -void CommQueueClass::Mono_Debug_Print2(int refresh) -{ -#ifdef WWLIB32_H - int i; // loop counter - char txt[80]; - int val; - - struct CommHdr { // this mirrors the CommHeaderType - unsigned short MagicNumber; - unsigned char Code; - unsigned long PacketID; - } *hdr; - - /*------------------------------------------------------------------------ - Refresh the screen - ------------------------------------------------------------------------*/ - if (refresh) { - Mono_Clear_Screen (); - Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("³ ³\n"); - Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"); - Mono_Printf("³ Send Queue ³ Receive Queue ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ID Ct Type Data Name ACK ³ ID Rd Type Data Name ACK ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("³ ³ ³\n"); - Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); - } - - /*------------------------------------------------------------------------ - Print Send Queue items - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxSend; i++) { - Mono_Set_Cursor (1,8 + i); - /*..................................................................... - Print an active entry - .....................................................................*/ - if (SendQueue[i].IsActive) { - /*.................................................................. - Get header info - ..................................................................*/ - hdr = (CommHdr *)SendQueue[i].Buffer; - hdr->MagicNumber = hdr->MagicNumber; - hdr->Code = hdr->Code; - sprintf(txt,"%4d %2d %-5s ", - hdr->PacketID, - SendQueue[i].SendCount, - ConnectionClass::Command_Name(hdr->Code)); - - /*.................................................................. - Decode app's ID & its name - ..................................................................*/ - if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) { - if (DebugSize==1) { - val = *(SendQueue[i].Buffer + DebugOffset); - } else { - if (DebugSize==2) { - val = *((short *)(SendQueue[i].Buffer + DebugOffset)); - } else { - if (DebugSize==4) { - val = *((int *)(SendQueue[i].Buffer + DebugOffset)); - } - } - } - sprintf(txt + strlen(txt),"%4d ",val); - - if (DebugMaxNames && val > 0 && val < DebugMaxNames) { - sprintf(txt + strlen(txt),"%-12s %x", - DebugNames[val], - SendQueue[i].IsACK); - } else { - sprintf(txt + strlen(txt)," %x",SendQueue[i].IsACK); - } - } - } else { - - /*..................................................................... - Entry isn't active; print blanks - .....................................................................*/ - Mono_Printf("____ __ _"); - } - } - - /*------------------------------------------------------------------------ - Print Receive Queue items - ------------------------------------------------------------------------*/ - for (i = 0; i < MaxReceive; i++) { - Mono_Set_Cursor (40,8 + i); - /*..................................................................... - Print an active entry - .....................................................................*/ - if (ReceiveQueue[i].IsActive) { - /*.................................................................. - Get header info - ..................................................................*/ - hdr = (CommHdr *)ReceiveQueue[i].Buffer; - hdr->MagicNumber = hdr->MagicNumber; - hdr->Code = hdr->Code; - sprintf(txt,"%4d %2d %-5s ", - hdr->PacketID, - ReceiveQueue[i].IsRead, - ConnectionClass::Command_Name(hdr->Code)); - /*.................................................................. - Decode app's ID & its name - ..................................................................*/ - if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) { - if (DebugSize==1) { - val = *(ReceiveQueue[i].Buffer + DebugOffset); - } else { - if (DebugSize==2) { - val = *((short *)(ReceiveQueue[i].Buffer + DebugOffset)); - } else { - if (DebugSize==4) { - val = *((int *)(ReceiveQueue[i].Buffer + DebugOffset)); - } - } - } - sprintf(txt + strlen(txt),"%4d ",val); - - if (DebugMaxNames && val > 0 && val < DebugMaxNames) { - sprintf(txt + strlen(txt),"%-12s %x", DebugNames[val], ReceiveQueue[i].IsACK); - } else { - sprintf(txt + strlen(txt)," %x",ReceiveQueue[i].IsACK); - } - } - } else { - - /*..................................................................... - Entry isn't active; print blanks - .....................................................................*/ - Mono_Printf("____ __ _"); - } - } - -#else - refresh = refresh; -#endif -} /* end of Mono_Debug_Print2 */ - - -#endif - - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/COMQUEUE.H b/code/TIBERIANDAWN/COMQUEUE.H deleted file mode 100644 index 3210ee5..0000000 --- a/code/TIBERIANDAWN/COMQUEUE.H +++ /dev/null @@ -1,190 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\comqueue.h_v 1.12 16 Oct 1995 16:45:08 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COMQUEUE.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 1, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This class's job is to queue up outgoing messages & incoming messages, * - * and serves as a storage area for various flags for ACK & Retry logic. * - * It allows the application to keep track of how many messages have * - * passed through this queue, in & out, so packets can use this as a * - * unique ID. (If packets have a unique ID, the application can use this * - * to detect re-sends.) * - * * - * The queues act as FIFO buffers (First-In, First-Out). The first entry * - * placed in a queue is the first one read from it, and so on. The * - * controlling application must ensure it places the entries on the queue * - * in the order it wants to access them. * - * * - * The queue is implemented as an array of Queue Entries. Index 0 is the * - * first element placed on the queue, and is the first retrieved. Index * - * 1 is the next, and so on. When Index 0 is retrieved, the next-available* - * entry becomes Index 1. The array is circular; when the end is reached, * - * the indices wrap around to the beginning. * - * * - * The class also contains routines to maintain a cumulative response time * - * for this queue. It's up to the caller to call Add_Delay() whenever * - * it detects that an outgoing message has been ACK'd; this class adds * - * that delay into a computed average delay over the last few message * - * delays. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef COMQUEUE_H -#define COMQUEUE_H - - - -/*--------------------------------------------------------------------------- -This is one output queue entry ----------------------------------------------------------------------------*/ -typedef struct { - unsigned int IsActive : 1; // 1 = this entry is ready to be processed - unsigned int IsACK : 1; // 1 = ACK received for this packet - unsigned long FirstTime; // time this packet was first sent - unsigned long LastTime; // time this packet was last sent - unsigned long SendCount; // # of times this packet has been sent - int BufLen; // size of the packet stored in this entry - char *Buffer; // the data packet -} SendQueueType; - -/*--------------------------------------------------------------------------- -This is one input queue entry ----------------------------------------------------------------------------*/ -typedef struct { - unsigned int IsActive : 1; // 1 = this entry is ready to be processed - unsigned int IsRead : 1; // 1 = caller has read this entry - unsigned int IsACK : 1; // 1 = ACK sent for this packet - int BufLen; // size of the packet stored in this entry - char *Buffer; // the data packet -} ReceiveQueueType; - -/* -***************************** Class Declaration ***************************** -*/ -class CommQueueClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /* - ....................... Constructor/Destructor ........................ - */ - CommQueueClass(int numsend, int numrecieve, int maxlen); - virtual ~CommQueueClass(); - void Init(void); - - /* - ......................... Send Queue routines ......................... - */ - int Queue_Send(void *buf, int buflen); // add to Send queue - int UnQueue_Send(void *buf, int *buflen); // remove from Send queue - SendQueueType * Next_Send(void); // ptr to next avail entry - int Num_Send(void) {return (SendCount);} // # entries in queue - int Max_Send(void) { return (MaxSend);} // max # send queue entries - SendQueueType * Get_Send(int index); // random access to queue - unsigned long Send_Total(void) {return (SendTotal);} - - /* - ....................... Receive Queue routines ........................ - */ - int Queue_Receive(void *buf, int buflen); // add to Receive queue - int UnQueue_Receive(void *buf, int *buflen); // remove from Receive queue - ReceiveQueueType * Next_Receive(void); // ptr to next avail entry - int Num_Receive(void) {return (ReceiveCount);} // # entries in queue - int Max_Receive(void) { return (MaxReceive); } // max # recv queue entries - ReceiveQueueType * Get_Receive(int index); // random access to queue - unsigned long Receive_Total(void) {return (ReceiveTotal);} - - /* - ....................... Response time routines ........................ - */ - void Add_Delay(unsigned long delay); // accumulates response time - unsigned long Avg_Response_Time(void); // gets mean response time - unsigned long Max_Response_Time(void); // gets max response time - void Reset_Response_Time(void); // resets computations - - /* - ........................ Debug output routines ........................ - */ - void Configure_Debug(int offset, int size, char **names, int maxnames); - void Mono_Debug_Print(int refresh = 0); - void Mono_Debug_Print2(int refresh = 0); - - /* - --------------------------- Private Interface ---------------------------- - */ - private: - /* - .......................... Limiting variables ......................... - */ - int MaxSend; // max # send queue entries - int MaxReceive; // max # receive queue entries - int MaxPacketSize; // max size of a packet, in bytes - - /* - ....................... Response time variables ....................... - */ - unsigned long DelaySum; // sum of last 4 delay times - unsigned long NumDelay; // current # delay times summed - unsigned long MeanDelay; // current average delay time - unsigned long MaxDelay; // max delay ever for this queue - - /* - ........................ Send Queue variables ......................... - */ - SendQueueType * SendQueue; // incoming packets - int SendCount; // # packets in the queue - int SendNext; // next entry read from queue - int SendEmpty; // next empty spot in queue - unsigned long SendTotal; // total # added to send queue - - /* - ....................... Receive Queue variables ....................... - */ - ReceiveQueueType * ReceiveQueue; // outgoing packets - int ReceiveCount; // # packets in the queue - int ReceiveNext; // next entry read from queue - int ReceiveEmpty; // next empty spot in queue - unsigned long ReceiveTotal; // total # added to receive queue - - /* - ......................... Debugging Variables ......................... - */ - int DebugOffset; // offset into app's packet for ID - int DebugSize; // size of app's ID - char **DebugNames; // ptr to array of app-specific names - int DebugMaxNames; // max # of names in array -}; - -#endif - -/*************************** end of comqueue.h *****************************/ - diff --git a/code/TIBERIANDAWN/CONFDLG.CPP b/code/TIBERIANDAWN/CONFDLG.CPP deleted file mode 100644 index ce6ebd3..0000000 --- a/code/TIBERIANDAWN/CONFDLG.CPP +++ /dev/null @@ -1,247 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\confdlg.cpv 2.17 16 Oct 1995 16:49:52 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONFDLG.CPP * - * * - * Programmer : Maria del Mar McCready Legg * - * Joe L. Bostic * - * * - * Start Date : Jan 30, 1995 * - * * - * Last Update : Jan 30, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ConfirmationClass::Process -- Handles all the options graphic interface. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "confdlg.h" - - -bool ConfirmationClass::Process(int text) -{ - return(Process(Text_String(text))); -} - - -/*********************************************************************************************** - * ConfirmationClass::Process -- Handles all the options graphic interface. * - * * - * This dialog uses an edit box to confirm a deletion. * - * * - * INPUT: char *string - display in edit box. * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 12/31/1994 MML : Created. * - *=============================================================================================*/ -bool ConfirmationClass::Process(char const * string) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - enum { - NUM_OF_BUTTONS = 2 - }; - - char buffer[80*3]; - int result = true; - int width; - int bwidth, bheight; // button width and height - int height; - int selection; - bool pressed; - int curbutton; - TextButtonClass *buttons[NUM_OF_BUTTONS]; - - /* - ** Set up the window. Window x-coords are in bytes not pixels. - */ - strcpy(buffer, string); - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(buffer, 200*factor, width, height); - width += 60*factor; - height += 60*factor; - int x = (320*factor - width) / 2; - int y = (200*factor - height) / 2; - - Set_Logic_Page(SeenBuff); - - /* - ** Create Buttons. Button coords are in pixels, but are window-relative. - */ - - bheight = FontHeight + FontYSpacing + 2; - bwidth = MAX( (String_Pixel_Width( Text_String( TXT_YES ) ) + 8), 30U); - - TextButtonClass yesbtn(BUTTON_YES, TXT_YES, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + 10*factor, y + height - (bheight + 5*factor), bwidth ); - - TextButtonClass nobtn(BUTTON_NO, TXT_NO, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + width - (bwidth + 10*factor), - y + height - (bheight + 5*factor), bwidth ); - - nobtn.Add_Tail(yesbtn); - - curbutton = 1; - buttons[0] = &yesbtn; - buttons[1] = &nobtn; - buttons[curbutton]->Turn_On(); - - /* - ** This causes left mouse button clicking within the confines of the dialog to - ** be ignored if it wasn't recognized by any other button or slider. - */ - GadgetClass dialog(x, y, width, height, GadgetClass::LEFTPRESS); - dialog.Add_Tail(yesbtn); - - /* - ** This causes a right click anywhere or a left click outside the dialog region - ** to be equivalent to clicking on the return to options dialog. - */ - ControlClass background(BUTTON_NO, 0, 0, SeenBuff.Get_Width(), SeenBuff.Get_Height(), GadgetClass::LEFTPRESS|GadgetClass::RIGHTPRESS); - background.Add_Tail(yesbtn); - - /* - ** Main Processing Loop. - */ - bool display = true; - bool process = true; - pressed = false; - while (process) { - - /* - ** Invoke game callback. - */ - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - result = false; - } - } - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Refresh display if needed. - */ - if (display) { - Hide_Mouse(); - - /* - ** Draw the background. - */ - Dialog_Box(x, y, width, height); - Draw_Caption(TXT_CONFIRMATION, x, y, width); - Fancy_Text_Print(buffer, x+20*factor, y+30*factor, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - - /* - ** Draw the titles. - */ - yesbtn.Draw_All(); - Show_Mouse(); - display = false; - } - - /* - ** Get user input. - */ - KeyNumType input = yesbtn.Input(); - - /* - ** Process Input. - */ - switch (input) { - case (BUTTON_YES | KN_BUTTON): - selection = BUTTON_YES; - pressed = true; - break; - - case (KN_ESC): - case (BUTTON_NO | KN_BUTTON): - selection = BUTTON_NO; - pressed = true; - break; - - case (KN_LEFT): - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - - curbutton--; - if (curbutton < 0) { - curbutton = NUM_OF_BUTTONS - 1; - } - - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case (KN_RIGHT): - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - - curbutton++; - if (curbutton > (NUM_OF_BUTTONS - 1) ) { - curbutton = 0; - } - - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case (KN_RETURN): - selection = curbutton + BUTTON_YES; - pressed = true; - break; - - default: - break; - } - - if (pressed) { - switch (selection) { - case (BUTTON_YES): - result = true; - process = false; - break; - - case (BUTTON_NO): - result = false; - process = false; - break; - } - - pressed = false; - } - } - return(result); -} diff --git a/code/TIBERIANDAWN/CONFDLG.H b/code/TIBERIANDAWN/CONFDLG.H deleted file mode 100644 index 2726766..0000000 --- a/code/TIBERIANDAWN/CONFDLG.H +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\confdlg.h_v 2.18 16 Oct 1995 16:46:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONFDLG.H * - * * - * Programmer : Maria del Mar McCready Legg * - * Joe L. Bostic * - * * - * Start Date : Jan 30, 1995 * - * * - * Last Update : Jan 30, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------*/ - -#ifndef CONFDLG_H -#define CONFDLG_H - -#include "gadget.h" - -class ConfirmationClass -{ - private: - enum ConfirmationClassEnum { - BUTTON_YES=1, // Button number for "Options menu" - BUTTON_NO, // Button number for "Options menu" - }; - - public: - ConfirmationClass(void) { }; - bool Process(char const * string); - bool Process(int text); -}; - -#endif diff --git a/code/TIBERIANDAWN/CONNECT.CPP b/code/TIBERIANDAWN/CONNECT.CPP deleted file mode 100644 index fe5289d..0000000 --- a/code/TIBERIANDAWN/CONNECT.CPP +++ /dev/null @@ -1,248 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\connect.cpv 1.9 16 Oct 1995 16:48:56 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONNECT.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 20, 1994 * - * * - * Last Update : May 31, 1995 [BRR] * - *-------------------------------------------------------------------------* - * Functions: * - * ConnectionClass::ConnectionClass -- class constructor * - * ConnectionClass::~ConnectionClass -- class destructor * - * ConnectionClass::Service -- main polling routine; services packets * - * ConnectionClass::Time -- gets current time * - * ConnectionClass::Command_Name -- returns name for a packet command * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef WWLIB32_H -#include "TIMER.H" -#else -#include -#endif - -/* -********************************* Globals *********************************** -*/ -char *ConnectionClass::Commands[PACKET_COUNT] = { - "ADATA", - "NDATA", - "ACK" -}; - - -/*************************************************************************** - * ConnectionClass::ConnectionClass -- class constructor * - * * - * If either max_retries or timeout is -1, that parameter is ignored in * - * timeout computations. If both are -1, the connection will just keep * - * retrying forever. * - * * - * INPUT: * - * numsend desired # of entries for the send queue * - * numreceive desired # of entries for the recieve queue * - * maxlen max length of an application packet * - * magicnum the packet "magic number" for this connection * - * retry_delta the time to wait between sends * - * max_retries the max # of retries allowed for a packet * - * (-1 means retry forever, based on this parameter) * - * timeout the max amount of time before we give up on a packet * - * (-1 means retry forever, based on this parameter) * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -ConnectionClass::ConnectionClass (int maxlen, unsigned short magicnum, - unsigned long retry_delta, unsigned long max_retries, unsigned long timeout) -{ - /*------------------------------------------------------------------------ - Compute our maximum packet length - ------------------------------------------------------------------------*/ - MaxPacketLen = maxlen + sizeof(CommHeaderType); - - /*------------------------------------------------------------------------ - Assign the magic number - ------------------------------------------------------------------------*/ - MagicNum = magicnum; - - /*------------------------------------------------------------------------ - Initialize the retry time. This is the time that t2 - t1 must be greater - than before a retry will occur. - ------------------------------------------------------------------------*/ - RetryDelta = retry_delta; - - /*------------------------------------------------------------------------ - Set the maximum allowable retries. - ------------------------------------------------------------------------*/ - MaxRetries = max_retries; - - /*------------------------------------------------------------------------ - Set the timeout for this connection. - ------------------------------------------------------------------------*/ - Timeout = timeout; - - /*------------------------------------------------------------------------ - Allocate the packet staging buffer. This will be used to - ------------------------------------------------------------------------*/ - PacketBuf = new char[ MaxPacketLen ]; - -} /* end of ConnectionClass */ - - -/*************************************************************************** - * ConnectionClass::~ConnectionClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -ConnectionClass::~ConnectionClass () -{ - /*------------------------------------------------------------------------ - Free memory. - ------------------------------------------------------------------------*/ - delete [] PacketBuf; - -} /* end of ~ConnectionClass */ - - -/*************************************************************************** - * ConnectionClass::Service -- main polling routine; services packets * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error (connection is broken!) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int ConnectionClass::Service (void) -{ - /*------------------------------------------------------------------------ - Service the Send Queue. This [re]sends packets in the Send Queue which - haven't been ACK'd yet, and if their retry timeout has expired, and - updates the FirstTime, LastTime & SendCount values in the Queue entry. - Entries that have been ACK'd should be removed. - ------------------------------------------------------------------------*/ -// if (!Service_Send_Queue()) -// return(0); - - /*------------------------------------------------------------------------ - Service the Receive Queue. This sends ACKs for packets that haven't - been ACK'd yet. Entries that the app has read, and have been ACK'd, - should be removed. - ------------------------------------------------------------------------*/ -// if (!Service_Receive_Queue()) -// return(0); - -// return(1); - - if ( Service_Send_Queue() && Service_Receive_Queue() ) { - return(1); - } else { - return(0); - } - -} /* end of Service */ - -// ST = 12/17/2018 5:44PM -#ifndef TickCount -extern TimerClass TickCount; -#endif - -/*************************************************************************** - * ConnectionClass::Time -- gets current time * - * * - * INPUT: * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -unsigned long ConnectionClass::Time (void) -{ -#ifdef WWLIB32_H - return(TickCount.Time()); // Westwood Library time -#else - static struct timeb mytime; // DOS time - unsigned long msec; - - ftime(&mytime); - msec = (unsigned long)mytime.time * 1000L + (unsigned long)mytime.millitm; - return((msec / 100) * 6); -#endif - -} /* end of Time */ - - -/*************************************************************************** - * ConnectionClass::Command_Name -- returns name for given packet command * - * * - * INPUT: * - * command packet Command value to get name for * - * * - * OUTPUT: * - * ptr to command name, NULL if invalid * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -char *ConnectionClass::Command_Name(int command) -{ - if (command >= 0 && command < PACKET_COUNT) { - return(Commands[command]); - } else { - return(NULL); - } -} - diff --git a/code/TIBERIANDAWN/CONNECT.H b/code/TIBERIANDAWN/CONNECT.H deleted file mode 100644 index eee968a..0000000 --- a/code/TIBERIANDAWN/CONNECT.H +++ /dev/null @@ -1,340 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\connect.h_v 1.12 16 Oct 1995 16:46:04 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONNECT.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 1, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * DESCRIPTION: * - * This class represents a single "connection" with another system. It's * - * a pure virtual base class that acts as a framework for other classes. * - * * - * This class contains a CommQueueClass member, which stores received * - * & transmitted packets. The ConnectionClass has virtual functions to * - * handle adding packets to the queue, reading them from the queue, * - * a Send routine for actually sending data, and a Receive_Packet function * - * which is used to tell the connection that a new packet has come in. * - * * - * The virtual Service routine will handle all ACK & Retry logic for * - * communicating between this system & another. Thus, any class derived * - * from this class must provide the basic ACK/Retry logic. * - * * - * THE HEADER: * - * The Connection Classes prefix every packet sent with a header that's * - * local to this class. The header contains a "Magic Number" which should * - * be unique for each product, and Packet "Code", which will tell the * - * receiving end if this is DATA, or an ACK packet, and a packet ID, which * - * is a unique numerical ID for this packet (useful for detecting resends).* - * The header is stored with each packet in the send & receive Queues; * - * it's removed before it's passed back to the application, via * - * Get_Packet() * - * * - * THE CONNECTION MANAGER: * - * It is assumed that there will be a "Connection Manager" class which * - * will handle parsing incoming packets; it will then tell the connection * - * that new packets have come in, and the connection will process them in * - * whatever way it needs to for its protocol (check for resends, handle * - * ACK packets, etc). The job of the connection manager is to parse * - * incoming packets & distribute them to the connections that need to * - * store them (for multi-connection protocols). * - * * - * NOTES ON ACK/RETRY: * - * The packet's ID is used to check for re-sends. The ID is set to the * - * Queue's total Send Count; if the receiving system checks this value, * - * and it's less than that system's Receive Count, this is a resend. * - * (ie packet 0 will be the 1st packet sent, since the Send Queue's count * - * is 0 when it's sent; as soon as it's received, the Receive Count goes * - * up to 1, and an ID of 0 then means a resend.) This scheme keeps the * - * application from seeing the same packet twice. All the Connection * - * Manager has to do is mark the resent packet as non-ACK'd. Of course, * - * the Manager doesn't have to use this value at all. * - * * - * Both DATA_ACK packets and DATA_NOACK packets must go through the Send * - * Queue when "sent", so that the SendTotal value for this system * - * will still match the ReceiveTotal value for the other system; this is * - * why a NOACK packet can't just be sent immediately; it must go through * - * the queue. * - * * - * If the protocol being used already guarantees delivery of packets, * - * no ACK is required for the packets. In this case, the connection * - * class for this protocol can overload the Service routine to avoid * - * sending ACK packets, or the Connection Manager can just mark the * - * packet as ACK'd when it adds it to the Receive Queue for the connection.* - * * - * Derived classes must provide: * - * - Init a version of Init that gives the connection * - * access to any hardware-specific values it needs * - * Must chain to the parent's Init routine. * - * - Send_Packet adds the CommHeaderType header, adds the packet * - * to the out-going queue * - * - Receive_Packet processes incoming ACK packets, detects resends,* - * adds new packets to the in-coming queue * - * - Get_Packet reads the next-available packet from the * - * receive queue * - * - Send the hardware-dependent data-sending routine * - * - Service_Send_Queue services the send queue; handles re-sends, * - * detects when outgoing packets have been ACK'd; * - * cleans out the queue of old packets * - * - Service_Receive_Queue services the receive queue; handles sending * - * ACK's for new or re-sent packets; cleans out * - * the queue of old packets * - * * - * Any other routines can be overloaded as the derived class needs. * - * * - * CLASS HIERARCHY: * - * ConnectionClass * - * | * - * | * - * -------------------------------------- * - * | | * - * | | * - * SequencedConnClass NonSequencedConnClass * - * | | * - * | | * - * IPXConnClass ------------------------ * - * | | | * - * | | | * - * IPXGlobalConnClass NullModemConnClass ModemConnClass * - * * - * * - * ConnectionClass: * - * Abstract base class. * - * Provides: Queue for sent/recv'd packets * - * PacketBuf for preparing packets * - * Timeout variables * - * Service() routine * - * * - * SequencedConnClass: * - * Abstract base class * - * Provides: * "Sequenced" ACK/Retry logic, in Service_Send_Queue() & * - * Service_Receive_Queue() routines * - * * Send_Packet(): adds header to packet, adds it to Queue * - * * Receive_Packet(): adds incoming packet to receive Queue, * - * handles incoming ACK's & resends * - * * Get_Packet(): gets packet from the receive queue * - * * - * NonSequencedConnClass: * - * Abstract base class * - * Provides: * "Non-Sequenced" ACK/Retry logic, in Service_Send_Queue() * - * & Service_Receive_Queue() routines * - * * Send_Packet(): adds header to packet, adds it to Queue * - * * Receive_Packet(): adds incoming packet to receive Queue, * - * handles incoming ACK's & resends * - * * Get_Packet(): gets packet from the receive queue * - * * - * IPXConnClass: * - * Provides: * Hardware-dependent IPX interface routines, which allow * - * Service_Send_Queue() & Service_Receive_Queue() to do * - * their job * - * * Ability to associate an IPX Address, a numerical ID, and * - * a character-string Name with a connection * - * Inherits: * Sequenced ACK/Retry logic, Service routines, Queue & * - * PacketBuf, timeout variables * - * * - * IPXGlobalConnClass: * - * Special type of IPX Connection; supports receiving packets from * - * multiple systems at once, and sending packets via Broadcast or * - * to a specific address. * - * Provides: * Specialized Receive_Packet() routine, which handles * - * receiving packets from multiple systems * - * * Specialized Send_Packet() & Get_Packet() routines, * - * which pass IPX address of destination through to * - * the application, giving the application control over * - * whether the packet will be Broadcast or sent to a * - * specific destination (embeds destination address within * - * the packet itself) * - * * Specialized Send routine, which extracts the destination * - * address from the packet * - * Inherits: * Sequenced ACK/Retry logic, Service routines, Queue & * - * PacketBuf, timeout variables, IPX-specific routines * - * * - * NullModemConnClass: * - * Provides: * Hardware-dependent Serial-communication routines, which * - * allow Service_Send_Queue() & Service_Receive_Queue() to * - * do their job * - * Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue & * - * PacketBuf, timeout variables * - * * - * ModemConnClass: * - * Provides: * Hardware-dependent Modem-communication routines, which * - * allow Service_Send_Queue() & Service_Receive_Queue() to * - * do their job * - * Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue & * - * PacketBuf, timeout variables * - * * - * So, do ya think this header is long enough, or what? * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CONNECTION_H -#define CONNECTION_H - -#define CONN_DEBUG 0 - -/* -********************************** Defines ********************************** -*/ -/*--------------------------------------------------------------------------- -This structure is the header prefixed to any packet sent by the application. -MagicNumber: This is a number unique to the application; it's up to the - Receive_Packet routine to check this value, to be sure we're - not getting data from some other product. This value should - be unique for each application. -Code: This will be one of the below-defined codes. -PacketID: This is a unique numerical ID for this packet. The Connection - sets this ID on all packets sent out. ----------------------------------------------------------------------------*/ -typedef struct { - unsigned short MagicNumber; - unsigned char Code; - unsigned long PacketID; -} CommHeaderType; - - -/* -***************************** Class Declaration ***************************** -*/ -class ConnectionClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - These are the possible values for the Code field of the CommHeaderType: - .....................................................................*/ - enum ConnectionEnum { - PACKET_DATA_ACK, // this is a data packet requiring an ACK - PACKET_DATA_NOACK, // this is a data packet not requiring an ACK - PACKET_ACK, // this is an ACK for a packet - PACKET_COUNT, // for computational purposes - }; - - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - ConnectionClass (int maxlen, unsigned short magicnum, - unsigned long retry_delta, unsigned long max_retries, - unsigned long timeout); - virtual ~ConnectionClass (); - - /*..................................................................... - Initialization. - .....................................................................*/ - virtual void Init (void) {}; - - /*..................................................................... - Send/Receive routines. - .....................................................................*/ - virtual int Send_Packet (void * buf, int buflen, int ack_req) = 0; - virtual int Receive_Packet (void * buf, int buflen) = 0; - virtual int Get_Packet (void * buf, int * buflen) = 0; - - /*..................................................................... - The main polling routine for the connection. Should be called as often - as possible. - .....................................................................*/ - virtual int Service (void); - - /*..................................................................... - This routine is used by the retry logic; returns the current time in - 60ths of a second. - .....................................................................*/ - static unsigned long Time (void); - - /*..................................................................... - Utility routines. - .....................................................................*/ - unsigned short Magic_Num (void) { return (MagicNum); } - unsigned long Retry_Delta (void) { return (RetryDelta); } - void Set_Retry_Delta (unsigned long delta) { RetryDelta = delta;} - unsigned long Max_Retries (void) { return (MaxRetries); } - void Set_Max_Retries (unsigned long retries) { MaxRetries = retries;} - unsigned long Time_Out (void) { return (Timeout); } - void Set_TimeOut (unsigned long t) { Timeout = t;} - unsigned long Max_Packet_Len (void) { return (MaxPacketLen); } - static char * Command_Name(int command); - - /* - -------------------------- Protected Interface --------------------------- - */ - protected: - /*..................................................................... - Routines to service the Send & Receive queues. - .....................................................................*/ - virtual int Service_Send_Queue(void) = 0; - virtual int Service_Receive_Queue(void) = 0; - - /*..................................................................... - This routine actually performs a hardware-dependent data send. It's - pure virtual, so it >must< be defined by a derived class. - .....................................................................*/ - virtual int Send(char *buf, int buflen) = 0; - - /*..................................................................... - This is the maximum packet length, including our own internal header. - .....................................................................*/ - int MaxPacketLen; - - /*..................................................................... - Packet staging area; this is where the CommHeaderType gets tacked onto - the application's packet before it's sent. - .....................................................................*/ - char *PacketBuf; - - /*..................................................................... - This is the magic number assigned to this connection. It is the first - few bytes of any transmission. - .....................................................................*/ - unsigned short MagicNum; - - /*..................................................................... - This value determines the time delay before a packet is re-sent. - .....................................................................*/ - unsigned long RetryDelta; - - /*..................................................................... - This is the maximum number of retries allowed for a packet; if this - value is exceeded, the connection is probably broken. - .....................................................................*/ - unsigned long MaxRetries; - - /*..................................................................... - This is the total timeout for this connection; if this time is exceeded - on a packet, the connection is probably broken. - .....................................................................*/ - unsigned long Timeout; - - /*..................................................................... - Names of all packet commands - .....................................................................*/ - static char *ConnectionClass::Commands[PACKET_COUNT]; -}; - -#endif - diff --git a/code/TIBERIANDAWN/CONNMGR.H b/code/TIBERIANDAWN/CONNMGR.H deleted file mode 100644 index e375af4..0000000 --- a/code/TIBERIANDAWN/CONNMGR.H +++ /dev/null @@ -1,148 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c0\vcs\code\connmgr.h_v 1.25 02 Jan 1996 11:14:54 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONNMGR.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 3, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This is the Connection Manager base class. This is an abstract base * - * class that's just a shell for more functional derived classes. * - * The main job of the Connection Manager classes is to parse a "pool" of * - * incoming packets, which may be from different computers, and distribute * - * those packets to Connection Classes via their Receive_Packet function. * - * * - * This class should be the only access to the network/modem for the * - * application, so if the app needs any functions to access the * - * connections or the queue's, the derived versions of this class should * - * provide them. * - * * - * It's up to the derived class to define: * - * - Service: polling routine; should Service each connection * - * - Init: initialization; should perform hardware-dependent * - * initialization, then Init each connection; this function * - * isn't defined in this class, since the parameters will * - * be highly protocol-dependent) * - * - Send_Message:sends a packet across the connection (this function * - * isn't defined in this class, since the parameters will * - * be highly protocol-dependent) * - * - Get_Message: gets a message from the connection (this function * - * isn't defined in this class, since the parameters will * - * be highly protocol-dependent) * - * * - * If the derived class supports multiple connections, it should provide * - * functions for creating the connections, associating them with a name * - * or ID or both, destroying them, and sending data through all or any * - * connection. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CONNMGR_H -#define CONNMGR_H - - -/* -***************************** Class Declaration ***************************** -*/ -class ConnManClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Various useful enums: - .....................................................................*/ - enum IPXConnTag { - CONNECTION_NONE = -1, // value of an invalid connection ID - }; - - /*..................................................................... - Constructor/Destructor. These currently do nothing. - .....................................................................*/ - ConnManClass (void) {}; - virtual ~ConnManClass () {}; - - /*..................................................................... - The Service routine: - - Parses incoming packets, and adds them to the Receive Queue for the - Connection Class(s) for this protocol - - Invokes each connection's Service routine; returns an error if the - connection's Service routine indicates an error. - .....................................................................*/ - virtual int Service (void) = 0; - - /*..................................................................... - Sending & receiving data - .....................................................................*/ - virtual int Send_Private_Message (void *buf, int buflen, - int ack_req = 1, int conn_id = CONNECTION_NONE) = 0; - virtual int Get_Private_Message (void *buf, int *buflen, - int *conn_id) = 0; - - /*..................................................................... - Connection management - .....................................................................*/ - virtual int Num_Connections(void) = 0; - virtual int Connection_ID(int index) = 0; - virtual int Connection_Index(int id) = 0; - - /*..................................................................... - Queue utility routines - .....................................................................*/ - virtual int Global_Num_Send(void) = 0; - virtual int Global_Num_Receive(void) = 0; - virtual int Private_Num_Send(int id = CONNECTION_NONE) = 0; - virtual int Private_Num_Receive(int id = CONNECTION_NONE) = 0; - - /*..................................................................... - Timing management - .....................................................................*/ - virtual void Reset_Response_Time(void) = 0; - virtual unsigned long Response_Time(void) = 0; - virtual void Set_Timing (unsigned long retrydelta, - unsigned long maxretries, unsigned long timeout) = 0; - - /*..................................................................... - Debugging - .....................................................................*/ - virtual void Configure_Debug(int index, int type_offset, int type_size, - char **names, int maxnames) = 0; - virtual void Mono_Debug_Print(int index, int refresh) = 0; - /* - --------------------------- Private Interface ---------------------------- - */ - private: - /*..................................................................... - This abstract class contains no data members; but a derived class - will contain: - - An instance of one or more derived Connection Classes - - A buffer to store incoming packets - .....................................................................*/ -}; - -#endif diff --git a/code/TIBERIANDAWN/CONQUER.CPP b/code/TIBERIANDAWN/CONQUER.CPP deleted file mode 100644 index 01d93d0..0000000 --- a/code/TIBERIANDAWN/CONQUER.CPP +++ /dev/null @@ -1,4257 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\conquer.cpv 2.18 16 Oct 1995 16:50:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONQUER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 3, 1991 * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CC_Draw_Shape -- Custom draw shape handler. * - * Call_Back -- Main game maintenance callback routine. * - * Color_Cycle -- Handle the general palette color cycling. * - * Disk_Space_Available -- returns bytes of free disk space * - * Do_Record_Playback -- handles saving/loading map pos & current object * - * Fading_Table_Name -- Builds a theater specific fading table name. * - * Fetch_Techno_Type -- Convert type and ID into TechnoTypeClass pointer. * - * Force_CD_Available -- Ensures that specified CD is available. * - * Get_Radar_Icon -- Builds and alloc a radar icon from a shape file * - * Handle_Team -- Processes team selection command. * - * Handle_View -- Either records or restores the tactical view. * - * KN_To_Facing -- Converts a keyboard input number into a facing value. * - * Keyboard_Process -- Processes the tactical map input codes. * - * Language_Name -- Build filename for current language. * - * Main_Game -- Main game startup routine. * - * Main_Loop -- This is the main game loop (as a single loop). * - * Map_Edit_Loop -- a mini-main loop for map edit mode only * - * Message_Input -- allows inter-player message input processing * - * MixFileHandler -- Handles VQ file access. * - * Name_From_Source -- retrieves the name for the given SourceType * - * Play_Movie -- Plays a VQ movie. * - * Source_From_Name -- Converts ASCII name into SourceType. * - * Sync_Delay -- Forces the game into a 15 FPS rate. * - * Theater_From_Name -- Converts ASCII name into a theater number. * - * Trap_Object -- gets a ptr to object of given type & coord * - * Unselect_All -- Causes all selected objects to become unselected. * - * VQ_Call_Back -- Maintenance callback used for VQ movies. * - * Validate_Error -- prints an error message when an object fails validation * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "tcpip.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ccdde.h" - -#define SHAPE_TRANS 0x40 - -void *Get_Shape_Header_Data(void *ptr); - -/**************************************** -** Function prototypes for this module ** -*****************************************/ -bool Main_Loop(); -void Keyboard_Process(KeyNumType & input); -#ifndef DEMO -static void Message_Input(KeyNumType &input); -#endif -bool Color_Cycle(void); -bool Map_Edit_Loop(void); -void Trap_Object(void); - -#ifdef CHEAT_KEYS -void Heap_Dump_Check( char *string ); -void Dump_Heap_Pointers( void ); -void Error_In_Heap_Pointers( char *string ); -#endif -static void Do_Record_Playback(void); -extern void Register_Game_Start_Time(void); -extern void Register_Game_End_Time(void); -extern void Send_Statistics_Packet(void); -extern "C" { - extern char *__nheapbeg; -} -bool InMainLoop = false; - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - -/*********************************************************************************************** - * Main_Game -- Main game startup routine. * - * * - * This is the first official routine of the game. It handles game initialization and * - * the main game loop control. * - * * - * Initialization: * - * - Init_Game handles one-time-only inits * - * - Select_Game is responsible for initializations required for each new game played * - * (these may be different depending on whether a multiplayer game is selected, and * - * other parameters) * - * - This routine performs any un-inits required, both for each game played, and one-time * - * * - * INPUT: argc -- Number of command line arguments (including program name itself). * - * * - * argv -- Array of command line argument pointers. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/01/1994 JLB : Created. * - *=============================================================================================*/ -extern int TotalLocks; -extern bool Spawn_WChat(bool can_launch); -extern bool SpawnedFromWChat; -void Main_Game(int argc, char *argv[]) -{ - bool fade = false; // don't fade title screen the first time through - - /* - ** Perform one-time-only initializations - */ - if (!Init_Game(argc, argv)) { - return; - } - - CCDebugString ("C&C95 - Game initialisation complete.\n"); - /* - ** Game processing loop: - ** 1) Select which game to play, or whether to exit (don't fade the palette - ** on the first game selection, but fade it in on subsequent calls) - ** 2) Invoke either the main-loop routine, or the editor-loop routine, - ** until they indicate that the user wants to exit the scenario. - */ - while (Select_Game(fade)) { - - if (RunningAsDLL) { - return; - } - ScenarioInit = 0; // Kludge. -// Theme.Queue_Song(THEME_PICK_ANOTHER); - - fade = true; - - /* - ** Make the game screen visible, clear the keyboard buffer of spurious - ** values, and then show the mouse. This PRESUMES that Select_Game() has - ** told the map to draw itself. - */ - Fade_Palette_To(GamePalette, FADE_PALETTE_MEDIUM, NULL); - Keyboard::Clear(); - - /* - ** Only show the mouse if we're not playing back a recording. - */ - if (PlaybackGame) { - Hide_Mouse(); - } else { - Show_Mouse(); - } - - SpecialDialog = SDLG_NONE; - //Start_Profiler(); - if (GameToPlay == GAME_INTERNET){ - Register_Game_Start_Time(); - GameStatisticsPacketSent = false; - PacketLater = NULL; - ConnectionLost = false; - }else{ - DDEServer.Disable(); - } - - InMainLoop = true; - -#ifdef SCENARIO_EDITOR - /* - ** Scenario-editor version of main-loop processing - */ - for (;;) { - - /* - ** Non-scenario-editor-mode: call the game's main loop - */ - if (!Debug_Map) { - TotalLocks=0; - if (Main_Loop()) { - break; - } - - if (SpecialDialog != SDLG_NONE) { - //Stop_Profiler(); - switch (SpecialDialog) { - case SDLG_SPECIAL: - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - Special_Dialog(); - Map.Revert_Mouse_Shape(); - SpecialDialog = SDLG_NONE; - break; - - case SDLG_OPTIONS: - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - Options.Process(); - Map.Revert_Mouse_Shape(); - SpecialDialog = SDLG_NONE; - break; - - case SDLG_SURRENDER: - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - if (Surrender_Dialog()) { - OutList.Add(EventClass(EventClass::DESTRUCT)); - } - SpecialDialog = SDLG_NONE; - Map.Revert_Mouse_Shape(); - break; - - default: - break; - } - } - } else { - - /* - ** Scenario-editor-mode: call the editor's main loop - */ - if (Map_Edit_Loop()) { - break; - } - } - } -#else - /* - ** Non-editor version of main-loop processing - */ - for (;;) { - - /* - ** Call the game's main loop - */ - TotalLocks=0; - if (Main_Loop()) { - break; - } - - /* - ** If the SpecialDialog flag is set, invoke the given special dialog. - ** This must be done outside the main loop, since the dialog will call - ** Main_Loop(), allowing the game to run in the background. - */ - if (SpecialDialog != SDLG_NONE) { - //Stop_Profiler(); - switch (SpecialDialog) { - case SDLG_SPECIAL: - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - Special_Dialog(); - Map.Revert_Mouse_Shape(); - SpecialDialog = SDLG_NONE; - break; - - case SDLG_OPTIONS: - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - Options.Process(); - Map.Revert_Mouse_Shape(); - SpecialDialog = SDLG_NONE; - break; - - case SDLG_SURRENDER: - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - if (Surrender_Dialog()) { - OutList.Add(EventClass(EventClass::DESTRUCT)); - } - SpecialDialog = SDLG_NONE; - Map.Revert_Mouse_Shape(); - break; - - default: - break; - } - } - } -#endif - //Stop_Profiler(); - InMainLoop = false; - - if (!GameStatisticsPacketSent && PacketLater){ - Send_Statistics_Packet(); - } - - /* - ** Scenario is done; fade palette to black - */ - Fade_Palette_To(BlackPalette, FADE_PALETTE_SLOW, NULL); - VisiblePage.Clear(); - -#ifndef DEMO - /* - ** Un-initialize whatever needs it, for each game played. - ** - ** Shut down either the modem or network; they'll get re-initialized if - ** the user selections those options again in Select_Game(). This - ** "re-boots" the modem & network code, which I currently feel is safer - ** than just letting it hang around. - ** (Skip this step if we're in playback mode; the modem or net won't have - ** been initialized in that case.) - */ - if ( (RecordGame && !SuperRecord) || PlaybackGame) { - RecordFile.Close(); - } - - if (!PlaybackGame){ - - switch (GameToPlay){ - case GAME_NULL_MODEM: - case GAME_MODEM: - //ST - 1/2/2019 4:04PM - //Modem_Signoff(); - break; - - case GAME_IPX: - Shutdown_Network(); - break; - - case GAME_INTERNET: - //Winsock.Close(); - break; - } - } - - - /* - ** If we're playing back, the mouse will be hidden; show it. - ** Also, set all variables back to normal, to return to the main menu. - */ - if (PlaybackGame) { - Show_Mouse(); - GameToPlay = GAME_NORMAL; - PlaybackGame = 0; - } - - - /* - ** If we were spawned from WChat then dont go back to the main menu - just quit - ** - ** New: If spawned from WChat then maximise WChat and go back to the main menu after all - */ -#ifdef FORCE_WINSOCK - if (Special.IsFromWChat){ - Shutdown_Network(); // Clear up the pseudo IPX stuff - Winsock.Close(); - Special.IsFromWChat = false; - SpawnedFromWChat = false; - DDEServer.Delete_MPlayer_Game_Info(); //Make sure we dont use the same start packet twice - GameToPlay = GAME_NORMAL; //Have to do this or we will got straight to the multiplayer menu - Spawn_WChat(false); //Will switch back to Wchat. It must be there because its been poking us - //break; - } -#endif //FORCE_WINSOCK - -#endif //DEMO - - } - -#ifdef DEMO - Hide_Mouse(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, NULL); - Load_Title_Screen("DEMOPIC.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, NULL); - Clear_KeyBuffer(); - Get_Key(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, NULL); -// Show_Mouse(); -#else - - /* - ** Free the scenario description buffers - */ - Free_Scenario_Descriptions(); -#endif - -#ifndef NOMEMCHECK - Uninit_Game(); -#endif - -} - - -/*********************************************************************************************** - * Keyboard_Process -- Processes the tactical map input codes. * - * * - * This routine is used to process the input codes while the player * - * has the tactical map displayed. It handles all the keys that * - * are appropriate to that mode. * - * * - * INPUT: input -- Input code as returned from Input_Num(). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/21/1992 JLB : Created. * - * 07/04/1995 JLB : Handles team and map control hotkeys. * - *=============================================================================================*/ -extern int DebugColour; -void Keyboard_Process(KeyNumType &input) -{ - ObjectClass * obj; - int index; - - /* - ** Don't do anything if there is not keyboard event. - */ - if (input == KN_NONE) { - return; - } - -#ifndef DEMO - /* - ** For network & modem, process user input for inter-player messages. - */ - Message_Input(input); -#endif - /* - ** Use WWKEY values because KN values have WWKEY_VK_BIT or'd in with them - ** and we need WWKEY_VK_BIT to still be set if it is. - */ - KeyNumType plain = input & ~(WWKEY_SHIFT_BIT|WWKEY_ALT_BIT|WWKEY_CTRL_BIT); - -#ifdef CHEAT_KEYS - - if (Debug_Flag) { - switch (input) { - case (int)KN_M|(int)KN_SHIFT_BIT: - case (int)KN_M|(int)KN_ALT_BIT: - case (int)KN_M|(int)KN_CTRL_BIT: - PlayerPtr->Credits += 10000; - break; - - default: - break; - } - } -#endif - -#ifdef VIRGIN_CHEAT_KEYS - if (Debug_Playtest && input == (KN_W|KN_ALT_BIT)) { - PlayerPtr->Blockage = false; - PlayerPtr->Flag_To_Win(); - } -#endif - -//#ifdef CHEAT_KEYS - if (/*Debug_Playtest && */input == (KN_W|KN_ALT_BIT)) { - PlayerPtr->Blockage = false; - PlayerPtr->Flag_To_Win(); - } - - if (Debug_Flag && input == KN_SLASH) { - if (GameToPlay != GAME_NORMAL) { - SpecialDialog = SDLG_SPECIAL; - input = KN_NONE; - } else { - Special_Dialog(); - } - } -//#endif - - /* - ** If the options key(s) were pressed, then bring up the options screen. - */ - if (input == KN_SPACE || input == KN_ESC) { - Map.Help_Text(TXT_NONE); // Turns off help text. - Queue_Options(); - input = KN_NONE; - //DebugColour++; - //DebugColour &=7; - } - - /* - ** Process prerecorded team selection. This will be an addative select - ** if the SHIFT key is held down. It will create the team if the - ** CTRL or ALT key is held down. - */ - int action = 0; - if (input & WWKEY_SHIFT_BIT) action = 1; - if (input & WWKEY_ALT_BIT) action = 3; - if (input & WWKEY_CTRL_BIT) action = 2; - - switch (KN_To_VK(plain)) { - - /* - ** Center the map around the currently selected objects. If no - ** objects are selected, then fall into the home case. - */ - case VK_HOME: - if (CurrentObject.Count()) { - Map.Center_Map(); - Map.Flag_To_Redraw(true); - break; - } - // Fall into next case. - - /* - ** Center the map about the construction yard or construction vehicle - ** if one is present. - */ - case VK_H: - for (index = 0; index < Units.Count(); index++) { - UnitClass * unit = Units.Ptr(index); - - if (unit && !unit->IsInLimbo && unit->House == PlayerPtr && *unit == UNIT_MCV) { - Unselect_All(); - unit->Select(); - break; - } - } - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && !building->IsInLimbo && building->House == PlayerPtr && *building == STRUCT_CONST) { - Unselect_All(); - building->Select(); - break; - } - } - Map.Center_Map(); - Map.Flag_To_Redraw(true); - break; - -#ifdef CHEAT_KEYS - /* - ** Toggle free scrolling mode. - */ - case VK_F: - Options.IsFreeScroll = (Options.IsFreeScroll == false); - break; -#endif - - /* - ** If the "N" key is pressed, then select the next object. - */ - case VK_N: - if (action) { - obj = Map.Prev_Object(CurrentObject.Count() ? CurrentObject[0] : NULL); - } else { - obj = Map.Next_Object(CurrentObject.Count() ? CurrentObject[0] : NULL); - } - if (obj) { - Unselect_All(); - obj->Select(); - Map.Center_Map(); - Map.Flag_To_Redraw(true); - } - break; - - /* - ** For multiplayer, 'R' pops up the surrender dialog. - */ - case VK_R: - if (/*GameToPlay != GAME_NORMAL &&*/ !PlayerPtr->IsDefeated) { - SpecialDialog = SDLG_SURRENDER; - input = KN_NONE; - } - break; - - /* - ** Handle making and breaking alliances. - */ - case VK_A: - if (GameToPlay != GAME_NORMAL || Debug_Flag) { - if (CurrentObject.Count() && !PlayerPtr->IsDefeated) { - if (CurrentObject[0]->Owner() != PlayerPtr->Class->House) { - OutList.Add(EventClass(EventClass::ALLY, (int)CurrentObject[0]->Owner())); - } - } - } - break; - - /* - ** Control the remembered tactical location. - */ - case VK_F7: - case VK_F8: - case VK_F9: - case VK_F10: - if (!Debug_Map) { - Handle_View(KN_To_VK(plain) - VK_F7, action); - } - break; -#if (0) - case VK_F11: - Winsock.Set_Protocol_UDP(FALSE); - break; - - case VK_F12: - Winsock.Set_Protocol_UDP(TRUE); - break; -#endif //(0) - - - /* - ** Control the custom team select state. - */ - case VK_1: - case VK_2: - case VK_3: - case VK_4: - case VK_5: - case VK_6: - case VK_7: - case VK_8: - case VK_9: - case VK_0: - Handle_Team(KN_To_VK(plain) - VK_1, action); - break; - - /* - ** All selected units will go into idle mode. - */ - case VK_S: - if (CurrentObject.Count()) { - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass const * tech = CurrentObject[index]; - - if (tech && (tech->Can_Player_Move() || (tech->Can_Player_Fire() && - tech->What_Am_I() != RTTI_BUILDING))) { - OutList.Add(EventClass(EventClass::IDLE, tech->As_Target())); - } - } - } - break; - - /* - ** All selected units will attempt to scatter. - */ - case VK_X: - if (CurrentObject.Count()) { - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass const * tech = CurrentObject[index]; - - if (tech && tech->Can_Player_Move()) { - OutList.Add(EventClass(EventClass::SCATTER, tech->As_Target())); - } - } - } - break; - - /* - ** All selected units will attempt to go into guard area mode. - */ - case VK_G: - if (CurrentObject.Count()) { - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass const * tech = CurrentObject[index]; - - if (tech && tech->Can_Player_Move() && tech->Can_Player_Fire()) { - OutList.Add(EventClass(tech->As_Target(), MISSION_GUARD_AREA)); - } - } - } - break; - - default: - break; - } - -#ifdef NEVER - FacingType facing = KN_To_Facing(input); - - /* - ** Scroll the map according to the cursor key pressed. - */ - if (facing != FACING_NONE) { - Map.Scroll_Map(facing); - input = 0; - facing = FACING_NONE; - } -#endif - -#ifdef NEVER - /* - ** If the key is pressed, then select the next object. - */ - if (input == KN_TAB) { - ObjectClass * obj = Map.Next_Object(CurrentObject); - if (obj) { - if (CurrentObject) { - CurrentObject->Unselect(); - } - obj->Select(); - } - } -#endif - -#ifdef CHEAT_KEYS - if (Debug_Flag && input && (input & KN_RLSE_BIT) == 0) { - Debug_Key(input); - } -#endif -} - - -#ifndef DEMO -/*********************************************************************************************** - * Message_Input -- allows inter-player message input processing * - * * - * INPUT: * - * input key value * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * MAX_MESSAGE_LENGTH has increased over the DOS version. COMPAT_MESSAGE_LENGTH reflects * * - * the length of the DOS message and also the length of the message in the packet header. * - * To allow transmission of longer messages I split the message into COMPAT_MESSAGE_LENGTH-4 * - * sized chunks and use the extra space after the zero terminator to specify which segment * - * of the whole message this is and also to supply a crc for the string. * - * This allows message segments to arrive out of order and still be displayed correctly. * - * * - * HISTORY: * - * 05/22/1995 BRR : Created. * - * 03/26/1995 ST : Modified to break up longer messages into multiple packets * - *=============================================================================================*/ -static void Message_Input(KeyNumType &input) -{ - int rc; - char txt[MAX_MESSAGE_LENGTH+12]; - int id; -//PG_TO_FIX -#if (0) - SerialPacketType *serial_packet; - int i; - int message_length; - int sent_so_far; - unsigned short magic_number; - unsigned short crc; -#endif - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - - /* - ** Check keyboard input for a request to send a message. - ** The 'to' argument for Add_Edit is prefixed to the message buffer; the - ** message buffer is big enough for the 'to' field plus MAX_MESSAGE_LENGTH. - ** To send the message, calling Get_Edit_Buf retrieves the buffer minus the - ** 'to' portion. At the other end, the buffer allocated to display the - ** message must be MAX_MESSAGE_LENGTH plus the size of "From: xxx (house)". - */ - if (input >= KN_F1 && input < (KN_F1 + MPlayerMax) && - Messages.Get_Edit_Buf()==NULL) { - memset (txt, 0, 40); - - /* - ** For a serial game, send a message on F1 or F4; set 'txt' to the - ** "Message:" string & add an editable message to the list. - */ - if (GameToPlay==GAME_NULL_MODEM - || GameToPlay==GAME_MODEM){ - //|| GameToPlay == GAME_INTERNET) { - if (input==KN_F1 || input==(KN_F1 + MPlayerMax - 1)) { - - strcpy(txt,Text_String(TXT_MESSAGE)); // "Message:" - - Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, 180*factor); - - Map.Flag_To_Redraw(false); - } - } else { - - /* - ** For a network game: - ** F1-F3 = "To (house):" (only allowed if we're not in ObiWan mode) - ** F4 = "To All:" - */ - if (GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) { - if (input==(KN_F1 + MPlayerMax - 1) && Messages.Get_Edit_Buf()==NULL) { - - MessageAddress = IPXAddressClass(); // set to broadcast - strcpy(txt,Text_String(TXT_TO_ALL)); // "To All:" - - Messages.Add_Edit(MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, 180*factor); - - Map.Flag_To_Redraw(false); - } else { - if (Messages.Get_Edit_Buf()==NULL) { - if ((input - KN_F1) < Ipx.Num_Connections() && !MPlayerObiWan) { - - id = Ipx.Connection_ID(input - KN_F1); - MessageAddress = (*(Ipx.Connection_Address (id))); - sprintf(txt,Text_String(TXT_TO),Ipx.Connection_Name(id)); - - Messages.Add_Edit(MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, 180*factor); - - Map.Flag_To_Redraw(false); - } - } - } - } - } - } - - /* - ** Function key input is meaningless beyond this point - */ - if (input >= KN_F1 && input <= KN_F10) return; - if (input >= KN_F11 && input <= KN_F12) return; - - /* - ** Process message-system input; send the message out if RETURN is hit. - */ - rc = Messages.Input(input); - - /* - ** If a single character has been added to an edit buffer, update the display. - */ - if (rc == 1) { - Map.Flag_To_Redraw(false); - } - - /* - ** If backspace was hit, redraw the map. This assumes the map is going to - ** completely refresh all cells covered by the messages. Set DisplayClass's - ** IsToRedraw to true to tell it to re-compute the cells that it needs to - ** redraw. - */ - if (rc==2) { - Map.Flag_To_Redraw(false); - Map.DisplayClass::IsToRedraw = true; - } - - - /* - ** Send a message - */ - if (rc==3) { -// -// PG_TO_FIX -#if (0) - /*..................................................................... - Store this message in our LastMessage buffer; the computer may send - us a version of it later. - .....................................................................*/ - if (strlen(Messages.Get_Edit_Buf())) { - strcpy(LastMessage,Messages.Get_Edit_Buf()); - } - - message_length = strlen(Messages.Get_Edit_Buf()); - - long actual_message_size; - char *the_string; - - /* - ** Serial game: fill in a SerialPacketType & send it. - ** (Note: The size of the SerialPacketType.Command must be the same as - ** the EventClass.Type!) - */ - if (GameToPlay==GAME_NULL_MODEM - || GameToPlay==GAME_MODEM){ - //|| GameToPlay==GAME_INTERNET) { - - sent_so_far = 0; - magic_number = MESSAGE_HEAD_MAGIC_NUMBER; - crc = (unsigned short) (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) & 0xffff); - - while (sent_so_far < message_length){ - - serial_packet = (SerialPacketType *)NullModem.BuildBuf; - - serial_packet->Command = SERIAL_MESSAGE; - strcpy (serial_packet->Name, MPlayerName); - memcpy (serial_packet->Message, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); - - /* - ** Steve I's stuff for splitting message on word boundries - */ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - - /* Start at the end of the message and find a space with 10 chars. */ - the_string = serial_packet->Message; - while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && - the_string[actual_message_size] != ' '){ - --actual_message_size; - } - if ( the_string[actual_message_size] == ' ' ){ - - /* Now delete the extra characters after the space (they musnt print) */ - for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ - the_string[i + actual_message_size] = 0xff; - } - }else{ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - } - - - *(serial_packet->Message + COMPAT_MESSAGE_LENGTH-5) = 0; - /* - ** Flag this message segment as either a message head or a message tail. - */ - *((unsigned short*)(serial_packet->Message + COMPAT_MESSAGE_LENGTH-4)) = magic_number; - *((unsigned short*)(serial_packet->Message + COMPAT_MESSAGE_LENGTH-2)) = crc; - serial_packet->ID = MPlayerLocalID; - - NullModem.Send_Message(NullModem.BuildBuf, sizeof(SerialPacketType), 1); - - magic_number++; - sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; - } - - } else { - - /* - ** Network game: fill in a GlobalPacketType & send it. - */ - if (GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) { - - sent_so_far = 0; - magic_number = MESSAGE_HEAD_MAGIC_NUMBER; - crc = (unsigned short) (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) & 0xffff); - - while (sent_so_far < message_length){ - - GPacket.Command = NET_MESSAGE; - strcpy (GPacket.Name, MPlayerName); - memcpy (GPacket.Message.Buf, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); - - /* - ** Steve I's stuff for splitting message on word boundries - */ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - - /* Start at the end of the message and find a space with 10 chars. */ - the_string = GPacket.Message.Buf; - while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && - the_string[actual_message_size] != ' '){ - --actual_message_size; - } - if ( the_string[actual_message_size] == ' ' ){ - - /* Now delete the extra characters after the space (they musnt print) */ - for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ - the_string[i + actual_message_size] = 0xff; - } - }else{ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - } - - *(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-5) = 0; - /* - ** Flag this message segment as either a message head or a message tail. - */ - *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-4)) = magic_number; - *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-2)) = crc; - - GPacket.Message.ID = MPlayerLocalID; - GPacket.Message.NameCRC = Compute_Name_CRC(MPlayerGameName); - - /* - ** If 'F4' was hit, MessageAddress will be a broadcast address; send - ** the message to every player we have a connection with. - */ - if (MessageAddress.Is_Broadcast()) { - for (i = 0; i < Ipx.Num_Connections(); i++) { - Ipx.Send_Global_Message(&GPacket, sizeof(GlobalPacketType), 1, - Ipx.Connection_Address(Ipx.Connection_ID(i))); - Ipx.Service(); - } - } else { - - /* - ** Otherwise, MessageAddress contains the exact address to send to. - ** Send to that address only. - */ - Ipx.Send_Global_Message(&GPacket, sizeof(GlobalPacketType), 1, - &MessageAddress); - Ipx.Service(); - } - - magic_number++; - sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; - } - } - - } - - /* - ** Tell the map to completely update itself, since a message is now missing. - */ - Map.Flag_To_Redraw(true); -#endif - } -} -#endif - - -/*********************************************************************************************** - * Color_Cycle -- Handle the general palette color cycling. * - * * - * This is a maintenance routine that handles the color cycling. It should be called as * - * often as necessary to achieve smooth color cycling effects -- at least 8 times a second. * - * * - * INPUT: none * - * * - * OUTPUT: true if palette changed * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 06/10/1994 JLB : Uses new cycle color values. * - * 12/21/1994 JLB : Handles text fade color. * - *=============================================================================================*/ -bool Color_Cycle(void) -{ - static CountDownTimerClass _timer(BT_SYSTEM,0L); - static CountDownTimerClass _ftimer(BT_SYSTEM,0L); - static bool _up = false; - bool changed = false; - - /* - ** Process the fading white color. It is used for the radar box and other glowing - ** game interface elements. - */ - if (!_ftimer.Time()) { - _ftimer.Set(TIMER_SECOND/8); - - /* - ** Pulse the pulsing text color. - */ - #define STEP_RATE 5 - if (_up) { - GamePalette[767] += STEP_RATE; - GamePalette[766] += STEP_RATE; - GamePalette[765] += STEP_RATE; - if (GamePalette[767] > MAX_CYCLE_COLOR) { - GamePalette[767] = MAX_CYCLE_COLOR; - GamePalette[766] = MAX_CYCLE_COLOR; - GamePalette[765] = MAX_CYCLE_COLOR; - _up = false; - } - } else { - GamePalette[767] -= STEP_RATE; - GamePalette[766] -= STEP_RATE; - GamePalette[765] -= STEP_RATE; - if ((unsigned)GamePalette[767] < MIN_CYCLE_COLOR) { - GamePalette[767] = MIN_CYCLE_COLOR; - GamePalette[766] = MIN_CYCLE_COLOR; - GamePalette[765] = MIN_CYCLE_COLOR; - _up = true; - } - } - changed = true; - } - - /* - ** Process the color cycling effects -- water. - */ - if (!_timer.Time()) { - unsigned char colors[3]; - - _timer.Set(TIMER_SECOND/4); - - memmove(colors, &GamePalette[(CYCLE_COLOR_START+CYCLE_COLOR_COUNT-1)*3], sizeof(colors)); - memmove(&GamePalette[(CYCLE_COLOR_START+1)*3], &GamePalette[CYCLE_COLOR_START*3], (CYCLE_COLOR_COUNT-1)*3); - memmove(&GamePalette[CYCLE_COLOR_START*3], colors, sizeof(colors)); - changed = true; - } - - /* - ** If any of the processing functions changed the palette, then this palette must be - ** passed to the system. - */ - if (changed) { - Wait_Vert_Blank(); - Set_Palette(GamePalette); - return (true); - } - return (false); -} - - -/*********************************************************************************************** - * Call_Back -- Main game maintenance callback routine. * - * * - * This routine handles all the "real time" processing that needs to * - * occur. This includes palette fading and sound updating. It needs * - * to be called as often as possible. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -void Call_Back(void) -{ -#ifndef DEMO - int i; - int id; - int color; - unsigned short magic_number; - unsigned short crc; -#endif - - /* - ** Score maintenance - */ - if (SampleType) { - Theme.AI(); - Speak_AI(); - } - -#ifndef DEMO - /* - ** Network maintenance - */ - if (GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) { - - Ipx.Service(); - - /* - ** Read packets only if the game is "closed", so we don't steal global - ** messages from the connection dialogs. - */ - if (!NetOpen) { - if (Ipx.Get_Global_Message (&GPacket, &GPacketlen, &GAddress, &GProductID)) { - if (GProductID == IPXGlobalConnClass::COMMAND_AND_CONQUER) { - - /* - ** If this is another player signing off, remove the connection & - ** mark that player's house as non-human, so the computer will take - ** it over. - */ - if (GPacket.Command == NET_SIGN_OFF) { - for (i = 0; i < Ipx.Num_Connections(); i++) { - - id = Ipx.Connection_ID(i); - - if (!strcmp (GPacket.Name, Ipx.Connection_Name(id) ) && - GAddress == (*Ipx.Connection_Address(id))) { - - CCDebugString ("C&C95 = Destroying connection due to sign off\n"); - Destroy_Connection (id,0); - } - } - } else { - - /* - ** Process a message from another user. - */ - if (GPacket.Command == NET_MESSAGE) { - bool msg_ok = false; - char txt[80]; - - /* - ** If NetProtect is set, make sure this message came from within - ** this game. - */ - if (!NetProtect) { - msg_ok = true; - } else { - if (GPacket.Message.NameCRC == Compute_Name_CRC(MPlayerGameName)) { - msg_ok = true; - } else { - msg_ok = false; - } - } - - if (msg_ok) { - sprintf(txt,Text_String (TXT_FROM), GPacket.Name, GPacket.Message.Buf); - magic_number = *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-4)); - crc = *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-2)); - color = MPlayerID_To_ColorIndex(GPacket.Message.ID); - Messages.Add_Message(txt, MPlayerTColors[color], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, magic_number, crc); - - /* - ** Tell the map to do a partial update (just to force the messages - ** to redraw). - */ - Map.Flag_To_Redraw(false); - - /* - ** Save this message in our last-message buffer - */ - if (strlen(GPacket.Message.Buf)) { - strcpy(LastMessage, GPacket.Message.Buf); - } - } - } else { - Process_Global_Packet(&GPacket, &GAddress); - } - } - } - } - } - } - - /* - ** Modem and Null Modem maintenance - */ - if (GameToPlay == GAME_NULL_MODEM - || ((GameToPlay == GAME_MODEM) && ModemService)){ - //|| GameToPlay == GAME_INTERNET) { - - // PG_TO_FIX - //NullModem.Service(); - } -#endif -} - - -/*********************************************************************************************** - * Language_Name -- Build filename for current language. * - * * - * This routine attaches a language specific suffix to the base * - * filename provided. Typical use of this is when loading language * - * specific files at game initialization time. * - * * - * INPUT: basename -- Base name to append language specific * - * extension to. * - * * - * OUTPUT: Returns with pointer to completed filename. * - * * - * WARNINGS: The return pointer value is valid only until the next time * - * this routine is called. * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -char const *Language_Name(char const *basename) -{ - static char _fullname[_MAX_FNAME+_MAX_EXT]; - - if (!basename) return(NULL); - - sprintf(_fullname, "%s.ENG", basename); - return(_fullname); -} - - -/*********************************************************************************************** - * Source_From_Name -- Converts ASCII name into SourceType. * - * * - * This routine is used to convert an ASCII name representing a * - * SourceType into the actual SourceType value. Typically, this is * - * used when processing the scenario INI file. * - * * - * INPUT: name -- The ASCII source name to process. * - * * - * OUTPUT: Returns with the SourceType represented by the name * - * specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/17/1994 JLB : Created. * - *=============================================================================================*/ -SourceType Source_From_Name(char const *name) -{ - if (name) { - for (SourceType source = SOURCE_FIRST; source < SOURCE_COUNT; source++) { - if (stricmp(SourceName[source], name) == 0) { - return(source); - } - } - } - return(SOURCE_NONE); -} - - -/*********************************************************************************************** - * Name_From_Source -- retrieves the name for the given SourceType * - * * - * INPUT: * - * source SourceType to get the name for * - * * - * OUTPUT: * - * name of SourceType * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/15/1994 BR : Created. * - *=============================================================================================*/ -char const *Name_From_Source(SourceType source) -{ - if ((unsigned)source < SOURCE_COUNT) { - return(SourceName[source]); - } - return("None"); -} - - -/*********************************************************************************************** - * Theater_From_Name -- Converts ASCII name into a theater number. * - * * - * This routine converts an ASCII representation of a theater and converts it into a * - * matching theater number. If no match was found, then THEATER_NONE is returned. * - * * - * INPUT: name -- Pointer to ASCII name to convert. * - * * - * OUTPUT: Returns with the name converted into a theater number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/01/1994 JLB : Created. * - *=============================================================================================*/ -TheaterType Theater_From_Name(char const *name) -{ - TheaterType index; - - if (name) { - for (index = THEATER_FIRST; index < THEATER_COUNT; index++) { - if (stricmp(name, Theaters[index].Name) == 0) { - return(index); - } - } - } - return(THEATER_NONE); -} - - -/*********************************************************************************************** - * KN_To_Facing -- Converts a keyboard input number into a facing value. * - * * - * This routine determine which compass direction is represented by the keyboard value * - * provided. It is used for map scrolling and other directional control operations from * - * the keyboard. * - * * - * INPUT: input -- The KN number to convert. * - * * - * OUTPUT: Returns with the facing type that the keyboard number represents. If it could * - * not be translated, then FACING_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -FacingType KN_To_Facing(int input) -{ - input &= ~(KN_ALT_BIT|KN_SHIFT_BIT|KN_CTRL_BIT); - switch (input) { - case KN_LEFT: - return(FACING_W); - - case KN_RIGHT: - return(FACING_E); - - case KN_UP: - return(FACING_N); - - case KN_DOWN: - return(FACING_S); - - case KN_UPLEFT: - return(FACING_NW); - - case KN_UPRIGHT: - return(FACING_NE); - - case KN_DOWNLEFT: - return(FACING_SW); - - case KN_DOWNRIGHT: - return(FACING_SE); - } - return(FACING_NONE); -} - - -/*********************************************************************************************** - * Sync_Delay -- Forces the game into a 15 FPS rate. * - * * - * This routine will wait until the timer for the current frame has expired before * - * returning. It is called at the end of every game loop in order to force the game loop * - * to run at a fixed rate. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Will delay for up to 1/15 of a second. * - * * - * HISTORY: * - * 01/04/1995 JLB : Created. * - * 03/06/1995 JLB : Fixed. * - *=============================================================================================*/ -static void Sync_Delay(void) -{ - /* - ** Delay one tick and keep a record that one tick was "wasted" here. - ** This accumulates into a running histogram of performance. - */ - SpareTicks += FrameTimer.Time(); - while (FrameTimer.Time()) { - Color_Cycle(); - Call_Back(); - - if (SpecialDialog == SDLG_NONE) { - WWMouse->Erase_Mouse(&HidPage, TRUE); - KeyNumType input = KN_NONE; - int x, y; - WWMouse->Erase_Mouse(&HidPage, TRUE); - Map.Input(input, x, y); - if (input) { - Keyboard_Process(input); - } - Map.Render(); - } - } - Color_Cycle(); - Call_Back(); -} - - -/*********************************************************************************************** - * Main_Loop -- This is the main game loop (as a single loop). * - * * - * This function will perform one game loop. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Should the game end? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/01/1994 JLB : Created. * - *=============================================================================================*/ -extern void Check_For_Focus_Loss(void); -void Reallocate_Big_Shape_Buffer(void); - - -bool Main_Loop() -{ - KeyNumType input; // Player input. - int x; - int y; - int framedelay; - -// InMainLoop = true; - - /* - ** I think I'm gonna cry if this makes it work - */ - if (Get_Mouse_State())Show_Mouse(); - - /* - ** Call the focus loss handler - */ - Check_For_Focus_Loss(); - - /* - ** Allocate extra memory for uncompressed shapes as needed - */ - Reallocate_Big_Shape_Buffer(); - - /* - ** Sync-bug trapping code - */ - if (Frame >= TrapFrame) { - Trap_Object(); - } - - // - // Initialize our AI processing timer - // - ProcessTimer.Set(0, true); - - -#if 1 - if (TrapCheckHeap) { - Debug_Trap_Check_Heap = true; - } -#endif - -#ifdef CHEAT_KEYS - Heap_Dump_Check( "After Trap" ); - - /* - ** Update the running status debug display. - */ - Self_Regulate(); -#endif - - /* - ** If there is no theme playing, but it looks like one is required, then start one - ** playing. This is usually the symptom of there being no transition score. - */ - if (SampleType && Theme.What_Is_Playing() == THEME_NONE) { - Theme.Queue_Song(THEME_PICK_ANOTHER); - } - - /* - ** Setup the timer so that the Main_Loop function processes at the correct rate. - */ - if (GameToPlay != GAME_NORMAL && CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - framedelay = 60 / DesiredFrameRate; - FrameTimer.Set(framedelay); - } else { - FrameTimer.Set(Options.GameSpeed); - } - - /* - ** Update the display, unless we're inside a dialog. - */ - if (!PlaybackGame) { - if (SpecialDialog == SDLG_NONE && GameInFocus) { - - WWMouse->Erase_Mouse(&HidPage, TRUE); - Map.Input(input, x, y); - if (input) { - Keyboard_Process(input); - } -// HidPage.Lock(); - Map.Render(); -// HidPage.Unlock(); - } - } - - /* - ** Save map's position & selected objects, if we're recording the game. - */ - if (RecordGame || PlaybackGame) { - Do_Record_Playback(); - } - - /* - ** Sort the map's ground layer by y-coordinate value. This is done - ** outside the IsToRedraw check, for the purposes of game sync'ing - ** between machines; this way, all machines will sort the Map's - ** layer in the same way, and any processing done that's based on - ** the order of this layer will sync on different machines. - */ - Map.Layer[LAYER_GROUND].Sort(); - -// Heap_Dump_Check( "Before Logic.AI" ); - - /* - ** AI logic operations are performed here. - */ - Logic.AI(); - -// Heap_Dump_Check( "After Logic.AI" ); - - /* - ** Manage the inter-player message list. If Manage() returns true, it means - ** a message has expired & been removed, and the entire map must be updated. - */ - if (Messages.Manage()) { - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - } - - // - // Measure how long it took to process the AI - // - ProcessTicks += ProcessTimer.Time(); - ProcessFrames++; - -// Heap_Dump_Check( "Before Queue_AI" ); - - /* - ** Process all commands that are ready to be processed. - */ - Queue_AI(); - -// Heap_Dump_Check( "After Queue_AI" ); - - /* - ** Keep track of elapsed time in the game. - */ - Score.ElapsedTime += TIMER_SECOND / TICKS_PER_SECOND; - - Call_Back(); - -// Heap_Dump_Check( "After Call_Back" ); - - /* - ** Perform any win/lose code as indicated by the global control flags. - */ - if (EndCountDown) EndCountDown--; - - /* - ** Check for player wins or loses according to global event flag. - */ - - - - if (PlayerWins) { - - if (GameToPlay == GAME_INTERNET && !GameStatisticsPacketSent){ - Register_Game_End_Time(); - Send_Statistics_Packet(); - } - - WWMouse->Erase_Mouse(&HidPage, TRUE); - PlayerLoses = false; - PlayerWins = false; - PlayerRestarts = false; - Map.Help_Text(TXT_NONE); - Do_Win(); - } - if (PlayerLoses) { - - if (GameToPlay == GAME_INTERNET && !GameStatisticsPacketSent){ - Register_Game_End_Time(); - Send_Statistics_Packet(); - } - - WWMouse->Erase_Mouse(&HidPage, TRUE); - PlayerWins = false; - PlayerLoses = false; - PlayerRestarts = false; - Map.Help_Text(TXT_NONE); - Do_Lose(); - } - if (PlayerRestarts) { - WWMouse->Erase_Mouse(&HidPage, TRUE); - PlayerWins = false; - PlayerLoses = false; - PlayerRestarts = false; - Map.Help_Text(TXT_NONE); - Do_Restart(); - } - - /* - ** The frame logic has been completed. Increment the frame - ** counter. - */ - Frame++; - - /* - ** Very rarely, the human players will get a message from the computer. - */ - if (GameToPlay != GAME_NORMAL && MPlayerGhosts && IRandom(0,10000) == 1) { - Computer_Message(); - } - - /* - ** Is there a memory trasher altering the map?? - */ - if (Debug_Check_Map) { - if (!Map.Validate()) { -#ifdef GERMAN - if (CCMessageBox().Process ("Kartenfehler!","Halt","Weiter")==0) -#else -#ifdef FRENCH - if (CCMessageBox().Process ("Erreur de carte!","Stop","Continuer")==0) -#else - if (CCMessageBox().Process ("Map Error!","Stop","Continue")==0) -#endif -#endif - GameActive = false; - Map.Validate(); // give debugger a chance to catch it - } - } - - Sync_Delay(); -// InMainLoop = false; - return(!GameActive); -} - - -#ifdef SCENARIO_EDITOR -/*************************************************************************** - * Map_Edit_Loop -- a mini-main loop for map edit mode only * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/19/1994 BR : Created. * - *=========================================================================*/ -bool Map_Edit_Loop(void) -{ - /* - ** Redraw the map. - */ - Map.Render(); - - /* - ** Get user input (keys, mouse clicks). - */ - KeyNumType input; - - int x; - int y; - Map.Input(input, x, y); - - /* - ** Process keypress. - */ - if (input) { - Keyboard_Process(input); - } - - Call_Back(); // maintains Theme.AI() for music - Color_Cycle(); - - return(!GameActive); -} - - -/*************************************************************************** - * Go_Editor -- Enables/disables the map editor * - * * - * INPUT: * - * flag true = go into editor mode; false = go into game mode * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/19/1994 BR : Created. * - *=========================================================================*/ -void Go_Editor(bool flag) -{ - /* - ** Go into Scenario Editor mode - */ - if (flag) { - Debug_Map = true; - Debug_Unshroud = true; - - /* - ** Un-select any selected objects - */ - Unselect_All(); - - /* - ** Turn off the sidebar if it's on - */ - Map.Activate(0); - - /* - ** Reset the map's Button list for the new mode - */ - Map.Init_IO(); - - /* - ** Force a complete redraw of the screen - */ - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); - - } else { - - /* - ** Go into normal game mode - */ - Debug_Map = false; - Debug_Unshroud = false; - - /* - ** Un-select any selected objects - */ - Unselect_All(); - - /* - ** Reset the map's Button list for the new mode - */ - Map.Init_IO(); - - /* - ** Force a complete redraw of the screen - */ - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); - } -} - -#endif - -#if (0) -#define VQ_THREAD_BUFFER_SIZE 1024*1024 -#define VQ_THREAD_BUFFER_CHUNK VQ_THREAD_BUFFER_SIZE/4 -unsigned char *VQThreadBuffer = NULL; -volatile bool ThreadReading = false; -unsigned long VQThreadBlockHead; -unsigned long VQThreadBlockTail; -unsigned long VQBytesLeft; -unsigned long VQBytesRead; - - -void Init_VQ_Threading(CCFileClass *file) -{ - if (!VQThreadBuffer){ - VQThreadBuffer = new unsigned char [VQ_THREAD_BUFFER_SIZE]; - } - Force_VM_Page_In(VQThreadBuffer, VQ_THREAD_BUFFER_SIZE); - VQThreadBlockHead = 0; - VQThreadBlockTail = 0; - VQBytesRead = 0; - VQBytesLeft = file->Size(); -} - - -void Cleanup_VQ_Threading(void) -{ - while (ThreadReading){} - if (VQThreadBuffer){ - delete VQThreadBuffer; - VQThreadBuffer = NULL; - } -} - -unsigned long __stdcall Thread_Read(void *file) -{ - int bytes_to_read; - int left_to_read; - int read_this_time; - unsigned long head; - int sleep_time; - - CCFileClass *ccfile = (CCFileClass*)file; - - bytes_to_read = MIN (VQBytesLeft, VQ_THREAD_BUFFER_CHUNK); - - if (!bytes_to_read){ - ThreadReading = false; - return(0); - } - - left_to_read = bytes_to_read; - - while (left_to_read){ - read_this_time = MIN(8*1024, left_to_read); - //if (read_this_time & 3){ - ccfile->Read(VQThreadBuffer+VQThreadBlockHead, read_this_time); - //}else{ - // ccfile->Read(VQThreadBuffer+VQThreadBlockHead, read_this_time/4); - // ccfile->Read(VQThreadBuffer+VQThreadBlockHead+read_this_time/4, read_this_time/4); - // ccfile->Read(VQThreadBuffer+VQThreadBlockHead+(read_this_time/4)*2, read_this_time/4); - // ccfile->Read(VQThreadBuffer+VQThreadBlockHead+(read_this_time/4)*3, read_this_time/4); - //} - VQThreadBlockHead += read_this_time; - left_to_read -= read_this_time; - - head = VQThreadBlockHead; - if (head VQThreadBlockTail){ - bytes_to_read = MIN(bytes, VQThreadBlockHead-VQThreadBlockTail); - - }else{ - bytes_to_read = MIN(bytes, VQThreadBlockHead+VQ_THREAD_BUFFER_SIZE - VQThreadBlockTail); - } - - }while(ThreadReading && bytes_to_read VQ_THREAD_BUFFER_SIZE){ - - int first_chunk = VQ_THREAD_BUFFER_SIZE - VQThreadBlockTail; - int second_chunk = bytes_to_read - first_chunk; - - memcpy (buffer, VQThreadBuffer + VQThreadBlockTail, first_chunk); - memcpy ((unsigned char*)buffer + first_chunk, VQThreadBuffer, second_chunk); - }else{ - memcpy (buffer, VQThreadBuffer + VQThreadBlockTail, bytes_to_read); - } - - VQThreadBlockTail += bytes_to_read; - VQThreadBlockTail &= VQ_THREAD_BUFFER_SIZE - 1; - - unsigned long head = VQThreadBlockHead; - if (headVQAio; - - /* - ** Perform the action specified by the stream command. - */ - switch (action) { - - /* - ** VQACMD_READ means read NBytes from the stream and place it in the - ** memory pointed to by Buffer. - ** - ** Any error code returned will be remapped by VQA library into - ** VQAERR_READ. - */ - case VQACMD_READ: - error = VQ_Thread_Read (file, buffer, nbytes); - //error = (file->Read(buffer, (unsigned short)nbytes) != (unsigned short)nbytes); - if (error == nbytes) error = 0; - break; - - /* - ** VQACMD_WRITE is analogous to VQACMD_READ. - ** - ** Writing is not allowed to the VQA file, VQA library will remap the - ** error into VQAERR_WRITE. - */ - case VQACMD_WRITE: - error = 1; - break; - - /* - ** VQACMD_SEEK asks that you perform a seek relative to the current - ** position. NBytes is a signed number, indicating seek direction - ** (positive for forward, negative for backward). Buffer has no meaning - ** here. - ** - ** Any error code returned will be remapped by VQA library into - ** VQAERR_SEEK. - */ - case VQACMD_SEEK: - //error = (file->Seek(nbytes, SEEK_CUR) == -1); - VQ_Thread_Seek(nbytes); - error = 0; - break; - - /* - ** VQACMD_OPEN asks that you open your stream for access. - */ - case VQACMD_OPEN: - file = new CCFileClass((char *)buffer); - - if (file != NULL && file->Is_Available()) { - error = file->Open((char *)buffer, READ); - - if (error != -1) { - vqa->VQAio = (unsigned long)file; - error = 0; - //file->Set_Buffer_Size(8*1024); - } else { - delete file; - file = 0; - error = 1; - } - } else { - error = 1; - } - - if (error != -1){ - Init_VQ_Threading(file); - Read_VQ_Thread_Block(file); - CountDownTimerClass timer; - timer.Set(60); - while (ThreadReading || timer.Time()){} - } - break; - - case VQACMD_CLOSE: - Cleanup_VQ_Threading(); - file->Close(); - delete file; - file = 0; - vqa->VQAio = 0; - error = 0; - break; - - /* - ** VQACMD_INIT means to prepare your stream for reading. This is used for - ** certain streams that can't be read immediately upon opening, and need - ** further preparation. This operation is allowed to fail; the error code - ** will be returned directly to the client. - */ - case VQACMD_INIT: - - /* - ** IFFCMD_CLEANUP means to terminate the transaction with the associated - ** stream. This is used for streams that can't simply be closed. This - ** operation is not allowed to fail; any error returned will be ignored. - */ - case VQACMD_CLEANUP: - error = 0; - break; - } - - return(error); -} -#endif //(0) -//#if (0) - - -// PG_TO_FIX -typedef void* VQAHandle; - -/*********************************************************************************************** - * MixFileHandler -- Handles VQ file access. * - * * - * This routine is called from the VQ player when it needs to access the source file. By * - * using this routine it is possible to virtualize the file system. * - * * - * INPUT: vqa -- Pointer to the VQA handle for this animation. * - * * - * action-- The requested action to perform. * - * * - * buffer-- Optional buffer pointer as needed by the type of action. * - * * - * nbytes-- The number of bytes (if needed) for this operation. * - * * - * OUTPUT: Returns a value consistent with the action requested. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -long MixFileHandler(VQAHandle *vqa, long action, void *buffer, long nbytes) -{ - return 0;; -#if (0) - CCFileClass *file; - long error; - - file = (CCFileClass *)vqa->VQAio; - - /* - ** Perform the action specified by the stream command. - */ - switch (action) { - - /* - ** VQACMD_READ means read NBytes from the stream and place it in the - ** memory pointed to by Buffer. - ** - ** Any error code returned will be remapped by VQA library into - ** VQAERR_READ. - */ - case VQACMD_READ: - error = (file->Read(buffer, (unsigned short)nbytes) != (unsigned short)nbytes); - break; - - /* - ** VQACMD_WRITE is analogous to VQACMD_READ. - ** - ** Writing is not allowed to the VQA file, VQA library will remap the - ** error into VQAERR_WRITE. - */ - case VQACMD_WRITE: - error = 1; - break; - - /* - ** VQACMD_SEEK asks that you perform a seek relative to the current - ** position. NBytes is a signed number, indicating seek direction - ** (positive for forward, negative for backward). Buffer has no meaning - ** here. - ** - ** Any error code returned will be remapped by VQA library into - ** VQAERR_SEEK. - */ - case VQACMD_SEEK: - error = (file->Seek(nbytes, SEEK_CUR) == -1); - break; - - /* - ** VQACMD_OPEN asks that you open your stream for access. - */ - case VQACMD_OPEN: - file = new CCFileClass((char *)buffer); - - if (file != NULL && file->Is_Available()) { - error = file->Open((char *)buffer, READ); - - if (error != -1) { - vqa->VQAio = (unsigned long)file; - error = 0; - file->Set_Buffer_Size(8*1024); - } else { - delete file; - file = 0; - error = 1; - } - } else { - error = 1; - } - break; - - case VQACMD_CLOSE: - file->Close(); - delete file; - file = 0; - vqa->VQAio = 0; - error = 0; - break; - - /* - ** VQACMD_INIT means to prepare your stream for reading. This is used for - ** certain streams that can't be read immediately upon opening, and need - ** further preparation. This operation is allowed to fail; the error code - ** will be returned directly to the client. - */ - case VQACMD_INIT: - - /* - ** IFFCMD_CLEANUP means to terminate the transaction with the associated - ** stream. This is used for streams that can't simply be closed. This - ** operation is not allowed to fail; any error returned will be ignored. - */ - case VQACMD_CLEANUP: - error = 0; - break; - } - - return(error); -#endif -} - -//#endif //(0) - - -void Rebuild_Interpolated_Palette(unsigned char *interpal) -{ - for (int y=0 ; y<255 ; y++){ - for (int x=y+1 ; x<256 ; x++){ - *(interpal + (y*256+x)) = *(interpal + (x*256+y)); - } - } -} - - -unsigned char *InterpolatedPalettes[100]; -BOOL PalettesRead; -unsigned PaletteCounter; - - -int Load_Interpolated_Palettes(char const *filename, BOOL add) -{ - int num_palettes=0; - int i; - int start_palette; - - PalettesRead = FALSE; - CCFileClass file(filename); - -// RawFileClass *palette_file; - - if (!add){ - for (i=0 ; iUnselect(); - //} - - //Added some error handling incase there was an issue removing the object - JAS 6/28/2019 - while (CurrentObject.Count()) { - - int count_before = CurrentObject.Count(); - CurrentObject[0]->Unselect(); - - if (count_before <= CurrentObject.Count()) { - GlyphX_Debug_Print("Unselect_All failed to remove an object"); - CurrentObject.Delete(CurrentObject[0]); - } - } - //End of change - JAS 6/28/2019 -} - - -void Unselect_All_Except(ObjectClass* object) -{ - int index = 0; - while (index < CurrentObject.Count()) { - - if (CurrentObject[index] == object) { - index++; - continue; - } - - int count_before = CurrentObject.Count(); - CurrentObject[index]->Unselect(); - - if (count_before <= CurrentObject.Count()) { - GlyphX_Debug_Print("Unselect_All failed to remove an object"); - CurrentObject.Delete(CurrentObject[index]); - } - } -} - - -/*********************************************************************************************** - * Fading_Table_Name -- Builds a theater specific fading table name. * - * * - * This routine builds a standard fading table name. This name is dependant on the theater * - * being played, since each theater has its own palette. * - * * - * INPUT: base -- The base name of this fading table. The base name can be no longer than * - * seven characters. * - * * - * theater -- The theater that this fading table is specific to. * - * * - * OUTPUT: Returns with a pointer to the constructed fading table filename. This pointer is * - * valid until this function is called again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -char const * Fading_Table_Name(char const * base, TheaterType theater) -{ - static char _buffer[_MAX_FNAME+_MAX_EXT]; - char root[_MAX_FNAME]; - - sprintf(root, "%1.1s%s", Theaters[theater].Root, base); - _makepath(_buffer, NULL, NULL, root, ".MRF"); - return(_buffer); -} - - -/*********************************************************************************************** - * Get_Radar_Icon -- Builds and alloc a radar icon from a shape file * - * * - * INPUT: void const * shapefile - pointer to a key framed shapefile * - * int shapenum - shape to extract from shapefile * - * * - * OUTPUT: void const * - 3/3 icon set of shape from file * - * * - * HISTORY: * - * 04/12/1995 PWG : Created. * - * 05/10/1995 JLB : Handles a null shapefile pointer. * - *=============================================================================================*/ -void const * Get_Radar_Icon(void const * shapefile, int shapenum, int frames, int zoomfactor) -{ - static int _offx[]={ 0, 0, -1, 1, 0, -1, 1, -1, 1}; - static int _offy[]={ 0, 0, -1, 1, 0, -1, 1, -1, 1}; - int lp,framelp; - char pixel; - - char *retval = NULL; - char *buffer = NULL; - void *ptr; - - - /* - ** If there is no shape file, then there can be no radar icon imagery. - */ - if (!shapefile) return(NULL); - - /* - ** Get the pixel width and height of the frame we built. This will - ** be used to extract icons and build pixels. - */ - int pixel_width = Get_Build_Frame_Width( shapefile ); - int pixel_height = Get_Build_Frame_Height( shapefile ); - - /* - ** Find the width and height in icons, adjust these by half an - ** icon because the artists may be sloppy and miss the edge of an - ** icon one way or the other. - */ - int icon_width = (pixel_width + 12) / 24; - int icon_height = (pixel_height + 12) / 24; - - /* - ** If we have been told to build as many frames as possible, then - ** find out how many frames there are to build. - */ - if (frames == -1) frames = Get_Build_Frame_Count( shapefile ); - - /* - ** Allocate a position to store our icons. If the alloc fails then - ** we dont add these icons to the set. - **/ - buffer = new char[(icon_width * icon_height * 9 * frames)+2]; - if (!buffer) return(NULL); - - /* - ** Save off the return value so that we can return it to the calling - ** function. - */ - retval = (char *)buffer; - *buffer++ = (char)icon_width; - *buffer++ = (char)icon_height; - int val = 24/zoomfactor; - - for (framelp = 0; framelp < frames; framelp ++) { - /* - ** Build the current frame. If the frame can not be built then we - ** just need to skip past this set of icons and try to build the - ** next frame. - */ - if ((ptr = (void *)(Build_Frame(shapefile, shapenum + framelp, SysMemPage.Get_Buffer()))) != NULL) { - ptr = Get_Shape_Header_Data(ptr); - /* - ** Loop through the icon width and the icon height building icons - ** into the buffer pointer. When the getx or gety falls outside of - ** the width and height of the shape, just insert transparent pixels. - */ - for (int icony = 0; icony < icon_height; icony ++) { - for (int iconx = 0; iconx < icon_width; iconx ++) { - for (int y = 0; y < zoomfactor; y++) { - for (int x = 0; x < zoomfactor; x++) { - int getx = (iconx * 24) + (x * val) + (zoomfactor / 2); - int gety = (icony * 24) + (y * val) + (zoomfactor / 2); - if ((getx < pixel_width) && (gety < pixel_height)) { - for (lp = 0; lp < 9; lp ++) { - pixel = *((char *)(Add_Long_To_Pointer(ptr, ((gety - _offy[lp]) * pixel_width) + getx-_offx[lp]))); - if (pixel == LTGREEN) pixel = 0; - if (pixel) { - break; - } - } - *buffer++ = pixel; - } else { - *buffer++ = 0; - } - } - } - } - } - } else { - buffer += icon_width * icon_height * 9; - } - } - return(retval); -} - - - - -void CC_Texture_Fill (void const *shapefile, int shapenum, int xpos, int ypos, int width, int height) -{ - unsigned char *shape_pointer; - //unsigned char *shape_save; - unsigned long shape_size; - //int x,y; - - if (shapefile && shapenum != -1) { - - /* - ** Build frame returns a pointer now instead of the shapes length - */ - shape_size=Build_Frame(shapefile , shapenum , _ShapeBuffer); - if (Get_Last_Frame_Length() > _ShapeBufferSize) { - Mono_Printf("Attempt to use shape buffer for size %d buffer is only size %d", shape_size, _ShapeBufferSize); - Get_Key(); - } - - if (shape_size) { - shape_pointer = (unsigned char *)Get_Shape_Header_Data ((void*)shape_size); - int source_width = Get_Build_Frame_Width (shapefile); - int source_height = Get_Build_Frame_Height (shapefile); - - - LogicPage->Texture_Fill_Rect (xpos, ypos, width, height, shape_pointer, source_width, source_height); -#if (0) - if (LogicPage->Lock()){ - - for (y = ypos ; y < ypos + MIN(source_height, height) ; y++ ){ - - shape_save = shape_pointer; - - for (x = xpos ; x < xpos + MIN(source_width, width) ; x++ ){ - LogicPage->Put_Pixel (x, y, *shape_pointer++); - } - - shape_pointer = shape_save + source_width; - } - - LogicPage->Unlock(); - } -#endif - } - } -} - - - - -extern void DLL_Draw_Intercept(int shape_number, int x, int y, int width, int height, int flags, ObjectClass *object, const char *shape_file_name, char override_owner, int scale); -extern void DLL_Draw_Pip_Intercept(const ObjectClass* object, int pip); -extern void DLL_Draw_Line_Intercept(int x, int y, int x1, int y1, unsigned char color, int frame); - -void CC_Draw_Shape(ObjectClass *object, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata, void const * ghostdata, int scale) -{ - if (window == WINDOW_VIRTUAL) { - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); - DLL_Draw_Intercept(shapenum, x, y, width, height, (int)flags, object, NULL, -1, scale); - return; - } - - CC_Draw_Shape(shapefile, shapenum, x, y, window, flags, fadingdata, ghostdata); -} - - -void CC_Draw_Shape(ObjectClass *object, const char *shape_file_name, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata, void const * ghostdata, char override_owner) -{ - if (window == WINDOW_VIRTUAL) { - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); - DLL_Draw_Intercept(shapenum, x, y, width, height, (int)flags, object, shape_file_name, override_owner, 0x100); - return; - } - - CC_Draw_Shape(shapefile, shapenum, x, y, window, flags, fadingdata, ghostdata); -} - - -void CC_Draw_Pip(ObjectClass *object, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata, void const * ghostdata) -{ - if (window == WINDOW_VIRTUAL) { - DLL_Draw_Pip_Intercept(object, shapenum); - return; - } - - CC_Draw_Shape(shapefile, shapenum, x, y, window, flags, fadingdata, ghostdata); -} - - -void CC_Draw_Line(int x, int y, int x1, int y1, unsigned char color, int frame, WindowNumberType window) -{ - if (window == WINDOW_VIRTUAL) { - DLL_Draw_Line_Intercept(x, y, x1, y1, color, frame); - return; - } - - LogicPage->Draw_Line(x, y, x1, y1, color); -} - - -/*********************************************************************************************** - * CC_Draw_Shape -- Custom draw shape handler. * - * * - * All draw shape calls will route through this function. It handles all draws for * - * C&C. Such draws always occur to the logical page and assume certain things about * - * the parameters passed. * - * * - * INPUT: shapefile -- Pointer to the shape data file. This data file contains all the * - * embedded shapes. * - * * - * shapenum -- The shape number within the shapefile that will be drawn. * - * * - * x,y -- The pixel coordinates to draw the shape. * - * * - * window -- The clipping window to use. * - * * - * flags -- The custom draw shape flags. This controls how the parameters * - * are used (if any). * - * * - * fadingdata -- If SHAPE_FADING is desired, then this points to the fading * - * data table. * - * * - * ghostdata -- If SHAPE_GHOST is desired, then this points to the ghost remap * - * table. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -//#pragma off(unreferenced) -void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata, void const * ghostdata) -{ -#if(TRUE) - int predoffset; - char *shape_pointer; - unsigned long shape_size; - - if (shapefile && shapenum != -1) { - - /* - ** Build frame returns a pointer now instead of the shapes length - */ - shape_size=Build_Frame(shapefile , shapenum , _ShapeBuffer); - if (Get_Last_Frame_Length() > _ShapeBufferSize) { - Mono_Printf("Attempt to use shape buffer for size %d buffer is only size %d", shape_size, _ShapeBufferSize); - Get_Key(); - } - - if (shape_size) { - GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(), - (WindowList[window][WINDOWX] << 3) + LogicPage->Get_XPos(), - WindowList[window][WINDOWY] + LogicPage->Get_YPos(), - WindowList[window][WINDOWWIDTH] << 3, - WindowList[window][WINDOWHEIGHT]); - - shape_pointer = (char *)shape_size; - - /* - ** Special shadow drawing code (used for aircraft and bullets). - */ - if ((flags & (SHAPE_FADING|SHAPE_PREDATOR)) == (SHAPE_FADING|SHAPE_PREDATOR)) { - flags = flags & ~(SHAPE_FADING|SHAPE_PREDATOR); - flags = flags | SHAPE_GHOST; - ghostdata = Map.SpecialGhost; - } - - predoffset = Frame; - - if (x > ( WindowList[window][WINDOWWIDTH] << 2)) { - predoffset = -predoffset; - } - - if (draw_window.Lock()){ - if ((flags & (SHAPE_GHOST|SHAPE_FADING)) == (SHAPE_GHOST|SHAPE_FADING)) { - Buffer_Frame_To_Page(x, y, Get_Build_Frame_Width(shapefile), Get_Build_Frame_Height(shapefile), - shape_pointer, draw_window, flags | SHAPE_TRANS, ghostdata, fadingdata, 1, predoffset); - } else { - if (flags & SHAPE_FADING) { - Buffer_Frame_To_Page(x, y, Get_Build_Frame_Width(shapefile), Get_Build_Frame_Height(shapefile), - shape_pointer, draw_window, flags | SHAPE_TRANS, fadingdata, 1, predoffset); - } else { - if (flags & SHAPE_PREDATOR) { - Buffer_Frame_To_Page(x, y, Get_Build_Frame_Width(shapefile), Get_Build_Frame_Height(shapefile), - shape_pointer, draw_window, flags | SHAPE_TRANS, predoffset); - } else { - Buffer_Frame_To_Page(x, y, Get_Build_Frame_Width(shapefile), Get_Build_Frame_Height(shapefile), - shape_pointer, draw_window, flags | SHAPE_TRANS, ghostdata, predoffset); - } - } - } - } - draw_window.Unlock(); -// } else { -// Mono_Printf( "Overrun ShapeBuffer!!!!!!!!!\n" ); - } - } -#endif -} - - - -/*********************************************************************************************** - * Fetch_Techno_Type -- Convert type and ID into TechnoTypeClass pointer. * - * * - * This routine will convert the supplied RTTI type number and the ID value into a valid * - * TechnoTypeClass pointer. If there is an error in conversion, then NULL is returned. * - * * - * INPUT: type -- RTTI type of the techno class object. * - * * - * id -- Integer representation of the techno sub type number. * - * * - * OUTPUT: Returns with a pointer to the techno type class object specified or NULL if the * - * conversion could not occur. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -TechnoTypeClass const * Fetch_Techno_Type(RTTIType type, int id) -{ - switch (type) { - case RTTI_UNITTYPE: - case RTTI_UNIT: - return(&UnitTypeClass::As_Reference((UnitType)id)); - - case RTTI_BUILDINGTYPE: - case RTTI_BUILDING: - return(&BuildingTypeClass::As_Reference((StructType)id)); - - case RTTI_INFANTRYTYPE: - case RTTI_INFANTRY: - return(&InfantryTypeClass::As_Reference((InfantryType)id)); - - case RTTI_AIRCRAFTTYPE: - case RTTI_AIRCRAFT: - return(&AircraftTypeClass::As_Reference((AircraftType)id)); - } - return(NULL); -} - - -/*************************************************************************** - * Trap_Object -- gets a ptr to object of given type & coord * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/02/1995 BRR : Created. * - *=========================================================================*/ -void Trap_Object(void) -{ - int i; - - TrapObject.Ptr.All = NULL; - - switch (TrapObjType) { - case RTTI_AIRCRAFT: - for (i = 0; i < Aircraft.Count(); i++) { - if (Aircraft.Ptr(i)->Coord == TrapCoord || Aircraft.Ptr(i)==TrapThis) { - TrapObject.Ptr.Aircraft = Aircraft.Ptr(i); - break; - } - } - break; - - case RTTI_ANIM: - for (i = 0; i < Anims.Count(); i++) { - if (Anims.Ptr(i)->Coord == TrapCoord || Anims.Ptr(i)==TrapThis) { - TrapObject.Ptr.Anim = Anims.Ptr(i); - break; - } - } - break; - - case RTTI_BUILDING: - for (i = 0; i < Buildings.Count(); i++) { - if (Buildings.Ptr(i)->Coord == TrapCoord || Buildings.Ptr(i)==TrapThis) { - TrapObject.Ptr.Building = Buildings.Ptr(i); - break; - } - } - break; - - case RTTI_BULLET: - for (i = 0; i < Bullets.Count(); i++) { - if (Bullets.Ptr(i)->Coord == TrapCoord || Bullets.Ptr(i)==TrapThis) { - TrapObject.Ptr.Bullet = Bullets.Ptr(i); - break; - } - } - break; - - case RTTI_INFANTRY: - for (i = 0; i < Infantry.Count(); i++) { - if (Infantry.Ptr(i)->Coord == TrapCoord || Infantry.Ptr(i)==TrapThis) { - TrapObject.Ptr.Infantry = Infantry.Ptr(i); - break; - } - } - break; - - case RTTI_UNIT: - for (i = 0; i < Units.Count(); i++) { - if (Units.Ptr(i)->Coord == TrapCoord || Units.Ptr(i)==TrapThis) { - TrapObject.Ptr.Unit = Units.Ptr(i); - break; - } - } - break; - - /* - ** Last-ditch find-the-object-right-now-darnit loop - */ - case RTTI_NONE: - for (i = 0; i < Aircraft.Count(); i++) { - if (Aircraft.Raw_Ptr(i)->Coord == TrapCoord || Aircraft.Raw_Ptr(i)==TrapThis) { - TrapObject.Ptr.Aircraft = Aircraft.Raw_Ptr(i); - TrapObjType = RTTI_AIRCRAFT; - return; - } - } - for (i = 0; i < Anims.Count(); i++) { - if (Anims.Raw_Ptr(i)->Coord == TrapCoord || Anims.Raw_Ptr(i)==TrapThis) { - TrapObject.Ptr.Anim = Anims.Raw_Ptr(i); - TrapObjType = RTTI_ANIM; - return; - } - } - for (i = 0; i < Buildings.Count(); i++) { - if (Buildings.Raw_Ptr(i)->Coord == TrapCoord || Buildings.Raw_Ptr(i)==TrapThis) { - TrapObject.Ptr.Building = Buildings.Raw_Ptr(i); - TrapObjType = RTTI_BUILDING; - return; - } - } - for (i = 0; i < Bullets.Count(); i++) { - if (Bullets.Raw_Ptr(i)->Coord == TrapCoord || Bullets.Raw_Ptr(i)==TrapThis) { - TrapObject.Ptr.Bullet = Bullets.Raw_Ptr(i); - TrapObjType = RTTI_BULLET; - return; - } - } - for (i = 0; i < Infantry.Count(); i++) { - if (Infantry.Raw_Ptr(i)->Coord == TrapCoord || Infantry.Raw_Ptr(i)==TrapThis) { - TrapObject.Ptr.Infantry = Infantry.Raw_Ptr(i); - TrapObjType = RTTI_INFANTRY; - return; - } - } - for (i = 0; i < Units.Count(); i++) { - if (Units.Raw_Ptr(i)->Coord == TrapCoord || Units.Raw_Ptr(i)==TrapThis) { - TrapObject.Ptr.Unit = Units.Raw_Ptr(i); - TrapObjType = RTTI_UNIT; - return; - } - } - - default: - break; - } -} - - -/*********************************************************************************************** - * VQ_Call_Back -- Maintenance callback used for VQ movies. * - * * - * This routine is called every frame of the VQ movie as it is being played. If this * - * routine returns non-zero, then the movie will stop. * - * * - * INPUT: buffer -- Pointer to the image buffer for the current frame. * - * * - * frame -- The frame number about to be displayed. * - * * - * OUTPUT: Should the movie be stopped? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 JLB : Created. * - *=============================================================================================*/ -void VQA_PauseAudio(void) {}; -void Check_VQ_Palette_Set(void); - -long VQ_Call_Back(unsigned char *, long ) -{ -// PG_TO_FIX - 1/2/2019 3:59PM -#if (0) - int key = 0; - if (Keyboard::Check()){ - key = Keyboard::Get(); - Keyboard::Clear(); - } - - Check_VQ_Palette_Set(); - - Interpolate_2X_Scale(&SysMemPage,&SeenBuff,NULL); - //Call_Back(); - if ((BreakoutAllowed || Debug_Flag) && key == KN_ESC) { - Keyboard::Clear(); - Brokeout = true; - return(true); - } - - if (!GameInFocus){ - VQA_PauseAudio(); - while (!GameInFocus){ - Keyboard::Check(); - Check_For_Focus_Loss(); - } - } -#endif - return(false); -} - - -/*********************************************************************************************** - * Handle_Team -- Processes team selection command. * - * * - * This routine will handle creation and selection of pseudo teams that the player can * - * create or control. A team in this sense is an arbitrary grouping of units such that * - * rapid selection control is allowed. * - * * - * INPUT: team -- The logical team number to process. * - * * - * action-- The action to perform on this team: * - * 0 - Toggle the select state for all members of this team. * - * 1 - Select the members of this team. * - * 2 - Make all selected objects members of this team. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/27/1995 JLB : Created. * - *=============================================================================================*/ -void Handle_Team(int team, int action) -{ - int index; - - AllowVoice = true; - switch (action) { - - /* - ** Toggle the team selection. If the team is selected, then merely unselect it. If the - ** team is not selected, then unselect all others before selecting this team. - */ - case 3: - case 0: - - /* - ** If a non team member is currently selected, then deselect all objects - ** before selecting this team. - */ - for (index = 0; index < CurrentObject.Count(); index++) { - ObjectClass * obj = CurrentObject[index]; - if (obj->What_Am_I() == RTTI_UNIT || obj->What_Am_I() == RTTI_INFANTRY || obj->What_Am_I() == RTTI_AIRCRAFT) { - if (((FootClass *)obj)->Group != team) { - Unselect_All(); - break; - } - } - } - for (index = 0; index < Units.Count(); index++) { - UnitClass * obj = Units.Ptr(index); - if (obj && !obj->IsInLimbo && obj->Group == team && obj->House == PlayerPtr) { - if (!obj->Is_Selected_By_Player()) { - obj->Select(); - AllowVoice = false; - } - } - } - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * obj = Infantry.Ptr(index); - if (obj && !obj->IsInLimbo && obj->Group == team && obj->House == PlayerPtr) { - if (!obj->Is_Selected_By_Player()) { - obj->Select(); - AllowVoice = false; - } - } - } - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass * obj = Aircraft.Ptr(index); - if (obj && !obj->IsInLimbo && obj->Group == team && obj->House == PlayerPtr) { - if (!obj->Is_Selected_By_Player()) { - obj->Select(); - AllowVoice = false; - } - } - } - - /* - ** Center the map around the team if the ALT key was pressed too. - */ - if (action == 3) { - Map.Center_Map(); - Map.Flag_To_Redraw(true); - } - break; - - /* - ** Additive selection of team. - */ - case 1: - for (index = 0; index < Units.Count(); index++) { - UnitClass * obj = Units.Ptr(index); - if (obj && !obj->IsInLimbo && obj->Group == team && obj->House == PlayerPtr) { - if (!obj->Is_Selected_By_Player()) { - obj->Select(); - AllowVoice = false; - } - } - } - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * obj = Infantry.Ptr(index); - if (obj && !obj->IsInLimbo && obj->Group == team && obj->House == PlayerPtr) { - if (!obj->Is_Selected_By_Player()) { - obj->Select(); - AllowVoice = false; - } - } - } - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass * obj = Aircraft.Ptr(index); - if (obj && !obj->IsInLimbo && obj->Group == team && obj->House == PlayerPtr) { - if (!obj->Is_Selected_By_Player()) { - obj->Select(); - AllowVoice = false; - } - } - } - break; - - /* - ** Create the team. - */ - case 2: - for (index = 0; index < Units.Count(); index++) { - UnitClass * obj = Units.Ptr(index); - if (obj && !obj->IsInLimbo && obj->House == PlayerPtr) { - if (obj->Group == team) obj->Group = -1; - if (obj->Is_Selected_By_Player()) obj->Group = team; - } - } - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * obj = Infantry.Ptr(index); - if (obj && !obj->IsInLimbo && obj->House == PlayerPtr) { - if (obj->Group == team) obj->Group = -1; - if (obj->Is_Selected_By_Player()) obj->Group = team; - } - } - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass * obj = Aircraft.Ptr(index); - if (obj && !obj->IsInLimbo && obj->House == PlayerPtr) { - if (obj->Group == team) obj->Group = -1; - if (obj->Is_Selected_By_Player()) obj->Group = team; - } - } - break; - } - AllowVoice = true; -} - - -/*********************************************************************************************** - * Handle_View -- Either records or restores the tactical view. * - * * - * This routine is used to record or restore the current map tactical view. * - * * - * INPUT: view -- The view number to work with. * - * * - * action-- The action to perform with this view number. * - * 0 = Restore the view to this previously remembered location. * - * 1 = Record the current view location. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -void Handle_View(int view, int action) -{ - if ((unsigned)view < sizeof(Views)/sizeof(Views[0])) { - if (action == 0) { - Map.Set_Tactical_Position(Cell_Coord(Views[view])&0xFF00FF00L); - Map.Flag_To_Redraw(true); - } else { - Views[view] = Coord_Cell(Map.TacticalCoord); - } - } -} - -#ifdef CHEAT_KEYS -void Heap_Dump_Check( char *string ) -{ -#if 0 - struct _heapinfo h_info; - int heap_status; -#endif - - - if ( !Debug_Trap_Check_Heap ) { // check the heap? - return; - } - -// Debug_Heap_Dump = true; - - Smart_Printf( "%s\n", string ); - - Dump_Heap_Pointers(); - -#if 0 - heap_status = _heapset( 0xee ); - -#if (1) - if ( heap_status == _HEAPOK || - heap_status == _HEAPEMPTY ) { - Debug_Heap_Dump = false; - return; - } - - h_info._pentry = NULL; - - for(;;) { - heap_status = _heapwalk( &h_info ); - - if ( heap_status != _HEAPOK ) - break; - } - - if (heap_status != _HEAPEND && - heap_status != _HEAPEMPTY) { -#endif - h_info._pentry = NULL; - - for(;;) { - heap_status = _heapwalk( &h_info ); - - if ( heap_status != _HEAPOK ) - break; - - Smart_Printf( " %s block at %Fp of size %4.4X\n", - (h_info._useflag == _USEDENTRY ? "USED" : "FREE"), - h_info._pentry, h_info._size ); - } - - Smart_Printf( " %d block at %Fp of size %4.4X\n", - h_info._useflag, h_info._pentry, h_info._size ); - - switch ( heap_status ) { -// case _HEAPEND: -// Smart_Printf( "OK - end of heap\n" ); -// break; - -// case _HEAPEMPTY: -// Smart_Printf( "OK - heap is empty\n" ); -// break; - - case _HEAPBADBEGIN: - Smart_Printf( "ERROR - heap is damaged\n" ); - break; - - case _HEAPBADPTR: - Smart_Printf( "ERROR - bad pointer to heap\n" ); - break; - - case _HEAPBADNODE: - Smart_Printf( "ERROR - bad node in heap\n" ); - break; - } -#if (1) - } -#endif -#endif - -// Debug_Heap_Dump = false; -} - - -void Dump_Heap_Pointers( void ) -{ -// ST - 1/2/2019 4:04PM -#if (0) - char *ptr, *lptr, *nptr, *cptr, *dptr, *wlptr, *nlptr, *aptr, *clptr; - int numallocs, numfrees, sizefree; - static char _freeorused[2][5] = { "FREE", "USED" }; - - - ptr = (char *)__nheapbeg; - - while ( ptr ) { - - if ( Debug_Heap_Dump ) { - Smart_Printf( "%p pre header\n", (ptr - 8) ); - Hex_Dump_Data( (ptr - 8), 0x08); - - Smart_Printf( "%p header\n", ptr ); - Hex_Dump_Data( ptr, 0x30); - } - - dptr = (char *)*(int *)(ptr + 0x0c); - - sizefree = *(int *)(ptr + 0x14); - numallocs = *(int *)(ptr + 0x18); - numfrees = *(int *)(ptr + 0x1c); - - cptr = (char *)*(int *)(ptr + 0x24); - lptr = (char *)*(int *)(ptr + 0x28); - - if ( ((int)cptr & 0xff000000) || - ((int)dptr & 0xff000000) || - ((int)lptr & 0xff000000) ) { - Error_In_Heap_Pointers( "local free heap ptrs too large" ); - } - - if ( Debug_Heap_Dump ) { - if ( lptr != dptr || - lptr != cptr || - cptr != dptr ) { - Smart_Printf( "The pointers are different!!\n" ); - } - } - - nptr = (char *)*(int *)(ptr + 8); // next block - - if ( ((int)nptr & 0xFF000000) ) { - Error_In_Heap_Pointers( "next block ptr too large" ); - } - - if ( lptr != (ptr + 0x20) ) { - - if ( !(*((int *)(ptr + 0x20))) ) { // allocated - aptr = (ptr + 0x2c); - - while ( aptr < lptr ) { - - if ( (*(int *)(aptr)) == -1) { -// Smart_Printf( "end alloc chain %p.\n", aptr ); -// Hex_Dump_Data( aptr, 0x10); - break; - } - - if ( Debug_Heap_Dump ) { - Smart_Printf( "%p chain %s, size %X.\n", aptr, - _freeorused[ ((*aptr) & 1) ], - ((*(int *)(aptr)) & 0xfffffffe) ); - Hex_Dump_Data( aptr, 0x10); - } - - if ( ((*(int *)(aptr)) & 0xff000000) ) { - Error_In_Heap_Pointers( "alloc block size way too large" ); - } - - aptr += ((*(int *)(aptr)) & 0xfffffffe); - - if ( ((int)aptr & 0xff000000) ) { - Error_In_Heap_Pointers( "next alloc block ptr way too large" ); - } - - numallocs--; - - if ( aptr > lptr ) { - Error_In_Heap_Pointers( "next alloc block ptr too large" ); - } - } - } else { - if ( sizefree != -1 ) { - sizefree -= ((*(int *)(ptr + 0x20)) & 0xfffffffe); - } - numfrees--; - } - - wlptr = lptr; - - while ( wlptr != (ptr + 0x20) ) { - - if ( Debug_Heap_Dump ) { - Smart_Printf( "%p link %s, size %X.\n", wlptr, - _freeorused[ ((*wlptr) & 1) ], - ((*(int *)(wlptr)) & 0xfffffffe) ); - Hex_Dump_Data( wlptr, 0x10); - } - - nlptr = (char *)*(int *)(wlptr + 8); - - if ( !(*((int *)(wlptr))) ) { // allocated - aptr = (wlptr + 0x0c); - } else { - if ( sizefree != -1 ) { - sizefree -= ((*(int *)(wlptr)) & 0xfffffffe); - } - numfrees--; - - aptr = (wlptr + ((*(int *)(wlptr)) & 0xfffffffe)); - } - - if (nlptr == (ptr + 0x20) ) { - clptr = nptr; - } else { - clptr = nlptr; - } - - while ( aptr < clptr ) { - - if ( (*(int *)(aptr)) == -1) { -// Smart_Printf( "end alloc chain %p.\n", aptr ); -// Hex_Dump_Data( aptr, 0x10); - break; - } - - if ( Debug_Heap_Dump ) { - Smart_Printf( "%p chain %s, size %X.\n", aptr, - _freeorused[ ((*aptr) & 1) ], - ((*(int *)(aptr)) & 0xfffffffe) ); - Hex_Dump_Data( aptr, 0x10); - } - - if ( ((*(int *)(aptr)) & 0xff000000) ) { - Error_In_Heap_Pointers( "alloc block size way too large" ); - } - - aptr += ((*(int *)(aptr)) & 0xfffffffe); - - if ( ((int)aptr & 0xff000000) ) { - Error_In_Heap_Pointers( "next alloc block ptr way too large" ); - } - - numallocs--; - - if ( aptr > clptr ) { - Error_In_Heap_Pointers( "next alloc block ptr too large" ); - } - } - - wlptr = nlptr; - } - } else { -// Smart_Printf( "only link %s, size %X.\n", -// _freeorused[ ((*lptr) & 1) ], -// ((*(int *)(lptr)) & 0xfffffffe) ); - - if ( !(*((int *)(lptr))) ) { // allocated - aptr = (ptr + 0x2c); - - while ( aptr < nptr ) { - - if ( (*(int *)(aptr)) == -1) { -// Smart_Printf( "end alloc chain %p.\n", aptr ); -// Hex_Dump_Data( aptr, 0x10); - break; - } - - if ( Debug_Heap_Dump ) { - Smart_Printf( "%p chain %s, size %X.\n", aptr, - _freeorused[ ((*aptr) & 1) ], - ((*(int *)(aptr)) & 0xfffffffe) ); - Hex_Dump_Data( aptr, 0x10); - } - - if ( ((*(int *)(aptr)) & 0xff000000) ) { - Error_In_Heap_Pointers( "alloc block size way too large" ); - } - - aptr += ((*(int *)(aptr)) & 0xfffffffe); - - if ( ((int)aptr & 0xff000000) ) { - Error_In_Heap_Pointers( "next alloc block ptr way too large" ); - } - - numallocs--; - - if ( aptr > nptr ) { - Error_In_Heap_Pointers( "next alloc block ptr too large" ); - } - } - } else { - if ( sizefree != -1 ) { - sizefree -= ((*(int *)(ptr + 0x20)) & 0xfffffffe); - } - numfrees--; - } - } - - if ( sizefree != 0 && sizefree != -1 ) { - Smart_Printf( "sizefree left over %X.\n", sizefree ); - } - - if ( numallocs != 0 ) { - Smart_Printf( "numallocs unaccounted for %d.\n", numallocs ); - } - - if ( numfrees != 0 ) { - Smart_Printf( "numfrees unaccounted for %d.\n", numfrees ); - } - - ptr = nptr; - } -#endif -} - - -void Error_In_Heap_Pointers( char *string ) -{ - Smart_Printf( "Error in Heap for %s\n", string ); -} -#endif - - -#ifndef ROR_NOT_READY -#define ROR_NOT_READY 21 -#endif - -/*********************************************************************************************** - * Get_CD_Index -- returns the volume type of the CD in the given drive * - * * - * * - * * - * INPUT: drive number * - * timeout * - * * - * OUTPUT: 0 = gdi * - * 1 = nod * - * 2 = covert * - * -1 = non C&C * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/21/96 5:27PM ST : Created * - *=============================================================================================*/ -int Get_CD_Index (int cd_drive, int timeout) -{ - char volume_name[128]; - unsigned filename_length; - unsigned misc_dword; - //unsigned error_code; - int count = 0; - - CountDownTimerClass timer; - - static char * _volid[] = { - "GDI95", - "NOD95", - "COVERT" - }; - static int num_volumes = 3; - - char buffer[128]; - - timer.Set(timeout); - - - /* - ** Get the volume label. If we get a 'not ready' error then retry for the timeout - ** period. - */ - do{ - sprintf(buffer, "%c:\\", 'A' + cd_drive); - - if (GetVolumeInformation ((char const *)buffer, - &volume_name[0] , - (unsigned long)128 , - (unsigned long *)NULL , - (unsigned long *)&filename_length, - (unsigned long *)&misc_dword , - (char *)NULL , - (unsigned long)0)) { - - /* - ** Try opening 'movies.mix' to verify that the CD is really there and is what - ** it says it is. - */ - sprintf(buffer, "%c:\\movies.mix", 'A' + cd_drive); - - HANDLE handle = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - - /* - ** Match the volume label to the list of known C&C volume labels. - */ - for (int i=0 ; i. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/11/1995 JLB : Created. * - * 05/22/1996 ST : Handles multiple CD drives / CD changers * - *=============================================================================================*/ -#pragma warning (disable : 4101) -bool Force_CD_Available(int cd) -{ - -#if (1) //ST - 1/2/2019 5:44PM - - static int _last = -1; - - if (_last != cd) { - - _last = cd; - - Theme.Stop(); - - if (MoviesMix) { - delete MoviesMix; - MoviesMix = 0; - } - if (GeneralMix) { - delete GeneralMix; - GeneralMix = 0; - } - if (ScoreMix) { - delete ScoreMix; - ScoreMix = 0; - } - - MoviesMix = new MixFileClass("MOVIES.MIX"); - GeneralMix = new MixFileClass("GENERAL.MIX"); - ScoreMix = new MixFileClass("SCORES.MIX"); -#if (0) - switch ( cd ) { - case -1: - default: - MoviesMix = new MixFileClass("MOVIES.MIX"); - GeneralMix = new MixFileClass("GENERAL.MIX"); - ScoreMix = new MixFileClass("SCORES.MIX"); - break; - - case 0: - MoviesMix = new MixFileClass("GDIMOVIES.MIX"); - GeneralMix = new MixFileClass("GENERAL.MIX"); - ScoreMix = new MixFileClass("GDISCORES.MIX"); - break; - - case 1: - MoviesMix = new MixFileClass("NODMOVIES.MIX"); - GeneralMix = new MixFileClass("GENERAL.MIX"); - ScoreMix = new MixFileClass("NODSCORES.MIX"); - break; - - case 2: - MoviesMix = new MixFileClass("COVERTMOVIES.MIX"); - GeneralMix = new MixFileClass("GENERAL.MIX"); - ScoreMix = new MixFileClass("COVERTSCORES.MIX"); - break; - } -#endif - ThemeClass::Scan(); - - } - - return true; - - - -#else - -#ifndef DEMO - static int _last = -1; - int open_failed; - int file; -#endif - static char _palette[768]; - static char _hold[256]; - static void *font; - static char * _volid[] = { - "GDI", - "NOD", - "COVERT" - }; - - int drive; - - char volume_name[100]; - unsigned filename_length; - unsigned misc_dword; - int new_cd_drive = 0; - int cd_index; - char buffer[128]; - int cd_drive; - int current_drive; - int drive_search_timeout; - bool old_in_main_loop; - - ThemeType theme_playing = THEME_NONE; - - /* - ** If the required CD is set to -2 then it means that the file is present - ** on the local hard drive and we shouldn't have to worry about it. - */ - if (cd == -2) return(true); - - - /* - ** Find out if the CD in the current drive is the one we are looking for - */ - current_drive = CCFileClass::Get_CD_Drive(); - cd_index = Get_CD_Index(current_drive, 1*60); - if (cd_index >= 0){ - if (cd == cd_index || cd == -1){ - /* - ** The required CD is still in the CD drive we used last time - */ - new_cd_drive = current_drive; - } - } - - - /* - ** Flag that we will have to restart the theme - */ - theme_playing = Theme.What_Is_Playing(); - Theme.Stop(); - - - if (!new_cd_drive){ - /* - ** Check the last CD drive we used if its different from the current one - */ - int last_drive = CCFileClass::Get_Last_CD_Drive(); - /* - ** Make sure the last drive is valid and it isnt the current drive - */ - if (last_drive && last_drive != CCFileClass::Get_CD_Drive()){ - /* - ** Find out if there is a C&C cd in the last drive and if so is it the one we are looking for - ** Give it a nice big timeout so the CD changer has time to swap the discs - */ - cd_index = Get_CD_Index(last_drive, 10*60); - if (cd_index >= 0){ - if (cd == cd_index || cd == -1){ - /* - ** The required CD is in the CD drive we used last time - */ - new_cd_drive = last_drive; - } - } - } - } - - /* - ** Lordy. No sign of that blimming CD anywhere. Search all the CD drives - ** then if we still cant find it prompt the user to insert it. - */ - if (!new_cd_drive){ - - /* - ** Small timeout for the first pass through the drives - */ - drive_search_timeout = 2*60; - - for (;;) { - /* - ** Search all present CD drives for the required disc. - */ - for (int i=0 ; i=0){ - /* - ** We found a C&C cd - lets see if it was the one we were looking for - */ - if (cd == cd_index || cd == -1){ - /* - ** Woohoo! The disk was in a different cd drive. Refresh the search path list - * and return. - */ - new_cd_drive = cd_drive; - break; - } - } - } - - /* - ** A new disc has become available so break - */ - if (new_cd_drive) break; - - /* - ** Increase the timeout for subsequent drive searches. - */ - drive_search_timeout = 5*60; - - /* - ** Prompt to insert the CD into the drive. - */ - if (cd == -1) { - sprintf(buffer, Text_String(TXT_CD_DIALOG_1), cd+1, _volid[cd]); - } else { - if (cd == 2) { - sprintf(buffer, Text_String(TXT_CD_DIALOG_3)); - } else { - sprintf(buffer, Text_String(TXT_CD_DIALOG_2), cd+1, _volid[cd]); - } - } - GraphicViewPortClass * oldpage = Set_Logic_Page(SeenBuff); - theme_playing = Theme.What_Is_Playing(); - Theme.Stop(); - int hidden = Get_Mouse_State(); - font = (void *)FontPtr; - Mem_Copy(CurrentPalette, _palette, 768); - Mem_Copy(Get_Font_Palette_Ptr(), _hold, 256); - - - /* - ** Only set the palette if necessary. - */ -// if (CurrentPalette[3] == 0) { - Set_Palette(GamePalette); -// } - - /* - ** Pretend we are in the game, even if we arent - */ - old_in_main_loop = InMainLoop; - InMainLoop = true; - - Keyboard::Clear(); - - while (Get_Mouse_State()) Show_Mouse(); - - if (CCMessageBox().Process(buffer, TXT_OK, TXT_CANCEL, TXT_NONE, TRUE) == 1) { - Set_Logic_Page(oldpage); - Hide_Mouse(); - InMainLoop = old_in_main_loop; - return(false); - } - while (hidden--) Hide_Mouse(); - Set_Palette(_palette); - Set_Font(font); - Mem_Copy(_hold, Get_Font_Palette_Ptr(), 256); - Set_Logic_Page(oldpage); - InMainLoop = old_in_main_loop; - } - } - - -#ifndef DEMO - - CCFileClass::Set_CD_Drive(new_cd_drive); - CCFileClass::Refresh_Search_Drives(); - - /* - ** If it broke out of the query for CD-ROM loop, then this means that the - ** CD-ROM has been inserted. - */ - if (cd > -1 && _last != cd) { - _last = cd; - - Theme.Stop(); - - if (MoviesMix) delete MoviesMix; - if (GeneralMix) delete GeneralMix; - if (ScoreMix) delete ScoreMix; - - MoviesMix = new MixFileClass("MOVIES.MIX"); - GeneralMix = new MixFileClass("GENERAL.MIX"); - ScoreMix = new MixFileClass("SCORES.MIX"); - ThemeClass::Scan(); - } -#endif - - if (theme_playing != THEME_NONE) { - Theme.Queue_Song(theme_playing); - } - - return(true); -#endif -} - - -/*************************************************************************** - * DISK_SPACE_AVAILABLE -- returns bytes of free disk space * - * * - * INPUT: none * - * * - * OUTPUT: returns amount of free disk space * - * * - * HISTORY: * - * 08/11/1995 PWG : Created. * - *=========================================================================*/ -unsigned long Disk_Space_Available(void) -{ - - return 0x7fffffff; - -#if (0) - struct diskfree_t diskdata; - unsigned drive; - - _dos_getdrive(&drive); - _dos_getdiskfree(drive, &diskdata); - - return(diskdata.avail_clusters * diskdata.sectors_per_cluster * diskdata.bytes_per_sector); -#endif -} - - -/*********************************************************************************************** - * Validate_Error -- prints an error message when an object fails validation * - * * - * INPUT: * - * name name of object type that failed * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/15/1995 BRR : Created. * - *=============================================================================================*/ -void Validate_Error(char *name) -{ - GlyphX_Debug_Print("Validate_Error"); - GlyphX_Debug_Print(name); -#ifdef CHEAT_KEYS - Prog_End(NULL, true); - printf("%s object error!\n",name); - if (!RunningAsDLL) { - exit(0); - } -#else - name = name; -#endif -} - - -/*********************************************************************************************** - * Do_Record_Playback -- handles saving/loading map pos & current object * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/15/1995 BRR : Created. * - *=============================================================================================*/ -static void Do_Record_Playback(void) -{ - int count; - TARGET tgt; - int i; - COORDINATE coord; - ObjectClass *obj; - unsigned long sum; - unsigned long sum2; - unsigned long ltgt; - - /*------------------------------------------------------------------------ - Record a game - ------------------------------------------------------------------------*/ - if (RecordGame) { - - /*..................................................................... - For 'SuperRecord', we'll open & close the file with every entry. - .....................................................................*/ - if (SuperRecord) { - RecordFile.Open(READ|WRITE); - RecordFile.Seek(0,SEEK_END); - } - - /*..................................................................... - Save the map's location - .....................................................................*/ - RecordFile.Write(&Map.DesiredTacticalCoord, sizeof (Map.DesiredTacticalCoord)); - - /*..................................................................... - Save the current object list count - .....................................................................*/ - count = CurrentObject.Count(); - RecordFile.Write(&count, sizeof(count)); - - /*..................................................................... - Save a CRC of the selected-object list. - .....................................................................*/ - sum = 0; - for (i = 0; i < count; i++) { - ltgt = (unsigned long)(CurrentObject[i]->As_Target()); - sum += ltgt; - } - RecordFile.Write (&sum, sizeof(sum)); - - /*..................................................................... - Save all selected objects. - .....................................................................*/ - for (i = 0; i < count; i++) { - tgt = CurrentObject[i]->As_Target(); - RecordFile.Write (&tgt, sizeof(tgt)); - } - - /*..................................................................... - If 'SuperRecord', close the file now. - .....................................................................*/ - if (SuperRecord) { - RecordFile.Close(); - } - } - - /*------------------------------------------------------------------------ - Play back a game ("attract" mode) - ------------------------------------------------------------------------*/ - if (PlaybackGame) { - - /*..................................................................... - Read & set the map's location. - .....................................................................*/ - if (RecordFile.Read(&coord, sizeof(coord))==sizeof(coord)) { - if (coord != Map.DesiredTacticalCoord) { - Map.Set_Tactical_Position(coord); - } - } - - if (RecordFile.Read(&count, sizeof(count))==sizeof(count)) { - /*.................................................................. - Compute a CRC of the current object-selection list. - ..................................................................*/ - sum = 0; - for (i = 0; i < CurrentObject.Count(); i++) { - ltgt = (unsigned long)(CurrentObject[i]->As_Target()); - sum += ltgt; - } - - /*.................................................................. - Load the CRC of the objects on disk; if it doesn't match, select - all objects as they're loaded. - ..................................................................*/ - RecordFile.Read (&sum2, sizeof(sum2)); - if (sum2 != sum) - Unselect_All(); - - AllowVoice = true; - - for (i = 0; i < count; i++) { - if (RecordFile.Read (&tgt, sizeof(tgt))==sizeof(tgt)) { - obj = As_Object(tgt); - if (obj && (sum2 != sum)) { - obj->Select(); - AllowVoice = false; - } - } - } - - AllowVoice = true; - - } - - /*..................................................................... - The map isn't drawn in playback mode, so draw it here. - .....................................................................*/ - Map.Render(); - } -} -/*************************************************************************** - * HIRES_RETRIEVE -- retrieves a resolution dependant file * - * * - * INPUT: char * file name of the file to retrieve * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 01/25/1996 : Created. * - *=========================================================================*/ -void const * Hires_Retrieve(char *name) -{ - char filename[30]; - - if (SeenBuff.Get_Width() != 320) { - sprintf(filename,"H%s", name); - } else { - strcpy(filename, name); - } - return(MixFileClass::Retrieve(filename)); -} -int Get_Resolution_Factor(void) -{ - return ((SeenBuff.Get_Width() == 320) ? 0 : 1); -} - - - - - -/************************************************************************************************** -* Blit_Hid_Page_To_Seen_Buff -- Intercept for when the game refreshes the visible page -* -* In: Command line -* -* Out: -* -* -* -* History: 1/3/2019 11:33AM - ST -**************************************************************************************************/ -void Blit_Hid_Page_To_Seen_Buff(void) -{ - HidPage.Blit(SeenBuff); -} - - -/*********************************************************************************************** - * Shake_The_Screen -- Dispatcher that shakes the screen. * - * * - * This routine will shake the game screen the number of shakes requested. * - * * - * INPUT: shakes -- The number of shakes to shake the screen. * - * house -- House to perform the shake for (or HOUSE_NONE if all players). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/04/1996 BWG : Created. * - *=============================================================================================*/ -void Shake_The_Screen(int shakes, HousesType house) -{ - for (char h = HOUSE_FIRST; h < HOUSE_COUNT; ++h) { - if ((house != HOUSE_NONE) && (h != house)) { - continue; - } - HouseClass* hptr = HouseClass::As_Pointer((HousesType)h); - if ((hptr != nullptr) && hptr->IsActive && hptr->IsHuman) { - hptr->ScreenShakeTime = hptr->ScreenShakeTime + shakes + shakes; - } - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/CONQUER.H b/code/TIBERIANDAWN/CONQUER.H deleted file mode 100644 index df85e2b..0000000 --- a/code/TIBERIANDAWN/CONQUER.H +++ /dev/null @@ -1,772 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -#define TXT_NONE 0 // -#define TXT_CREDIT_FORMAT 1 // %3d.%02d -#define TXT_BUTTON_UPGRADE 2 // Upgrade -#define TXT_UPGRADE 3 // Upgrade Structure -#define TXT_UPGRADE_BUTTON 4 // Upgrade -#define TXT_BUTTON_SELL 5 // Sell -#define TXT_SELL 6 // Sell Structure -#define TXT_DEMOLISH 7 // Demolish Structure -#define TXT_BUTTON_REPAIR 8 // Repair -#define TXT_REPAIR 9 // Repair Structure -#define TXT_REPAIR_BUTTON 10 // Repair -#define TXT_YOU 11 // You: -#define TXT_ENEMY 12 // Enemy: -#define TXT_BUILD_DEST 13 // Buildings Destroyed By -#define TXT_UNIT_DEST 14 // Units Destroyed By -#define TXT_TIB_HARV 15 // Tiberium Harvested By -#define TXT_SCORE_1 16 // Score: %d -#define TXT_RANK_OF 17 // You have attained the rank -#define TXT_YES 18 // Yes -#define TXT_NO 19 // No -#define TXT_READY 20 // Ready -#define TXT_HOLDING 21 // Holding -#define TXT_SCENARIO_WON 22 // Accomplished -#define TXT_SCENARIO_LOST 23 // Failed -#define TXT_CHOOSE_SIDE 24 // Choose Your Side -#define TXT_START_NEW_GAME 25 // Start New Game -#define TXT_INTRO 26 // Intro & Sneak Peek -#define TXT_CANCEL 27 // Cancel -#define TXT_ROCK 28 // Rock -#define TXT_CHOAM_RESUME 29 // Resume Game -#define TXT_CHOAM_BUILD_THIS 30 // Build This -#define TXT_THANK_YOU 31 // Thank you for playing -#define TXT_FAME 32 // Hall of Fame -#define TXT_GDI 33 // Global Defense Initiative -#define TXT_NOD 34 // Brotherhood of Nod -#define TXT_CIVILIAN 35 // Civilian -#define TXT_JP 36 // Containment Team -#define TXT_OK 37 // OK -#define TXT_TREE 38 // Tree -#define TXT_LEFT 39 //  -#define TXT_RIGHT 40 //  -#define TXT_UP 41 //  -#define TXT_DOWN 42 //  -#define TXT_CLEAR_MAP 43 // Clear the map -#define TXT_INHERIT_MAP 44 // Inherit previous map -#define TXT_CLEAR 45 // Clear -#define TXT_WATER 46 // Water -#define TXT_ROAD 47 // Road -#define TXT_TILE 48 // Tile Object -#define TXT_SLOPE 49 // Slope -#define TXT_BRUSH 50 // Brush -#define TXT_PATCH 51 // Patch -#define TXT_RIVER 52 // River -#define TXT_LOAD_MISSION 53 // Load Mission -#define TXT_SAVE_MISSION 54 // Save Mission -#define TXT_DELETE_MISSION 55 // Delete Mission -#define TXT_LOAD_BUTTON 56 // Load -#define TXT_SAVE_BUTTON 57 // Save -#define TXT_DELETE_BUTTON 58 // Delete -#define TXT_GAME_CONTROLS 59 // Game Controls -#define TXT_SOUND_CONTROLS 60 // Sound Controls -#define TXT_RESUME_MISSION 61 // Resume Mission -#define TXT_VISUAL_CONTROLS 62 // Visual Controls -#define TXT_QUIT_MISSION 63 // Abort Mission -#define TXT_EXIT_GAME 64 // Exit Game -#define TXT_OPTIONS 65 // Options -#define TXT_TIBERIUM 66 // Tiberium -#define TXT_TIBERIUM_ON 67 // Tiberium On -#define TXT_TIBERIUM_OFF 68 // Tiberium Off -#define TXT_SQUISH 69 // Squish mark -#define TXT_CRATER 70 // Crater -#define TXT_SCORCH 71 // Scorch Mark -#define TXT_BRIGHTNESS 72 // BRIGHTNESS: -#define TXT_MUSIC 73 // MUSIC VOLUME -#define TXT_VOLUME 74 // SOUND VOLUME -#define TXT_TINT 75 // TINT: -#define TXT_CONTRAST 76 // CONTRAST: -#define TXT_SPEED 77 // GAME SPEED: -#define TXT_SCROLLRATE 78 // SCROLL RATE: -#define TXT_COLOR 79 // COLOR: -#define TXT_RETURN_TO_GAME 80 // Return to game -#define TXT_ENEMY_SOLDIER 81 // Enemy Soldier -#define TXT_ENEMY_VEHICLE 82 // Enemy Vehicle -#define TXT_ENEMY_STRUCTURE 83 // Enemy Structure -#define TXT_FTANK 84 // Flame Tank -#define TXT_STANK 85 // Stealth Tank -#define TXT_LTANK 86 // Light Tank -#define TXT_MTANK 87 // Med. Tank -#define TXT_HTANK 88 // Mammoth Tank -#define TXT_DUNE_BUGGY 89 // Nod Buggy -#define TXT_SAM 90 // SAM Site -#define TXT_EYE 91 // Advanced Com. Center -#define TXT_MLRS 92 // Rocket Launcher -#define TXT_MHQ 93 // Mobile HQ -#define TXT_JEEP 94 // Hum-vee -#define TXT_TRANS 95 // Transport Helicopter -#define TXT_A10 96 // A10 -#define TXT_C17 97 // C17 -#define TXT_HARVESTER 98 // Harvester -#define TXT_ARTY 99 // Artillery -#define TXT_MSAM 100 // S.S.M. Launcher -#define TXT_E1 101 // Minigunner -#define TXT_E2 102 // Grenadier -#define TXT_E3 103 // Bazooka -#define TXT_E4 104 // Flamethrower -#define TXT_E5 105 // Chem-warrior -#define TXT_RAMBO 106 // Commando -#define TXT_HOVER 107 // Hovercraft -#define TXT_HELI 108 // Attack Helicopter -#define TXT_ORCA 109 // Orca -#define TXT_APC 110 // APC -#define TXT_GUARD_TOWER 111 // Guard Tower -#define TXT_COMMAND 112 // Communications Center -#define TXT_HELIPAD 113 // Helicopter Pad -#define TXT_AIRSTRIP 114 // Airstrip -#define TXT_STORAGE 115 // Tiberium Silo -#define TXT_CONST_YARD 116 // Construction Yard -#define TXT_REFINERY 117 // Tiberium Refinery -#define TXT_CIV1 118 // Church -#define TXT_CIV2 119 // Han's and Gretel's -#define TXT_CIV3 120 // Hewitt's Manor -#define TXT_CIV4 121 // Ricktor's House -#define TXT_CIV5 122 // Gretchin's House -#define TXT_CIV6 123 // The Barn -#define TXT_CIV7 124 // Damon's pub -#define TXT_CIV8 125 // Fran's House -#define TXT_CIV9 126 // Music Factory -#define TXT_CIV10 127 // Toymaker's -#define TXT_CIV11 128 // Ludwig's House -#define TXT_CIV12 129 // Haystacks -#define TXT_CIV13 130 // Haystack -#define TXT_CIV14 131 // Wheat Field -#define TXT_CIV15 132 // Fallow Field -#define TXT_CIV16 133 // Corn Field -#define TXT_CIV17 134 // Celery Field -#define TXT_CIV18 135 // Potato Field -#define TXT_CIV20 136 // Sala's House -#define TXT_CIV21 137 // Abdul's House -#define TXT_CIV22 138 // Pablo's Wicked Pub -#define TXT_CIV23 139 // Village Well -#define TXT_CIV24 140 // Camel Trader -#define TXT_CIV25 141 // Church -#define TXT_CIV26 142 // Ali's House -#define TXT_CIV27 143 // Trader Ted's -#define TXT_CIV28 144 // Menelik's House -#define TXT_CIV29 145 // Prestor John's House -#define TXT_CIV30 146 // Village Well -#define TXT_CIV31 147 // Witch Doctor's Hut -#define TXT_CIV32 148 // Rikitikitembo's Hut -#define TXT_CIV33 149 // Roarke's Hut -#define TXT_CIV34 150 // Mubasa's Hut -#define TXT_CIV35 151 // Aksum's Hut -#define TXT_CIV36 152 // Mambo's Hut -#define TXT_CIV37 153 // The Studio -#define TXT_CIVMISS 154 // Technology Center -#define TXT_TURRET 155 // Gun Turret -#define TXT_GUNBOAT 156 // Gun Boat -#define TXT_MCV 157 // Mobile Construction Yard -#define TXT_BIKE 158 // Recon Bike -#define TXT_POWER 159 // Power Plant -#define TXT_ADVANCED_POWER 160 // Advanced Power Plant -#define TXT_HOSPITAL 161 // Hospital -#define TXT_BARRACKS 162 // Barracks -#define TXT_CONCRETE 163 // Concrete -#define TXT_PUMP 164 // Oil Pump -#define TXT_TANKER 165 // Oil Tanker -#define TXT_SANDBAG_WALL 166 // Sandbag Wall -#define TXT_CYCLONE_WALL 167 // Chain Link Fence -#define TXT_BRICK_WALL 168 // Concrete Wall -#define TXT_BARBWIRE_WALL 169 // Barbwire Fence -#define TXT_WOOD_WALL 170 // Wood Fence -#define TXT_WEAPON_FACTORY 171 // Weapons Factory -#define TXT_AGUARD_TOWER 172 // Advanced Guard Tower -#define TXT_OBELISK 173 // Obelisk Guard Tower -#define TXT_BIO_LAB 174 // Bio-Research Laboratory -#define TXT_HAND 175 // Hand of Nod -#define TXT_TEMPLE 176 // Temple of Nod -#define TXT_FIX_IT 177 // Repair Bay -#define TXT_TAB_SIDEBAR 178 // Sidebar -#define TXT_TAB_BUTTON_CONTROLS 179 // Options -#define TXT_TAB_BUTTON_DATABASE 180 // Database -#define TXT_SHADOW 181 // Unrevealed Terrain -#define TXT_OPTIONS_MENU 182 // Options Menu -#define TXT_STOP 183 // STOP -#define TXT_PLAY 184 // PLAY -#define TXT_SHUFFLE 185 // SHUFFLE -#define TXT_REPEAT 186 // REPEAT -#define TXT_MUSIC_VOLUME 187 // Music volume: -#define TXT_SOUND_VOLUME 188 // Sound volume: -#define TXT_ON 189 // On -#define TXT_OFF 190 // Off -#define TXT_THEME_AOI 191 // Act On Instinct -#define TXT_THEME_TROUBLE 192 // Looks Like Trouble -#define TXT_THEME_IND 193 // Industrial -#define TXT_THEME_ROUT 194 // Reaching Out -#define TXT_THEME_OTP 195 // On The Prowl -#define TXT_THEME_PRP 196 // Prepare For Battle -#define TXT_THEME_JUSTDOIT 197 // Just Do It! -#define TXT_THEME_LINEFIRE 198 // In The Line Of Fire -#define TXT_THEME_MARCH 199 // March To Doom -#define TXT_THEME_STOPTHEM 200 // Deception -#define TXT_THEME_CCTHANG 201 // C&C Thang -#define TXT_THEME_BEFEARED 202 // Enemies To Be Feared -#define TXT_THEME_WARFARE 203 // Warfare -#define TXT_THEME_FWP 204 // Fight, Win, Prevail -#define TXT_THEME_DIE 205 // Die!! -#define TXT_THEME_NOMERCY 206 // No Mercy -#define TXT_THEME_TARGET 207 // Mechanical Man -#define TXT_THEME_IAM 208 // I Am -#define TXT_THEME_WIN1 209 // Great Shot! -#define TXT_MULTIPLAYER_GAME 210 // Multiplayer Game -#define TXT_NO_FILES 211 // No files available -#define TXT_DELETE_SINGLE_FILE 212 // Do you want to delete this -#define TXT_DELETE_MULTIPLE_FILES 213 // Do you want to delete %d -#define TXT_RESET_MENU 214 // Reset Values -#define TXT_CONFIRMATION 215 // Confirmation -#define TXT_CONFIRM_EXIT 216 // Do you want to abort the -#define TXT_MISSION_DESCRIPTION 217 // Mission Description -#define TXT_C1 218 // Joe -#define TXT_C2 219 // Bill -#define TXT_C3 220 // Shelly -#define TXT_C4 221 // Maria -#define TXT_C5 222 // Eydie -#define TXT_C6 223 // Dave -#define TXT_C7 224 // Phil -#define TXT_C8 225 // Dwight -#define TXT_C9 226 // Erik -#define TXT_MOEBIUS 227 // Dr. Moebius -#define TXT_BIB 228 // Road Bib -#define TXT_FASTER 229 // Faster -#define TXT_SLOWER 230 // Slower -#define TXT_ION_CANNON 231 // Ion Cannon -#define TXT_NUKE_STRIKE 232 // Nuclear Strike -#define TXT_AIR_STRIKE 233 // Air Strike -#define TXT_TREX 234 // Tyrannosaurus Rex -#define TXT_TRIC 235 // Triceratops -#define TXT_RAPT 236 // Velociraptor -#define TXT_STEG 237 // Stegasaurus -#define TXT_STEEL_CRATE 238 // Steel Crate -#define TXT_WOOD_CRATE 239 // Wood Crate -#define TXT_FLAG_SPOT 240 // Flag Location -#define TXT_G_D_I 241 // GDI -#define TXT_N_O_D 242 // NOD -#define TXT_UNABLE_READ_SCENARIO 243 // Unable to read scenario! -#define TXT_ERROR_LOADING_GAME 244 // Error loading game! -#define TXT_OBSOLETE_SAVEGAME 245 // Obsolete saved game. -#define TXT_MUSTENTER_DESCRIPTION 246 // You must enter a -#define TXT_ERROR_SAVING_GAME 247 // Error saving game! -#define TXT_DELETE_FILE_QUERY 248 // Delete this file? -#define TXT_EMPTY_SLOT 249 // [EMPTY SLOT] -#define TXT_SELECT_MPLAYER_GAME 250 // Select Multiplayer Game -#define TXT_MODEM_SERIAL 251 // Modem/Serial -#define TXT_NETWORK 252 // Network -#define TXT_INIT_NET_ERROR 253 // Unable to initialize -#define TXT_JOIN_NETWORK_GAME 254 // Join Network Game -#define TXT_NEW 255 // New -#define TXT_JOIN 256 // Join -#define TXT_SEND_MESSAGE 257 // Send Message -#define TXT_YOUR_NAME 258 // Your Name: -#define TXT_SIDE_COLON 259 // Side: -#define TXT_COLOR_COLON 260 // Color: -#define TXT_GAMES 261 // Games -#define TXT_PLAYERS 262 // Players -#define TXT_SCENARIO_COLON 263 // Scenario: -#define TXT_NOT_FOUND 264 // >> NOT FOUND << -#define TXT_START_CREDITS_COLON 265 // Starting Credits: -#define TXT_BASES_COLON 266 // Bases: -#define TXT_TIBERIUM_COLON 267 // Tiberium: -#define TXT_CRATES_COLON 268 // Crates: -#define TXT_AI_PLAYERS_COLON 269 // AI Players: -#define TXT_REQUEST_DENIED 270 // Request denied. -#define TXT_UNABLE_PLAY_WAAUGH 271 // Unable to play; scenario -#define TXT_NOTHING_TO_JOIN 272 // Nothing to join! -#define TXT_NAME_ERROR 273 // You must enter a name! -#define TXT_DUPENAMES_NOTALLOWED 274 // Duplicate names are not -#define TXT_YOURGAME_OUTDATED 275 // Your game version is -#define TXT_DESTGAME_OUTDATED 276 // Destination game version is -#define TXT_THATGUYS_GAME 277 // %s's Game -#define TXT_THATGUYS_GAME_BRACKET 278 // [%s's Game] -#define TXT_NETGAME_SETUP 279 // Network Game Setup -#define TXT_REJECT 280 // Reject -#define TXT_CANT_REJECT_SELF 281 // You can't reject yourself! -#define TXT_SELECT_PLAYER_REJECT 282 // You must select a player to -#define TXT_BASES_ON 283 // Bases On -#define TXT_BASES_OFF 284 // Bases Off -#define TXT_CRATES_ON 285 // Crates On -#define TXT_CRATES_OFF 286 // Crates Off -#define TXT_AI_PLAYERS_ON 287 // AI Players On -#define TXT_AI_PLAYERS_OFF 288 // AI Players Off -#define TXT_SCENARIOS 289 // Scenarios -#define TXT_START_CREDITS 290 // Starting Credits -#define TXT_ONLY_ONE 291 // Only one player? -#define TXT_OOPS 292 // Oops! -#define TXT_TO 293 // To %s: -#define TXT_TO_ALL 294 // To All: -#define TXT_MESSAGE 295 // Message: -#define TXT_CONNECTION_LOST 296 // Connection to %s lost! -#define TXT_LEFT_GAME 297 // %s has left the game. -#define TXT_PLAYER_DEFEATED 298 // %s has been defeated! -#define TXT_WAITING_CONNECT 299 // Waiting to Connect... -#define TXT_NULL_CONNERR_CHECK_CABLES 300 // Connection error! Check -#define TXT_MODEM_CONNERR_REDIALING 301 // Connection -#define TXT_MODEM_CONNERR_WAITING 302 // Connection error! Waiting -#define TXT_SELECT_SERIAL_GAME 303 // Select Serial Game -#define TXT_DIAL_MODEM 304 // Dial Modem -#define TXT_ANSWER_MODEM 305 // Answer Modem -#define TXT_NULL_MODEM 306 // Null Modem -#define TXT_SETTINGS 307 // Settings -#define TXT_PORT_COLON 308 // Port: -#define TXT_IRQ_COLON 309 // IRQ: -#define TXT_BAUD_COLON 310 // Baud: -#define TXT_INIT_STRING 311 // Init String: -#define TXT_CWAIT_STRING 312 // Call Waiting String: -#define TXT_TONE_BUTTON 313 // Tone Dialing -#define TXT_PULSE_BUTTON 314 // Pulse Dialing -#define TXT_HOST_SERIAL_GAME 315 // Host Serial Game -#define TXT_OPPONENT_COLON 316 // Opponent: -#define TXT_USER_SIGNED_OFF 317 // User signed off! -#define TXT_JOIN_SERIAL_GAME 318 // Join Serial Game -#define TXT_PHONE_LIST 319 // Phone List -#define TXT_ADD 320 // Add -#define TXT_EDIT 321 // Edit -#define TXT_DIAL 322 // Dial -#define TXT_DEFAULT 323 // Default -#define TXT_DEFAULT_SETTINGS 324 // Default Settings -#define TXT_CUSTOM_SETTINGS 325 // Custom Settings -#define TXT_PHONE_LISTING 326 // Phone Listing -#define TXT_NAME_COLON 327 // Name: -#define TXT_NUMBER_COLON 328 // Number: -#define TXT_UNABLE_FIND_MODEM 329 // Unable to find modem. Check -#define TXT_NO_CARRIER 330 // No carrier. -#define TXT_LINE_BUSY 331 // Line busy. -#define TXT_NUMBER_INVALID 332 // Number invalid. -#define TXT_SYSTEM_NOT_RESPONDING 333 // Other system not -#define TXT_OUT_OF_SYNC 334 // Games are out of sync! -#define TXT_PACKET_TOO_LATE 335 // Packet received too late! -#define TXT_PLAYER_LEFT_GAME 336 // Other player has left the -#define TXT_FROM 337 // From %s:%s -#define TXT_MAP_P01 338 // 2,728,000 -#define TXT_MAP_P02 339 // 38,385,000 -#define TXT_MAP_P03 340 // 10,373,000 -#define TXT_MAP_P04 341 // 51,994,000 -#define TXT_MAP_P05 342 // 80,387,000 -#define TXT_MAP_P06 343 // 10,400,000 -#define TXT_MAP_P07 344 // 5,300,000 -#define TXT_MAP_P08 345 // 7,867,000 -#define TXT_MAP_P09 346 // 10,333,000 -#define TXT_MAP_P10 347 // 1,974,000 -#define TXT_MAP_P11 348 // 23,169,000 -#define TXT_MAP_P12 349 // 10,064,000 -#define TXT_MAP_P13 350 // 3,285,000 -#define TXT_MAP_P14 351 // 8,868,000 -#define TXT_MAP_P15 352 // 10,337,000 -#define TXT_MAP_P16 353 // 4,365,000 -#define TXT_MAP_P17 354 // 1,607,000 -#define TXT_MAP_P18 355 // 4,485,000 -#define TXT_MAP_P19 356 // 56,386,000 -#define TXT_MAP_P20 357 // 28,305,000 -#define TXT_MAP_P21 358 // 5,238,000 -#define TXT_MAP_P22 359 // 2,059,000 -#define TXT_MAP_P23 360 // 13,497,000 -#define TXT_MAP_P24 361 // 4,997,000 -#define TXT_MAP_P25 362 // 88,500,000 -#define TXT_MAP_P26 363 // 1,106,000 -#define TXT_MAP_P27 364 // 12,658,000 -#define TXT_MAP_P28 365 // 3,029,000 -#define TXT_MAP_P29 366 // 39,084,000 -#define TXT_MAP_P30 367 // 23,154,000 -#define TXT_MAP_P31 368 // 8,902,000 -#define TXT_MAP_P32 369 // 27,791,000 -#define TXT_MAP_P33 370 // 1,574,000 -#define TXT_MAP_P34 371 // 15,469,000 -#define TXT_MAP_P35 372 // 1,300,000 -#define TXT_MAP_P36 373 // 41,688,000 -#define TXT_MAP_A00 374 // 24,900 SQ. MI. -#define TXT_MAP_A01 375 // 120,727 SQ. MI. -#define TXT_MAP_A02 376 // 80,134 SQ. MI. -#define TXT_MAP_A03 377 // 233,100 SQ. MI. -#define TXT_MAP_A04 378 // 137,838 SQ. MI. -#define TXT_MAP_A05 379 // 30,449 SQ. MI. -#define TXT_MAP_A06 380 // 18,932 SQ. MI. -#define TXT_MAP_A07 381 // 32,377 SQ. MI. -#define TXT_MAP_A08 382 // 35,919 SQ. MI. -#define TXT_MAP_A09 383 // 7,819 SQ. MI. -#define TXT_MAP_A10 384 // 91,699 SQ. MI. -#define TXT_MAP_A11 385 // 51,146 SQ. MI. -#define TXT_MAP_A12 386 // 11,100 SQ. MI. -#define TXT_MAP_A13 387 // 44,365 SQ. MI. -#define TXT_MAP_A14 388 // 39,449 SQ. MI. -#define TXT_MAP_A15 389 // 19,741 SQ. MI. -#define TXT_MAP_A16 390 // 17,413 SQ. MI. -#define TXT_MAP_C00 391 // RIGA -#define TXT_MAP_C01 392 // WARSAW -#define TXT_MAP_C02 393 // MINSK -#define TXT_MAP_C03 394 // KIEV -#define TXT_MAP_C04 395 // BERLIN -#define TXT_MAP_C05 396 // PRAGUE -#define TXT_MAP_C06 397 // BRATISLAVA -#define TXT_MAP_C07 398 // VIENNA -#define TXT_MAP_C08 399 // BUDAPEST -#define TXT_MAP_C09 400 // LJUBLJANA -#define TXT_MAP_C10 401 // BUCHAREST -#define TXT_MAP_C11 402 // ATHENS -#define TXT_MAP_C12 403 // TIRANA -#define TXT_MAP_C13 404 // SOFIA -#define TXT_MAP_C14 405 // BELGRADE -#define TXT_MAP_C15 406 // SARAJEVO -#define TXT_MAP_C16 407 // TALLINN -#define TXT_MAP_C17 408 // TRIPOLI -#define TXT_MAP_C18 409 // CAIRO -#define TXT_MAP_C19 410 // KHARTOUM -#define TXT_MAP_C20 411 // N'DJAMENA -#define TXT_MAP_C21 412 // NOUAKCHOTT -#define TXT_MAP_C22 413 // YAMOUSSOUKRO -#define TXT_MAP_C23 414 // PORTO-NOVO -#define TXT_MAP_C24 415 // ABUJA -#define TXT_MAP_C25 416 // LIBREVILLE -#define TXT_MAP_C26 417 // YAOUNDE -#define TXT_MAP_C27 418 // BANGUI -#define TXT_MAP_C28 419 // KINSHASA -#define TXT_MAP_C29 420 // CAIRO -#define TXT_MAP_C30 421 // LUANDA -#define TXT_MAP_C31 422 // DAR-ES-SALAAM -#define TXT_MAP_C32 423 // WINDHOEK -#define TXT_MAP_C33 424 // MAPUTO -#define TXT_MAP_C34 425 // GABARONE -#define TXT_MAP_C35 426 // CAPE TOWN -#define TXT_MAP_GDP00 427 // NEGLIGIBLE -#define TXT_MAP_GDP01 428 // $162.7 BLN -#define TXT_MAP_GDP02 429 // $47.6 BLN -#define TXT_MAP_GDP03 430 // $1,131 BLN -#define TXT_MAP_GDP04 431 // $120 BLN -#define TXT_MAP_GDP05 432 // $164 BLN -#define TXT_MAP_GDP06 433 // $60.1 BLN -#define TXT_MAP_GDP07 434 // $21 BLN -#define TXT_MAP_GDP08 435 // $71.9 BLN -#define TXT_MAP_GDP09 436 // $77 BLN -#define TXT_MAP_GDP10 437 // $4.0 BLN -#define TXT_MAP_GDP11 438 // $47.3 BLN -#define TXT_MAP_GDP12 439 // $120.1 BLN -#define TXT_MAP_GDP13 440 // $14.0 BLN -#define TXT_MAP_GDP14 441 // $28.9 BLN -#define TXT_MAP_GDP15 442 // $39.2 BLN -#define TXT_MAP_GDP16 443 // $12.1 BLN -#define TXT_MAP_GDP17 444 // $1.0 BLN -#define TXT_MAP_GDP18 445 // $10.0 BLN -#define TXT_MAP_GDP19 446 // $1.7 BLN -#define TXT_MAP_GDP20 447 // $28.0 BLN -#define TXT_MAP_GDP21 448 // $5.3 BLN -#define TXT_MAP_GDP22 449 // $11.6 BLN -#define TXT_MAP_GDP23 450 // $1.3 BLN -#define TXT_MAP_GDP24 451 // $6.6 BLN -#define TXT_MAP_GDP25 452 // $8.3 BLN -#define TXT_MAP_GDP26 453 // $6.9 BLN -#define TXT_MAP_GDP27 454 // $2.0 BLN -#define TXT_MAP_GDP28 455 // $3.1 BLN -#define TXT_MAP_GDP29 456 // $104.0 BLN -#define TXT_MAP_PC00 457 // JELGAVA -#define TXT_MAP_PC01 458 // GDANSK -#define TXT_MAP_PC02 459 // BYELISTOK -#define TXT_MAP_PC03 460 // BOBYRUSK -#define TXT_MAP_PC04 461 // IVANO-FRANKOVSK -#define TXT_MAP_PC05 462 // HANOVER -#define TXT_MAP_PC06 463 // DRESDEN -#define TXT_MAP_PC07 464 // OSTRAVA -#define TXT_MAP_PC08 465 // BRATISLAVA -#define TXT_MAP_PC09 466 // SALZBURG -#define TXT_MAP_PC10 467 // BUDAPEST -#define TXT_MAP_PC11 468 // TRIESTE -#define TXT_MAP_PC12 469 // ARAD -#define TXT_MAP_PC13 470 // CORINTH -#define TXT_MAP_PC14 471 // SHKODER -#define TXT_MAP_PC15 472 // SOFIA -#define TXT_MAP_PC16 473 // NIS -#define TXT_MAP_PC17 474 // BELGRADE -#define TXT_MAP_PC18 475 // ? -#define TXT_MAP_PC19 476 // PARNU -#define TXT_MAP_PC20 477 // TMASSAH -#define TXT_MAP_PC21 478 // AL-ALAMYN -#define TXT_MAP_PC22 479 // AL-KHARIJAH -#define TXT_MAP_PC23 480 // AL-UBAYYID -#define TXT_MAP_PC24 481 // KAFIA-KINGI -#define TXT_MAP_PC25 482 // OUM HADJER -#define TXT_MAP_PC26 483 // MAO -#define TXT_MAP_PC27 484 // TIDJIKDJA -#define TXT_MAP_PC28 485 // ABIDJAN -#define TXT_MAP_PC29 486 // PORTO-NOVO -#define TXT_MAP_PC30 487 // ABUJA -#define TXT_MAP_PC31 488 // KOULA-MOUTOU -#define TXT_MAP_PC32 489 // BERTOUA -#define TXT_MAP_PC33 490 // BANGASSOU -#define TXT_MAP_PC34 491 // LODJA -#define TXT_MAP_PC35 492 // KINSHASA -#define TXT_MAP_PC36 493 // LUXOR -#define TXT_MAP_PC37 494 // CAIUNDO -#define TXT_MAP_PC38 495 // MZUZU -#define TXT_MAP_PC39 496 // KEETMANSHOOP -#define TXT_MAP_PC40 497 // XAI-XAI -#define TXT_MAP_PC41 498 // GHANZI -#define TXT_MAP_PC42 499 // CAPE TOWN -#define TXT_MAP_GDI 500 // GDI PROGRESSION -#define TXT_MAP_NOD 501 // NOD PROGRESSION -#define TXT_MAP_LOCATE 502 // LOCATING COORDINATES -#define TXT_MAP_NEXT_MISSION 503 // OF NEXT MISSION -#define TXT_MAP_SELECT 504 // SELECT TERRITORY -#define TXT_MAP_TO_ATTACK 505 // TO ATTACK -#define TXT_MAP_GDISTAT0 506 // POPULATION: -#define TXT_MAP_GDISTAT1 507 // GEOGRAPHIC AREA: -#define TXT_MAP_GDISTAT2 508 // CAPITAL: -#define TXT_MAP_GDISTAT3 509 // GOVERNMENT: -#define TXT_MAP_GDISTAT4 510 // GROSS DOMESTIC PRODUCT: -#define TXT_MAP_GDISTAT5 511 // POINT OF CONFLICT: -#define TXT_MAP_GDISTAT6 512 // MILITARY POWER: -#define TXT_MAP_NODSTAT0 513 // EXPENDABILITY: -#define TXT_MAP_NODSTAT1 514 // GOVT CORRUPTABILITY: -#define TXT_MAP_NODSTAT2 515 // NET WORTH: -#define TXT_MAP_NODSTAT3 516 // MILITARY STRENGTH: -#define TXT_MAP_NODSTAT4 517 // MILITARY RESISTANCE: -#define TXT_MAP_COUNTRYNAME0 518 // LATVIA -#define TXT_MAP_COUNTRYNAME1 519 // POLAND -#define TXT_MAP_COUNTRYNAME2 520 // BELARUS -#define TXT_MAP_COUNTRYNAME3 521 // UKRAINE -#define TXT_MAP_COUNTRYNAME4 522 // GERMANY -#define TXT_MAP_COUNTRYNAME5 523 // CZECH REPUBLIC -#define TXT_MAP_COUNTRYNAME6 524 // SLOVAKIA -#define TXT_MAP_COUNTRYNAME7 525 // AUSTRIA -#define TXT_MAP_COUNTRYNAME8 526 // HUNGARY -#define TXT_MAP_COUNTRYNAME9 527 // SLOVENIA -#define TXT_MAP_COUNTRYNAME10 528 // ROMANIA -#define TXT_MAP_COUNTRYNAME11 529 // GREECE -#define TXT_MAP_COUNTRYNAME12 530 // ALBANIA -#define TXT_MAP_COUNTRYNAME13 531 // BULGARIA -#define TXT_MAP_COUNTRYNAME14 532 // YUGOSLAVIA -#define TXT_MAP_COUNTRYNAME15 533 // BOSNIA/HERZOGOVINA -#define TXT_MAP_COUNTRYNAME16 534 // LIBYA -#define TXT_MAP_COUNTRYNAME17 535 // EGYPT -#define TXT_MAP_COUNTRYNAME18 536 // SUDAN -#define TXT_MAP_COUNTRYNAME19 537 // CHAD -#define TXT_MAP_COUNTRYNAME20 538 // MAURITANIA -#define TXT_MAP_COUNTRYNAME21 539 // IVORY COAST -#define TXT_MAP_COUNTRYNAME22 540 // BENIN -#define TXT_MAP_COUNTRYNAME23 541 // NIGERIA -#define TXT_MAP_COUNTRYNAME24 542 // GABON -#define TXT_MAP_COUNTRYNAME25 543 // CAMEROON -#define TXT_MAP_COUNTRYNAME26 544 // CENTRAL AFRICAN REPUBLIC -#define TXT_MAP_COUNTRYNAME27 545 // ZAIRE -#define TXT_MAP_COUNTRYNAME28 546 // ANGOLA -#define TXT_MAP_COUNTRYNAME29 547 // TANZANIA -#define TXT_MAP_COUNTRYNAME30 548 // NAMIBIA -#define TXT_MAP_COUNTRYNAME31 549 // MOZAMBIQUE -#define TXT_MAP_COUNTRYNAME32 550 // BOTSWANA -#define TXT_MAP_COUNTRYNAME33 551 // SOUTH AFRICA -#define TXT_MAP_COUNTRYNAME34 552 // ESTONIA -#define TXT_MAP_GOVT0 553 // REPUBLIC -#define TXT_MAP_GOVT1 554 // DEMOCRATIC STATE -#define TXT_MAP_GOVT2 555 // FEDERAL REPUBLIC -#define TXT_MAP_GOVT3 556 // CONST. REPUBLIC -#define TXT_MAP_GOVT4 557 // PARL. DEMOCRACY -#define TXT_MAP_GOVT5 558 // PRES. PARL. REPUBLIC -#define TXT_MAP_GOVT6 559 // DEMOCRACY -#define TXT_MAP_GOVT7 560 // IN TRANSITION -#define TXT_MAP_GOVT8 561 // ISLAMIC SOCIALIST -#define TXT_MAP_GOVT9 562 // MILITARY -#define TXT_MAP_GOVT10 563 // ISLAMIC REPUBLIC -#define TXT_MAP_GOVT11 564 // PARL. REPUBLIC -#define TXT_MAP_ARMY0 565 // LOCAL MILITIA -#define TXT_MAP_ARMY1 566 // STATE MILITIA -#define TXT_MAP_ARMY2 567 // NATIONAL GUARD -#define TXT_MAP_ARMY3 568 // FREE STANDING ARMY -#define TXT_MAP_ARMY4 569 // ? -#define TXT_MAP_ARMY5 570 // NATIONAL POWER -#define TXT_MAP_MILITARY0 571 // RESPECTABLE -#define TXT_MAP_MILITARY1 572 // FORMIDABLE -#define TXT_MAP_MILITARY2 573 // LAUGHABLE -#define TXT_MAP_MILITARY3 574 // REASONABLE -#define TXT_MAP_MILITARY4 575 // INSIGNIFICANT -#define TXT_MAP_CLICK2 576 // CLICK TO CONTINUE -#define TXT_MAP_LMH0 577 // LOW -#define TXT_MAP_LMH1 578 // MEDIUM -#define TXT_MAP_LMH2 579 // HIGH -#define TXT_SCORE_TIME 580 // TIME: -#define TXT_SCORE_LEAD 581 // LEADERSHIP: -#define TXT_SCORE_EFFI 582 // EFFICIENCY: -#define TXT_SCORE_TOTA 583 // TOTAL SCORE: -#define TXT_SCORE_CASU 584 // CASUALTIES: -#define TXT_SCORE_NEUT 585 // NEUTRAL: -#define TXT_SCORE_GDI 586 // GDI: -#define TXT_SCORE_BUIL 587 // BUILDINGS LOST -#define TXT_SCORE_BUIL1 588 // BUILDINGS -#define TXT_SCORE_BUIL2 589 // LOST: -#define TXT_SCORE_TOP 590 // TOP SCORES -#define TXT_SCORE_ENDCRED 591 // ENDING CREDITS: -#define TXT_SCORE_TIMEFORMAT1 592 // %dh %dm -#define TXT_SCORE_TIMEFORMAT2 593 // %dm -#define TXT_SCORE_NOD 594 // NOD: -#define TXT_DIALING 595 // Dialing... -#define TXT_DIALING_CANCELED 596 // Dialing Canceled -#define TXT_WAITING_FOR_CALL 597 // Waiting for Call... -#define TXT_ANSWERING_CANCELED 598 // Answering Canceled -#define TXT_E7 599 // Engineer -#define TXT_SPECIAL_OPTIONS 600 // Special Options -#define TXT_VISIBLE_TARGET 601 // Targeting flash visible to -#define TXT_TREE_TARGET 602 // Allow targeting of trees. -#define TXT_MCV_DEPLOY 603 // Allow undeploy of -#define TXT_SMART_DEFENCE 604 // Employ smarter self defense -#define TXT_SLOW_BUILD 605 // Moderate production speed. -#define TXT_THREE_POINT 606 // Use three point turn logic. -#define TXT_TIBERIUM_GROWTH 607 // Tiberium will grow. -#define TXT_TIBERIUM_SPREAD 608 // Tiberium will spread. -#define TXT_ROAD_PIECES 609 // Disable building "bib" -#define TXT_SCATTER 610 // Allow running from -#define TXT_MODEM_OR_LOOPBACK 611 // Not a Null Modem Cable -#define TXT_MAP 612 // Map -#define TXT_FROM_COMPUTER 613 // From Computer: -#define TXT_COMP_MSG1 614 // Prepare to die! -#define TXT_COMP_MSG2 615 // How about a bullet -#define TXT_COMP_MSG3 616 // Incoming! -#define TXT_COMP_MSG4 617 // I see you! -#define TXT_COMP_MSG5 618 // Hey, I'm over here! -#define TXT_COMP_MSG6 619 // Come get some! -#define TXT_COMP_MSG7 620 // I got you! -#define TXT_COMP_MSG8 621 // You humans are never a -#define TXT_COMP_MSG9 622 // Abort, Retry, Ignore? (Ha -#define TXT_COMP_MSG10 623 // Format another? (Just -#define TXT_COMP_MSG11 624 // Beat me and I'll reboot! -#define TXT_COMP_MSG12 625 // You're artificial -#define TXT_COMP_MSG13 626 // My AI is better than your -#define TXT_THEME_AIRSTRIKE 627 // Air Strike -#define TXT_THEME_HEAVYG 628 // Demolition -#define TXT_THEME_J1 629 // Untamed Land -#define TXT_THEME_JDI_V2 630 // Take 'em Out -#define TXT_THEME_RADIO 631 // Radio -#define TXT_THEME_RAIN 632 // Rain In The Night -#define TXT_THEME_IND2 633 // Canyon Chase -#define TXT_THEME_HEART 634 // Heartbreak -#define TXT_BLOSSOM_TREE 635 // Blossom Tree -#define TXT_RESTATE_MISSION 636 // Restate -#define TXT_COMPUTER 637 // Computer -#define TXT_COUNT 638 // Unit Count: -#define TXT_LEVEL 639 // Tech Level: -#define TXT_OPPONENT 640 // Opponent -#define TXT_KILLS_COLON 641 // Kills: -#define TXT_VIDEO 642 // Video -#define TXT_C10 643 // Nikoomba -#define TXT_CAPTURE_THE_FLAG 644 // Capture The Flag -#define TXT_THEME_VALK 645 // Ride of the Valkyries -#define TXT_OBJECTIVE 646 // Mission Objective -#define TXT_MISSION 647 // Mission -#define TXT_NO_SAVES 648 // No saved games available. -#define TXT_CIVILIAN_BUILDING 649 // Civilian Building -#define TXT_TECHNICIAN 650 // Technician -#define TXT_VISCEROID 651 // Visceroid -#define TXT_NO_SAVELOAD 652 // Save game options are not -#define TXT_DEFENDER_ADVANTAGE 653 // Defender has the advantage. -#define TXT_SHOW_NAMES 654 // Show true object names. -#define TXT_DELPHI 655 // Agent Delphi -#define TXT_TO_REPLAY 656 // Would you like to replay -#define TXT_RECONN_TO 657 // Reconnecting to %s. -#define TXT_PLEASE_WAIT 658 // Please wait %02d seconds. -#define TXT_SURRENDER 659 // Do you wish to surrender? -#define TXT_GDI_NAME 660 // GLOBAL DEFENSE INITIATIVE -#define TXT_NOD_NAME 661 // BROTHERHOOD OF NOD -#define TXT_SEL_TRANS 662 // SELECT TRANSMISSION -#define TXT_GAMENAME_MUSTBE_UNIQUE 663 // Your game name must be -#define TXT_GAME_IS_CLOSED 664 // Game is closed. -#define TXT_NAME_MUSTBE_UNIQUE 665 // Your name must be unique. -#define TXT_RECONNECTING_TO 666 // Reconnecting to %s -#define TXT_WAITING_FOR_CONNECTIONS 667 // Waiting for connections... -#define TXT_TIME_ALLOWED 668 // Time allowed: %02d seconds -#define TXT_PRESS_ESC 669 // Press ESC to cancel. -#define TXT_JUST_YOU_AND_ME 670 // From Computer: It's just -#define TXT_CAPTURE_THE_FLAG_COLON 671 // Capture the Flag: -#define TXT_CHAN 672 // Dr. Chan -#define TXT_HAS_ALLIED 673 // %s has allied with %s -#define TXT_AT_WAR 674 // %s declares war on %s -#define TXT_SEL_TARGET 675 // Select a target -#define TXT_SEPARATE_HELIPAD 676 // Allow separate helipad -#define TXT_RESIGN 677 // Resign Game -#define TXT_TIBERIUM_FAST 678 // Tiberium grows quickly. -#define TXT_ANSWERING 679 // Answering... -#define TXT_INITIALIZING_MODEM 680 // Initializing Modem... -#define TXT_SCENARIOS_DO_NOT_MATCH 681 // Scenarios don't match. -#define TXT_POWER_OUTPUT 682 // Power Output -#define TXT_POWER_OUTPUT_LOW 683 // Power Output (low) -#define TXT_CONTINUE 684 // Continue -#define TXT_QUEUE_FULL 685 // Data Queue Overflow -#define TXT_SPECIAL_WARNING 686 // %s changed game options! -#define TXT_CD_DIALOG_1 687 // Please insert a Command & -#define TXT_CD_DIALOG_2 688 // Please insert CD %d (%s) -#define TXT_CD_ERROR1 689 // Command & Conquer is unable -#define TXT_NO_SOUND_CARD 690 // No Sound Card Detected -#define TXT_UNKNOWN 691 // UNKNOWN -#define TXT_OLD_GAME 692 // (old) -#define TXT_NO_SPACE 693 // Insufficient Disk Space to -#define TXT_MUST_HAVE_SPACE 694 // You must have %d megabytes -#define TXT_RUN_SETUP 695 // Run SETUP program first. -#define TXT_WAITING_FOR_OPPONENT 696 // Waiting for Opponent -#define TXT_SELECT_SETTINGS 697 // Please select 'Settings' to -#define TXT_PRISON 698 // Prison -#define TXT_GAME_WAS_SAVED 699 // Game Saved -#define TXT_SPACE_CANT_SAVE 700 // Insufficient disk space to -#define TXT_INVALID_PORT_ADDRESS 701 // Invalid Port/Address. COM -#define TXT_INVALID_SETTINGS 702 // Invalid Port and/or IRQ -#define TXT_IRQ_ALREADY_IN_USE 703 // IRQ already in use -#define TXT_ABORT 704 // Abort -#define TXT_RESTART 705 // Restart -#define TXT_RESTARTING 706 // Mission is -#define TXT_LOADING 707 // Mission is loading. Please -#define TXT_ERROR_IN_INITSTRING 708 // Error in the InitString -#define TXT_ORDER_INFO 709 // Order Info -#define TXT_SCENES 710 // Scenes -#define TXT_NEW_MISSIONS 711 // New Missions -#define TXT_THEME_CHRG 712 // Depth Charge -#define TXT_THEME_DRON 713 // Drone -#define TXT_THEME_FIST 714 // Iron Fist -#define TXT_THEME_CREP 715 // Creeping Upon -#define TXT_THEME_80MX 716 // C&C 80's Mix -#define TXT_THEME_DRIL 717 // Drill -#define TXT_CD_DIALOG_3 718 // Please insert the Covert -#define TXT_THEME_RECON 719 // Recon -#define TXT_THEME_VOICE 720 // Voice Rhythm -#define TXT_ERROR_NO_INIT 721 // Error - modem did not -#define TXT_NO_FLOW_CONTROL_RESPONSE 722 // Error - Modem failed to -#define TXT_NO_COMPRESSION_RESPONSE 723 // Error - Modem failed to -#define TXT_NO_ERROR_CORRECTION_RESPONSE 724 // Error - Modem failed to -#define TXT_ERROR_NO_DISABLE 725 // Error - unable to disable -#define TXT_ERROR_TOO_MANY 726 // Error - Too many errors -#define TXT_IGNORE 727 // Ignore -#define TXT_CONNECTING 728 // Connecting... Please Wait. -#define TXT_EXPLAIN_REGISTRATION 729 // To play Command & Conquer -#define TXT_REGISTER 730 // Register -#define TXT_ERROR_UNABLE_TO_RUN_WCHAT 731 // Wchat not installed. Please -#define TXT_INTERNET 732 // Internet Game -#define TXT_UNABLE_TO_SET_VIDEO_MODE 733 // Error - Unable to set the -#define TXT_UNABLE_TO_ALLOCATE_PRIMARY_VIDEO_BUFFER 734 // Error - Unable to allocate -#define TXT_NO_DIAL_TONE 735 // No dial tone. Ensure your -#define TXT_MODEM_INITIALISATION 736 // Modem Initialization -#define TXT_DATA_COMPRESSION 737 // Data Compression -#define TXT_ERROR_CORRECTION 738 // Error Correction -#define TXT_HARDWARE_FLOW_CONTROL 739 // Hardware Flow Control -#define TXT_ADVANCED 740 // Advanced -#define TXT_JUST_INTRO 741 // Intro -#define TXT_READING_IMAGE_DATA 742 // READING IMAGE DATA -#define TXT_ANALYZING 743 // ANALYZING -#define TXT_ENHANCING_IMAGE_DATA 744 // ENHANCING IMAGE DATA -#define TXT_ISOLATING_OPERATIONAL_THEATER 745 // ISOLATING OPERATIONAL -#define TXT_ESTABLISHING_TRADITIONAL_BOUNDARIES 746 // ESTABLISHING TRADITIONAL -#define TXT_FOR_VISUAL_REFERENCE 747 // FOR VISUAL REFERENCE -#define TXT_ENHANCING_IMAGE 748 // ENHANCING IMAGE -#define TXT_BONUS_MISSIONS 749 // Bonus Missions -#define TXT_BONUS_MISSION_1 750 // Bonus Mission 1 -#define TXT_BONUS_MISSION_2 751 // Bonus Mission 2 -#define TXT_BONUS_MISSION_3 752 // Bonus Mission 3 -#define TXT_BONUS_MISSION_4 753 // Bonus Mission 4 -#define TXT_BONUS_MISSION_5 754 // Bonus Mission 5 -#define TXT_LOW_POWER 755 -#define TXT_INSUFFICIENT_FUNDS 756 \ No newline at end of file diff --git a/code/TIBERIANDAWN/CONST.CPP b/code/TIBERIANDAWN/CONST.CPP deleted file mode 100644 index f9d481e..0000000 --- a/code/TIBERIANDAWN/CONST.CPP +++ /dev/null @@ -1,425 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\const.cpv 2.17 16 Oct 1995 16:52:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONST.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 20, 1993 * - * * - * Last Update : September 20, 1993 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -char const * SourceName[SOURCE_COUNT] = -{ - "North", - "East", - "South", - "West", - "Shipping", - "Beach", - "Air", - "Visible", - "EnemyBase", - "HomeBase", - "Ocean", -}; - - -/*************************************************************************** -** Relative coordinate offsets from the center of a cell for each -** of the legal positions that an object in a cell may stop at. Only infantry -** are allowed to stop at other than the center of the cell. -*/ -COORDINATE const StoppingCoordAbs[5] = { - 0x00800080L, // center - 0x00400040L, // upper left - 0x004000C0L, // upper right - 0x00C00040L, // lower left - 0x00C000C0L // lower right -}; - - -/*************************************************************************** -** These are the various weapons and their characteristics. -** -** bullet type dmg, rof, range, sound -*/ -WeaponTypeClass const Weapons[WEAPON_COUNT] = { - {BULLET_SNIPER, 125, 40, 0x0580, VOC_SNIPER, ANIM_NONE}, // WEAPON_RIFLE - {BULLET_SPREADFIRE, 25, 50, 0x0400, VOC_MINI, ANIM_GUN_N}, // WEAPON_CHAIN_GUN - {BULLET_BULLET, 1, 7, 0x01C0, VOC_RIFLE, ANIM_NONE}, // WEAPON_PISTOL - {BULLET_BULLET, 15, 20, 0x0200, VOC_MGUN2, ANIM_NONE}, // WEAPON_M16 - {BULLET_TOW, 30, 60, 0x0400, VOC_BAZOOKA,ANIM_NONE}, // WEAPON_DRAGON - {BULLET_FLAME, 35, 50, 0x0200, VOC_FLAMER1,ANIM_FLAME_N}, // WEAPON_FLAMETHROWER - {BULLET_FLAME, 50, 50, 0x0200, VOC_FLAMER1,ANIM_FLAME_N}, // WEAPON_FLAME_TONGUE - {BULLET_CHEMSPRAY, 80, 70, 0x0200, VOC_FLAMER1,ANIM_CHEM_N}, // WEAPON_CHEMSPRAY - {BULLET_GRENADE, 50, 60, 0x0340, VOC_TOSS, ANIM_NONE}, // WEAPON_GRENADE - {BULLET_APDS, 25, 60, 0x0400, VOC_TANK2, ANIM_MUZZLE_FLASH}, // WEAPON_75MM - {BULLET_APDS, 30, 50, 0x04C0, VOC_TANK3, ANIM_MUZZLE_FLASH}, // WEAPON_105MM - {BULLET_APDS, 40, 80, 0x04C0, VOC_TANK4, ANIM_MUZZLE_FLASH}, // WEAPON_120MM - {BULLET_APDS, 40, 60, 0x0600, VOC_TANK4, ANIM_MUZZLE_FLASH}, // WEAPON_TURRET_GUN - {BULLET_SSM, 75, 80, 0x0500, VOC_ROCKET1,ANIM_NONE}, // WEAPON_MAMMOTH_TUSK - {BULLET_SSM2, 75, 80, 0x0600, VOC_ROCKET1,ANIM_NONE}, // WEAPON_MLRS - {BULLET_HE, 150, 65, 0x0600, VOC_TANK1, ANIM_MUZZLE_FLASH}, // WEAPON_155MM - {BULLET_BULLET, 15, 30, 0x0400, VOC_MGUN11, ANIM_GUN_N}, // WEAPON_M60MG - {BULLET_SSM, 60, 35, 0x0780, VOC_ROCKET2,ANIM_NONE}, // WEAPON_TOMAHAWK - {BULLET_SSM, 60, 40, 0x0680, VOC_ROCKET2,ANIM_NONE}, // WEAPON_TOW_TWO - {BULLET_NAPALM, 100, 20, 0x0480, VOC_NONE, ANIM_NONE}, // WEAPON_NAPALM - {BULLET_LASER, 200, 90, 0x0780, VOC_LASER, ANIM_NONE}, // WEAPON_OBELISK_LASER - {BULLET_SAM, 50, 50, 0x0780, VOC_ROCKET2,ANIM_NONE}, // WEAPON_NIKE - {BULLET_HONEST_JOHN, 100, 200, 0x0A00, VOC_ROCKET1,ANIM_NONE}, // WEAPON_HONEST_JOHN - {BULLET_HEADBUTT, 100, 30, 0x0180, VOC_DINOATK1,ANIM_NONE}, // WEAPON_STEG - {BULLET_TREXBITE, 155, 30, 0x0180, VOC_DINOATK1,ANIM_NONE}, // WEAPON_TREX -#ifdef PETROGLYPH_EXAMPLE_MOD - {BULLET_NUKE_LOB, 150, 130, 0x0B00, VOC_NUKE_LOB, ANIM_MUZZLE_FLASH}, // WEAPON_NUKE_LOB -#endif //PETROGLYPH_EXAMPLE_MOD -}; - - -/*************************************************************************** -** These are the various warheads. -** -** spread factor, destroys walls, destroys wood, destroys Tiberium, {armor defense table} -** -vs- {none, wood, aluminum, steel, concrete} -*/ -WarheadTypeClass const Warheads[WARHEAD_COUNT] = { - { 2,false,false,false,{0x100, 0x80, 0x90, 0x40, 0x40}}, // WARHEAD_SA Small arms -- good against infantry. - { 6,true,true,true,{0xE0, 0xC0, 0x90, 0x40, 0x100}}, // WARHEAD_HE High explosive -- good against buildings & infantry. - { 6,true,true,false,{0x40, 0xC0, 0xC0, 0x100, 0x80}}, // WARHEAD_AP Armor piercing -- good against armor. - { 8,false,true,true,{0xE0, 0x100, 0xB0, 0x40, 0x80}}, // WARHEAD_FIRE Incendiary -- Good against flammables. - { 4,false,false,false,{0x100, 0x100, 0x100, 0x100, 0x100}},// WARHEAD_LASER Light Amplification of Stimulated Emission by Radiation. - { 7,true,true,true,{0x100, 0x100, 0xC0, 0xC0, 0xC0}}, // WARHEAD_PB Particle beam (neutron beam). - { 4,false,false,false,{0x100, 0x20, 0x20, 0x10, 0x10}}, // WARHEAD_FIST Punching in hand-to-hand combat. - { 4,false,false,false,{0x100, 0x20, 0x20, 0x10, 0x10}}, // WARHEAD_FOOT Kicking in hand-to-hand combat. - { 4,false,false,false,{0x100, 0x08, 0x08, 0x08, 0x08}}, // WARHEAD_HOLLOW_POINT Sniper bullet type. - {255,false,false,false,{0x100, 0x01, 0x01, 0x01, 0x01}}, // WARHEAD_SPORE - { 1, true,true,false,{0x100, 0xC0, 0x80, 0x20, 0x08}}, // WARHEAD_HEADBUTT - { 1, true,true,false,{0x100, 0xC0, 0x80, 0x20, 0x08}}, // WARHEAD_FEEDME -}; - - -/*************************************************************************** -** Converts pixel values (cell relative) into the appropriate lepton (sub cell) -** value. This is used to convert pixel (screen) coordinates into the underlying -** coordinate system. -*/ -unsigned char const Pixel2Lepton[24] = { - 0x00,0x0B,0x15,0x20,0x2B,0x35,0x40,0x4B, - 0x55,0x60,0x6B,0x75,0x80,0x8B,0x95,0xA0, - 0xAB,0xB5,0xC0,0xCB,0xD5,0xE0,0xEB,0xF5 -}; - - -/*************************************************************************** -** This array is used to index a facing in order to retrieve a cell -** offset that, when added to another cell, will achieve the adjacent cell -** in the indexed direction. -*/ -CELL const AdjacentCell[FACING_COUNT] = { - -(MAP_CELL_W), // North - -(MAP_CELL_W-1), // North East - 1, // East - MAP_CELL_W+1, // South East - MAP_CELL_W, // South - MAP_CELL_W-1, // South West - -1, // West - -(MAP_CELL_W+1) // North West -}; - -COORDINATE const AdjacentCoord[FACING_COUNT] = { - 0xFF000000L, - 0xFF000100L, - 0x00000100L, - 0x01000100L, - 0x01000000L, - 0x0100FF00L, - 0x0000FF00L, - 0xFF00FF00L -}; - - -/*************************************************************************** -** This converts 0..255 facing values into either 8, 16, or 32 facing values. -** Note: a simple shift won't suffice because 0..255 facing values should -** be converted to the CLOSEST appropriate facing, NOT rounded down to the -** nearest facing. -*/ -unsigned char const Facing8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -#ifdef NEVER -unsigned char const Facing16[256] = { - 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14, - 14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,0,0,0,0,0,0 -}; -#endif - -/* -** This table incorporates a compensating factor for the distortion caused -** by 3D-Studio when it tries to render 45% angles. -*/ -unsigned char const Facing32[256] = { - 0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3, - 3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8, - 8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12, - 13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16, - 16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19, - 19,20,20,20,20,20,20,21,21,21,21,21,21,21,22,22,22,22,22,22,22,23,23,23,23,23,23,23,24,24,24,24, - 24,24,24,25,25,25,25,25,25,25,26,26,26,26,26,26,26,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28, - 29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0 -}; - -#ifdef OBSOLETE -unsigned char const Facing32[256] = { - 0,0,0,0, - 1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3, - 4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7, - 8,8,8,8,8,8,8,8, - 9,9,9,9,9,9,9,9, - 10,10,10,10,10,10,10,10, - 11,11,11,11,11,11,11,11, - 12,12,12,12,12,12,12,12, - 13,13,13,13,13,13,13,13, - 14,14,14,14,14,14,14,14, - 15,15,15,15,15,15,15,15, - 16,16,16,16,16,16,16,16, - 17,17,17,17,17,17,17,17, - 18,18,18,18,18,18,18,18, - 19,19,19,19,19,19,19,19, - 20,20,20,20,20,20,20,20, - 21,21,21,21,21,21,21,21, - 22,22,22,22,22,22,22,22, - 23,23,23,23,23,23,23,23, - 24,24,24,24,24,24,24,24, - 25,25,25,25,25,25,25,25, - 26,26,26,26,26,26,26,26, - 27,27,27,27,27,27,27,27, - 28,28,28,28,28,28,28,28, - 29,29,29,29,29,29,29,29, - 30,30,30,30,30,30,30,30, - 31,31,31,31,31,31,31,31, - 0,0,0,0 -}; -#endif - - -/*************************************************************************** -** These are the movement costs (in ticks at fastest speed) to enter each -** of the given terrain cells. -*/ -#define S1 0x00 -#define S2 0x40 -#define S3 0x70 -#define S4 0xA0 -#define S5 0xC0 -#define S6 0xFF -GroundType const Ground[LAND_COUNT] = { -// Foot -// | Tracked -// | | Harvester -// | | | Wheeled -// | | | | Winged -// | | | | | Hover -// | | | | | | float build - {66, {S3, S3, S3, S4, S6, S5, S1 }, true}, // LAND_CLEAR - {68, {S5, S4, S4, S4, S6, S5, S1 }, true}, // LAND_ROAD - {BLUE, {S1, S1, S1, S1, S6, S5, S6 }, false}, // LAND_WATER - {DKGREY, {S1, S1, S1, S1, S6, S1, S1 }, false}, // LAND_ROCK - {DKGREY, {S1, S1, S1, S1, S6, S1, S1 }, false}, // LAND_WALL - {143, {S3, S3, S3, S4, S6, S5, S1 }, false}, // LAND_TIBERIUM - {66, {S3, S3, S3, S4, S6, S5, S1 }, false}, // LAND_BEACH -}; - - -/*************************************************************************** -** These are the names of the theaters. -*/ -TheaterDataType const Theaters[THEATER_COUNT] = { - {"DESERT","DESERT","DES"}, - {"JUNGLE","JUNGLE","JUN"}, - {"TEMPERATE","TEMPERAT","TEM"}, - {"WINTER","WINTER","WIN"} -}; - - -/*************************************************************************** -** These are the remap tables that are used to convert the units/buildings -** into the other color schemes. -*/ -unsigned char const RemapGold[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const RemapRed[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 127,126,125,124,122,46,120,47,125,124,123,122,42,121,120,120, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const RemapBlue[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 2,119,118,135,136,138,112,12,118,135,136,137,138,139,114,112, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const RemapOrange[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 24,25,26,27,29,31,46,47,26,27,28,29,30,31,43,47, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const RemapGreen[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 5,165,166,167,159,142,140,199,166,167,157,3,159,143,142,141, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const RemapLtBlue[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 161,200,201,202,204,205,206,12,201,202,203,204,205,115,198,114, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const RemapNone[256] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // 0..15 - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31 - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47 - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63 - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79 - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95 - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; \ No newline at end of file diff --git a/code/TIBERIANDAWN/CONTROL.CPP b/code/TIBERIANDAWN/CONTROL.CPP deleted file mode 100644 index 2868305..0000000 --- a/code/TIBERIANDAWN/CONTROL.CPP +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\control.cpv 2.18 16 Oct 1995 16:51:38 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONTROL.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 19, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ControlClass::Action -- Normal action for control gaget objects. * - * ControlClass::ControlClass -- Constructor for control class objects. * - * ControlClass::Draw_Me -- Draw logic for the control class object. * - * ControlClass::Get_ID -- Gets the ID number for this gadget. * - * ControlClass::Make_Peer -- Assigns a peer gadget to this gadget. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * ControlClass::ControlClass -- Constructor for control class objects. * - * * - * This is the normal constructor for control class objects. At this level, it only needs * - * to record the ID number assigned to this button. * - * * - * INPUT: id -- The ID number for this gadget. If the ID number specified is 0, then * - * this tells the system that no special ID code should be returned. * - * * - * x,y -- Pixel coordinate of upper left corner of gadget's region. * - * * - * w,h -- Pixel dimensions of the gadget's region. * - * * - * flags -- The input event flags that this gadget recognizes. * - * * - * sticky-- This this a "sticky" gadget? A sticky gadget is one that takes over the * - * gadget list while the mouse button is held down, if the mouse button was * - * initially clicked over its region. This is the behavior of "normal" * - * buttons in Windows. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -ControlClass::ControlClass(unsigned id, int x, int y, int w, int h, unsigned flags, int sticky) - : GadgetClass(x, y, w, h, flags, sticky) -{ - ID = id; - Peer = 0; -} - - -/*********************************************************************************************** - * ControlClass::Action -- Normal action for control gaget objects. * - * * - * This function gets called when the input event that this control gadget is looking for * - * occurs. In such a case, the return key code value is changed to the gaget's ID number * - * with the special button bit flag attached. * - * * - * INPUT: flags -- The event that triggered this function call. If this value is NULL, then * - * this is a forced (probably due to the sticky flag) call and the key code * - * is not altered. * - * * - * key -- Reference to the key code that will be returned by the controlling * - * Input() function. * - * * - * OUTPUT: bool; Should futher list processing be aborted? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int ControlClass::Action(unsigned flags, KeyNumType & key) -{ - /* - ** If there is a peer link established, inform that gadget of this - ** action call. - */ - if (Peer) { - Peer->Peer_To_Peer(flags, key, *this); - } - - /* - ** Only if the flags indicate that a recognized action has occured, do the - ** normal processing of this gadget and set return value to the gadget ID. - */ - if (flags) { - if (ID) { - key = (KeyNumType)(ID | KN_BUTTON); - } else { - key = KN_NONE; - } - } - - return(GadgetClass::Action(flags, key)); -} - - -/*********************************************************************************************** - * ControlClass::Make_Peer -- Assigns a peer gadget to this gadget. * - * * - * This function will assign another gadget to this one. That other gadget will receive * - * notification of any Action() call to this gadget. Presumably, this is how one gadget * - * can automatically adapt to changes in another. Say for example, a slider bar can affect * - * the list box it is attached to. * - * * - * INPUT: gadget -- The gadget to inform when any Action() function is called. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void ControlClass::Make_Peer(GadgetClass & gadget) -{ - Peer = &gadget; -} - - -/*********************************************************************************************** - * ControlClass::Get_ID -- Gets the ID number for this gadget. * - * * - * This function will query and return with the ID number for this gadget. It is primarily * - * used by the Extract_Gadget() function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the ID number for this gadget. If zero is returned, this means that * - * no ID was assigned to this gadget. This is a special case since a zero value will * - * never be returned as a pseudo-key as is done with non-zero values. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -unsigned ControlClass::Get_ID(void) const -{ - return(ID); -} - - -/*********************************************************************************************** - * ControlClass::Draw_Me -- Draw logic for the control class object. * - * * - * This is called when the control object might need to be redrawn or when redrawing is * - * necessary. Since at this level of the class heirarchy, no actual drawing occurs, this * - * routine doesn't perform any rendering. It does, however, inform any peer attached * - * object that a Draw_Me function has been called. Presumably, the attached peer gadget * - * might very well need to be redrawn as a result of some action by this gadget. Since this * - * gadget might, more than likely, be of the "sticky" variety, a normal call to Draw_Me * - * for the other gadget will not occur. It must rely on the call by this routine in order * - * to update correctly. A typical example of this would be a slider that is attached to * - * a list box. As the slider is being drug around, the attached list box must be redrawn. * - * * - * INPUT: forced -- Should the redraw be forced regardless of the redraw flag? * - * * - * OUTPUT: bool; Was the gadget redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ControlClass::Draw_Me(int forced) -{ - if (Peer) { - Peer->Draw_Me(); - } - return(GadgetClass::Draw_Me(forced)); -} diff --git a/code/TIBERIANDAWN/CONTROL.H b/code/TIBERIANDAWN/CONTROL.H deleted file mode 100644 index d20262b..0000000 --- a/code/TIBERIANDAWN/CONTROL.H +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\control.h_v 2.18 16 Oct 1995 16:46:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONTROL.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CONTROL_H -#define CONTROL_H - -#include "gadget.h" - -/*************************************************************************** - * ControlClass -- Region tracking class * - * * - * INPUT: int x -- x position of gadget * - * int y -- y position of gadget * - * int w -- width of gadget * - * int h -- height of gadget * - * UWORD flags -- see enumeration choices * - * * - * OUTPUT: 0 = new scenario created, -1 = not * - * WARNINGS: This class is Abstract (cannot make an instance of it) * - * * - * HISTORY: * - * 01/03/1995 MML : Created. * - *=========================================================================*/ -class ControlClass : public GadgetClass -{ - public: - ControlClass(unsigned id, int x, int y, int w, int h, unsigned flags=LEFTPRESS|RIGHTPRESS, int sticky=false); -// static ControlClass * Create_One_Of(unsigned id, int x, int y, int w, int h, unsigned flags=LEFTPRESS|RIGHTPRESS, int sticky=false); - - virtual void Make_Peer(GadgetClass & gadget); - - /* - ** Render support function. - */ - virtual int Draw_Me(int forced=false); - - /* - ** This is the ID number for this control gadget. This number is used to generate - ** a special pseudo-key when the gadget detects valid input. - */ - unsigned ID; - - protected: - virtual unsigned Get_ID(void) const; - virtual int Action(unsigned flags, KeyNumType & key); - - /* - ** This points to the peer button to inform when something happens to this - ** gadget. - */ - GadgetClass * Peer; -}; - -#endif - diff --git a/code/TIBERIANDAWN/COORD.CPP b/code/TIBERIANDAWN/COORD.CPP deleted file mode 100644 index f8e6d76..0000000 --- a/code/TIBERIANDAWN/COORD.CPP +++ /dev/null @@ -1,599 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\coord.cpv 2.18 16 Oct 1995 16:51:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : COORD.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : January 7, 1995 [JLB] * - * * - * Support code to handle the coordinate system is located in this module. * - * Routines here will be called QUITE frequently during play and must be * - * as efficient as possible. * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * - * Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance * - * Coord_Scatter -- Determines a random coordinate from an anchor point. * - * Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. * - * Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. * - * * - * This routine will take an arbitrary position and object size and return with a list of * - * cell offsets from the current cell for all cells that are overlapped by the object. The * - * first cell offset is always zero, so to just get the adjacent spill cell list, add one * - * to the return pointer. * - * * - * INPUT: coord -- The coordinate to examine. * - * * - * maxsize -- The maximum width/height of the object (pixels). * - * * - * OUTPUT: Returns with a pointer to a spillage list. * - * * - * WARNINGS: The algorithm is limited to working with a maxsize of 48 or less. Larger values * - * will generate an incomplete overlap list. * - * * - * HISTORY: * - * 11/06/1993 JLB : Created. * - * 03/25/1994 JLB : Added width optimization. * - * 04/29/1994 JLB : Converted to C. * - * 06/03/1994 JLB : Converted to general purpose spillage functionality. * - * 01/07/1995 JLB : Manually calculates spillage list for large objects. * - *=============================================================================================*/ -short const * Coord_Spillage_List(COORDINATE coord, int maxsize) -{ - static short const _MoveSpillage[(int)FACING_COUNT+1][5] = { - {0, -MAP_CELL_W, REFRESH_EOL, 0, 0}, // N - {0, -MAP_CELL_W, 1, -(MAP_CELL_W-1), REFRESH_EOL}, // NE - {0, 1, REFRESH_EOL, 0, 0}, // E - {0, 1, MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL}, // SE - {0, MAP_CELL_W, REFRESH_EOL, 0, 0}, // S - {0, -1, MAP_CELL_W, MAP_CELL_W-1, REFRESH_EOL}, // SW - {0, -1, REFRESH_EOL, 0, 0}, // W - {0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), REFRESH_EOL}, // NW - {0, REFRESH_EOL, 0, 0, 0} // non-moving. -// {0, -MAP_CELL_W, -(MAP_CELL_W-1), 1, MAP_CELL_W+1, MAP_CELL_W, MAP_CELL_W-1, -1, -(MAP_CELL_W+1), REFRESH_EOL} - }; - static short _manual[10]; -//; 00 = on axis -//; 01 = below axis -//; 10 = above axis -//; 11 = undefined - static char const _SpillTable[16] = {8,6,2,-1,0,7,1,-1,4,5,3,-1,-1,-1,-1,-1}; - int index=0; - int x,y; - - /* - ** For mondo-enourmo-gigundo objects, use a prebuilt mammoth table - ** that covers a 5x5 square region. - */ - if (maxsize > ICON_PIXEL_W * 2) { - static short const _gigundo[] = { - -((2*MAP_CELL_W)-2),-((2*MAP_CELL_W)-1),-((2*MAP_CELL_W)),-((2*MAP_CELL_W)+1),-((2*MAP_CELL_W)+2), - -((1*MAP_CELL_W)-2),-((1*MAP_CELL_W)-1),-((1*MAP_CELL_W)),-((1*MAP_CELL_W)+1),-((1*MAP_CELL_W)+2), - -((0*MAP_CELL_W)-2),-((0*MAP_CELL_W)-1),-((0*MAP_CELL_W)),-((0*MAP_CELL_W)+1),-((0*MAP_CELL_W)+2), - ((1*MAP_CELL_W)-2),((1*MAP_CELL_W)-1),((1*MAP_CELL_W)),((1*MAP_CELL_W)+1),((1*MAP_CELL_W)+2), - +((2*MAP_CELL_W)-2),+((2*MAP_CELL_W)-1),+((2*MAP_CELL_W)),+((2*MAP_CELL_W)+1),+((2*MAP_CELL_W)+2), - REFRESH_EOL - }; - return(&_gigundo[0]); - } - - /* - ** For very large objects, build the overlap list by hand. This is time consuming, but - ** not nearly as time consuming as drawing even a single cell unnecessarily. - */ - if (maxsize > ICON_PIXEL_W) { - maxsize = MIN(maxsize, (ICON_PIXEL_W*2))/2; - - x = Fixed_To_Cardinal(ICON_PIXEL_W, Coord_XLepton(coord)); - y = Fixed_To_Cardinal(ICON_PIXEL_H, Coord_YLepton(coord)); - int left = x-maxsize; - int right = x+maxsize; - int top = y-maxsize; - int bottom = y+maxsize; - - _manual[index++] = 0; - if (left < 0) _manual[index++] = -1; - if (right >= ICON_PIXEL_W) _manual[index++] = 1; - if (top < 0) _manual[index++] = -MAP_CELL_W; - if (bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W; - if (left < 0 && top < 0) _manual[index++] = -(MAP_CELL_W+1); - if (right >= ICON_PIXEL_W && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W+1; - if (left < 0 && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W-1; - if (right >= ICON_PIXEL_H && top < 0) _manual[index++] = -(MAP_CELL_W-1); - _manual[index] = REFRESH_EOL; - return(&_manual[0]); - } - - /* - ** Determine the number of leptons "leeway" allowed this unit. - */ - int posval = Pixel2Lepton[(ICON_PIXEL_W-maxsize)/2]; - - x = Coord_XLepton(coord) - 0x0080; - y = Coord_YLepton(coord) - 0x0080; - if (y > posval) index |= 0x08; // Spilling South. - if (y < -posval) index |= 0x04; // Spilling North. - if (x > posval) index |= 0x02; // Spilling East. - if (x < -posval) index |= 0x01; // Spilling West. - - return(&_MoveSpillage[_SpillTable[index]][0]); -} - - -/*********************************************************************************************** - * Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance * - * * - * This function will move a coordinate in a using SIN and COS arithmetic. * - * * - * INPUT: start -- The starting coordinate. * - * * - * dir -- The direction to move the coordinate. * - * * - * distance -- The distance to move the coordinate position (in leptons). * - * * - * OUTPUT: Returns the new coordinate position. * - * * - * WARNINGS: This routine uses multiplies -- use with caution. * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE Coord_Move(COORDINATE start, register DirType dir, unsigned short distance) -{ - short x = Coord_X(start); - short y = Coord_Y(start); - - Move_Point(x, y, dir, distance); - return(XY_Coord(x,y)); -#ifdef NEVER - static char const CosTable[256] = { - 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15, - 0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d, - 0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43, - 0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57, - 0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67, - 0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b, - 0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e, - - 0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d, - 0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76, - 0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b, - 0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b, - 0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49, - 0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33, - 0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b, - 0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03, - - 0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb, - 0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3, - 0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd, - 0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9, - 0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99, - 0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c, - 0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85, - 0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82, - - 0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83, - 0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a, - 0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95, - 0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5, - 0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7, - 0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd, - 0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5, - 0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd, - }; - - static char const SinTable[256] = { - 0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d, - 0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76, - 0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b, - 0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b, - 0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49, - 0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33, - 0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b, - 0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03, - - 0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb, - 0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3, - 0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd, - 0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9, - 0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99, - 0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c, - 0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85, - 0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82, - - 0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83, - 0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a, - 0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95, - 0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5, - 0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7, - 0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd, - 0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5, - 0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd, - - 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15, - 0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d, - 0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43, - 0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57, - 0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67, - 0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b, - 0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e, - }; - distance = distance; // Keep LINT quiet. - - /* - ** Calculate and add in the X component of the move. - */ - _AX = CosTable[dir]; - asm imul word ptr distance - asm shl ax,1 - asm rcl dx,1 - asm mov al,ah - asm mov ah,dl - _DX = _AX; - *((int*)&start) += _DX; -// asm add [word ptr start],ax - - /* - ** Calculate and add in the Y component of the move. - */ - _AX = SinTable[dir]; - asm imul word ptr distance - asm shl ax,1 - asm rcl dx,1 - asm mov al,ah - asm mov ah,dl - asm neg ax // Subtraction needed because of inverted sine table. - _DX = _AX; - *(((int*)&start)+1) += _DX; -// asm add [word ptr start+2],ax - - return(start); -#endif -} - -#ifdef OBSOLETE -//BG: Note, this routine is replaced by assembly in COORDA.ASM -/*********************************************************************************************** - * Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * - * * - * This utility function will convert cardinal numbers into a fixed point fraction. The * - * use of fixed point numbers occurs throughout the product -- since it is a convenient * - * tool. The fixed point number is based on the formula: * - * * - * result = cardinal / base * - * * - * The accuracy of the fixed point number is limited to 1/256 as the lowest and up to * - * 256 as the largest. * - * * - * INPUT: base -- The key number to base the fraction about. * - * * - * cardinal -- The other number (hey -- what do you call it?) * - * * - * OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates * - * to the "base" parameter. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal) -{ - long temp = 0; - - if (base) { - *(unsigned*)(((char*)&temp)+1) = cardinal; // Shift up by 8 bits. - _DX = FP_SEG(temp); - _AX = FP_OFF(temp); - asm div word ptr base - return(_AX); - } - return(0xFFFF); -} -#endif - -#ifdef OBSOLETE -//BG: Note, this routine is replaced by assembly in COORDA.ASM -/*********************************************************************************************** - * Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. * - * * - * Use this routine to convert a fixed point number into a cardinal number. * - * * - * INPUT: base -- The base number that the original fixed point number was created from. * - * * - * fixed -- The fixed point number to convert. * - * * - * OUTPUT: Returns with the reconverted number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed) -{ - unsigned long temp; - - _AX = base; - asm mul word ptr fixed - _CX = _AX; - temp = ((unsigned long)MK_FP(_DX, _CX)) + 0x80; - if ( *((char*)&temp+3) ) { - return(0xFFFF); - } - return(*(unsigned*)(((char*)&temp)+1)); -} -#endif - - -/*********************************************************************************************** - * Coord_Scatter -- Determines a random coordinate from an anchor point. * - * * - * This routine will perform a scatter algorithm on the specified * - * anchor point in order to return with another coordinate that is * - * randomly nearby the original. Typical use of this would be for * - * missile targeting. * - * * - * INPUT: coord -- This is the anchor coordinate. * - * * - * distance -- This is the distance in pixels that the scatter * - * should fall within. * - * * - * lock -- bool; Convert the new coordinate into a center * - * cell based coordinate? * - * * - * OUTPUT: Returns with a new coordinate that is nearby the original. * - * * - * WARNINGS: Maximum pixel scatter distance is 255. * - * * - * HISTORY: * - * 02/01/1992 JLB : Created. * - * 05/13/1992 JLB : Only uses Random(). * - *=============================================================================================*/ -COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock) -{ - COORDINATE newcoord; - - newcoord = Coord_Move(coord, Random_Pick(DIR_N, DIR_MAX), distance); - - if (newcoord & 0xC000C000L) newcoord = coord; - - if (lock) { - newcoord = Coord_Snap(newcoord); - } - - return(newcoord); -} - - - -int __cdecl calcx(signed short param1, short distance) -{ - __asm { - -//#pragma aux calcx parm [ax] [bx] \ - - movzx eax, [param1] - mov bx, [distance] - imul bx - shl ax,1 - rcl dx,1 - mov al,ah - mov ah,dl - cwd - } -} - - -int __cdecl calcy(signed short param1, short distance) -{ - __asm { - -//#pragma aux calcy parm [ax] [bx] \ - - movzx eax, [param1] - mov bx, [distance] - imul bx - shl ax,1 - rcl dx,1 - mov al,ah - mov ah,dl - cwd - neg eax - } -} - - - - -#if (0) -extern int calcx(signed short, short distance); -#pragma aux calcx parm [ax] [bx] \ - modify [eax dx] \ - value [eax] = \ - "imul bx" \ - "shl ax,1" \ - "rcl dx,1" \ - "mov al,ah" \ - "mov ah,dl" \ - "cwd" \ -// "and eax,0FFFFh"; - -extern int calcy(signed short, short distance); -#pragma aux calcy parm [ax] [bx] \ - modify [eax dx] \ - value [eax] = \ - "imul bx" \ - "shl ax,1" \ - "rcl dx,1" \ - "mov al,ah" \ - "mov ah,dl" \ - "cwd" \ - "neg eax"; -// "and eax,0FFFFh" -#endif - - - -void Move_Point(short &x, short &y, register DirType dir, unsigned short distance) -{ -// static char const CosTable[256] = { - static unsigned char const CosTable[256] = { - 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15, - 0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d, - 0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43, - 0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57, - 0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67, - 0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b, - 0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e, - - 0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d, - 0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76, - 0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b, - 0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b, - 0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49, - 0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33, - 0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b, - 0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03, - - 0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb, - 0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3, - 0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd, - 0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9, - 0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99, - 0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c, - 0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85, - 0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82, - - 0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83, - 0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a, - 0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95, - 0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5, - 0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7, - 0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd, - 0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5, - 0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd, - }; - -// static char const SinTable[256] = { - static unsigned char const SinTable[256] = { - 0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d, - 0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76, - 0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b, - 0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b, - 0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49, - 0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33, - 0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b, - 0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03, - - 0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb, - 0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3, - 0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd, - 0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9, - 0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99, - 0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c, - 0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85, - 0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82, - - 0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83, - 0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a, - 0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95, - 0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5, - 0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7, - 0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd, - 0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5, - 0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd, - - 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15, - 0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d, - 0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43, - 0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57, - 0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67, - 0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b, - 0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e, - }; - distance = distance; // Keep LINT quiet. - -#ifdef OBSOLETE - /* - ** Calculate and add in the X component of the move. - */ - _AX = CosTable[dir]; - asm imul word ptr distance - asm shl ax,1 - asm rcl dx,1 - asm mov al,ah - asm mov ah,dl - _DX = _AX; - x += _DX; -#else - // - // Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed. - // - // ST - 1/10/2019 11:20AM - // - char *cos_table = (char*)&CosTable[0]; - x += calcx(cos_table[dir], distance); -#endif -// asm add [word ptr start],ax - -#ifdef OBSOLETE - /* - ** Calculate and add in the Y component of the move. - */ - _AX = SinTable[dir]; - asm imul word ptr distance - asm shl ax,1 - asm rcl dx,1 - asm mov al,ah - asm mov ah,dl - asm neg ax // Subtraction needed because of inverted sine table. - _DX = _AX; - y += _DX; -#else - // - // Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed. - // - // ST - 1/10/2019 11:20AM - // - char *sin_table = (char*)&SinTable[0]; - y += calcy(sin_table[dir], distance); -#endif -// asm add [word ptr start+2],ax - -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/COORDA.ASM b/code/TIBERIANDAWN/COORDA.ASM deleted file mode 100644 index 398ab7c..0000000 --- a/code/TIBERIANDAWN/COORDA.ASM +++ /dev/null @@ -1,131 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S I N C ** -;*************************************************************************** -;* * -;* Project Name : Command & Conquer * -;* * -;* File Name : COORDA.ASM * -;* * -;* Programmer : Barry W. Green * -;* * -;* Start Date : February 17, 1995 * -;* * -;* Last Update : February 17, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -global C Cardinal_To_Fixed :NEAR -global C Fixed_To_Cardinal :NEAR - - CODESEG - -;*********************************************************************************************** -;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * -;* * -;* This utility function will convert cardinal numbers into a fixed point fraction. The * -;* use of fixed point numbers occurs throughout the product -- since it is a convenient * -;* tool. The fixed point number is based on the formula: * -;* * -;* result = cardinal / base * -;* * -;* The accuracy of the fixed point number is limited to 1/256 as the lowest and up to * -;* 256 as the largest. * -;* * -;* INPUT: base -- The key number to base the fraction about. * -;* * -;* cardinal -- The other number (hey -- what do you call it?) * -;* * -;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates * -;* to the "base" parameter. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 02/17/1995 BWG : Created. * -;*=============================================================================================*/ -;unsigned int Cardinal_To_Fixed(unsigned base, unsigned cardinal); - - PROC Cardinal_To_Fixed C near - USES ebx, edx - - ARG base:DWORD - ARG cardinal:DWORD - - mov eax,0FFFFh ; establish default return value - - mov ebx,[base] - or ebx,ebx - jz near ??retneg1 ; if base==0, return 65535 - - mov eax,[cardinal] ; otherwise, return (cardinal*256)/base - shl eax,8 - xor edx,edx - div ebx - -??retneg1: - ret - - ENDP Cardinal_To_Fixed - - -;*********************************************************************************************** -;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. * -;* * -;* Use this routine to convert a fixed point number into a cardinal number. * -;* * -;* INPUT: base -- The base number that the original fixed point number was created from. * -;* * -;* fixed -- The fixed point number to convert. * -;* * -;* OUTPUT: Returns with the reconverted number. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 02/17/1995 BWG : Created. * -;*=============================================================================================*/ -;unsigned int Fixed_To_Cardinal(unsigned base, unsigned fixed); - PROC Fixed_To_Cardinal C near - USES edx - - ARG base:DWORD - ARG fixed:DWORD - - mov eax,[base] - mul [fixed] - add eax,080h ; eax = (base * fixed) + 0x80 - - test eax,0FF000000h ; if high byte set, return FFFF - jnz ??rneg1 - shr eax,8 ; else, return eax/256 - ret -??rneg1 : - mov eax,0FFFFh ; establish default return value - ret - - ENDP Fixed_To_Cardinal - - END diff --git a/code/TIBERIANDAWN/COORDA.h b/code/TIBERIANDAWN/COORDA.h deleted file mode 100644 index 912c662..0000000 --- a/code/TIBERIANDAWN/COORDA.h +++ /dev/null @@ -1,141 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S I N C ** -;*************************************************************************** -;* * -;* Project Name : Command & Conquer * -;* * -;* File Name : COORDA.ASM * -;* * -;* Programmer : Barry W. Green * -;* * -;* Start Date : February 17, 1995 * -;* * -;* Last Update : February 17, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -*/ - -#ifndef COORD_A_H - -//IDEAL -//P386 -//MODEL USE32 FLAT - -//global C Cardinal_To_Fixed :NEAR -//global C Fixed_To_Cardinal :NEAR - -// CODESEG -/* -;*********************************************************************************************** -;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * -;* * -;* This utility function will convert cardinal numbers into a fixed point fraction. The * -;* use of fixed point numbers occurs throughout the product -- since it is a convenient * -;* tool. The fixed point number is based on the formula: * -;* * -;* result = cardinal / base * -;* * -;* The accuracy of the fixed point number is limited to 1/256 as the lowest and up to * -;* 256 as the largest. * -;* * -;* INPUT: base -- The key number to base the fraction about. * -;* * -;* cardinal -- The other number (hey -- what do you call it?) * -;* * -;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates * -;* to the "base" parameter. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 02/17/1995 BWG : Created. * -;*=============================================================================================*/ - -unsigned int __cdecl Cardinal_To_Fixed(unsigned base, unsigned cardinal); - -#if (0) - PROC Cardinal_To_Fixed C near - USES ebx, edx - - ARG base:DWORD - ARG cardinal:DWORD - - mov eax,0FFFFh ; establish default return value - - mov ebx,[base] - or ebx,ebx - jz near ??retneg1 ; if base==0, return 65535 - - mov eax,[cardinal] ; otherwise, return (cardinal*256)/base - shl eax,8 - xor edx,edx - div ebx - -??retneg1: - ret - - ENDP Cardinal_To_Fixed -#endif - -/* -;*********************************************************************************************** -;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. * -;* * -;* Use this routine to convert a fixed point number into a cardinal number. * -;* * -;* INPUT: base -- The base number that the original fixed point number was created from. * -;* * -;* fixed -- The fixed point number to convert. * -;* * -;* OUTPUT: Returns with the reconverted number. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 02/17/1995 BWG : Created. * -;*=============================================================================================*/ - -unsigned int __cdecl Fixed_To_Cardinal(unsigned base, unsigned fixed); - -#if (0) - mov eax,[base] - mul [fixed] - add eax,080h ; eax = (base * fixed) + 0x80 - - test eax,0FF000000h ; if high byte set, return FFFF - jnz ??rneg1 - shr eax,8 ; else, return eax/256 - ret -??rneg1 : - mov eax,0FFFFh ; establish default return value - ret - - ENDP Fixed_To_Cardinal - - END -#endif - - - - - -#endif COORD_A_H \ No newline at end of file diff --git a/code/TIBERIANDAWN/CREDITS.CPP b/code/TIBERIANDAWN/CREDITS.CPP deleted file mode 100644 index 098f8de..0000000 --- a/code/TIBERIANDAWN/CREDITS.CPP +++ /dev/null @@ -1,183 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\credits.cpv 2.17 16 Oct 1995 16:51:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CREDITS.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 17, 1994 * - * * - * Last Update : March 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CreditClass::AI -- Handles updating the credit display. * - * CreditClass::Graphic_Logic -- Handles the credit redraw logic. * - * CreditClass::CreditClass -- Default constructor for the credit class object. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * CreditClass::CreditClass -- Default constructor for the credit class object. * - * * - * This is the constructor for the credit class object. It merely sets the credit display * - * state to null. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -CreditClass::CreditClass(void) -{ - IsToRedraw = false; - IsUp = false; - IsAudible = false; - Credits = 0; - Current = 0; - Countdown = 0; -} - - -/*********************************************************************************************** - * CreditClass::Graphic_Logic -- Handles the credit redraw logic. * - * * - * This routine should be called whenever the main game screen is to be updated. It will * - * check to see if the credit display should be redrawn. If so, it will redraw it. * - * * - * INPUT: forced -- Should the credit display be redrawn regardless of whether the redraw * - * flag is set? This is typically the case when the screen needs to be * - * redrawn from scratch. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -#define XX (320-120) -#define WW 50 -void CreditClass::Graphic_Logic(bool forced) -{ - int factor = Get_Resolution_Factor(); - int xx = SeenBuff.Get_Width() - (120 << factor); - if (forced || IsToRedraw) { - - /* - ** Play a sound effect when the money display changes, but only if a sound - ** effect was requested. - */ - if (IsAudible) { - if (IsUp) { - Sound_Effect(VOC_UP, VOL_1); - } else { - Sound_Effect(VOC_DOWN, VOL_1); - } - } - - /* - ** Display the new current value. - */ - //LogicPage->Fill_Rect(xx-(20 << factor), 1 << factor, xx+(20 << factor), 6 << factor, LTGREY); - TabClass::Draw_Credits_Tab(); - Fancy_Text_Print("%ld", xx, 0, 11, TBLACK, TPF_GREEN12_GRAD|TPF_CENTER | TPF_USE_GRAD_PAL, Current); - - IsToRedraw = false; - IsAudible = false; - } -} - - -/*********************************************************************************************** - * CreditClass::AI -- Handles updating the credit display. * - * * - * This routine handles the logic that controls the rate of credit change in the credit * - * display. It doesn't actually redraw the credit display, but will flag it to be redrawn * - * if it detects that a change is to occur. * - * * - * INPUT: forced -- Should the credit display immediately reflect the current credit * - * total for the player? This is usually desired when initially loading * - * a scenario or saved game. * - * player_ptr -- Player to calculate visible credits for * - * logic_only -- If true, don't flag map for redraw * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - * 10/16/2019 ST : Added house and logic parameters so we can call this from HouseClass::AI * - *=============================================================================================*/ -void CreditClass::AI(bool forced, HouseClass *player_ptr, bool logic_only) -{ - if (player_ptr == NULL) { - return; - } - - Credits = player_ptr->Available_Money(); - - /* - ** Make sure that the credit counter doesn't drop below zero. - */ - Credits = MAX(Credits, 0L); - - if (Current == Credits) return; - - if (forced) { - IsAudible = false; - Current = Credits; - } else { - - if (Countdown) Countdown--; - if (Countdown) return; - - /* - ** Determine the amount to change the display toward the - ** desired value. - */ - long adder = Credits - Current; - adder = ABS(adder); - adder >>= 5; - adder = Bound(adder, 1L, 71+72); - if (Current > Credits) adder = -adder; - Current += adder; - Countdown = 1; - - if (Current-adder != Current) { - IsAudible = true; - IsUp = (adder > 0); - } - } - IsToRedraw = true; - - if (!logic_only) { - Map.Flag_To_Redraw(false); - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/CREDITS.H b/code/TIBERIANDAWN/CREDITS.H deleted file mode 100644 index 52cb0dd..0000000 --- a/code/TIBERIANDAWN/CREDITS.H +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\credits.h_v 2.18 16 Oct 1995 16:47:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CREDIT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 19, 1994 * - * * - * Last Update : April 19, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CREDITS_H -#define CREDITS_H - -class HouseClass; -extern HouseClass *PlayerPtr; - -/**************************************************************************** -** The animating credit counter display is controlled by this class. -*/ -class CreditClass { - public: - long Credits; // Value of credits trying to update display to. - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - CreditClass(void); - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - void Update(bool forced=false, bool redraw=false); - - void Graphic_Logic(bool forced=false); - void AI(bool forced=false, HouseClass *player_ptr = PlayerPtr, bool logic_only = false); // Added house and logic_only parameters. ST - 10/16/2019 2:26PM - - long Current; // Credit value currently displayed. - - unsigned IsToRedraw:1; - unsigned IsUp:1; - unsigned IsAudible:1; - - private: - int Countdown; // Delay between ticks. -}; - -#endif diff --git a/code/TIBERIANDAWN/CREW.CPP b/code/TIBERIANDAWN/CREW.CPP deleted file mode 100644 index c38fa7a..0000000 --- a/code/TIBERIANDAWN/CREW.CPP +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\crew.cpv 2.18 16 Oct 1995 16:50:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CREW.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" diff --git a/code/TIBERIANDAWN/CREW.H b/code/TIBERIANDAWN/CREW.H deleted file mode 100644 index fb02b4b..0000000 --- a/code/TIBERIANDAWN/CREW.H +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\crew.h_v 2.18 16 Oct 1995 16:47:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CREW.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef CREW_H -#define CREW_H - - -/**************************************************************************** -** This class handles the basic crew logic. This includes hero tracking, -** crew bail-out, and attached object logic. -*/ -class CrewClass -{ - public: - /* - ** This keeps track of the number of "kills" the unit as accumulated. - ** When it reaches a certain point, the unit improves. - */ - unsigned short Kills; - - /* - ** Constructors, Destructors, and overloaded operators. - */ - CrewClass(void) {Kills = 0;}; - - int Made_A_Kill(void) {Kills++;return(Kills);}; - - private: -}; - -#endif diff --git a/code/TIBERIANDAWN/DDE.CPP b/code/TIBERIANDAWN/DDE.CPP deleted file mode 100644 index 7be3749..0000000 --- a/code/TIBERIANDAWN/DDE.CPP +++ /dev/null @@ -1,465 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Dynamic Data Encapsulation * - * * - * File Name : DDE.CPP * - * * - * Programmer : Steve Wetherill * - * * - * Start Date : June 1, 1996 * - * * - * Last Update : June 8, 1996 [SW] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Instance_Class::InstanceClass -- class constructor * - * Instance_Class::InstanceClass -- class destructor * - * Instance_Class::Enable_Callback -- enables local processing of pokes * - * Instance_Class::Register_Servers -- registers a local DDE DNS service * - * Instance_Class::Cleanup_App -- currently does nothing * - * Instance_Class::Test_Server_Running -- does a trial connect to remote * - * Instance_Class::Open_Poke_Connection -- pokes some data to server * - * Instance_Class::Close_Poke_Connectionp -- closes connection to remote * - * Instance_Class::Poke_Server -- sends a chunk of data to remote * - * Instance_Class::dde_callback -- processes DDE transactions * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include -#include "dde.h" - -/*************************************************************************** - * These are static members of Instance_Class - *=========================================================================*/ - -DWORD Instance_Class::id_inst; // instance identifier set by DdeInitialize -BOOL Instance_Class::process_pokes; // controls response to pokes -char Instance_Class::ascii_name[32]; // name of server - -//PG_TO_FIX ST - 12/20/2018 2:17PM -#if (0) -static BOOL CALLBACK (*Instance_Class::callback) ( - LPBYTE pointer, // pointer to received data - long length // length of received data or advisory flag - ) = NULL; -#endif - -/*************************************************************************** - * Instance_Class::InstanceClass -- class constructor * - * * - * INPUT: * - * name1 null terminated ASCII client name * - * name1 null terminated ASCII server name * - * * - * OUTPUT: * - * dde_error = TRUE if error occurs when initializing DDE * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -Instance_Class::Instance_Class( LPSTR name1, LPSTR name2 ) -{ - name1; - name2; - return; - -#if (0) //ST - 1/2/2019 5:35PM - dde_error = FALSE; // no errors - process_pokes = FALSE; // disable pokes in callback - - id_inst = 0; // set to 0 for first time through - conv_handle = 0; // conversation handle reset - - lstrcpy( ascii_name, name1 ); // keep a record of ASCII name - - if ( DdeInitialize( - (LPDWORD) &id_inst, // instance identifier - dde_callback, - APPCLASS_STANDARD | // filter server messages - CBF_FAIL_SELFCONNECTIONS, // prevent from connecting with self - 0) != DMLERR_NO_ERROR) { // reserved - dde_error = TRUE; // flag an error - } - - local_name = DdeCreateStringHandle( - id_inst, // instance identifier - name1, // string to register - CP_WINANSI); // Windows ANSI code page - - remote_name = DdeCreateStringHandle( - id_inst, // instance identifier - name2, // string to register - CP_WINANSI); // Windows ANSI code page - - poke_topic = DdeCreateStringHandle( - id_inst, // instance identifier - "POKE TOPIC", // System topic - CP_WINANSI); // Windows ANSI code page - - poke_item = DdeCreateStringHandle( - id_inst, // instance identifier - "POKE ITEM", // System topic - CP_WINANSI); // Windows ANSI code page - - system_topic = DdeCreateStringHandle( - id_inst, // instance identifier - SZDDESYS_TOPIC, // System topic - CP_WINANSI); // Windows ANSI code page -#endif -} - -/*************************************************************************** - * Instance_Class::~Instance_Class -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -Instance_Class::~Instance_Class() -{ - DdeUninitialize( id_inst ); -} - -/*************************************************************************** - * Instance_Class::Enable_Callback -- enables user callback * - * * - * INPUT: * - * TRUE = enable poke processing * - * FALSE = disable poke processing * - * * - * OUTPUT: * - * echos the input * - * * - * WARNINGS: * - * user callback must be explicitly enabled. Disbabled by default. * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -BOOL Instance_Class::Enable_Callback( BOOL flag ) // enable or disable callback -{ - return (process_pokes = flag); - -} - -/*************************************************************************** - * Instance_Class::Register_Server -- registers a local DDE DNS service * - * * - * INPUT: * - * BOOL CALLBACK ( *callback_fnc) ( LPBYTE, DWORD) = user poke callbacl * - * * - * OUTPUT: * - * TRUE == success * - * FALSE == failed * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ -#if (0) -BOOL Instance_Class::Register_Server( BOOL (CALLBACK *)(LPBYTE, long)); - -//BOOL Instance_Class::Register_Server( BOOL CALLBACK ( *callback_fnc) (LPBYTE, long) ) -{ - - if (DdeNameService( id_inst, local_name, 0L, DNS_REGISTER ) != 0L) { - callback = callback_fnc; - return ( TRUE ); - } else { - return ( FALSE ); - } -} -#endif -/*************************************************************************** - * Instance_Class::Test_Server_Running -- does a trial connect to remote * - * * - * INPUT: * - * name = HSZ string handle of server name. * - * * - * OUTPUT: * - * TRUE == successfully connected to remote * - * FALSE == failed to connect * - * * - * WARNINGS: * - * - Can be called for local or remote server but of course will * - * fail if a called for local and local server is not "up". * - * - Disconects before exiting. * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -BOOL Instance_Class::Test_Server_Running( HSZ name ) -{ - - if( Open_Poke_Connection( name ) == TRUE) { - Close_Poke_Connection(); - return( TRUE ); - } else { - return( FALSE ); - } -} - -/*************************************************************************** - * Instance_Class::Open_Poke_Connection -- open a connection to server * - * * - * INPUT: * - * name = HSZ server name. * - * * - * OUTPUT: * - * TRUE == successfully opened connection * - * FALSE == failed to connect * - * * - * WARNINGS: * - * Can be called for local or remote server but of course will * - * fail if a called for local and local server is not "up". * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -BOOL Instance_Class::Open_Poke_Connection( HSZ name ) -{ - conv_handle = DdeConnect( - id_inst, // instance identifier - name, // service name string handle - poke_topic, // topic string handle - (PCONVCONTEXT) NULL);// use default context - - if (conv_handle == NULL) { - return FALSE; - } else { - return TRUE; - } -} - -/*************************************************************************** - * Instance_Class::Close_Poke_Connection -- closes poke connection * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * TRUE == successfully closed connection * - * FALSE == failed to close connection for some reason * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -BOOL Instance_Class::Close_Poke_Connection( void ) -{ - if( conv_handle ) { - HCONV temp_handle = conv_handle; - conv_handle = NULL; - return( DdeDisconnect( temp_handle )); - } else { - return( TRUE ); - } -} - -/*************************************************************************** - * Instance_Class::Poke_Server -- pokes some data to server * - * * - * INPUT: * - * poke_data points to data to send to remote * - * poke_length length of buffer to send * - * * - * OUTPUT: * - * TRUE == successfully poked the data * - * FALSE == failed to connect * - * * - * WARNINGS: * - * has a 3 second timeout (change POKE_TIMEOUT, in milliseconds) * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -#define POKE_TIMEOUT 60*1000 // 60 sec timeout - -BOOL Instance_Class::Poke_Server( LPBYTE poke_data, DWORD poke_length ) -{ - - if( DdeClientTransaction( - - poke_data, // address of data to pass to server - poke_length, // length of data - conv_handle, // handle of conversation - poke_topic, // handle of item name string - CF_TEXT, // no special clipboard data format - XTYP_POKE, // transaction type - POKE_TIMEOUT, // time-out duration (millisecs) - (LPDWORD) NULL // address of transaction result (don't check) - ) == 0) { - - return( FALSE); - } else { - return( TRUE ); - } -} - -/*************************************************************************** - * Instance_Class::dde_callback -- callback dde event handler * - * * - * INPUT: * - * dde_event transaction type * - * uFmt clipboard data format * - * hconv handle of the conversation * - * hsz1 handle of a string * - * hsz2 handle of a string * - * hdata handle of a global memory object * - * dwData1 transaction-specific data * - * dwData2 transaction-specific data * - * * - * OUTPUT: * - * context specific HDDEDATA object * - * * - * WARNINGS: * - * NOTE: declared as HDDEDATA CALLBACK which means PASCAL parameters * - * * - * HISTORY: * - * 6/1/1996 SW : Created. * - *=========================================================================*/ - -HDDEDATA CALLBACK Instance_Class::dde_callback( - - UINT dde_event, // transaction type - UINT uFmt, // clipboard data format - HCONV , // handle of the conversation - HSZ hsz1, // handle of a string - HSZ hsz2, // handle of a string - HDDEDATA hdata, // handle of a global memory object - DWORD , // transaction-specific data - DWORD // transaction-specific data - ) -{ - - dde_event; - uFmt; - hsz1; - hsz2; - hdata; - return (HDDEDATA) NULL; - - -#if (0) //ST - 1/2/2019 5:38PM - if (!Instance_Class::callback){ - return (HDDEDATA) NULL; - } - - switch ( dde_event ) { - - case XTYP_REGISTER: - case XTYP_UNREGISTER: - - return (HDDEDATA) NULL; - - case XTYP_ADVDATA: - return (HDDEDATA) DDE_FACK; - - case XTYP_XACT_COMPLETE: - - return (HDDEDATA) NULL; - - case XTYP_DISCONNECT: - - Instance_Class::callback( NULL, DDE_ADVISE_DISCONNECT); - return (HDDEDATA) NULL; - - case XTYP_CONNECT: { - - char buffer[32]; - - DdeQueryString (Instance_Class::id_inst, hsz2, buffer, sizeof (buffer), 0) ; - - if (0 != strcmp (buffer, Instance_Class::ascii_name)) { - return (HDDEDATA) NULL; - } - - DdeQueryString (Instance_Class::id_inst, hsz1, buffer, sizeof (buffer), 0) ; - - if (0 != strcmp (buffer, "POKE TOPIC")) { - return (HDDEDATA) NULL; - } - - Instance_Class::callback( NULL, DDE_ADVISE_CONNECT); - return (HDDEDATA) TRUE; - } - - case XTYP_POKE: - - if (Instance_Class::process_pokes == FALSE ) { - return (HDDEDATA) DDE_FNOTPROCESSED; // processing disabled - } else { - - char buffer[32]; - - DdeQueryString (Instance_Class::id_inst, hsz1, buffer, sizeof (buffer), 0) ; - - if (0 != strcmp (buffer, "POKE TOPIC")) { - return (HDDEDATA) DDE_FNOTPROCESSED; - } else if (uFmt == CF_TEXT) { // make sure it's CF_TEXT - - BOOL processed; - BYTE FAR *pdata; - DWORD dw_length; - - if ( (pdata = DdeAccessData( hdata, &dw_length)) == NULL ) { - return (HDDEDATA) DDE_FNOTPROCESSED; - } - - processed = Instance_Class::callback((LPBYTE) pdata, dw_length); - - DdeUnaccessData( hdata ); - - if (processed == TRUE) { - return (HDDEDATA) DDE_FACK; - } else { - return (HDDEDATA) NULL; - } - - } - } - - default: - return (HDDEDATA) NULL; - } -#endif -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/DDE.H b/code/TIBERIANDAWN/DDE.H deleted file mode 100644 index 258b973..0000000 --- a/code/TIBERIANDAWN/DDE.H +++ /dev/null @@ -1,176 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Dynamic Data Encapsulation * - * * - * File Name : DDE.H * - * * - * Programmer : Steve Wetherill * - * * - * Start Date : June 1, 1996 * - * * - * Last Update : June 8, 1996 [SW] * - * * - *-------------------------------------------------------------------------* - * * - * This is the DDE (Instance_Class) which provides a simple CLIENT/SERVER * - * DDE model for data transactions between Windows applications. * - * This is a fairly naieve implementation allowing only one client/server * - * per Instance_Class object. * - * * - * Typical uses for this class are: * - * * - * i. Robust verification of whether an application is running * - * ii. Data transfer between applications * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -/* -***************************** Class defines ***************************** -*/ -#ifndef __DDE_H -#define __DDE_H - -//#if (0) - -#define DDE_ADVISE_CONNECT -1 // advisory "client has connected" -#define DDE_ADVISE_DISCONNECT -2 // advisory "client has disconnected" - -/* -***************************** Class Declaration ***************************** -*/ - -class Instance_Class { - - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - - /*..................................................................... - Constructor: - - takes null terminated ASCII strings names for client and server - .....................................................................*/ - - Instance_Class( // constructor - LPSTR, // null terminated local sever name string - LPSTR // null terminated remote server name string - ); - - /*..................................................................... - Destructor: - .....................................................................*/ - ~Instance_Class(void); // the destructor - - /*..................................................................... - Send data routine: - - sends an unsolicited packet of data to the remote server - .....................................................................*/ - BOOL Poke_Server( LPBYTE, DWORD); - - /*..................................................................... - Send data routine: - - sets up DNS for the server and registers a user callback to handle - incoming data - .....................................................................*/ - BOOL Register_Server( BOOL (CALLBACK *)(LPBYTE, long)); - -//typedef void (CALLBACK *LPDXUTCALLBACKFRAMEMOVE)( double fTime, float fElapsedTime, void* pUserContext ); - - - /*..................................................................... - Does a trial connect to the remote server. - - used to determine whether server is alive or not (and thus running) - .....................................................................*/ - BOOL Test_Server_Running( HSZ ); - - /*..................................................................... - Enables user callback (disabled by default) - .....................................................................*/ - BOOL Enable_Callback( BOOL ); // enable or disable callback - - /*..................................................................... - Open a connection for sending data to remote server - .....................................................................*/ - BOOL Open_Poke_Connection( HSZ ); - - /*..................................................................... - Close connection with remote server - .....................................................................*/ - BOOL Close_Poke_Connection( void ); - - // - // static members - // - - /*..................................................................... - User callback - called upon receipt of incoming data (static member!) - .....................................................................*/ - static BOOL (CALLBACK *callback) ( - - LPBYTE pointer, // pointer to received data - long length // if >0 length of received data - // if <0 - // -1 == client connect detected - // -2 == client disconnect detected - ); - - /*..................................................................... - DDE callback, called when DDEML has an event for us - .....................................................................*/ - static HDDEDATA CALLBACK dde_callback( - - UINT uType, // transaction type - UINT uFmt, // clipboard data format - HCONV hconv, // handle of the conversation - HSZ hsz1, // handle of a string - HSZ hsz2, // handle of a string - HDDEDATA hdata, // handle of a global memory object - DWORD dwData1, // transaction-specific data - DWORD dwData2 // transaction-specific data - ); - HANDLE instance; // this application's instance - HWND hwnd; // valid window handle - - /*..................................................................... - member variables - .....................................................................*/ - - static DWORD id_inst; // instance identifier set by DdeInitialize - static BOOL process_pokes; // controls response to pokes - static char ascii_name[32]; // name of server - - // - // non-static member variables - // - - HSZ remote_name; // string handle for remote server name - HSZ local_name; // string handle for local server name - HSZ system_topic; // string handle for the "system" topic - HSZ poke_topic; // string handle for poking data to server topic - HSZ poke_item; // string handle for poking data to server item - - HCONV conv_handle; // conversation handle - BOOL dde_error; // error flag - -}; -#endif - -//#endif - diff --git a/code/TIBERIANDAWN/DEBUG.CPP b/code/TIBERIANDAWN/DEBUG.CPP deleted file mode 100644 index 0e38168..0000000 --- a/code/TIBERIANDAWN/DEBUG.CPP +++ /dev/null @@ -1,690 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\debug.cpv 2.17 16 Oct 1995 16:49:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DEBUG.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : July 5, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Self_Regulate -- Regulates the logic timer to result in smooth animation. * - * Debug_Key -- Debug mode keyboard processing. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include -#include -#include -#ifdef CHEAT_KEYS - -extern bool ScreenRecording; - -/*********************************************************************************************** - * Debug_Key -- Debug mode keyboard processing. * - * * - * If debugging is enabled, then this routine will be called for every keystroke that the * - * game doesn't recognize. These extra keys usually perform some debugging function. * - * * - * INPUT: input -- The key code that was pressed. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -void Debug_Key(unsigned input) -{ - static int map_x = -1; - static int map_y = -1; - static int map_width = -1; - static int map_height = -1; - - if (!input || input & KN_BUTTON) return; - - /* - ** Processing of normal keystrokes. - */ - if (Debug_Flag) { - - switch (input) { - - case KN_L: - extern int NetMonoMode,NewMonoMode; - if (NetMonoMode) - NetMonoMode = 0; - else - NetMonoMode = 1; - NewMonoMode = 1; - break; - - /* - ** Start saving off screens - */ - case (int)KN_K|(int)KN_CTRL_BIT: - ScreenRecording = true; - break; - - case KN_K: -//PG_TO_FIX -#if (0) - /* - ** time to create a screen shot using the PCX code (if it works) - */ - { - GraphicBufferClass temp_page( SeenBuff.Get_Width(), - SeenBuff.Get_Height(), - NULL, - SeenBuff.Get_Width() * SeenBuff.Get_Height()); - char filename[30]; - - SeenBuff.Blit(temp_page); - for (int lp = 0; lp < 99; lp ++) { - if (lp < 10) { - sprintf(filename, "scrsht0%d.pcx", lp); - } else { - sprintf(filename, "scrsht%d.pcx", lp); - } - if (access(filename, F_OK) == -1) - break; - } - - Write_PCX_File(filename, temp_page, (unsigned char *)CurrentPalette); - //Map.Place_Random_Crate(); - } -#endif - break; - - case KN_P: - Keyboard::Clear(); - while (!Keyboard::Check()) { - Self_Regulate(); - Sound_Callback(); - } - Keyboard::Clear(); - break; - - case KN_O: - { - AircraftClass * air = new AircraftClass(AIRCRAFT_ORCA, PlayerPtr->Class->House); - if (air) { - air->Altitude = 0; - air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N); - } - } - break; - - case (int)KN_B|(int)KN_ALT_BIT: - { - Debug_Instant_Build ^= 1; - } - break; - case KN_B: - { - AircraftClass * air = new AircraftClass(AIRCRAFT_HELICOPTER, PlayerPtr->Class->House); - if (air) { - air->Altitude = 0; - air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N); - } - } - break; - - case KN_T: - { - AircraftClass * air = new AircraftClass(AIRCRAFT_TRANSPORT, PlayerPtr->Class->House); - if (air) { - air->Altitude = 0; - air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N); - } - } - break; - - case KN_GRAVE: - new AnimClass(ANIM_ART_EXP1, Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y())); - Explosion_Damage(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), 250, NULL, WARHEAD_HE); - break; - - case KN_Z: -// new AnimClass(ANIM_LZ_SMOKE, Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y())); - GDI_Ending(); - break; - - case KN_C: - Debug_Cheat = (Debug_Cheat == false); - PlayerPtr->IsRecalcNeeded = true; - PlayerPtr->Add_Nuke_Piece(); - PlayerPtr->Add_Nuke_Piece(); - PlayerPtr->Add_Nuke_Piece(); - - /* - ** This placement might affect any prerequisite requirements for construction - ** lists. Update the buildable options accordingly. - */ - if (!ScenarioInit) { - Map.Recalc(); - for (int index = 0; index < Buildings.Count(); index++) { - Buildings.Ptr(index)->Update_Buildables(); - } - } - break; - - case (int)KN_Z|(int)KN_ALT_BIT: - if (map_x == -1) { - map_x = Map.MapCellX; - map_y = Map.MapCellY; - map_width = Map.MapCellWidth; - map_height = Map.MapCellHeight; - Map.MapCellX = 1; - Map.MapCellY = 1; - Map.MapCellWidth = 62; - Map.MapCellHeight = 62; - } else { - Map.MapCellX = map_x; - Map.MapCellY = map_y; - Map.MapCellWidth = map_width; - Map.MapCellHeight = map_height; - map_x = -1; - map_y = -1; - map_width = -1; - map_height = -1; - } - break; - -#ifdef NEVER - case KN_G: - HouseClass::As_Pointer(HOUSE_GOOD)->Flag_Attach(Map.Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y())); - break; - - case KN_N: - HouseClass::As_Pointer(HOUSE_BAD)->Flag_Attach(Map.Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y())); - break; -#endif - - case KN_R: - if (CurrentObject.Count()) { - ((TechnoClass *)CurrentObject[0])->IsCloakable = true; - } - break; - - case KN_M: - if (Debug_Flag) { - if (MonoClass::Is_Enabled()) { - MonoClass::Disable(); - } else { - MonoClass::Enable(); - } - } - break; - - case (int)KN_W|(int)KN_ALT_BIT: - PlayerPtr->Flag_To_Win(); - break; - - case (int)KN_L|(int)KN_ALT_BIT: - PlayerPtr->Flag_To_Lose(); - break; - - case KN_F: - Debug_Find_Path ^= 1; - break; - - case KN_DELETE: - if (CurrentObject.Count()) { - Map.Recalc(); - //CurrentObject[0]->Detach_All(); - delete CurrentObject[0]; - } - break; - - case KN_D: - if (Teams.Ptr(0)) { - delete Teams.Ptr(0); - } - break; - - case (int)KN_DELETE|(int)KN_SHIFT_BIT: - if (CurrentObject.Count()) { - Map.Recalc(); - int damage = 50; - CurrentObject[0]->Take_Damage(damage, 0, WARHEAD_SA); - } - break; - - case KN_INSERT: - if (CurrentObject.Count()) { - Map.PendingObject = &CurrentObject[0]->Class_Of(); - if (Map.PendingObject) { - Map.PendingHouse = CurrentObject[0]->Owner(); - Map.PendingObjectPtr = Map.PendingObject->Create_One_Of(HouseClass::As_Pointer(Map.PendingHouse)); - if (Map.PendingObjectPtr) { - Map.Set_Cursor_Pos(); - Map.Set_Cursor_Shape(Map.PendingObject->Occupy_List()); - } - } - } - break; - -#ifdef NEVER - case KN_1: - case KN_2: - case KN_3: - case KN_4: - case KN_5: - case KN_6: - case KN_7: - case KN_8: - case KN_9: - case KN_0: - MonoPage = (input & 0xFF) - KN_1; - MonoPage %= sizeof(MonoArray)/sizeof(MonoArray[0]); - MonoArray[MonoPage].View(); - input = 0; - break; -#endif - -#ifdef NEVER - case ((int)KN_F1 | (int)KN_SHIFT_BIT): - Special.IsBarOn = (Special.IsBarOn == false); - Map.Flag_To_Redraw(true); - break; - - case ((int)KN_F1 | (int)KN_SHIFT_BIT): // quick load/save for debugging - if (!Save_Game(0,"Command & Conquer Save Game File")) { - CCMessageBox().Process("Error saving game!"); - Prog_End(); - exit(EXIT_SUCCESS); - } - break; - - case ((int)KN_F2 | (int)KN_SHIFT_BIT): // quick load/save for debugging - if (!Load_Game(0)) { - CCMessageBox().Process("Error loading game!"); - Prog_End(); - exit(EXIT_SUCCESS); - } - break; - -//#ifdef SCENARIO_EDITOR - case KN_F2: // enable/disable the map editor - Go_Editor(!Debug_Map); - break; -//#endif -#endif - -#ifdef NEVER - case KN_F2: { - Debug_Map++; - Scenario_Editor(); - Debug_Map--; -#ifdef NEVER - COORDINATE coord; - int index; - static COORDINATE _coords[] = { - 0x00010001L, - 0x00800080L, - 0x00810081L, - 0x00010081L, - 0x00810001L, - 0x00800081L, - 0x00800001L, - 0x00010080L, - 0x00810080L, - 0L - }; - index = 0; - while (_coords[index]) { - coord = _coords[index++]; - Mono_Printf("Spillage for %08lX = %d.\r", coord, Coord_Spillage_Number(coord)); - } - Keyboard::Clear(); - Keyboard::Get(); - -#endif - -#ifdef NEVER -#define MAX_RADIUS 10 - COORDINATE coord; - int x,y; - COORDINATE const *ptr; - int input; - int f1,f2; - TurnTrackType const *track; - - #define XCENTER 160 - #define YCENTER 100 - for (;;) { - VisiblePage.Clear(); - - // Draw grid. - { - static int _gridx[] = {0,64,128,192,0,64,128,192,0,64,128,192}; - static int _gridy[] = {0,0,0,0,64,64,64,64,128,128,128,128}; - int index; - - for (index = 0; index < 12; index++) { - LogicPage->Put_Pixel((_gridx[index]+XCENTER)-(32+64),(_gridy[index]+YCENTER)-(32+64), DKGRAY); - } - } - - // Get facing #1. - LogicPage->Print("Facing #1 (0-7)?", 0, 0, WHITE, BLACK); - input = Keyboard::Get(); - if (input == KA_ESC) break; - input -= KA_0; - input = Bound(input, 0, 7); -// input = MAX(input, 0); -// input = MIN(input, 7); - f1 = input; - Int_Print(f1, 100, 0, WHITE, BLACK); - - // Get facing #2. - LogicPage->Print("Facing #2 (0-7)?", 0, 10, WHITE, BLACK); - input = Keyboard::Get(); - if (input == KA_ESC) break; - input -= KA_0; - input = Bound(input, 0, 7); -// input = MAX(input, 0); -// input = MIN(input, 7); - f2 = input; - Int_Print(f2, 100, 10, WHITE, BLACK); - - track = &TrackControl[f1][f2]; - if (track->Track == 0) { - LogicPage->Print("Undefined track.", 0, 30, WHITE, BLACK); - } else { - int index; // Track index counter. - - ptr = TrackPointers[track->Track-1]; - index = 0; - while (ptr[index]) { - coord = Smooth_Turn(NULL, ptr[index], track->Flag); - - x = (int)(coord & 0xFFFF); - y = (int)((coord >> 16) & 0xFFFF); - LogicPage->Put_Pixel(XCENTER + (x>>2), YCENTER + (y>>2), WHITE); - Delay(1); - index++; - } - - } - input = Keyboard::Get(); - if (input == KA_ESC) break; - } - - Map.Flag_To_Redraw(true); -#endif -#ifdef NEVER - FILE *fh; - int index; - COORDINATE coord; - - fh = fopen("diagonal.txt", "wt"); - if (fh) { - - fprintf(fh, "track 2\n"); - coord = 0x0100FF00L; - for (index = 0; index <= 48; index++) { - fprintf(fh, "0x%08lXL\n", coord); - coord = Coord_Move(coord, 32, 11); - } - fprintf(fh, "\n\n"); - - fprintf(fh, "track 1\n"); - coord = 0x01000000L; - for (index = 0; index <= 40; index++) { - fprintf(fh, "0x%08lXL\n", coord); - coord = Coord_Move(coord, 0, 11); - } - fprintf(fh, "\n\n"); - - fclose(fh); - } -#endif -#ifdef NEVER - FILE *fh; - int x,y,radius; - int radsize[MAX_RADIUS+2]; - int count; - - memset(radsize, 0, sizeof(radsize)); - fh = fopen("Range.txt", "wt"); - if (fh) { - fprintf(fh, "int const RadiusOffset[] = {\n"); - - for (radius = 0; radius <= MAX_RADIUS; radius++) { - - fprintf(fh, "\t/* %-2d */\t", radius); - for (y = -MAX_RADIUS; y <= MAX_RADIUS; y++) { - for (x = -MAX_RADIUS; x <= MAX_RADIUS; x++) { - int xd,yd,dist; - - xd = ABS(x); - yd = ABS(y); - if (xd > yd) { - dist = yd/2 + xd; - } else { - dist = xd/2 + yd; - } - if (dist == radius) { - dist = y*MAP_CELL_W + x; - - if (y) { - if (y < 0) { - fprintf(fh, "(-MCW*%d)", ABS(y)); - } else { - fprintf(fh, "(MCW*%d)", ABS(y)); - } - fprintf(fh, "%c%d,", (x<0) ? '-' : '+', ABS(x)); - } else { - fprintf(fh, "%d,", x); - } - radsize[radius]++; - } - } - } - fprintf(fh, "\n"); - } - fprintf(fh, "};\n\n"); - - count = 0; - fprintf(fh, "int const RadiusCount[%d] = {", MAX_RADIUS+1); - for (radius = 0; radius <= MAX_RADIUS; radius++) { - count += radsize[radius]; - fprintf(fh, "%d", count); - if (radius != MAX_RADIUS) { - fprintf(fh, ","); - } - } - fprintf(fh, "};\n"); - fclose(fh); - } -#endif - } - break; -#endif - -#ifdef NEVER - case ((int)KN_F3 | (int)KN_ALT_BIT): // quick load/save for debugging - Debug_Threat = (Debug_Threat == false); - Map.Flag_To_Redraw(true); - break; - -#endif - - case KN_F3: - Debug_Icon = (Debug_Icon == false); - Map.Flag_To_Redraw(true); - break; - - - /* - ** Reveal entire map to player. - */ - case KN_F4: - if (GameToPlay == GAME_NORMAL) { - Debug_Unshroud = (Debug_Unshroud == false); - Map.Flag_To_Redraw(true); - } - break; - - /* - ** Shows sight and fire range in the form of circles emanating from the currently - ** selected unit. The white circle is for sight range, the red circle is for - ** fire range. - */ - case KN_F7: - if (CurrentObject.Count() && CurrentObject[0]->Is_Techno()) { - TechnoTypeClass const & ttype = (TechnoTypeClass const &)CurrentObject[0]->Class_Of(); - int sight = ((int)ttype.SightRange)<<8; - int weapon = 0; - if (ttype.Primary != WEAPON_NONE) weapon = Weapons[ttype.Primary].Range; - Set_Logic_Page(SeenBuff); - COORDINATE center = CurrentObject[0]->Center_Coord(); - COORDINATE center2 = CurrentObject[0]->Fire_Coord(0); - - for (int r = 0; r < 255; r += 10) { - int x,y,x1,y1; - DirType r1 = (DirType)r; - DirType r2 = (DirType)((r+10) & 0xFF); - - if (Map.Coord_To_Pixel(Coord_Move(center, r1, sight), x, y)) { - Map.Coord_To_Pixel(Coord_Move(center, r2, sight), x1, y1); - LogicPage->Draw_Line(x, y+8, x1, y1+8, WHITE); - } - if (Map.Coord_To_Pixel(Coord_Move(center2, r1, weapon), x, y)) { - Map.Coord_To_Pixel(Coord_Move(center2, r2, weapon), x1, y1); - LogicPage->Draw_Line(x, y+8, x1, y1+8, RED); - } - } - } - break; - - case ((int)KN_F4 | (int)KN_CTRL_BIT): - Debug_Unshroud = (Debug_Unshroud == false); - Map.Flag_To_Redraw(true); - break; - -#ifdef NEVER - case KN_F5: - Special.IsShowPath = (Special.IsShowPath == false); - //PlayerPtr->Credits += 1000; - break; - - case KN_F6: - if (Map.In_Radar(XY_Cell(Map.MapCellX+5, Map.MapCellY - 1))) { - Mono_Printf("Arrrggggghhhhh!"); - } else { - Mono_Printf("No Arrrggggghhhhh!"); - } - break; - - case ((int)KN_F9 | (int)KN_CTRL_BIT): - if (HouseClass::As_Pointer(HOUSE_GOOD)) - (HouseClass::As_Pointer(HOUSE_GOOD))->Blowup_All(); - break; - - case ((int)KN_F10 | (int)KN_CTRL_BIT): - if (HouseClass::As_Pointer(HOUSE_BAD)) - (HouseClass::As_Pointer(HOUSE_BAD))->Blowup_All(); - break; -#endif - } - - } -} - - -/*********************************************************************************************** - * Self_Regulate -- Regulates the logic timer to result in smooth animation * - * * - * The self regulation process checks the number of frames displayed * - * per second and from this determines the amount of time to devote * - * to internal logic processing. By adjusting the time allotted to * - * internal processing, smooth animation can be maintained. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: In order for this routine to work properly it MUST be * - * called every display loop. * - * * - * HISTORY: * - * 07/31/1991 JLB : Created. * - * 07/05/1994 JLB : Handles new monochrome system. * - *=============================================================================================*/ -#define UPDATE_INTERVAL TIMER_SECOND -void Self_Regulate(void) -{ - static CountDownTimerClass DebugTimer(BT_SYSTEM); - static ObjectClass * _lastobject = 0; - - if (!DebugTimer.Time()) { - DebugTimer.Set(UPDATE_INTERVAL); - - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - mono->Set_Default_Attribute(2); - - switch (MonoPage) { - case 0: - mono = &MonoArray[0]; - mono->Clear(); - - /* - ** Display the status of the currently selected object. - */ - if (CurrentObject.Count()) { - _lastobject = CurrentObject[0]; - } - if (_lastobject && !_lastobject->IsActive) { - _lastobject = 0; - } - if (_lastobject) { - _lastobject->Debug_Dump(mono); - } - Logic.Debug_Dump(mono); - mono->Set_Cursor(0, 20); - mono->Printf( - "Heap size:%10ld \r" - "Largest: %10ld \r" - "Ttl Free: %10ld \r" - "Frag: %10ld \r", - Heap_Size(MEM_NORMAL), - Ram_Free(MEM_NORMAL), - Total_Ram_Free(MEM_NORMAL), - Total_Ram_Free(MEM_NORMAL)-Ram_Free(MEM_NORMAL) - ); - *MonoClass::Get_Current() = *mono; - break; - } - - MonoArray[MonoPage] = *mono; - } - } -} -#endif diff --git a/code/TIBERIANDAWN/DEBUG.H b/code/TIBERIANDAWN/DEBUG.H deleted file mode 100644 index 57ad063..0000000 --- a/code/TIBERIANDAWN/DEBUG.H +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -#define TXT_NONE_DEBUG 0x3e8 // -#define TXTED_BLANK 0x3e9 // ____ -#define TXTED_UNABLETOREAD 0x3ea // Unable to read scenario! -#define TXTED_FILEEXISTS 0x3eb // File exists. Replace? -#define TXTED_LOWMEM 0x3ec // Insufficient memory! -#define TXTED_EXIT 0x3ed // Exit Scenario Editor? -#define TXT_GENERIC_EXCEPTION 0x3ee // ERROR: Exception was -#define TXT_RADIO_1 0x3ef // hisssss -#define TXT_RADIO_2 0x3f0 // Roger. -#define TXT_RADIO_3 0x3f1 // Come in. -#define TXT_RADIO_4 0x3f2 // Over and out. -#define TXT_RADIO_5 0x3f3 // Requesting transport. -#define TXT_RADIO_6 0x3f4 // I've got a delivery for -#define TXT_RADIO_7 0x3f5 // I'm performing load/unload -#define TXT_RADIO_8 0x3f6 // I'm clear. -#define TXT_RADIO_9 0x3f7 // You are clear to unload. -#define TXT_RADIO_10 0x3f8 // Am unable to comply. -#define TXT_RADIO_11 0x3f9 // I'm starting construction -#define TXT_RADIO_12 0x3fa // I've finished construction. -#define TXT_RADIO_13 0x3fb // Oops, sorry. I might have -#define TXT_RADIO_14 0x3fc // I'm full. May I unload at -#define TXT_RADIO_15 0x3fd // Are you a refinery and are -#define TXT_RADIO_16 0x3fe // Take this kick! You... -#define TXT_RADIO_17 0x3ff // Take this punch! You... diff --git a/code/TIBERIANDAWN/DEFINES.H b/code/TIBERIANDAWN/DEFINES.H deleted file mode 100644 index a5c3179..0000000 --- a/code/TIBERIANDAWN/DEFINES.H +++ /dev/null @@ -1,2965 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\defines.h_v 2.19 16 Oct 1995 16:44:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DEFINES.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : September 10, 1993 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DEFINES_H -#define DEFINES_H - - -//#define PETROGLYPH_EXAMPLE_MOD - -/********************************************************************** -** If defined, then the advanced balancing features will be enabled -** for this version. -*/ -//#define ADVANCED -#define PATCH // Super patch (1.17?) - - -/********************************************************************** -** The demo version of C&C will be built if the following define -** is active. -*/ -//#define DEMO - - -/* -** Use AI pulled in from Red Alert. ST - 7/26/2019 11:42AM -*/ -#define USE_RA_AI - - -/********************************************************************** -** Define this to allow play of the bonus missions for the Gateway -** bundle deal. -*/ -#define BONUS_MISSIONS - - -/********************************************************************** -** Handle expansion scnearios as a set of single missions with all -** necessary information self contained within the mission file. -*/ -#ifndef DEMO -#define NEWMENU -#endif - - -/********************************************************************** -** If the scenario editor to to be active in this build then uncomment -** the following #define line. -*/ -//#define SCENARIO_EDITOR - - -/********************************************************************** -** This define enables the full set of cheat keys and special -** command line options. -*/ -#define CHEAT_KEYS - - -/********************************************************************** -** If this is defined, the special Virgin limited cheat keys -** are enabled. This allows the "cheat" parameter and then only -** allows the ALT-W to win the mission. -*/ -//#define VIRGIN_CHEAT_KEYS - - -/********************************************************************** -** Optional parameter control for special options. -*/ -//#define PARM_6PLAYER 0x5D9F6F24 // "6" -#define PARM_6PLAYER 0x9CAFC93B // Alternate 6 player keyphrase. - -/* -** Enable the set of limited cheat key options. -*/ -#ifdef VIRGIN_CHEAT_KEYS -#define PARM_PLAYTEST 0xF7DDC227 // "PLAYTEST" -#endif - -/* -** Enable the full set of cheat key options. -*/ -#ifdef CHEAT_KEYS -#ifndef PARM_PLAYTEST -#define PARM_PLAYTEST 0xF7DDC227 // "PLAYTEST" -#endif -#define PARM_CHEATDAVID 0xBE79088C // Cheat keys for David Dettmer -#define PARM_CHEATERIK 0x9F38A19D // Cheat keys for Erik Yeo -#define PARM_EDITORERIK 0xC2AA509B // Map editor for Erik Yeo -#define PARM_CHEATPHIL 0x39D01821 // Cheat keys for Phil Gorrow -#define PARM_CHEATJOE 0xABDD0362 // Cheat keys for Joe Bostic -#define PARM_CHEATBILL 0xB5B63531 // Cheat keys for Bill Randolph -#define PARM_CHEAT_STEVET 0x2E7FE493 // Cheat keys for Steve Tall -#define PARM_EDITORBILL 0x7E7C4CCA // "-EDITOR" -#define PARM_CHEATMIKE 0x00532693 // Mike Lightner -#define PARM_CHEATADAM 0xDFABC23A // Adam Isgreen -#endif - -//#define PARM_CHEAT 0x6F4BE7CA // "CHEAT" -//#define PARM_EDITOR 0x7E7C4CCA // "-EDITOR" - -#define PARM_EASY 0x59E975CE // "EASY" Enables easy mode. -#define PARM_HARD 0xACFE9D13 // "HARD" Enables hard mode. - -#define PARM_INSTALL 0xD95C68A2 // "FROMINSTALL" -#define PARM_TRUENAME 0xB1A34435 // Enables true object names. -#define PARM_3POINT 0x03552894 // Enable three point turns. -#define PARM_SCORE 0x7FDE2C33 // Enables alternate themes. -#define PARM_COMBAT 0xDC57C4B2 // Gives combat advantage to attacker. -#define PARM_TREETARGET 0x00AB6BEF // Allows targeting of trees without key. -#define PARM_BIB 0xF7867BF0 // Disables building bibs. -#define PARM_MCV 0x104DF10F // MCV undeploys rather than sells. -#define PARM_HELIPAD 0x53EBECBC // Helipad can be purchased separately from helicopter. -#define PARM_IQ 0x9E3881B8 // Smart self defense logic enable. -#define PARM_SQUISH 0x4EA2FBDF // Squish images for infantry bodies. -#define PARM_HUMAN 0xACB58F61 // Human generated sound effects. -#define PARM_SCROLLING 0xC084AE82 // Restricts scrolling over the tabs. -//#define PARM_SPECIAL 0xD18129F6 // Enables special mode. -//#define PARM_SPECIAL 0x2E84E394 // #1 -//#define PARM_SPECIAL 0x63CE7584 // #2 -//#define PARM_SPECIAL 0x85F110A5 // #3 -///#define PARM_SPECIAL 0x7F65F13C // #4 -//#define PARM_SPECIAL 0x431F5F61 // #5 -#define PARM_SPECIAL 0x11CA05BB // #6 funpark -//#define PARM_SPECIAL 0xE0F651B9 // #7 -//#define PARM_SPECIAL 0x10B9683D // #8 -//#define PARM_SPECIAL 0xEE1CD37D // #9 - - -/********************************************************************** -** Defines for verifying free disk space -*/ -#define INIT_FREE_DISK_SPACE 1024*4096 //8388608 -#define SAVE_GAME_DISK_SPACE INIT_FREE_DISK_SPACE // (INIT_FREE_DISK_SPACE - (1024*4096)) -//#define SAVE_GAME_DISK_SPACE 100000 - - -/********************************************************************** -** This is the credit threshold that the computer's money must exceed -** in order for structure repair to commence. -*/ -#define REPAIR_THRESHHOLD 1000 - - -//#define GERMAN 1 -//#define FRENCH 1 -//#define JAPANESE 1 - -#define FOREIGN_VERSION_NUMBER 6 - -// -// typedef enums with -1 will show this warning, even when the type of the enum is signed. It's a compiler bug, apparently -// ST - 1/8/2019 9:23AM -// -#pragma warning (push) -#pragma warning (disable:4341) - -/********************************************************************** -** These enumerations are used to implement RTTI. -*/ -typedef enum RTTIType : unsigned char { - RTTI_NONE=0, - RTTI_INFANTRY, - RTTI_INFANTRYTYPE, - RTTI_UNIT, - RTTI_UNITTYPE, - RTTI_AIRCRAFT, - RTTI_AIRCRAFTTYPE, - RTTI_BUILDING, - RTTI_BUILDINGTYPE, - - RTTI_TERRAIN, - RTTI_ABSTRACTTYPE, - RTTI_ANIM, - RTTI_ANIMTYPE, - RTTI_BULLET, - RTTI_BULLETTYPE, - RTTI_OVERLAY, - RTTI_OVERLAYTYPE, - RTTI_SMUDGE, - RTTI_SMUDGETYPE, - RTTI_TEAM, - RTTI_TEMPLATE, - RTTI_TEMPLATETYPE, - RTTI_TERRAINTYPE, - RTTI_OBJECT, - RTTI_SPECIAL -} RTTIType; - - -/********************************************************************** -** These are the difficulty settings of the game. -*/ -typedef enum DiffType : unsigned char { - DIFF_EASY, - DIFF_NORMAL, - DIFF_HARD, - - DIFF_COUNT, - DIFF_FIRST = 0 -} DiffType; - - -/********************************************************************** -** This is the size of the speech buffer. This value should be as large -** as the largest speech sample, plus a few bytes for overhead -** (16 bytes is sufficient). -*/ -#define SPEECH_BUFFER_SIZE 50000L - - -/********************************************************************** -** This is the size of the shape buffer. This buffer is used as a staging -** buffer for the shape drawing technology. It MUST be as big as the -** largest shape (uncompressed) that will be drawn. If this value is -** changed, be sure to update the makefile and rebuild all of the shape -** data files. -*/ -#define SHAPE_BUFFER_SIZE 131072L - -// Use this to allow keep track of versions as they affect saved games. -#define VERSION_NUMBER 1 -#define RELEASE_NUMBER 01 - -#define FAME_FILE_NAME "HALLFAME.DAT" - - -/********************************************************************** -** Map controls. The map is composed of square elements called 'cells'. -** All larger elements are build upon these. -*/ - -// Size of the map in cells. The width of the map must be a power -// of two. This is accomplished by setting the width by the number of -// bits it occupies. The number of meta-cells will be a subset of the -// cell width. -#define MAP_CELL_MAX_X_BITS 6 -#define MAP_CELL_MAX_Y_BITS 6 -#define MAP_CELL_X_MASK (~(~0 << MAP_CELL_MAX_X_BITS)) -//#define MAP_CELL_Y_MASK ((~(~0 << MAP_CELL_MAX_Y_BITS)) << MAP_CELL_MAX_Y_BITS) - -// Size of the map in cells. -#define MAP_CELL_W (1<(static_cast(a) | static_cast(b));} - -inline ThreatType operator&(ThreatType a, ThreatType b) -{return static_cast(static_cast(a) & static_cast(b));} - -inline ThreatType operator~(ThreatType a) -{return static_cast(~static_cast(a));} - - -#define THREAT_GROUND (THREAT_VEHICLES|THREAT_BUILDINGS|THREAT_INFANTRY) - - -/********************************************************************** -** These return values are used when determine if firing is legal. -** By examining this value it can be determined what should be done -** to fix the reason why firing wasn't allowed. -*/ -typedef enum FireErrorType : unsigned char { - FIRE_OK, // Weapon is allowed to fire. - FIRE_AMMO, // No ammo available to fire? - FIRE_FACING, // Not correctly facing target? - FIRE_REARM, // It is busy rearming? - FIRE_ROTATING, // Is it in process of rotating? - FIRE_ILLEGAL, // Is it targeting something illegal? - FIRE_CANT, // Is this unit one that cannot fire anything? - FIRE_MOVING, // Is it moving and not allowed to fire while moving? - FIRE_RANGE, // Is the target out of range? - FIRE_CLOAKED, // Is the shooter currently cloaked? - FIRE_BUSY // Is shooter currently doing something else? -} FireErrorType; - - -/********************************************************************** -** If an object can cloak, then it will be in one of these states. -** For objects that cannot cloak, they will always be in the -** UNCLOAKED state. This state controls how the obect transitions between -** cloaked and uncloaked conditions. -*/ -typedef enum CloakType : unsigned char { - UNCLOAKED, // Completely visible (normal state). - CLOAKING, // In process of claoking. - CLOAKED, // Completely cloaked (invisible). - UNCLOAKING // In process of uncloaking. -} CloakType; - - -/********************************************************************** -** For units that are cloaking, these value specify the visual character -** of the object. -*/ -typedef enum VisualType : unsigned char { - VISUAL_NORMAL, // Completely visible -- normal. - VISUAL_INDISTINCT, // The edges shimmer and become indistinct. - VISUAL_DARKEN, // Color and texture is muted along with shimmering. - VISUAL_SHADOWY, // Body is translucent in addition to shimmering. - VISUAL_RIPPLE, // Just a ripple (true predator effect). - VISUAL_HIDDEN, // Nothing at all is visible. -} VisualType; - - -/********************************************************************** -** These missions enumerate the various state machines that can apply to -** a game object. Only one of these state machines is active at any one -** time. -*/ -typedef enum MissionType : char { - MISSION_NONE=-1, - - MISSION_SLEEP, // Do nothing whatsoever. - MISSION_ATTACK, // Attack nearest enemy. - MISSION_MOVE, // Guard location or unit. - MISSION_RETREAT, // Return home for R & R. - MISSION_GUARD, // Stay still. - MISSION_STICKY, // Stay still -- never recruit. - MISSION_ENTER, // Move into object cooperatively. - MISSION_CAPTURE, // Move into in order to capture. - MISSION_HARVEST, // Hunt for and collect nearby Tiberium. - MISSION_GUARD_AREA, // Active guard of area. - MISSION_RETURN, // Head back to refinery. - MISSION_STOP, // Sit still. - MISSION_AMBUSH, // Wait until discovered. - MISSION_HUNT, // Active search and destroy. - MISSION_TIMED_HUNT, // Wait a while, then go into HUNT (multiplayer AI) - MISSION_UNLOAD, // Search for and deliver cargo. - MISSION_SABOTAGE, // Move into in order to destroy. - MISSION_CONSTRUCTION, // Building buildup operation. - MISSION_DECONSTRUCTION, // Building builddown operation. - MISSION_REPAIR, // Repair process mission. - MISSION_RESCUE, - MISSION_MISSILE, - - MISSION_COUNT, - MISSION_FIRST=0 -} MissionType; - - -/********************************************************************** -** These are the enumerated animation sequences that a building may -** be processing. These serve to control the way that a building -** appears. -*/ -typedef enum BStateType : char { - BSTATE_NONE=-1, - BSTATE_CONSTRUCTION, // Construction animation. - BSTATE_IDLE, // Idle animation. - BSTATE_ACTIVE, // Animation when building is "doing its thing". - BSTATE_FULL, // Special alternate active state. - BSTATE_AUX1, // Auxiliary animation. - BSTATE_AUX2, // Auxiliary animation. - - BSTATE_COUNT -} BStateType; - - -/********************************************************************** -** Whenever a unit is selected and a click occurs over another object -** or terrain element, there is some action to initiate. This specifies -** the different types of actions possible. This also controls how the -** mouse cursor looks when "hovering" over the spot that clicking would -** occur at. -*/ -typedef enum ActionType : unsigned char { - ACTION_NONE, // Either undefined action or "do nothing". - ACTION_MOVE, // Can move there or at least try to. - ACTION_NOMOVE, // Special case for movable object, but illegal mouse position. - ACTION_ENTER, // Special case for infantry->APC or vehicle->Repair facility. - ACTION_SELF, // Self select special case. - ACTION_ATTACK, // Can attack or fire upon it in some fashion. - ACTION_HARVEST, // Special harvest mode. - ACTION_SELECT, // Would change selection to specified object. - ACTION_TOGGLE_SELECT,// Toggles select state of the object. - ACTION_CAPTURE, // The unit will try to capture the object. - ACTION_REPAIR, // The target object should be repaired. - ACTION_SELL, // The target building should be sold back. - ACTION_SELL_UNIT, // The target unit should be sold back. - ACTION_NO_SELL, // No sell or no repair. - ACTION_NO_REPAIR, // No sell or no repair. - ACTION_SABOTAGE, // The unit will try to sabotage/destroy the object. - ACTION_ION, // That target object should be blasted. - ACTION_NUKE_BOMB, // That target object should be blasted. - ACTION_AIR_STRIKE, // That target object should be blasted. - ACTION_GUARD_AREA, // Guard the area/object clicked on. - ACTION_TOGGLE_PRIMARY, // Toggle the primary status of the factory. - ACTION_NO_DEPLOY, - - ACTION_COUNT -} ActionType; - - -/********************************************************************** -** When a unit gets damaged, the result of the damage is returned as -** this type. It can range from no damage taken to complete destruction. -*/ -typedef enum ResultType : unsigned char { - RESULT_NONE, // No damage was taken by the target. - RESULT_LIGHT, // Some damage was taken, but no state change occurred. - RESULT_HALF, // Damaged to below half strength (only returned on transition). - RESULT_MAJOR, // Damaged down to 1 hit point. - RESULT_DESTROYED, // Damaged to complete destruction. -} ResultType; - - -/********************************************************************** -** These are the special concrete control defines. They enumerate the -** sequence order of the concrete icons in the concrete art file. -*/ -// DEBUG === convert this to be zero based so that a nulled cell is the -// default cell. -enum ConcreteEnum : char { - C_NONE=-1, - C_LEFT=0, - C_RIGHT=1, - C_RIGHT_UPDOWN=2, - C_LEFT_UPDOWN=3, - C_UP_RIGHT=4, - C_UP_LEFT=5, - C_DOWN_RIGHT=6, - C_DOWN_LEFT=7, - C_RIGHT_DOWN=8, - C_LEFT_DOWN=9, - C_RIGHT_UP=10, - C_LEFT_UP=11, - C_UPDOWN_RIGHT=12, - C_UPDOWN_LEFT=13 -}; - - -/********************************************************************** -** Units that move can move at different speeds. These enumerate the -** different speeds that a unit can move. -*/ -typedef enum MPHType: unsigned char { - MPH_IMMOBILE=0, - MPH_VERY_SLOW=5, - MPH_KINDA_SLOW=6, - MPH_SLOW=8, - MPH_SLOW_ISH=10, - MPH_MEDIUM_SLOW=12, - MPH_MEDIUM=18, - MPH_MEDIUM_FAST=30, - MPH_MEDIUM_FASTER=35, - MPH_FAST=40, - MPH_ROCKET=60, - MPH_VERY_FAST=100, - MPH_LIGHT_SPEED=255 -} MPHType; - - -/********************************************************************** -** General audio volume is enumerated by these identifiers. Since small -** volume variations are usually unnoticable when specifying the volume -** to play a sample, this enumeration list creates more readable code. -*/ -typedef enum VolType : unsigned char -{ - VOL_OFF=0, - VOL_0=VOL_OFF, - VOL_1=0x19, - VOL_2=0x32, - VOL_3=0x4C, - VOL_4=0x66, - VOL_5=0x80, - VOL_6=0x9A, - VOL_7=0xB4, - VOL_8=0xCC, - VOL_9=0xE6, - VOL_10=0xFF, - VOL_FULL=VOL_10 -} VolType; - - -/********************************************************************** -** The houses that can be played are listed here. Each has their own -** personality and strengths. -*/ -typedef enum HousesType : char { - HOUSE_NONE=-1, - HOUSE_GOOD, // Global Defense Initiative - HOUSE_BAD, // Brotherhood of Nod - HOUSE_NEUTRAL, // Civilians - HOUSE_JP, // Disaster Containment Team - HOUSE_MULTI1, // Multi-Player house #1 - HOUSE_MULTI2, // Multi-Player house #2 - HOUSE_MULTI3, // Multi-Player house #3 - HOUSE_MULTI4, // Multi-Player house #4 - HOUSE_MULTI5, // Multi-Player house #5 - HOUSE_MULTI6, // Multi-Player house #6 - - HOUSE_COUNT, - HOUSE_FIRST=HOUSE_GOOD -} HousesType; - -//inline HousesType operator++(HousesType &, int); - -#define HOUSEF_GOOD (1< 2 players. -*/ -typedef enum ScenarioPlayerEnum : char -{ - SCEN_PLAYER_NONE = -1, - SCEN_PLAYER_GDI, - SCEN_PLAYER_NOD, - SCEN_PLAYER_JP, - SCEN_PLAYER_2PLAYER, - SCEN_PLAYER_MPLAYER, - SCEN_PLAYER_COUNT, - SCEN_PLAYER_FIRST = 0, -} ScenarioPlayerType; - -//inline ScenarioPlayerType operator++(ScenarioPlayerType &, int); - - -/********************************************************************** -** These are the directional parameters for a scenario. -*/ -typedef enum ScenarioDirEnum : char -{ - SCEN_DIR_NONE = -1, - SCEN_DIR_EAST, - SCEN_DIR_WEST, - SCEN_DIR_COUNT, - SCEN_DIR_FIRST = 0, -} ScenarioDirType; - -//inline ScenarioDirType operator++(ScenarioDirType &, int); - - -/********************************************************************** -** These are the random variations of a scenario. -*/ -typedef enum ScenarioVarEnum : char -{ - SCEN_VAR_NONE = -1, - SCEN_VAR_A, - SCEN_VAR_B, - SCEN_VAR_C, - SCEN_VAR_D, - SCEN_VAR_COUNT, // comes before the Lose value! - SCEN_VAR_LOSE, - SCEN_VAR_FIRST = 0, -} ScenarioVarType; - -//inline ScenarioVarType operator++(ScenarioVarType &, int); - - -/********************************************************************** -** The objects to be drawn on the map are grouped into layers. These -** enumerated values specify those layers. The ground layer is sorted -** from back to front. -*/ -typedef enum LayerType : char { - LAYER_NONE=-1, - LAYER_GROUND, // Touching the ground type object (units & buildings). - LAYER_AIR, // Flying above the ground (explosions & flames). - LAYER_TOP, // Topmost layer (aircraft & bullets). - - LAYER_COUNT, - LAYER_FIRST=0 -} LayerType; - -//inline LayerType operator++(LayerType &, int); - - -/********************************************************************** -** This enumerates the various bullet types. These types specify bullet's -** visual and explosive characteristics. -*/ -typedef enum BulletType : char { - BULLET_NONE=-1, - BULLET_SNIPER, // Sniper bullet. - BULLET_BULLET, // Small arms - BULLET_APDS, // Armor piercing projectile. - BULLET_HE, // High explosive shell. - BULLET_SSM, // Surface to surface small missile type. - BULLET_SSM2, // MLRS missile. - BULLET_SAM, // Fast homing anti-aircraft missile. - BULLET_TOW, // TOW anti-vehicle short range missile. - BULLET_FLAME, // Flame thrower flame. - BULLET_CHEMSPRAY, // Chemical weapon spray. - BULLET_NAPALM, // Napalm bomblet. - BULLET_GRENADE, // Hand tossed grenade. - BULLET_LASER, // Laser beam from obelisk - BULLET_NUKE_UP, // Nuclear Missile on its way down - BULLET_NUKE_DOWN, // Nuclear Missile on its way up - BULLET_HONEST_JOHN, // SSM with napalm warhead. - BULLET_SPREADFIRE, // Chain gun bullets. - BULLET_HEADBUTT, // Stegosaurus, Triceratops head butt - BULLET_TREXBITE, // Tyrannosaurus Rex's bite - especially bad for infantry - -#ifdef PETROGLYPH_EXAMPLE_MOD - BULLET_NUKE_LOB, // Nuke projectile -#endif //PETROGLYPH_EXAMPLE_MOD - - BULLET_COUNT, - BULLET_FIRST=0 -} BulletType; - -//inline BulletType operator++(BulletType &, int); - - -/********************************************************************** -** All game buildings (structures) are enumerated here. This includes -** civilian structures as well. -*/ -typedef enum StructType : char { - STRUCT_NONE=-1, - STRUCT_WEAP, - STRUCT_GTOWER, - STRUCT_ATOWER, - STRUCT_OBELISK, - STRUCT_RADAR, - STRUCT_TURRET, - STRUCT_CONST, - STRUCT_REFINERY, - STRUCT_STORAGE, - STRUCT_HELIPAD, - STRUCT_SAM, - STRUCT_AIRSTRIP, - STRUCT_POWER, - STRUCT_ADVANCED_POWER, - STRUCT_HOSPITAL, - STRUCT_BARRACKS, - STRUCT_TANKER, - STRUCT_REPAIR, - STRUCT_BIO_LAB, - STRUCT_HAND, - STRUCT_TEMPLE, - STRUCT_EYE, - STRUCT_MISSION, - - /* - ** All buildings that are never used as a prerequisite - ** for construction, follow this point. Typically, this is - ** limited to civilian structures. - */ - STRUCT_V01, - STRUCT_V02, - STRUCT_V03, - STRUCT_V04, - STRUCT_V05, - STRUCT_V06, - STRUCT_V07, - STRUCT_V08, - STRUCT_V09, - STRUCT_V10, - STRUCT_V11, - STRUCT_V12, - STRUCT_V13, - STRUCT_V14, - STRUCT_V15, - STRUCT_V16, - STRUCT_V17, - STRUCT_V18, - STRUCT_PUMP, - STRUCT_V20, - STRUCT_V21, - STRUCT_V22, - STRUCT_V23, - STRUCT_V24, - STRUCT_V25, - STRUCT_V26, - STRUCT_V27, - STRUCT_V28, - STRUCT_V29, - STRUCT_V30, - STRUCT_V31, - STRUCT_V32, - STRUCT_V33, - STRUCT_V34, - STRUCT_V35, - STRUCT_V36, - STRUCT_V37, -#ifdef OBSOLETE - STRUCT_ROAD, -#endif - STRUCT_SANDBAG_WALL, - STRUCT_CYCLONE_WALL, - STRUCT_BRICK_WALL, - STRUCT_BARBWIRE_WALL, - STRUCT_WOOD_WALL, - - STRUCT_COUNT, - STRUCT_FIRST=0 -} StructType; - -//inline StructType operator++(StructType &, int); - -#define STRUCTF_NONE 0L -#define STRUCTF_ADVANCED_POWER (1L << STRUCT_ADVANCED_POWER) -#define STRUCTF_REPAIR (1L << STRUCT_REPAIR) -#define STRUCTF_EYE (1L << STRUCT_EYE) -#define STRUCTF_TEMPLE (1L << STRUCT_TEMPLE) -#define STRUCTF_HAND (1L << STRUCT_HAND) -#define STRUCTF_BIO_LAB (1L << STRUCT_BIO_LAB) -#define STRUCTF_OBELISK (1L << STRUCT_OBELISK) -#define STRUCTF_ATOWER (1L << STRUCT_ATOWER) -#define STRUCTF_WEAP (1L << STRUCT_WEAP) -#define STRUCTF_GTOWER (1L << STRUCT_GTOWER) -#define STRUCTF_RADAR (1L << STRUCT_RADAR) -#define STRUCTF_TURRET (1L << STRUCT_TURRET) -#define STRUCTF_CIV1 (1L << STRUCT_CIV1) -#define STRUCTF_CIV2 (1L << STRUCT_CIV2) -#define STRUCTF_CIV3 (1L << STRUCT_CIV3) -#define STRUCTF_CONST (1L << STRUCT_CONST) -#define STRUCTF_REFINERY (1L << STRUCT_REFINERY) -#define STRUCTF_STORAGE (1L << STRUCT_STORAGE) -#define STRUCTF_HELIPAD (1L << STRUCT_HELIPAD) -#define STRUCTF_SAM (1L << STRUCT_SAM) -#define STRUCTF_AIRSTRIP (1L << STRUCT_AIRSTRIP) -#define STRUCTF_POWER (1L << STRUCT_POWER) -#define STRUCTF_HOSPITAL (1L << STRUCT_HOSPITAL) -#define STRUCTF_BARRACKS (1L << STRUCT_BARRACKS) -#define STRUCTF_TANKER (1L << STRUCT_TANKER) -#define STRUCTF_MISSION (1L << STRUCT_MISSION) - - -/********************************************************************** -** The overlays are enumerated here. An overlay functions similarly to -** a transparent icon. It is placed over the terrain but usually falls -** "under" buildings, trees, and units. -*/ -typedef enum OverlayType : char { - OVERLAY_NONE=-1, - OVERLAY_CONCRETE, // Concrete. - OVERLAY_SANDBAG_WALL, // Piled sandbags. - OVERLAY_CYCLONE_WALL, // Chain-link fence. - OVERLAY_BRICK_WALL, // Solid concrete wall. - OVERLAY_BARBWIRE_WALL, // Barbed-wire wall. - OVERLAY_WOOD_WALL, // Wooden fence. - OVERLAY_TIBERIUM1, // Tiberium patch. - OVERLAY_TIBERIUM2, // Tiberium patch. - OVERLAY_TIBERIUM3, // Tiberium patch. - OVERLAY_TIBERIUM4, // Tiberium patch. - OVERLAY_TIBERIUM5, // Tiberium patch. - OVERLAY_TIBERIUM6, // Tiberium patch. - OVERLAY_TIBERIUM7, // Tiberium patch. - OVERLAY_TIBERIUM8, // Tiberium patch. - OVERLAY_TIBERIUM9, // Tiberium patch. - OVERLAY_TIBERIUM10, // Tiberium patch. - OVERLAY_TIBERIUM11, // Tiberium patch. - OVERLAY_TIBERIUM12, // Tiberium patch. - OVERLAY_ROAD, // Road/concrete piece. - OVERLAY_SQUISH, // Squish mark for overran infantry. - OVERLAY_V12, // Haystacks - OVERLAY_V13, // Haystack - OVERLAY_V14, // Wheat field - OVERLAY_V15, // Fallow field - OVERLAY_V16, // Corn field - OVERLAY_V17, // Celery field - OVERLAY_V18, // Potato field - OVERLAY_FLAG_SPOT, // Flag start location. - OVERLAY_WOOD_CRATE, // Wooden goodie crate. - OVERLAY_STEEL_CRATE, // Steel goodie crate. - - OVERLAY_COUNT, - OVERLAY_FIRST=0 -} OverlayType; - -//inline OverlayType operator++(OverlayType &, int); - - -/********************************************************************** -** This specifies the infantry in the game. The "E" designation is -** similar to the army classification of enlisted soldiers. -*/ -typedef enum InfantryType : char { - INFANTRY_NONE=-1, - INFANTRY_E1, // Mini-gun armed. - INFANTRY_E2, // Grenade thrower. - INFANTRY_E3, // Rocket launcher. - INFANTRY_E4, // Flame thrower equipped. - INFANTRY_E5, // Chemical thrower equipped. - INFANTRY_E7, // Engineer. - INFANTRY_RAMBO, // Commando. - - INFANTRY_C1, // Civilian - INFANTRY_C2, // Civilian - INFANTRY_C3, // Civilian - INFANTRY_C4, // Civilian - INFANTRY_C5, // Civilian - INFANTRY_C6, // Civilian - INFANTRY_C7, // Civilian - INFANTRY_C8, // Civilian - INFANTRY_C9, // Civilian - INFANTRY_C10, // Nikumba - INFANTRY_MOEBIUS, // Dr. Moebius - INFANTRY_DELPHI, // Agent "Delphi" - INFANTRY_CHAN, // Dr. Chan - - INFANTRY_COUNT, - INFANTRY_FIRST=0 -} InfantryType; - -//inline InfantryType operator++(InfantryType &, int); - - -/********************************************************************** -** The game units are enumerated here. These include not only traditional -** vehicles, but also hovercraft and gunboats. -*/ -typedef enum UnitType : char{ - UNIT_NONE=-1, - UNIT_HTANK, // Heavy tank (Mammoth). - UNIT_MTANK, // Medium tank (M1). - UNIT_LTANK, // Light tank ('Bradly'). - UNIT_STANK, // Stealth tank (Romulan). - UNIT_FTANK, // Flame thrower tank. - UNIT_VICE, // Visceroid - UNIT_APC, // APC. - UNIT_MLRS, // MLRS rocket launcher. - UNIT_JEEP, // 4x4 jeep replacement. - UNIT_BUGGY, // Rat patrol dune buggy type. - UNIT_HARVESTER, // Resource gathering vehicle. - UNIT_ARTY, // Artillery unit. - UNIT_MSAM, // Anti-Aircraft vehicle. - UNIT_HOVER, // Hovercraft. - UNIT_MHQ, // Mobile Head Quarters. - UNIT_GUNBOAT, // Gunboat - UNIT_MCV, // Mobile construction vehicle. - UNIT_BIKE, // Nod recon motor-bike. - UNIT_TRIC, // Triceratops - UNIT_TREX, // Tyranosaurus Rex - UNIT_RAPT, // Velociraptor - UNIT_STEG, // Stegasaurus - -#ifdef PETROGLYPH_EXAMPLE_MOD - UNIT_NUKE_TANK, // Mammoth with a nuke -#endif - - UNIT_COUNT, - UNIT_FIRST=0 -} UnitType; - -//inline UnitType operator++(UnitType &, int); - -#define UNITF_HTANK (1L<(static_cast(a) | static_cast(b));} - -inline TextPrintType operator&(TextPrintType a, TextPrintType b) -{return static_cast(static_cast(a) & static_cast(b));} - -inline TextPrintType operator~(TextPrintType a) -{return static_cast(~static_cast(a));} - - -/********************************************************************** -** These control the maximum number of objects in the game. Make sure that these -** maximums never exceed the maximum value for the "ID" element in the -** object class. -*/ -#define AIRCRAFT_MAX 100 // Lasts for minutes. -#define ANIM_MAX 200 // Lasts only a few seconds. -#define BUILDING_MAX 500 // Lasts for hours. -#define BULLET_MAX 50 // Lasts several seconds. -#define FACTORY_MAX 32 // Lasts a few minutes. -#define HOUSE_MAX 12 // Lasts entire scenario. -#define INFANTRY_MAX 500 // Lasts for minutes. -#define OVERLAY_MAX 1 // Very transitory. -#define REINFORCEMENT_MAX 50 // Maximum number of reinforcements. -#define SMUDGE_MAX 1 // Very transitory. -#define TEAM_MAX 60 // Lasts forever. -#define TEMPLATE_MAX 1 // Very transitory. -#define TERRAIN_MAX 500 // Lasts for hours or eternity. -#define TRIGGER_MAX 80 // Lasts forever. -#define UNIT_MAX 500 // Lasts for minutes. -#define TEAMTYPE_MAX 60 // Lasts forever. - -// Save filename description. -#define DESCRIP_MAX 44 // 40 chars + CR + LF + CTRL-Z + NULL - -#define MAX_ENTRY_SIZE 15 - -#define OBUTTON_HEIGHT 9 // Is defined in mapedit.h, need for buttons - -#define CONQUER_PATH_MAX 9 // Number of cells to look ahead for movement. - -#define EACH_UNIT_MAX (UNIT_MAX/4) // Default maximum any one player can have. -#define EACH_BUILDING_MAX (BUILDING_MAX/4) // Default maximum any one player can build. - - -/********************************************************************** -** Terrain can be of these different classes. At any point in the game -** a particular piece of ground must fall under one of these classifications. -** This is true, even if it is undergoing a temporary transition. -*/ -typedef enum LandType : unsigned char { - LAND_CLEAR, // "Clear" terrain. - LAND_ROAD, // Road terrain. - LAND_WATER, // Water. - LAND_ROCK, // Impassable rock. - LAND_WALL, // Wall (blocks movement). - LAND_TIBERIUM, // Tiberium field. - LAND_BEACH, // Beach terrain. - - LAND_COUNT -} LandType; - - -/********************************************************************** -** The theaters of operation are as follows. -*/ -typedef enum TheaterType : char { - THEATER_NONE=-1, - THEATER_DESERT, - THEATER_JUNGLE, - THEATER_TEMPERATE, - THEATER_WINTER, - - THEATER_COUNT, - THEATER_FIRST=0 -} TheaterType; - -//inline TheaterType operator++(TheaterType &, int); - -#define THEATERF_DESERT (1<id) - - - - -/* -** -** Imports from Red Alert for AI. ST - 7/16/2019 11:44AM -** -** -** -*/ -#ifdef USE_RA_AI - - -/********************************************************************** -** A base is broken up into several zones. This type enumerates the -** various zones. -*/ -typedef enum ZoneType : char { - ZONE_CORE, // Center of base. - ZONE_NORTH, // North section. - ZONE_EAST, // East section. - ZONE_SOUTH, // South section. - ZONE_WEST, // West section. - - ZONE_COUNT, - ZONE_FIRST=0, - ZONE_NONE=-1 -} ZoneType; - - -/********************************************************************** -** The map is prescanned to mark of movement zones according to certain -** movement characteristics. This enum specifies those characteristics -** and movement zones kept track of. -*/ -typedef enum MZoneType : unsigned char { - MZONE_NORMAL, // Normal terrestrial objects (can't crush walls). - MZONE_CRUSHER, // Can crush crushable wall types. - MZONE_DESTROYER, // Can destroy walls. - MZONE_WATER, // Water based objects. - - MZONE_COUNT, - MZONE_FIRST=0 -} MZoneType; - -#define MZONEF_NORMAL (1<Draw_Line(FaceX+1, FaceY+1, FaceLine[Facing][0]+1, FaceLine[Facing][1]+1,CC_GREEN_SHADOW); - LogicPage->Draw_Line(FaceX, FaceY, FaceLine[Facing][0], FaceLine[Facing][1],CC_LIGHT_GREEN); - - /* - ** Restore the mouse. - */ - if (LogicPage == &SeenBuff) { - Show_Mouse(); - } - - return(true); - } - - return(false); -} - - -/*************************************************************************** - * Dial8Class::Get_Direction -- retrieves direction (0-255) of dial * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * DirType dial is pointing to * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/17/1994 BR : Created. * - *=========================================================================*/ -DirType Dial8Class::Get_Direction(void) const -{ - return(Direction); -} - - -/*************************************************************************** - * Dial8Class::Set_Direction -- sets current direction (0-255) of dial * - * * - * INPUT: * - * DirType to set dial to * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/17/1994 BR : Created. * - *=========================================================================*/ -void Dial8Class::Set_Direction(DirType dir) -{ - Direction = dir; - Facing = Dir_Facing(Direction); - OldFacing = Facing; - Flag_To_Redraw(); -} diff --git a/code/TIBERIANDAWN/DIAL8.H b/code/TIBERIANDAWN/DIAL8.H deleted file mode 100644 index 676b154..0000000 --- a/code/TIBERIANDAWN/DIAL8.H +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\dial8.h_v 2.18 16 Oct 1995 16:47:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DIAL8.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : 02/06/95 * - * * - * Last Update : February 6, 1995 [BR] * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DIAL8_H -#define DIAL8_H - -class Dial8Class : public ControlClass -{ - public: - /* - ** Constructor/Destructor - */ - Dial8Class(int id, int x, int y, int w, int h, DirType dir); - - /* - ** Get/Set the direction the dial is currently pointing - */ - DirType Get_Direction(void) const; - void Set_Direction(DirType dir); - - /* - ** Overloaded draw routine - */ - virtual int Draw_Me(int forced = false); - - protected: - /* - ** Overloaded event processing routine - */ - virtual int Action(unsigned flags, KeyNumType &key); - - private: - int FaceX; // x-coord of center of face - int FaceY; // y-coord of center of face - int FacePoint[8][2]; // coords of the little dial decorations - int FaceLine[8][2]; // coords for drawing the dial hand - DirType Direction; // 0-255 numerical direction of dial - FacingType Facing; // numerical facing direction of dial (0 - 7) - FacingType OldFacing; // previous Facing value - -}; - -#endif - diff --git a/code/TIBERIANDAWN/DIALOG.CPP b/code/TIBERIANDAWN/DIALOG.CPP deleted file mode 100644 index 14ef937..0000000 --- a/code/TIBERIANDAWN/DIALOG.CPP +++ /dev/null @@ -1,787 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\dialog.cpv 2.17 16 Oct 1995 16:51:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DIALOG.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : May 18, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Clip_Text_Print -- Prints text with clipping and support. * - * Dialog_Box -- draws a dialog background box * - * Display_Place_Building -- Displays the "place building" dialog box. * - * Display_Select_Target -- Displays the "choose target" prompt. * - * Display_Status -- Display the player scenario status box. * - * Draw_Box -- Displays a highlighted box. * - * Fancy_Text_Print -- Prints text with a drop shadow. * - * Redraw_Needed -- Determine if sidebar needs to be redrawn. * - * Render_Bar_Graph -- Renders a specified bargraph. * - * Simple_Text_Print -- Prints text with a drop shadow. * - * Window_Box -- Draws a fancy box over the specified window. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * Dialog_Box -- draws a dialog background box * - * * - * INPUT: * - * x,y,w,h the usual * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/26/1995 BR : Created. * - *=============================================================================================*/ -void Dialog_Box(int x, int y, int w, int h) -{ - Draw_Box( x, y, w, h, BOXSTYLE_GREEN_BORDER, true); -} - - -/*********************************************************************************************** - * Draw_Box -- Displays a highlighted box. * - * * - * This will draw a highlighted box to the logicpage. It can * - * optionally fill the box with a color as well. This is a low level * - * function and thus, it doesn't do any graphic mode color adjustments. * - * * - * INPUT: x,y -- Upper left corner of the box to be drawn (pixels). * - * * - * w,h -- Width and height of box (in pixels). * - * * - * up -- Is the box rendered in the "up" stated? * - * * - * filled-- Is the box to be filled. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1991 JLB : Created. * - * 05/30/1992 JLB : Embedded color codes. * - * 07/31/1992 JLB : Depressed option added. * - *=============================================================================================*/ -extern void CC_Texture_Fill (void const *shapefile, int shapenum, int xpos, int ypos, int width, int height); - -void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled) -{ - static BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = { - - //Filler, Shadow, Hilite, Corner colors - - { LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down. - { LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border. - { LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue. - { DKGREY, WHITE, BLACK, DKGREY}, // 3 Button is disabled down. - { DKGREY, BLACK, WHITE, LTGREY}, // 4 Button is disabled up. - { LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows. - //{ CC_GREEN_BKGD, CC_LIGHT_GREEN, CC_GREEN_SHADOW, CC_GREEN_CORNERS }, // 6 Button is down. - //{ CC_GREEN_BKGD, CC_GREEN_SHADOW, CC_LIGHT_GREEN, CC_GREEN_CORNERS }, // 7 Button is up w/border. - { CC_GREEN_BKGD, 14, 12, 13 }, // 6 Button is down. - { CC_GREEN_BKGD, 12, 14, 13 }, // 7 Button is up w/border. - { DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down. - { DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up. - //{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box. - //{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box. - { BLACK, 14, 14, BLACK}, // 10 List box. - { BLACK, 14, 14, BLACK}, // 11 Menu box. - }; - - w--; - h--; - BoxStyleType const &style = ButtonColors[up]; - - if (filled) { - if (style.Filler == CC_GREEN_BKGD){ - CC_Texture_Fill (MixFileClass::Retrieve("BTEXTURE.SHP"), InMainLoop, x, y, w, h); - }else{ - LogicPage->Fill_Rect( x, y, x+w, y+h, style.Filler); - } - } - - switch ( up ) { - case ( BOXSTYLE_GREEN_BOX ): - LogicPage->Draw_Rect(x, y, x+w, y+h, style.Highlight); - break; - - case ( BOXSTYLE_GREEN_BORDER ): - LogicPage->Draw_Rect(x+1, y+1, x+w-1, y+h-1, style.Highlight); - break; - - default: - LogicPage->Draw_Line(x, y+h, x+w, y+h, style.Shadow); - LogicPage->Draw_Line(x+w, y, x+w, y+h, style.Shadow); - - LogicPage->Draw_Line(x, y, x+w, y, style.Highlight); - LogicPage->Draw_Line(x, y, x, y+h, style.Highlight); - - LogicPage->Put_Pixel(x, y+h, style.Corner); - LogicPage->Put_Pixel(x+w, y, style.Corner); - break; - } -} - - -/*********************************************************************************************** - * Format_Window_String -- Separates a String into Lines. * - * This function will take a long string and break it up into lines * - * which are not longer then the window width. Any character < ' ' is * - * considered a new line marker and will be replaced by a NULL. * - * * - * INPUT: char *String - string to be formated. * - * int maxlinelen - Max length of any line in pixels. * - * * - * OUTPUT: int - number of lines string is. * - * * - * WARNINGS: The string passed in will be modified - NULLs will be put * - * into each position that will be a new line. * - * * - * HISTORY: * - * 03/27/1992 SB : Created. * - * 05/18/1995 JLB : Greatly revised for new font system. * - *=============================================================================================*/ -int Format_Window_String(char * string, int maxlinelen, int & width, int & height) -{ - int linelen; - int lines = 0; - width = 0; - height = 0; - - // In no string was passed in, then there are no lines. - if (!string) return(0); - - // While there are more letters left divide the line up. - while (*string) { - linelen = 0; - height += FontHeight + FontYSpacing; - lines++; - - // While the current line is less then the max length... - while (linelen < maxlinelen && *string != '\r' && *string != '\0') { - linelen += Char_Pixel_Width(*string++); - } - - // if the line is to long... - if (linelen >= maxlinelen) { - - /* - ** Back up to an appropriate location to break. - */ - while (*string != ' ' && *string != '\r' && *string != '\0') { - linelen -= Char_Pixel_Width(*string--); - } - - } - - /* - ** Record the largest width of the worst case string. - */ - if (linelen > width) { - width = linelen; - } - - /* - ** Force a break at the end of the line. - */ - if (*string) { - *string++ = '\r'; - } - } - return(lines); -} - - -/*********************************************************************************************** - * Window_Box -- Draws a fancy box over the specified window. * - * * - * This routine will draw a fancy (shaded) box over the specified * - * window. This is the effect used to give the polished look to * - * screen rectangles without having to use art. * - * * - * INPUT: window -- Specified window to fill and border. * - * * - * style -- The style to render the window. * - * * - * OUTPUT: none * - * * - * WARNINGS: The rendering is done to the LogicPage. * - * * - * HISTORY: * - * 03/03/1992 JLB : Created. * - * 07/31/1992 JLB : Cool raised border effect. * - * 06/08/1994 JLB : Takes appropriate enumeration parameters. * - *=============================================================================================*/ -void Window_Box(WindowNumberType window, BoxStyleEnum style) -{ - int x,y,w,h; // Window dimensions. - int border; // Width of border. - - static int _border[BOXSTYLE_COUNT][2] = { - {0,0}, // 0 Simple beveled edge. - {2,4}, // 1 Wide raised border. - {1,1}, // 2 Thick beveled edge. - {2,1}, // 3 Thin raised border. - {0,0}, // 4 Simple beveled edge. - {20,0}, // 5 Simple beveled edge. - {0,0}, // 6 Simple beveled edge. - {2,4}, // 7 Wide raised border. - {0,0}, // 8 Simple beveled edge. - {20,0}, // 9 Simple beveled edge. - {0,1} // 10 Simple 1 pixel box. - }; - - x = WindowList[window][WINDOWX]<<3; - y = WindowList[window][WINDOWY]; - w = WindowList[window][WINDOWWIDTH]<<3; - h = WindowList[window][WINDOWHEIGHT]; - - /* - ** If it is to be rendered to the seenpage, then - ** hide the mouse. - */ - if (LogicPage == (&SeenBuff)) Conditional_Hide_Mouse(x,y,x+w,y+h); - - Draw_Box(x, y, w, h, style, true); - border = _border[style][1]; - - /* - ** Draw the second border if requested. - */ - if (border) { - Draw_Box(x+border, y+border, w-(border<<1), h-(border<<1), style, false); - } - - /* - ** Restore the mouse if it has been hidden and return. - */ - if (LogicPage == &SeenBuff) Conditional_Show_Mouse(); -} - - -/*********************************************************************************************** - * Simple_Text_Print -- Prints text with a drop shadow. * - * * - * This routine functions like Text_Print, but will render a drop * - * shadow (in black). * - * * - * INPUT: text -- Pointer to text to render. * - * * - * x,y -- Pixel coordinate for to print text. * - * * - * fore -- Foreground color. * - * * - * back -- Background color. * - * * - * flag -- Text print control flags. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1991 JLB : Created. * - * 10/26/94 JLB : Handles font X spacing in a more friendly manner. * - *=============================================================================================*/ -void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag) -{ - static int yspace=0; // Y spacing adjustment for font. - static int xspace=0; // Spacing adjustment for font. - void const * font=0; // Font to use. - -////////////////#if (0) - static unsigned char _textfontpal[16][16] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 26, 25, 24 }, - { 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 136,135,119, 2 }, - { 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 143,159,41 ,167 }, - - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,157,158, 5 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0,179, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,179,178,176 }, - - { 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 122,123,125,127 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 }, - { 0, 1, 4,166, 41, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - - { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 }, - { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 }, - - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - }; - static unsigned char _textpalmedium[16] = { - 0, 25, 119,41, 0, 158,0, 178, 125,0, 202,0, 0, 0, 0, 0 - }; - - static unsigned char _textpalbright[16] = { - 0, 24, 2, 4, 0, 5, 0, 176, 127,0, 201,0, 0, 0, 0, 0 - }; -///////////////////////#endif //(0) - - int point; // Requested font size. - int shadow; // Requested shadow value. - unsigned char fontpalette[16]; // Working font palette array. - memset(&fontpalette[0], back, 16); - - if ((flag & 0xf) == TPF_VCR) { - fontpalette[3] = 12; - fontpalette[9] = 15; - fontpalette[10] = 200; - fontpalette[11] = 201; - fontpalette[12] = 202; - fontpalette[13] = 203; - fontpalette[14] = 204; - fontpalette[15] = 205; - } - - char *tempstr = NULL; - - if (text){ - /* - ** remove any 0xff characters from the string - */ - tempstr = new char [strlen (text)+1]; - char *tempptr = tempstr; - - for ( int i=0 ; i<(int)strlen(text)+1 ; i++ ) { - if (text[i] != -1){ - *tempptr = text[i]; - tempptr++; - } - } - } - - /* - ** A gradient font always requires special fixups for the palette. - */ - if ((flag & 0xf) == TPF_6PT_GRAD || - (flag & 0xf) == TPF_GREEN12_GRAD || - (flag & 0xf) == TPF_GREEN12) { - /* - ** If a gradient palette was requested, then fill in the font palette array - ** according to the color index specified. - */ - if (flag & TPF_USE_GRAD_PAL) { - memcpy(&fontpalette[0], _textfontpal[ (fore & 0x0f) ], 16); - } else { - - /* - ** Special adjustment for fonts that have gradient artwork. When there is - ** no special gradient effect desired, then set the font color based on the - ** forground color specified. - */ - memset(&fontpalette[4], fore, 12); - } - - if (flag & TPF_MEDIUM_COLOR) { - fore = _textpalmedium[fore & 0x0F]; - memset(&fontpalette[4], fore, 12); - }else{ - if (flag & TPF_BRIGHT_COLOR) { - fore = _textpalbright[fore & 0x0F]; - memset(&fontpalette[4], fore, 12); - }else{ - fore = fontpalette[1]; - } - } - } - - - /* - ** Change the current font if it differs from the font desired. - */ - point = (flag & (TextPrintType)0x000F); - xspace = 1; - yspace = 0; - - switch (point) { - case TPF_GREEN12: - font = Green12FontPtr; - break; - - case TPF_GREEN12_GRAD: - font = Green12GradFontPtr; - break; - - case TPF_MAP: - font = MapFontPtr; - xspace -= 1; - break; - - case TPF_VCR: - font = VCRFontPtr; - break; - - case TPF_6PT_GRAD: - font = GradFont6Ptr; - xspace -= 1; - //yspace -= 1; - break; - - case TPF_3POINT: - xspace += 1; - font = Font3Ptr; - flag = flag & ~(TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_NOSHADOW); - break; - - case TPF_6POINT: - font = Font6Ptr; - xspace -= 1; - //yspace -= 1; - break; - - case TPF_8POINT: - font = Font8Ptr; - xspace -= 2; - yspace -= 4; - break; - - case TPF_LED: - xspace -= 4; - font = FontLEDPtr; - break; - - default: - font = FontPtr; - break; - } - - /* - ** Change the current font palette according to the dropshadow flags. - */ - shadow = (flag & (TPF_NOSHADOW|TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_LIGHTSHADOW)); - switch (shadow) { - - /* - ** The text is rendered plain. - */ - case TPF_NOSHADOW: - fontpalette[2] = back; - fontpalette[3] = back; - xspace -= 1; - yspace -= 2; - break; - - /* - ** The text is rendered with a simple - ** drop shadow. - */ - case TPF_DROPSHADOW: - fontpalette[2] = BLACK; - fontpalette[3] = back; - xspace -= 1; - break; - - /* - ** Special engraved text look for the options - ** dialog system. - */ - case TPF_LIGHTSHADOW: - fontpalette[2] = ((14 * 16) + 7)+1; - fontpalette[3] = back; - xspace -= 1; - break; - - /* - ** Each letter is surrounded by black. This is used - ** when the text will be over a non-plain background. - */ - case TPF_FULLSHADOW: - fontpalette[2] = BLACK; - fontpalette[3] = BLACK; - xspace -= 1; - break; - - default: - break; - } - fontpalette[0] = back; - fontpalette[1] = fore; - - /* - ** Set the font and spacing according to the values they should be. - */ - FontXSpacing = xspace; - FontYSpacing = yspace; - Set_Font(font); - Set_Font_Palette(fontpalette); - - /* - ** Display the (centered) message if there is one. - */ - if (text && *text) { - switch (flag & (TPF_CENTER|TPF_RIGHT)) { - case TPF_CENTER: - x -= String_Pixel_Width(tempstr)>>1; - break; - - case TPF_RIGHT: - x -= String_Pixel_Width(tempstr); - break; - - default: - break; - } - - if (x < (unsigned)SeenBuff.Get_Width() && y < (unsigned)SeenBuff.Get_Height()) { - LogicPage->Print(tempstr, x, y, fore, back); - } - } - if (tempstr){ - delete [] tempstr; - } - -} - - -/*********************************************************************************************** - * Fancy_Text_Print -- Prints text with a drop shadow. * - * * - * This routine functions like Text_Print, but will render a drop * - * shadow (in black). * - * * - * INPUT: text -- Text number to print. * - * * - * x,y -- Pixel coordinate for to print text. * - * * - * fore -- Foreground color. * - * * - * back -- Background color. * - * * - * flag -- Text print control flags. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine is much slower than normal text print and * - * if rendered to the SEENPAGE, the intermediate rendering * - * steps could be visible. * - * * - * HISTORY: * - * 11/29/1994 JLB : Created * - *=============================================================================================*/ -void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...) -{ - char buffer[512]; // Working staging buffer. - va_list arg; // Argument list var. - - /* - ** If the text number is valid, then process it. - */ - if (text != TXT_NONE) { - va_start(arg, flag); - - /* - ** The text string must be locked since the vsprintf function doesn't know - ** how to handle EMS pointers. - */ - char const * tptr = Text_String(text); - vsprintf(buffer, tptr, arg); - va_end(arg); - - Simple_Text_Print(buffer, x, y, fore, back, flag); - } else { - - /* - ** Just the flags are to be changed, since the text number is TXT_NONE. - */ - Simple_Text_Print((char const *)0, x, y, fore, back, flag); - } -} - - -/*********************************************************************************************** - * Fancy_Text_Print -- Prints text with a drop shadow. * - * * - * This routine functions like Text_Print, but will render a drop * - * shadow (in black). * - * * - * INPUT: text -- Pointer to text to render. * - * * - * x,y -- Pixel coordinate for to print text. * - * * - * fore -- Foreground color. * - * * - * back -- Background color. * - * * - * flag -- Text print control flags. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine is much slower than normal text print and * - * if rendered to the SEENPAGE, the intermediate rendering * - * steps could be visible. * - * * - * HISTORY: * - * 12/24/1991 JLB : Created. * - * 10/26/94 JLB : Handles font X spacing in a more friendly manner. * - * 11/29/1994 JLB : Separated actual draw action. * - *=============================================================================================*/ -void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...) -{ - char buffer[512]; // Working staging buffer. - va_list arg; // Argument list var. - - /* - ** If there is a valid text string pointer then build the final string into the - ** working buffer before sending it to the simple string printing routine. - */ - if (text) { - - /* - ** Since vsprintf doesn't know about EMS pointers, be sure to surround this - ** call with locking code. - */ - va_start(arg, flag); - vsprintf(buffer, text, arg); - va_end(arg); - - Simple_Text_Print(buffer, x, y, fore, back, flag); - } else { - - /* - ** Just the flags are desired to be changed, so call the simple print routine with - ** a NULL text pointer. - */ - Simple_Text_Print((char const *)0, x, y, fore, back, flag); - } -} - - -/*********************************************************************************************** - * Clip_Text_Print -- Prints text with clipping and support. * - * * - * Use this routine to print text that that should be clipped at an arbitrary right margin * - * as well as possibly recognizing characters. Typical users of this routine would * - * be list boxes. * - * * - * INPUT: text -- Reference to the text to print. * - * * - * x,y -- Pixel coordinate of the upper left corner of the text position. * - * * - * fore -- The foreground color to use. * - * * - * back -- The background color to use. * - * * - * flag -- The text print flags to use. * - * * - * width -- The maximum pixel width to draw the text. Extra characters beyond this * - * point will not be printed. * - * * - * tabs -- Optional pointer to a series of pixel tabstop positions. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -void Conquer_Clip_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, unsigned width, int const * tabs) -{ - char buffer[512]; - - if (text) { - strcpy(buffer, text); - - /* - ** Set the font and spacing characteristics according to the flag - ** value passed in. - */ - Simple_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, flag); - - char * source = &buffer[0]; - unsigned offset = 0; - int processing = true; - while (processing && offset < width) { - char * ptr = strchr(source, '\t'); - - /* - ** Zap the tab character. It will be processed later. - */ - if (ptr) { - *ptr = '\0'; - } - - if (*source) { - - /* - ** Scan forward until the end of the string is reached or the - ** maximum width, whichever comes first. - */ - int w = 0; - char * bptr = source; - do { - w += Char_Pixel_Width(*bptr++); - } while(*bptr && offset+w < width); - - /* - ** If the maximum width has been exceeded, then remove the last - ** character and signal that further processing is not necessary. - */ - if (offset+w >= width) { - bptr--; - w -= Char_Pixel_Width(*bptr); - *bptr = '\0'; - processing = 0; - } - - /* - ** Print this text block and advance the offset accordingly. - */ - Simple_Text_Print(source, x+offset, y, fore, back, flag); - offset += w; - } - - /* - ** If a was the terminator for this text block, then advance - ** to the next tabstop. - */ - if (ptr) { - if (tabs) { - while (offset > (unsigned) *tabs) { - tabs++; - } - offset = (unsigned) *tabs; - } else { - offset = ((offset+1 / 50) + 1) * 50; - } - source = ptr+1; - } else { - break; - } - } - } -} diff --git a/code/TIBERIANDAWN/DISPLAY.CPP b/code/TIBERIANDAWN/DISPLAY.CPP deleted file mode 100644 index 188c55a..0000000 --- a/code/TIBERIANDAWN/DISPLAY.CPP +++ /dev/null @@ -1,4407 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\display.cpv 2.16 16 Oct 1995 16:48:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DISPLAY.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : August 24, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * DisplayClass::AI -- Handles the maintenance tasks for the map display. * - * DisplayClass::Calculated_Cell -- Fetch a map cell based on specified method. * - * DisplayClass::Cell_Object -- Determines what has been clicked on. * - * DisplayClass::Cell_Shadow -- Determine what shadow icon to use for the cell. * - * DisplayClass::Click_Cell_Calc -- Determines cell from screen X & Y. * - * DisplayClass::Coord_To_Pixel -- Determines X and Y pixel coordinates. * - * DisplayClass::Cursor_Mark -- Set or resets the cursor display flag bits. * - * DisplayClass::DisplayClass -- Default constructor for display class. * - * DisplayClass::Draw_It -- Draws the tactical map. * - * DisplayClass::Flag_To_Redraw -- Flags the display so that it will be redrawn as soon as poss* - * DisplayClass::Get_Occupy_Dimensions -- computes width & height of the given occupy list * - * DisplayClass::Init_Clear -- Clears the display to a known state. * - * DisplayClass::Init_IO -- Creates the map's button list * - * DisplayClass::Init_Theater -- Theater-specific initialization * - * DisplayClass::Map_Cell -- Mark specified cell as having been mapped. * - * DisplayClass::Mouse_Left_Held -- Handles the left button held down. * - * DisplayClass::Mouse_Left_Press -- Handles the left mouse button press. * - * DisplayClass::Mouse_Left_Release -- Handles the left mouse button release. * - * DisplayClass::Mouse_Left_Up -- Handles the left mouse "cruising" over the map. * - * DisplayClass::Mouse_Right_Press -- Handles the right mouse button press. * - * DisplayClass::Next_Object -- Searches for next object on display. * - * DisplayClass::One_Time -- Performs any special one time initializations. * - * DisplayClass::Passes_Proximity_Check -- Determines if building placement is near friendly sq* - * DisplayClass::Pixel_To_Coord -- converts screen coord to COORDINATE * - * DisplayClass::Read_INI -- Reads map control data from INI file. * - * DisplayClass::Redraw_Icons -- Draws all terrain icons necessary. * - * DisplayClass::Redraw_Shadow -- Draw the shadow overlay. * - * DisplayClass::Refresh_Band -- Causes all cells under the rubber band to be redrawn. * - * DisplayClass::Refresh_Cells -- Redraws all cells in list. * - * DisplayClass::Remove -- Removes a game object from the rendering system. * - * DisplayClass::Repair_Mode_Control -- Controls the repair mode. * - * DisplayClass::Scroll_Map -- Scroll the tactical map in desired direction. * - * DisplayClass::Select_These -- All selectable objects in region are selected. * - * DisplayClass::Sell_Mode_Control -- Controls the sell mode. * - * DisplayClass::Set_Cursor_Pos -- Controls the display and animation of the tac cursor. * - * DisplayClass::Set_Cursor_Shape -- Changes the shape of the terrain square cursor. * - * DisplayClass::Set_View_Dimensions -- Sets the tactical display screen coordinates. * - * DisplayClass::Submit -- Adds a game object to the map rendering system. * - * DisplayClass::TacticalClass::Action -- Processes input for the tactical map. * - * DisplayClass::Text_Overlap_List -- Creates cell overlap list for specified text string. * - * DisplayClass::Write_INI -- Writes map data into INI file. * - * DisplayClass::Set_Tactical_Position -- Sets the tactical view position. * - * DisplayClass::Center_Map -- Centers the map about the currently selected objects * - * DisplayClass::Prev_Object -- Searches for the previous object on the map. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include "function.h" - -/* -** These layer control elements are used to group the displayable objects -** so that proper overlap can be obtained. -*/ -LayerClass DisplayClass::Layer[LAYER_COUNT]; - -/* -** Fading tables -*/ -unsigned char DisplayClass::FadingBrighten[256]; -unsigned char DisplayClass::FadingShade[256]; -unsigned char DisplayClass::FadingLight[256]; -unsigned char DisplayClass::RemapTables[HOUSE_COUNT][3][256]; -unsigned char DisplayClass::FadingGreen[256]; -unsigned char DisplayClass::FadingYellow[256]; -unsigned char DisplayClass::FadingRed[256]; -unsigned char DisplayClass::TranslucentTable[(MAGIC_COL_COUNT+1)*256]; -unsigned char DisplayClass::WhiteTranslucentTable[(1+1)*256]; -unsigned char DisplayClass::MouseTranslucentTable[(4+1)*256]; -void const * DisplayClass::TransIconset; -unsigned char DisplayClass::UnitShadow[(USHADOW_COL_COUNT+1)*256]; -unsigned char DisplayClass::SpecialGhost[2*256]; - -void const * DisplayClass::ShadowShapes; -unsigned char DisplayClass::ShadowTrans[(SHADOW_COL_COUNT+1)*256]; - -/* -** Bit array of cell redraw flags -*/ -BooleanVectorClass DisplayClass::CellRedraw; - -/* -** The main button that intercepts user input to the map -*/ -DisplayClass::TacticalClass DisplayClass::TacButton; - -// -// We need a way to bypass visible view checks when we are running in the context of GlyphX without using the -// internal C&C renderer. We shouldn't know or care what the user is actually looking at -// ST - 4/17/2019 9:01AM -// -bool DisplayClass::IgnoreViewConstraints = false; - -/* -** Define "_RETRIEVE" if the palette morphing tables are part of the loaded data. If this -** is undefined, then the files will be created. -*/ -#define _RETRIEVE - - -static int const TEX_X = 0; -static int const TEX_Y = 6; -static int const TEX_W = 14; - -extern MixFileClass *TheaterIcons; - - -//Added for getting the input for special character keys from the client -// - 6/26/2019 JAS -extern bool DLL_Export_Get_Input_Key_State(KeyNumType key); - - -/*********************************************************************************************** - * DisplayClass::DisplayClass -- Default constructor for display class. * - * * - * This constructor for the display class just initializes some of the display settings. * - * Most settings are initialized with the correct values at the time that the Init function * - * is called. There are some cases where default values are wise and this routine fills * - * those particular ones in. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/06/1994 JLB : Created. * - *=============================================================================================*/ -DisplayClass::DisplayClass(void) -{ - TacticalCoord = 0; - ShadowShapes = 0; - TransIconset = 0; - ZoneCell = 0; - ZoneOffset = 0; - CursorSize = 0; - ProximityCheck = false; - PendingObjectPtr = 0; - PendingObject = 0; - PendingHouse = HOUSE_NONE; - IsRepairMode = false; - IsTargettingMode = false; - IsToRedraw = true; - IsRubberBand = false; - IsTentative = false; - IsSellMode = false; -} - - -/*********************************************************************************************** - * DisplayClass::One_Time -- Performs any special one time initializations. * - * * - * This routine is called from the game initialization process. It is to perform any one * - * time initializations necessary for the map display system. It allocates the staging * - * buffer needed for the radar map. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine must be called ONCE and only once. * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 05/31/1994 JLB : Handles layer system now. * - * 06/02/1994 JLB : Takes care of misc display tables and data allocation. * - *=============================================================================================*/ -void DisplayClass::One_Time(void) -{ - Set_View_Dimensions(0, Map.Get_Tab_Height()); - - MapClass::One_Time(); - - /* - ** Init the CellRedraw bit array. Do not do this in the constructor, since the - ** BooleanVector may not have been constructed yet. - */ - CellRedraw.Resize(MAP_CELL_TOTAL); - - for (LayerType layer = LAYER_FIRST; layer < LAYER_COUNT; layer++) { - Layer[layer].One_Time(); - } - - /* - ** Load the generic transparent icon set. - */ - TransIconset = MixFileClass::Retrieve("TRANS.ICN"); - - ShadowShapes = MixFileClass::Retrieve("SHADOW.SHP"); - - Set_View_Dimensions(0, Map.Get_Tab_Height()); - - /* - ** Allocate and initialize the remap tables needed for each "house". - */ - HousesType hindex; - int fade; - - for (fade = 0; fade < 3; fade++) { - for (hindex = HOUSE_FIRST; hindex < HOUSE_COUNT; hindex++) { - int color; - - switch (fade) { - case 0: - for (color = 0; color < 256; color++) { - RemapTables[hindex][fade][color] = color; - } - break; - - case 1: - Mem_Copy(FadingLight, RemapTables[hindex][fade], 256); - break; - - case 2: - Mem_Copy(FadingShade, RemapTables[hindex][fade], 256); - break; - } - Mem_Copy(&RemapTables[hindex][fade][((int)hindex+11)*16], &RemapTables[hindex][fade][(0+11)*16], 16); - } - } -} - - -/*********************************************************************************************** - * DisplayClass::Init_Clear -- clears the display to a known state * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void DisplayClass::Init_Clear(void) -{ - MapClass::Init_Clear(); - - /* - ** Clear any object being placed - */ - PendingObjectPtr = 0; - PendingObject = 0; - PendingHouse = HOUSE_NONE; - CursorSize = 0; - IsTargettingMode = false; - IsRepairMode = false; - IsRubberBand = false; - IsTentative = false; - IsSellMode = false; - - /* - ** Empty all the display's layers - */ - for (LayerType layer = LAYER_FIRST; layer < LAYER_COUNT; layer++) { - Layer[layer].Init(); - } -} - - -/*********************************************************************************************** - * DisplayClass::Init_IO -- clears & re-builds the map's button list * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void DisplayClass::Init_IO(void) -{ - MapClass::Init_IO(); - - /* - ** Re-attach our buttons to the main map button list, only in non-edit mode. - */ - if (!Debug_Map) { - TacButton.Zap(); - Add_A_Button(TacButton); - } -} - - -/*********************************************************************************************** - * DisplayClass::Init_Theater -- Performs theater-specific initialization (mixfiles, etc) * - * * - * INPUT: * - * theater new theater * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void DisplayClass::Init_Theater(TheaterType theater) -{ - char fullname[16]; - char iconname[16]; -#ifndef _RETRIEVE - static TLucentType const MouseCols[4] = { - {BLACK, BLACK, 110, 0}, - {WHITE, WHITE, 110, 0}, - {LTGREY, LTGREY, 110, 0}, - {DKGREY, DKGREY, 110, 0} - }; - static TLucentType const MagicCols[MAGIC_COL_COUNT] = { - {32,32,110,0}, - {33,33,110,0}, - {34,34,110,0}, - {35,35,110,0}, - {36,36,110,0}, - {37,37,110,0}, - {38,38,110,0}, - {39,39,110,0}, - {BLACK, BLACK, 200, 0}, - {WHITE, BLACK, 40, 0}, - {LTGREY, BLACK, 80, 0}, - {DKGREY, BLACK, 140, 0} - }; - static TLucentType const WhiteCols[1] = { - {1, WHITE, 80, 0} - }; - static TLucentType const ShadowCols[SHADOW_COL_COUNT] = { - {WHITE+1, BLACK,130,0}, - {WHITE, BLACK,170,0}, - {LTGRAY, BLACK,250,0}, - {DKGRAY, BLACK,250,0} - }; - static TLucentType const UShadowCols[USHADOW_COL_COUNT] = { - {LTGREEN, BLACK,130,0} - }; -#endif - - /* - ---------------------- Invoke parent's init routine ---------------------- - */ - MapClass::Init_Theater(theater); - - /* - ** Save the new theater value - */ - Theater = theater; - -#ifndef DEMO - /* - ** Unload old mixfiles, and cache the new ones - */ - sprintf(fullname, "%s.MIX", Theaters[Theater].Root); - if (Theater != LastTheater){ - if (TheaterData) { - delete TheaterData; - } - TheaterData = new MixFileClass(fullname); - TheaterData->Cache(); - } - -#endif - /* - ** Register the hi-res icons mix file now since it is theater specific - */ - sprintf(fullname, "%s.MIX", Theaters[Theater].Root); - strcpy (iconname, fullname); - strcpy (&iconname[4], "ICNH.MIX"); - if (Theater != LastTheater){ - if (TheaterIcons) { - delete TheaterIcons; - } - TheaterIcons = new MixFileClass(iconname); - TheaterIcons->Cache(); - } - - - - /* - ** Load the custom palette associated with this theater. - ** The fading palettes will have to be generated as well. - */ - sprintf(fullname, "%s.PAL", Theaters[theater].Root); - void const * ptr = MixFileClass::Retrieve(fullname); - Mem_Copy((void *)ptr, GamePalette, 768); - - - Mem_Copy(GamePalette, OriginalPalette, 768); - -#ifndef _RETRIEVE - /* - ** Make sure that remapping doesn't occur on the colors that cycle. - */ - memset(&GamePalette[CYCLE_COLOR_START*3], 0x3F, CYCLE_COLOR_COUNT*3); -#endif - - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("GREEN", theater)).Read(FadingGreen, sizeof(FadingGreen)); -#else - Build_Fading_Table(GamePalette, FadingGreen, GREEN, 110); - CCFileClass(Fading_Table_Name("GREEN", theater)).Write(FadingGreen, sizeof(FadingGreen)); -#endif - if (theater == THEATER_DESERT) { - FadingGreen[196] = 160; - } - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("YELLOW", theater)).Read(FadingYellow, sizeof(FadingYellow)); -#else - Build_Fading_Table(GamePalette, FadingYellow, YELLOW, 140); - CCFileClass(Fading_Table_Name("YELLOW", theater)).Write(FadingYellow, sizeof(FadingYellow)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("RED", theater)).Read(FadingRed, sizeof(FadingRed)); -#else - Build_Fading_Table(GamePalette, FadingRed, RED, 140); - CCFileClass(Fading_Table_Name("RED", theater)).Write(FadingRed, sizeof(FadingRed)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("MOUSE", theater)).Read(MouseTranslucentTable, sizeof(MouseTranslucentTable)); -#else - Build_Translucent_Table(GamePalette, &MouseCols[0], 4, MouseTranslucentTable); - CCFileClass(Fading_Table_Name("MOUSE", theater)).Write(MouseTranslucentTable, sizeof(MouseTranslucentTable)); -#endif - -// MouseDrawPtr = MouseTranslucentTable; -// MouseDrawPtr2 = Add_Long_To_Pointer(MouseTranslucentTable, 256L); -// MouseDrawVal = 1; -// MouseDrawFlags = (int)SHAPE_GHOST; - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("TRANS", theater)).Read(TranslucentTable, sizeof(TranslucentTable)); -#else - Build_Translucent_Table(GamePalette, &MagicCols[0], MAGIC_COL_COUNT, TranslucentTable); - CCFileClass(Fading_Table_Name("TRANS", theater)).Write(TranslucentTable, sizeof(TranslucentTable)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("WHITE", theater)).Read(WhiteTranslucentTable, sizeof(WhiteTranslucentTable)); -#else - Build_Translucent_Table(GamePalette, &WhiteCols[0], 1, WhiteTranslucentTable); - CCFileClass(Fading_Table_Name("WHITE", theater)).Write(WhiteTranslucentTable, sizeof(WhiteTranslucentTable)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("SHADOW", theater)).Read(ShadowTrans, sizeof(ShadowTrans)); -#else - Build_Translucent_Table(GamePalette, &ShadowCols[0], SHADOW_COL_COUNT, ShadowTrans); - CCFileClass(Fading_Table_Name("SHADOW", theater)).Write(ShadowTrans, sizeof(ShadowTrans)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("UNITS", theater)).Read(UnitShadow, sizeof(UnitShadow)); -#else - Conquer_Build_Translucent_Table(GamePalette, &UShadowCols[0], USHADOW_COL_COUNT, UnitShadow); - CCFileClass(Fading_Table_Name("UNITS", theater)).Write(UnitShadow, sizeof(UnitShadow)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("SHADE", theater)).Read(FadingShade, sizeof(FadingShade)); -#else - Conquer_Build_Fading_Table(GamePalette, FadingShade, BLACK, 150); - CCFileClass(Fading_Table_Name("SHADE", theater)).Write(FadingShade, sizeof(FadingShade)); -#endif - -#ifdef _RETRIEVE - CCFileClass(Fading_Table_Name("LIGHT", theater)).Read(FadingLight, sizeof(FadingLight)); -#else - Conquer_Build_Fading_Table(GamePalette, FadingLight, WHITE, 85); - CCFileClass(Fading_Table_Name("LIGHT", theater)).Write(FadingLight, sizeof(FadingLight)); -#endif - - /* - ** Create the shadow color used by aircraft. - */ - Conquer_Build_Fading_Table(GamePalette, &SpecialGhost[256], BLACK, 100); - for (int index = 0; index < 256; index++) { - SpecialGhost[index] = 0; - } - - Build_Fading_Table(GamePalette, FadingBrighten, WHITE, 25); - - -#ifndef _RETRIEVE - /* - ** Restore the palette since it was mangled while building the fading tables. - */ - sprintf(fullname, "%s.PAL", Theaters[theater].Root); - ptr = MixFileClass::Retrieve(fullname); - Mem_Copy((void *)ptr, GamePalette, 768); - Mem_Copy(GamePalette, OriginalPalette, 768); -#endif - - /* - ** Adjust the palette according to the visual control option settings. - */ - Options.Fixup_Palette(); -} - - -/*********************************************************************************************** - * DisplayClass::Text_Overlap_List -- Creates cell overlap list for specified text string. * - * * - * This routine is used to create an overlap list that specifies all the cells that are * - * covered by the specified text string. This overlap list is used to handle map refresh * - * logic. * - * * - * INPUT: text -- Pointer to the text that would appear on the map and must have an * - * overlap list generated. * - * * - * x,y -- The coordinates that the text would appear (upper left corner). * - * * - * OUTPUT: Returns with a pointer to an overlap list that covers all cells "under" the text * - * if were displayed at the coordinates specified. The list is actually a series of * - * offsets from the display's upper left corner cell number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/06/1994 JLB : Created. * - * 12/07/1994 JLB : Sidebar fixup. * - * 08/13/1995 JLB : Optimized for variable sized help text. * - *=============================================================================================*/ -short const * DisplayClass::Text_Overlap_List(char const * text, int x, int y, int lines) -{ - static short _list[30]; - - if (text) { - short * ptr = &_list[0]; - int len = String_Pixel_Width(text)+CELL_PIXEL_W; - int right = TacPixelX + Lepton_To_Pixel(TacLeptonWidth); - - /* - ** If the help text would spill into the sidebar, then flag this fact, but - ** shorten the apparent length so that the icon list calculation will - ** function correctly. - */ - if (x+len >= TacPixelX+Lepton_To_Pixel(TacLeptonWidth)) { - len = right-x; - *ptr++ = REFRESH_SIDEBAR; - } - - /* - ** Build the list of overlap cell offset values according to the text - ** coordinate and the length. - */ - int height = (((FontHeight * lines) + 23) / 24) * 24; - - if (x <= right) { - CELL ul = Click_Cell_Calc(x, y-1); - CELL lr = Click_Cell_Calc(x+len-1, Bound(y+height, TacPixelY, SeenBuff.Get_Height() - 1)); - - if (ul == -1) ul = Click_Cell_Calc(x, y); -// if (lr == -1) lr = Click_Cell_Calc(x+len, y); - - if (ul != -1 && lr != -1) { - for (int yy = Cell_Y(ul); yy <= Cell_Y(lr); yy++) { - for (int xx = Cell_X(ul); xx <= Cell_X(lr); xx++) { - *ptr++ = XY_Cell(xx, yy) - Coord_Cell(TacticalCoord); - } - } - } - } - - *ptr = REFRESH_EOL; - } - return(_list); -} - - -/*********************************************************************************************** - * DisplayClass::Set_View_Dimensions -- Sets the tactical display screen coordinates. * - * * - * Use this routine to set the tactical map screen coordinates and dimensions. This routine * - * is typically used when the screen size or position changes as a result of the sidebar * - * changing position or appearance. * - * * - * INPUT: x,y -- The X and Y pixel position on the screen for the tactical map upper left * - * corner. * - * * - * width -- The width of the tactical display (in pixels). If this parameter is * - * omitted, then the width will be as wide as the screen will allow. * - * * - * height-- The height of the tactial display (in pixels). If this parameter is * - * omitted, then the width wil be as wide as the screen will allow. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/06/1994 JLB : Created. * - * 06/27/1995 JLB : Adjusts tactical map position if necessary. * - *=============================================================================================*/ -void DisplayClass::Set_View_Dimensions(int x, int y, int width, int height) -{ -#if (1) // This code pulled in from RA1. ST - 1/9/2019 10:53AM - if (width == -1) { - TacLeptonWidth = Pixel_To_Lepton(SeenBuff.Get_Width()-x); - } else { - TacLeptonWidth = width * CELL_LEPTON_W; - } - - // ST - 3/1/2019 12:05PM - // Made the below code more consistent with the width calculation. This is needed if we aren't going to draw the tabs at the top of the screen - // - if (height == -1) { - TacLeptonHeight = Pixel_To_Lepton(SeenBuff.Get_Height()-y); - //height = (SeenBuff.Get_Height()-y) / CELL_PIXEL_H; - } else { - TacLeptonHeight = height * CELL_LEPTON_H; - } - //TacLeptonHeight = height * CELL_LEPTON_H; - - /* - ** Adjust the tactical cell if it is now in an invalid position - ** because of the changed dimensions. - */ - int xx = 0;// Coord_X(TacticalCoord) - (MapCellX * CELL_LEPTON_W); - int yy = 0;// Coord_Y(TacticalCoord) - (MapCellY * CELL_LEPTON_H); - - Confine_Rect(&xx, &yy, TacLeptonWidth, TacLeptonHeight, MapCellWidth * CELL_LEPTON_W, MapCellHeight * CELL_LEPTON_H); - - Set_Tactical_Position(XY_Coord(xx + (MapCellX * CELL_LEPTON_W), yy + (MapCellY * CELL_LEPTON_H))); - - TacPixelX = x; - TacPixelY = y; - WindowList[WINDOW_TACTICAL][WINDOWX] = x; - WindowList[WINDOW_TACTICAL][WINDOWY] = y; - WindowList[WINDOW_TACTICAL][WINDOWWIDTH] = Lepton_To_Pixel(TacLeptonWidth); - WindowList[WINDOW_TACTICAL][WINDOWHEIGHT] = Lepton_To_Pixel(TacLeptonHeight); - if (Window == WINDOW_TACTICAL) { - Change_Window(0); - Change_Window(Window); - } - IsToRedraw = true; - Flag_To_Redraw(false); - - TacButton.X = TacPixelX; - TacButton.Y = TacPixelY; - TacButton.Width = Lepton_To_Pixel(TacLeptonWidth); - TacButton.Height = Lepton_To_Pixel(TacLeptonHeight); - -#else //CNC code - if (width == -1) { - width = SeenBuff.Get_Width() - x; - } - TacLeptonWidth = Pixel_To_Lepton(width); - - if (height == -1) { - height = SeenBuff.Get_Height() - y; - } - TacLeptonHeight = Pixel_To_Lepton(height); - - /* - ** Adjust the tactical cell if it is now in an invalid position - ** because of the changed dimensions. - */ - int xx = Coord_X(TacticalCoord) - (MapCellX * CELL_LEPTON_W); - int yy = Coord_Y(TacticalCoord) - (MapCellY * CELL_LEPTON_H); - - Confine_Rect(&xx, &yy, TacLeptonWidth, TacLeptonHeight, MapCellWidth * CELL_LEPTON_W, MapCellHeight * CELL_LEPTON_H); - - Set_Tactical_Position(XY_Coord(xx + (MapCellX * CELL_LEPTON_W), yy + (MapCellY * CELL_LEPTON_H))); - - TacPixelX = x; - TacPixelY = y; - WindowList[WINDOW_TACTICAL][WINDOWX] = x >> 3; - WindowList[WINDOW_TACTICAL][WINDOWY] = y; - WindowList[WINDOW_TACTICAL][WINDOWWIDTH] = width >> 3; - WindowList[WINDOW_TACTICAL][WINDOWHEIGHT] = height; - if (Window == WINDOW_TACTICAL) { - Change_Window(0); - Change_Window(Window); - } - IsToRedraw = true; - Flag_To_Redraw(false); - - TacButton.X = TacPixelX; - TacButton.Y = TacPixelY; - TacButton.Width = Lepton_To_Pixel(TacLeptonWidth); - TacButton.Height = Lepton_To_Pixel(TacLeptonHeight); -#endif -} - - -/*********************************************************************************************** - * DisplayClass::Set_Cursor_Shape -- Changes the shape of the terrain square cursor. * - * * - * This routine is used to set up the terrain cursor according to the size of the object * - * that is to be placed down. The terrain cursor looks like an arbitrary collection of * - * hatched square overlays. Typical use is when placing buildings. * - * * - * INPUT: list -- A pointer to the list that contains offsets to the cells that are to * - * be marked. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/03/1994 JLB : Created. * - * 06/26/1995 JLB : Puts placement cursor into static buffer. * - *=============================================================================================*/ -void DisplayClass::Set_Cursor_Shape(short const * list) -{ - if (CursorSize) { - Cursor_Mark(ZoneCell+ZoneOffset, false); - } - - ZoneOffset = 0; - - if (list) { - int w,h; - static short _list[50]; - - memcpy(_list, list, sizeof(_list)); - CursorSize = _list; - Get_Occupy_Dimensions (w, h, CursorSize); - ZoneOffset = -(((h/2)*MAP_CELL_W)+(w/2)); - Cursor_Mark(ZoneCell+ZoneOffset, true); - } else { - CursorSize = 0; - } -} - - -/*********************************************************************************************** - * DisplayClass::Passes_Proximity_Check -- Determines if building placement is near friendly sq* - * * - * This routine is used by the building placement cursor logic to determine whether the * - * at the current cursor position if the building would be adjacent to another friendly * - * building. In cases where this is not true, then the building cannot be placed at all. * - * This determination is returned by the function. * - * * - * INPUT: object -- The building object that the current placement system is examining. * - * * - * OUTPUT: bool; Can the pending building object be placed at the present cursor location * - * checking only for proximity to friendly buildings? If this isn't for a * - * building type object, then this routine always returns true. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/06/1994 JLB : Created. * - * 06/07/1994 JLB : Handles concrete check. * - *=============================================================================================*/ -bool DisplayClass::Passes_Proximity_Check(ObjectTypeClass const *object) -{ -#ifdef USE_RA_AI - - return Passes_Proximity_Check(object, PendingHouse, CursorSize, ZoneCell + ZoneOffset); - -#else //USE_RA_AI // Replaced by more generic function from RA, for RA AI. ST - 7/24/2019 5:46PM - - short const *ptr; - - /* - ** In editor mode, the proximity check always passes. - */ - if (Debug_Map) { - return(true); - } - - if (!object || !CursorSize || object->What_Am_I() != RTTI_BUILDINGTYPE) { - return(true); - } - - /* - ** Scan through all cells that the building foundation would cover. If any adjacent - ** cells to these are of friendly persuasion, then consider the proximity check to - ** have been a success. - */ - ptr = CursorSize; - while (*ptr != REFRESH_EOL) { - CELL cell = ZoneCell + ZoneOffset + *ptr++; - - for (FacingType facing = FACING_N; facing < FACING_COUNT; facing++) { - CELL newcell = Adjacent_Cell(cell, facing); - - if (!In_Radar(cell)) return(false); - - TechnoClass * base = (*this)[newcell].Cell_Techno(); - - /* - ** The special cell ownership flag allows building adjacent - ** to friendly walls and bibs even though there is no official - ** building located there. - */ - if ((*this)[newcell].Owner == PendingHouse) { - return(true); - } - - if (base && base->What_Am_I() == RTTI_BUILDING && base->House->Class->House == PendingHouse) { - return(true); - } - } - } - return(false); -#endif -} - - - - -#ifdef USE_RA_AI -/* -** Additional version of Passes_Proximity_Check, inspired by RA implementation. Needed for RA AI. ST - 7/24/2019 5:42PM -*/ - -/*********************************************************************************************** - * DisplayClass::Passes_Proximity_Check -- Determines if building placement is near friendly sq* - * * - * This routine is used by the building placement cursor logic to determine whether the * - * at the current cursor position if the building would be adjacent to another friendly * - * building. In cases where this is not true, then the building cannot be placed at all. * - * This determination is returned by the function. * - * * - * INPUT: object -- The building object that the current placement system is examining. * - * * - * house -- The house to base the proximity check upon. Typically this is the * - * player's house, but in multiplay, the computer needs to check for * - * proximity as well. * - * * - * list -- Pointer to the building's offset list. * - * * - * trycell -- The cell to base the offset list on. * - * * - * OUTPUT: bool; Can the pending building object be placed at the present cursor location * - * checking only for proximity to friendly buildings? If this isn't for a * - * building type object, then this routine always returns true. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/06/1994 JLB : Created. * - * 06/07/1994 JLB : Handles concrete check. * - * 10/11/1994 BWG : Added IsProximate check for ore refineries * - *=============================================================================================*/ -bool DisplayClass::Passes_Proximity_Check(ObjectTypeClass const * object, HousesType house, short const * list, CELL trycell) const -{ - short const *ptr; - - /* - ** In editor mode, the proximity check always passes. - */ - if (Debug_Map) { - return(true); - } - - if (!object || object->What_Am_I() != RTTI_BUILDINGTYPE) { - return(true); - } - - /* - ** Scan through all cells that the building foundation would cover. If any adjacent - ** cells to these are of friendly persuasion, then consider the proximity check to - ** have been a success. - */ - ptr = list; - while (*ptr != REFRESH_EOL) { - CELL cell = trycell + *ptr++; - - for (FacingType facing = FACING_N; facing < FACING_COUNT; facing++) { - CELL newcell = Adjacent_Cell(cell, facing); - - if (!In_Radar(cell)) return(false); - - TechnoClass * base = (*this)[newcell].Cell_Techno(); - - /* - ** The special cell ownership flag allows building adjacent - ** to friendly walls and bibs even though there is no official - ** building located there. - */ - if ((*this)[newcell].Owner == house) { - return(true); - } - - if (base && base->What_Am_I() == RTTI_BUILDING && base->House->Class->House == house) { - return(true); - } - } - } - return(false); -} - -#endif //USE_RA_AI - - - - - - - -/*********************************************************************************************** - * DisplayClass::Set_Cursor_Pos -- Controls the display and animation of the tac cursor. * - * * - * This routine controls the location, display, and animation of the * - * tactical map cursor. * - * * - * INPUT: pos -- Position to move the cursor do. If -1 is passed then * - * the cursor will just be hidden. If the position * - * passed is the same as the last position passed in, * - * then animation could occur (based on timers). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1991 JLB : Created. * - * 06/02/1994 JLB : Converted to member function. * - * 06/08/1994 JLB : If position is -1, then follow mouse. * - * 02/28/1995 JLB : Forces placement cursor to fit on map. * - *=============================================================================================*/ -CELL DisplayClass::Set_Cursor_Pos(CELL pos) -{ - CELL prevpos; // Last position of cursor (for jump-back reasons). - - /* - ** Follow the mouse position if no cell number is provided. - */ - if (pos == -1) { - pos = Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y()); - } - - if (!CursorSize) { - prevpos = ZoneCell; - ZoneCell = pos; - return(prevpos); - } - - /* - ** Adjusts the position so that the placement cursor is never partway off the - ** tactical map. - */ - int w,h; - Get_Occupy_Dimensions (w, h, CursorSize); - - int x = Cell_X(pos + ZoneOffset); - int y = Cell_Y(pos + ZoneOffset); - - if (x < Coord_XCell(TacticalCoord)) x = Coord_XCell(TacticalCoord); -// if (x < TacMapX) x = TacMapX; - if (y < Coord_YCell(TacticalCoord)) y = Coord_YCell(TacticalCoord); -// if (y < TacMapY) y = TacMapY; - if (x+w >= Coord_XCell(TacticalCoord) + Lepton_To_Cell(TacLeptonWidth)) x = Coord_XCell(TacticalCoord)+Lepton_To_Cell(TacLeptonWidth)-w; -// if (x+w >= TacMapX+TacWidth) x = TacMapX+TacWidth-w; - if (y+h >= Coord_YCell(TacticalCoord) + Lepton_To_Cell(TacLeptonHeight)) x = Coord_YCell(TacticalCoord)+Lepton_To_Cell(TacLeptonHeight)-h; -// if (y+h >= TacMapY+TacHeight) y = TacMapY+TacHeight-h; - pos = XY_Cell(x, y) - ZoneOffset; - - /* - ** This checks to see if NO animation or drawing is to occur and, if so, - ** exits. - */ - if (pos == ZoneCell) return(pos); - - prevpos = ZoneCell; - - /* - ** If the cursor is visible, then handle the graphic update. - ** Otherwise, just update the global position of the cursor. - */ - if (CursorSize) { - - /* - ** Erase the old cursor (if it exists) AND the cursor is moving. - */ - if (pos != ZoneCell && ZoneCell != -1) { - Cursor_Mark(ZoneCell+ZoneOffset, false); - } - - /* - ** Render the cursor (could just be animation). - */ - if (pos != -1) { - Cursor_Mark(pos+ZoneOffset, true); - } - } - ZoneCell = pos; - ProximityCheck = Passes_Proximity_Check(PendingObject); - - return(prevpos); -} - - -/*********************************************************************************************** - * DisplayClass::Get_Occupy_Dimensions -- computes width & height of the given occupy list * - * * - * INPUT: * - * w ptr to fill in with height * - * h ptr to fill in with width * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/31/1995 BRR : Created. * - *=============================================================================================*/ -void DisplayClass::Get_Occupy_Dimensions(int & w, int & h, short const *list) -{ - int min_x = MAP_CELL_W; - int max_x = -MAP_CELL_W; - int min_y = MAP_CELL_H; - int max_y = -MAP_CELL_H; - int x,y; - - w = 0; - h = 0; - - if (!list) { - /* - ** Loop through all cell offsets, accumulating max & min x- & y-coords - */ - while (*list != REFRESH_EOL) { - /* - ** Compute x & y coords of the current cell offset. We can't use Cell_X() - ** & Cell_Y(), because they use shifts to compute the values, and if the - ** offset is negative we'll get a bogus coordinate! - */ - x = (*list) % MAP_CELL_W; - y = (*list) / MAP_CELL_H; - - max_x = MAX(max_x, x); - min_x = MIN(min_x, x); - max_y = MAX(max_y, y); - min_y = MIN(min_y, y); - - list++; - } - - w = MAX(1, max_x - min_x + 1); - h = MAX(1, max_y - min_y + 1); - } -} - - -/*********************************************************************************************** - * DisplayClass::Cursor_Mark -- Set or resets the cursor display flag bits. * - * * - * This routine will clear or set the cursor display bits on the map. * - * If the bit is set, then the cursor will be rendered on that map * - * icon. * - * * - * INPUT: pos -- Position of the upper left corner of the cursor. * - * * - * on -- Should the bit be turned on? * - * * - * OUTPUT: none * - * * - * WARNINGS: Be sure that every call to set the bits is matched by a * - * corresponding call to clear the bits. * - * * - * HISTORY: * - * 09/04/1991 JLB : Created. * - * 06/02/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void DisplayClass::Cursor_Mark(CELL pos, bool on) -{ - CELL const *ptr; - CellClass *cellptr; - - if (pos == -1) return; - - /* - ** For every cell in the CursorSize list, invoke its Redraw_Objects and - ** toggle its IsCursorHere flag - */ - ptr = CursorSize; - while (*ptr != REFRESH_EOL) { - CELL cell = pos + *ptr++; - if (In_Radar(cell)) { - cellptr = &(*this)[cell]; - cellptr->Redraw_Objects(); - if (on) { - cellptr->IsCursorHere = true; - } else { - cellptr->IsCursorHere = false; - } - } - } - - /* - ** For every cell in the PendingObjectPtr's Overlap_List, invoke its - ** Redraw_Objects routine. - */ - if (PendingObjectPtr) { - ptr = PendingObjectPtr->Overlap_List(); - while (*ptr != REFRESH_EOL) { - CELL cell = pos + *ptr++; - if (In_Radar(cell)) { - cellptr = &(*this)[cell]; - cellptr->Redraw_Objects(); - } - } - } -} - - -/*********************************************************************************************** - * DisplayClass::AI -- Handles the maintenance tasks for the map display. * - * * - * This routine is called once per game display frame (15 times per second). It handles * - * the mouse shape tracking and map scrolling as necessary. * - * * - * INPUT: input -- The next key just fetched from the input queue. * - * * - * x,y -- Mouse coordinates. * - * * - * OUTPUT: Modifies the input code if necessary. When the input code is consumed, it gets * - * set to 0. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/01/1994 JLB : Created. * - * 06/02/1994 JLB : Filters mouse click input. * - * 06/07/1994 JLB : Fixed so template click will behave right. * - * 10/14/1994 JLB : Changing cursor shape over target. * - * 12/31/1994 JLB : Takes mouse coordinates as parameters. * - * 06/27/1995 JLB : Breaks out of rubber band mode if mouse leaves map. * - *=============================================================================================*/ -void DisplayClass::AI(KeyNumType & input, int x, int y) -{ - if ( - IsRubberBand && - (Get_Mouse_X() < TacPixelX || - Get_Mouse_Y() < TacPixelY || - Get_Mouse_X() >= (TacPixelX + Lepton_To_Pixel(TacLeptonWidth)) || - Get_Mouse_Y() >= (TacPixelY + Lepton_To_Pixel(TacLeptonHeight)))) { - Mouse_Left_Release(-1, Get_Mouse_X(), Get_Mouse_Y(), NULL, ACTION_NONE); - } - - MapClass::AI(input, x, y); -} - - -/*********************************************************************************************** - * DisplayClass::Submit -- Adds a game object to the map rendering system. * - * * - * This routine is used to add an arbitrary (but tangible) game object to the map. It will * - * be rendered (made visible) once it is submitted to this function. This function builds * - * the list of game objects that get rendered each frame as necessary. It is possible to * - * submit the game object to different rendering layers. All objects in a layer get drawn * - * at the same time. Using this layer method it becomes possible to have objects "below" * - * other objects. * - * * - * INPUT: object -- Pointer to the object to add. * - * * - * layer -- The layer to add the object to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 05/31/1994 JLB : Improved layer system. * - * 05/31/1994 JLB : Sorts object position if this is for the ground layer. * - *=============================================================================================*/ -void DisplayClass::Submit(ObjectClass const * object, LayerType layer) -{ - if (object) { - Layer[layer].Submit(object, (layer == LAYER_GROUND)); - } -} - - -/*********************************************************************************************** - * DisplayClass::Remove -- Removes a game object from the rendering system. * - * * - * Every object that is to disappear from the map must be removed from the rendering * - * system. * - * * - * INPUT: object -- The object to remove. * - * * - * layer -- The layer to remove it from. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 05/31/1994 JLB : Improved layer system. * - *=============================================================================================*/ -void DisplayClass::Remove(ObjectClass const * object, LayerType layer) -{ - if (object) { - Layer[layer].Delete((ObjectClass *)object); - } -} - - -/*********************************************************************************************** - * DisplayClass::Click_Cell_Calc -- Determines cell from screen X & Y. * - * * - * This routine is used to determine the cell that is located at the * - * screen pixel coordinates given. Typical use is when the player * - * clicks with the mouse on the tactical map. * - * * - * INPUT: x,y -- Screen pixel coordinates. * - * * - * OUTPUT: Returns with cell that is under the coordinates specified. * - * If the coordinate specified is outside of the tactical * - * map, then -1 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -CELL DisplayClass::Click_Cell_Calc(int x, int y) -{ - x -= TacPixelX; - x = Pixel_To_Lepton(x); - y -= TacPixelY; - y = Pixel_To_Lepton(y); - - // Possibly ignore the view constraints if we aren't using the internal renderer. ST - 4/17/2019 9:06AM - //if (x < TacLeptonWidth && y < TacLeptonHeight) { - if (IgnoreViewConstraints || (x < TacLeptonWidth && y < TacLeptonHeight)) { - - COORDINATE tcoord = XY_Coord(Pixel_To_Lepton(Lepton_To_Pixel(Coord_X(TacticalCoord))), Pixel_To_Lepton(Lepton_To_Pixel(Coord_Y(TacticalCoord)))); - - return(Coord_Cell(Coord_Add(tcoord, XY_Coord(x, y)))); - } - return(-1); -} - - -/*********************************************************************************************** - * DisplayClass::Read_INI -- Reads map control data from INI file. * - * * - * This routine is used to read the map control data from the INI * - * file. * - * * - * INPUT: buffer -- Pointer to the loaded INI file data. * - * * - * OUTPUT: none * - * * - * WARNINGS: The TriggerClass INI data must have been read before calling this function. * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Read_INI(char *buffer) -{ - char name[16]; - int len; // Length of data in buffer. - char *tbuffer; // Accumulation buffer of Trigger names. - char *trigsection = "CellTriggers"; - char buf[20]; // trigger name for a cell - int cell; - int i; - - /* - ** Read the map dimensions. - */ - Set_Map_Dimensions(WWGetPrivateProfileInt("MAP", "X", 1, buffer), - WWGetPrivateProfileInt("MAP", "Y", 1, buffer), - WWGetPrivateProfileInt("MAP", "Width", MAP_CELL_W-2, buffer), - WWGetPrivateProfileInt("MAP", "Height", MAP_CELL_H-2, buffer)); - - /* - ** The theater is determined at this point. There is specific data that - ** is custom to this data. Load the custom data (as it related to terrain) - ** at this point. - */ - WWGetPrivateProfileString("MAP", "Theater", Theaters[THEATER_DESERT].Name, name, 13, buffer); - Theater = Theater_From_Name(name); - if (Theater == THEATER_NONE) { - Theater = THEATER_DESERT; - } - - /* - ** Remove any old theater specific uncompressed shapes - */ - if (Theater != LastTheater){ - Reset_Theater_Shapes(); - } - - /* - ** Now that the theater is known, init the entire map hierarchy - */ - Init(Theater); - - /* - ** Special initializations occur when the theater is known. - */ - TerrainTypeClass::Init(Theater); - TemplateTypeClass::Init(Theater); - OverlayTypeClass::Init(Theater); - UnitTypeClass::Init(Theater); - InfantryTypeClass::Init(Theater); - BuildingTypeClass::Init(Theater); - BulletTypeClass::Init(Theater); - AnimTypeClass::Init(Theater); - AircraftTypeClass::Init(Theater); - SmudgeTypeClass::Init(Theater); - - LastTheater = Theater; - - /* - ** Read the Waypoint entries. - */ - for (i = 0; i < WAYPT_COUNT; i++) { - sprintf(buf,"%d",i); - Waypoint[i] = WWGetPrivateProfileInt ("Waypoints",buf,-1,buffer); - if (Waypoint[i] != -1) { - (*this)[Waypoint[i]].IsWaypoint = 1; - } - } - - /* - ** Set the starting position (do this after Init(), which clears the cells' - ** IsWaypoint flags). - */ - if (Waypoint[WAYPT_HOME] == -1) { - Waypoint[WAYPT_HOME] = XY_Cell(MapCellX, MapCellY); - } - Set_Tactical_Position(Cell_Coord(Waypoint[WAYPT_HOME])&0xFF00FF00L); - Views[0] = Views[1] = Views[2] = Views[3] = Waypoint[WAYPT_HOME]; - - /* - ** Read the cell trigger names, and assign TriggerClass pointers - */ - len = strlen(buffer) + 2; // len is the length of the INI data - tbuffer = buffer + len; // tbuffer is after the INI data - - /* - ** Read all entry names into 'tbuffer'. - */ - WWGetPrivateProfileString(trigsection, NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - - /* - ** Loop through all CellTrigger entries. - */ - while (*tbuffer != '\0') { - - /* - ** Get a cell trigger assignment. - */ - WWGetPrivateProfileString(trigsection, tbuffer, NULL, buf, sizeof(buf) - 1, buffer); - - /* - ** Get cell # from entry name. - */ - cell = atoi(tbuffer); - if (cell > 0 && cell < MAP_CELL_TOTAL && !(*this)[cell].IsTrigger) { - - /* - ** Assign trigger pointer using trigger name. - */ - CellTriggers[cell] = TriggerClass::As_Pointer(buf); - if (CellTriggers[cell]) { - (*this)[cell].IsTrigger = 1; - if (CellTriggers[cell]) { - CellTriggers[cell]->AttachCount++; - } - } - } - - /* - ** Step to next entry name. - */ - tbuffer += strlen(tbuffer) + 1; - } -} - - -/*********************************************************************************************** - * DisplayClass::Write_INI -- Writes map data into INI file. * - * * - * This routine is used to write the map control data into the INI * - * file. The scenario editor uses this when creating the scenario * - * startup file. * - * * - * INPUT: buffer -- Pointer to INI file data. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Write_INI(char *buffer) -{ - char entry[20]; - - /* - ** Save the map parameters. - */ - WWWritePrivateProfileString("MAP", "Theater", Theaters[Theater].Name, buffer); - WWWritePrivateProfileInt("MAP", "X", MapCellX, buffer); - WWWritePrivateProfileInt("MAP", "Y", MapCellY, buffer); - WWWritePrivateProfileInt("MAP", "Width", MapCellWidth, buffer); - WWWritePrivateProfileInt("MAP", "Height", MapCellHeight, buffer); - - /* - ** Save the Waypoint entries. - */ - for (int i = 0; i < WAYPT_COUNT; i++) { - sprintf(entry,"%d",i); - WWWritePrivateProfileInt ("Waypoints",entry,Waypoint[i],buffer); - } - - /* - ** Erase the CellTriggers section. - */ - WWWritePrivateProfileString("CellTriggers",NULL,NULL,buffer); - - /* - ** Save the cell's triggers. - */ - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { - if ((*this)[cell].IsTrigger) { - - /* - ** Get cell trigger pointer. - */ - TriggerClass const * trig = CellTriggers[cell]; - - /* - ** Generate entry name. - */ - sprintf(entry,"%d",cell); - - /* - ** Save entry. - */ - WWWritePrivateProfileString("CellTriggers", entry, trig->Get_Name(), buffer); - } - } -} - - -/*********************************************************************************************** - * DisplayClass::Scroll_Map -- Scroll the tactical map in desired direction. * - * * - * This routine is used to scroll the tactical map view in the desired * - * direction. It can also be used to determine if scrolling would be * - * legal without actually performing any scrolling action. * - * * - * INPUT: facing -- The direction to scroll the tactical map. * - * * - * distance -- The distance in leptons to scroll the map. * - * * - * really -- Should the map actually be scrolled? If false, * - * then only the legality of a scroll is checked. * - * * - * OUTPUT: bool; Would scrolling in the desired direction be possible? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 05/20/1994 JLB : Converted to member function. * - * 08/09/1995 JLB : Added distance parameter. * - * 08/10/1995 JLB : Any direction scrolling. * - *=============================================================================================*/ -bool DisplayClass::Scroll_Map(DirType facing, int & distance, bool really) -{ - /* - ** If the distance is invalid then no further checking is required. Bail - ** with a no-can-do flag. - */ - if (distance == 0) return(false); - FacingType crude = Dir_Facing(facing); - - if (Coord_X(TacticalCoord) == Cell_To_Lepton(MapCellX) && crude != FACING_W) { - if (crude == FACING_SW) facing = DIR_S; - if (crude == FACING_NW) facing = DIR_N; - } - if (Coord_Y(TacticalCoord) == Cell_To_Lepton(MapCellY) && crude != FACING_N) { - if (crude == FACING_NW) facing = DIR_W; - if (crude == FACING_NE) facing = DIR_E; - } - if (Coord_X(TacticalCoord) + TacLeptonWidth == Cell_To_Lepton(MapCellX+MapCellWidth) && crude != FACING_E) { - if (crude == FACING_NE) facing = DIR_N; - if (crude == FACING_SE) facing = DIR_S; - } - if (Coord_Y(TacticalCoord) + TacLeptonHeight == Cell_To_Lepton(MapCellY+MapCellHeight) && crude != FACING_S) { - if (crude == FACING_SE) facing = DIR_E; - if (crude == FACING_SW) facing = DIR_W; - } - - /* - ** Determine the coordinate that it wants to scroll to. - */ - COORDINATE coord = Coord_Move(TacticalCoord, facing, distance); - - /* - ** Clip the new coordinate to the edges of the game world. - */ - int xx = Coord_X(coord) - Cell_To_Lepton(MapCellX); - int yy = Coord_Y(coord) - Cell_To_Lepton(MapCellY); - bool shifted = Confine_Rect(&xx, &yy, TacLeptonWidth, TacLeptonHeight, Cell_To_Lepton(MapCellWidth), Cell_To_Lepton(MapCellHeight)); - if (xx < 0) { - xx = 0; - shifted = true; - } - if (yy < 0) { - yy = 0; - shifted = true; - } - coord = XY_Coord(xx + Cell_To_Lepton(MapCellX), yy + Cell_To_Lepton(MapCellY)); - - /* - ** If the desired scroll was bound by the edge of the map, then adjust the distance to more accurately - ** reflect the actual distance moved. - */ - if (shifted) { - distance = Distance(TacticalCoord, coord); - } - - /* - ** If the new coordinate is the same as the old, then no scrolling would occur. - */ - if (!distance || coord == TacticalCoord) return(false); - - /* - ** Since the new coordinate is different than the old one, possibly adjust the real - ** tactical map accordingly. - */ - if (really) { - Set_Tactical_Position(coord); - IsToRedraw = true; - Flag_To_Redraw(false); - } - return(true); -} - - -/*********************************************************************************************** - * DisplayClass::Refresh_Cells -- Redraws all cells in list. * - * * - * This routine is used to flag all cells in the specified list for * - * redrawing. * - * * - * INPUT: cell -- The origin cell that the list is offset from. * - * * - * list -- Pointer to a list of offsets from the origin cell. * - * Each cell so specified is flagged for redraw. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine is rather slow (by definition). * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - * 08/01/1994 JLB : Simplified. * - *=============================================================================================*/ -void DisplayClass::Refresh_Cells(CELL cell, short const *list) -{ - if (*list == REFRESH_SIDEBAR) { - list++; - } - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if (In_Radar(newcell)) { - (*this)[newcell].Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * DisplayClass::Cell_Shadow -- Determine what shadow icon to use for the cell. * - * * - * This routine will examine the specified cell and adjacent cells to * - * determine what shadow icon to use. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: Returns with the shadow icon to use. -2= all black. * - * -1= map cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/01/1994 JLB : Created. * - * 04/04/1994 JLB : Revamped for new shadow icon method. * - * 04/30/1994 JLB : Converted to member function. * - * 03/06/2019 ST : Added house parameter so we can do this per player * - *=============================================================================================*/ -int DisplayClass::Cell_Shadow(CELL cell, HouseClass *house) -{ - if (house == NULL) { - return -1; - } - int index; - int value = -1; - CellClass *cellptr; - static char const CardShadow[16] = {-2,0,1,2,3,-1,4,-1,5,6,-1,-1,7,-1,-1,-1}; - static char const DiagShadow[16] = {-2,8,9,-1,10,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1}; - - /* - ** Don't map cells that are at the edges. This solves - ** problem of accessing cells off the bounds of map and into - ** who-knows-what memory. - */ - if ((unsigned)(Cell_X(cell)-1) >= MAP_CELL_W-2) return(-2); - if ((unsigned)(Cell_Y(cell)-1) >= MAP_CELL_H-2) return(-2); // Changed > to >= per Red Alert to fix out of bounds crash. ST - 3/25/2020 11:02PM - - cellptr = &(*this)[cell]; - if (!cellptr->Is_Mapped(house)) { - - /* - ** Check the cardinal directions first. This will either result - ** in a solution or the flag to check the diagonals. - */ - index = 0; - cellptr--; - if (cellptr->Is_Mapped(house)) index |= 0x08; - cellptr += MAP_CELL_W+1; - if (cellptr->Is_Mapped(house)) index |= 0x04; - cellptr -= MAP_CELL_W-1; - if (cellptr->Is_Mapped(house)) index |= 0x02; - cellptr -= MAP_CELL_W+1; - if (cellptr->Is_Mapped(house)) index |= 0x01; - value = CardShadow[index]; - - /* - ** The diagonals must be checked, since the cardinal directions - ** did not yield a valid result. - */ - if (value == -2) { - index = 0; - cellptr--; - if (cellptr->Is_Mapped(house)) index |= 0x08; - cellptr += MAP_CELL_W*2; - if (cellptr->Is_Mapped(house)) index |= 0x04; - cellptr += 2; - if (cellptr->Is_Mapped(house)) index |= 0x02; - cellptr -= MAP_CELL_W*2; - if (cellptr->Is_Mapped(house)) index |= 0x01; - value = DiagShadow[index]; - } - - /* - ** Randomizer should go here. Add sets in multiples of 12. - */ - - } - return(value); -} - -#if (0) -/*********************************************************************************************** - * DisplayClass::Cell_Shadow -- Determine what shadow icon to use for the cell. * - * * - * This routine will examine the specified cell and adjacent cells to * - * determine what shadow icon to use. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: Returns with the shadow icon to use. -2= all black. * - * -1= map cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/01/1994 JLB : Created. * - * 04/04/1994 JLB : Revamped for new shadow icon method. * - * 04/30/1994 JLB : Converted to member function. * - *=============================================================================================*/ -int DisplayClass::Cell_Shadow(CELL cell) -{ - int index; - int value = -1; - CellClass *cellptr; - static char const CardShadow[16] = {-2,0,1,2,3,-1,4,-1,5,6,-1,-1,7,-1,-1,-1}; - static char const DiagShadow[16] = {-2,8,9,-1,10,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1}; - - /* - ** Don't map cells that are at the top or bottom edge. This solves - ** problem of accessing cells off the top or bottom of the map and into - ** who-knows-what memory. - */ - if ((unsigned)(Cell_Y(cell)-1) > MAP_CELL_H-2) return(-2); - - cellptr = &(*this)[cell]; - if (!cellptr->IsMapped) { - - /* - ** Check the cardinal directions first. This will either result - ** in a solution or the flag to check the diagonals. - */ - index = 0; - cellptr--; - if (cellptr->IsMapped) index |= 0x08; - cellptr += MAP_CELL_W+1; - if (cellptr->IsMapped) index |= 0x04; - cellptr -= MAP_CELL_W-1; - if (cellptr->IsMapped) index |= 0x02; - cellptr -= MAP_CELL_W+1; - if (cellptr->IsMapped) index |= 0x01; - value = CardShadow[index]; - - /* - ** The diagonals must be checked, since the cardinal directions - ** did not yield a valid result. - */ - if (value == -2) { - index = 0; - cellptr--; - if (cellptr->IsMapped) index |= 0x08; - cellptr += MAP_CELL_W*2; - if (cellptr->IsMapped) index |= 0x04; - cellptr += 2; - if (cellptr->IsMapped) index |= 0x02; - cellptr -= MAP_CELL_W*2; - if (cellptr->IsMapped) index |= 0x01; - value = DiagShadow[index]; - } - - /* - ** Randomizer should go here. Add sets in multiples of 12. - */ - - } - return(value); -} -#endif - - - -/*********************************************************************************************** - * DisplayClass::Map_Cell -- Mark specified cell as having been mapped. * - * * - * This routine maps the specified cell. The cell must not already * - * have been mapped and the mapping player must be the human. * - * This routine will update any adjacent cell map icon as appropriate. * - * * - * INPUT: cell -- The cell to be mapped. * - * * - * house -- The player that is doing the mapping. * - * * - * OUTPUT: bool; Was action taken to map this cell? * - * * - * WARNINGS: none. * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - * 05/24/1994 JLB : Takes pointer to HouseClass. * - * 03/06/2019 ST : Use per-player mapping so we can track the shroud for all players * - *=============================================================================================*/ -bool DisplayClass::Map_Cell(CELL cell, HouseClass * house, bool and_for_allies) -{ - // It's OK to do this if the house isn't the local player. ST - 3/6/2019 11:06AM - //if (house != PlayerPtr || cell >= (CELL)Size) return(false); - if (house == NULL || cell >= (CELL)Size) return(false); - - if (!house->IsHuman) { - if (!ShareAllyVisibility || !and_for_allies) { - return false; - } - } - - /* - ** Maybe also recurse to map for allies - */ - if (ShareAllyVisibility && and_for_allies && GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - for (HousesType house_type = HOUSE_MULTI1; house_type < HOUSE_COUNT; house_type++) { - HouseClass *hptr = HouseClass::As_Pointer(house_type); - if (hptr && hptr->IsActive) { - if (hptr != house && house->Is_Ally(hptr)) { - Map_Cell(cell, hptr, false); - } - } - } - } - - /* - ** Don't bother remapping this cell if it is already mapped. - */ - //if ((*this)[cell].IsMapped) { - if ((*this)[cell].Is_Mapped(house)) { // Check by player. ST - 3/6/2019 10:28AM - return(false); - } - - /* - ** Mark the cell as being mapped. - */ - //(*this)[cell].IsMapped = true; - //(*this)[cell].IsVisible = true; - // Set by player. ST - 3/6/2019 10:29AM - (*this)[cell].Set_Mapped(house); - (*this)[cell].Set_Visible(house); - - (*this)[cell].Redraw_Objects(); - - /* - ** Check out all adjacent cells to see if they need - ** to be mapped as well. This is necessary because of the - ** "unique" method of showing shadowed cells. Many combinations - ** are not allowed, and to fix this, just map the cells until - ** all is ok. - */ - int xx = Cell_X(cell); - for (FacingType dir = FACING_FIRST; dir < FACING_COUNT; dir++) { - int shadow; - CELL c; - int xdiff; - - c = Adjacent_Cell(cell, dir); - - /* - ** Determine if the map edge has been wrapped. If so, - ** then don't process the cell. - */ - if ((unsigned)c >= MAP_CELL_TOTAL) continue; - xdiff = Cell_X(c) - xx; - xdiff = ABS(xdiff); - if (xdiff > 1) continue; - - if (c != cell && !(*this)[c].Is_Mapped(house)) { // Check by player. ST - 3/6/2019 10:28AM - shadow = Cell_Shadow(c, house); - - /* - ** Either map the cell or mark it to be refreshed. It - ** will probably change form if it isn't actually mapped. - */ - if (shadow == -1) { - Map_Cell(c, house, false); - } else { - if (shadow != -2) { - //(*this)[c].IsVisible = true; - (*this)[c].Set_Visible(house); // Set by player. ST - 3/6/2019 11:07AM - (*this)[c].Redraw_Objects(); - } - } - } - } - - TechnoClass * tech = (*this)[cell].Cell_Techno(); - if (tech) { - tech->Revealed(house); - } - return(true); -} - - -/*********************************************************************************************** - * DisplayClass::Coord_To_Pixel -- Determines X and Y pixel coordinates. * - * * - * This is the routine that figures out the location on the screen for * - * a specified coordinate. It is one of the fundamental routines * - * necessary for rendering the game objects. It performs some quick * - * tests to see if the coordinate is in a visible region and returns * - * this check as a boolean value. * - * * - * INPUT: coord -- The coordinate to check. * - * * - * x,y -- Reference to the pixel coordinates that this * - * coordinate would be when rendered. * - * * - * OUTPUT: bool; Is this coordinate in a visible portion of the map? * - * * - * WARNINGS: If the coordinate is not in a visible portion of the * - * map, then this X and Y parameters are not set. * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - * 12/15/1994 JLB : Converted to member function. * - * 01/07/1995 JLB : Uses inline functions to extract coord components. * - * 08/09/1995 JLB : Uses new coordinate system. * - *=============================================================================================*/ -#define EDGE_ZONE (CELL_LEPTON_W*2) -bool DisplayClass::Coord_To_Pixel(COORDINATE coord, int &x, int &y) -{ - int xtac = Pixel_To_Lepton(Lepton_To_Pixel(Coord_X(TacticalCoord))); - int xoff = Pixel_To_Lepton(Lepton_To_Pixel(Coord_X(coord))); - xoff = (xoff + EDGE_ZONE) - xtac; - - int ytac = Pixel_To_Lepton(Lepton_To_Pixel(Coord_Y(TacticalCoord))); - int yoff = Pixel_To_Lepton(Lepton_To_Pixel(Coord_Y(coord))); - yoff = (yoff + EDGE_ZONE) - ytac; - - x = Lepton_To_Pixel(xoff) - CELL_PIXEL_W * 2; - y = Lepton_To_Pixel(yoff) - CELL_PIXEL_H * 2; - - // Possibly ignore the view constraints if we aren't using the internal renderer. ST - 4/17/2019 9:06AM - return(coord && (IgnoreViewConstraints || ((xoff <= TacLeptonWidth + EDGE_ZONE * 2) && (yoff <= TacLeptonHeight + EDGE_ZONE * 2)))); -} - - -#if (0) // reference. ST - 4/17/2019 9:07AM -bool DisplayClass::Coord_To_Pixel(COORDINATE coord, int &x, int &y) -{ - if (coord) { - int xtac = Pixel_To_Lepton(Lepton_To_Pixel(Coord_X(TacticalCoord))); - int xoff = Pixel_To_Lepton(Lepton_To_Pixel(Coord_X(coord))); - - xoff = (xoff+EDGE_ZONE) - xtac; - if (xoff <= TacLeptonWidth + EDGE_ZONE*2) { - int ytac = Pixel_To_Lepton(Lepton_To_Pixel(Coord_Y(TacticalCoord))); - int yoff = Pixel_To_Lepton(Lepton_To_Pixel(Coord_Y(coord))); - - yoff = (yoff+EDGE_ZONE) - ytac; - if (yoff <= TacLeptonHeight + EDGE_ZONE*2) { - x = Lepton_To_Pixel(xoff)-CELL_PIXEL_W*2; - y = Lepton_To_Pixel(yoff)-CELL_PIXEL_H*2; - return(true); - } - } - } - return(false); -} -#endif - - - -/*********************************************************************************************** - * DisplayClass::Push_Onto_TacMap -- Moves x & y coords to being on tactical map * - * * - * This routine expects a line to be drawn between SOURCE & DEST, so it pushes the coords to * - * be within the region bounded by TacMapX,Y - + TacMapW,H. * - * * - * INPUT: source, dest -- References to the coordinates to check. * - * * - * * - * OUTPUT: bool; Are these coordinates in a visible portion of the map? * - * Returns true if the pushed source & dest are visible, but if neither are * - * within the map, then it returns false. * - * * - * * - * HISTORY: * - * 03/27/1995 BWG : Created. * - *=============================================================================================*/ -bool DisplayClass::Push_Onto_TacMap(COORDINATE &source, COORDINATE &dest) -{ - if (!source || !dest) return(false); - - int x1 = Coord_X(source); - int y1 = Coord_Y(source); - int x2 = Coord_X(dest); - int y2 = Coord_Y(dest); - int left = Coord_X(TacticalCoord); - int right = Coord_X(TacticalCoord) + TacLeptonWidth; - int top = Coord_Y(TacticalCoord); - int bottom = Coord_Y(TacticalCoord) + TacLeptonHeight; - - if (x1 < left && x2 < left) return(false); - if (x1 > right && x2 > right) return(false); - if (y1 < top && y2 < top) return(false); - if (y1 > bottom && y2 > bottom) return(false); - - x1 = Bound(x1, left, right); - x2 = Bound(x2, left, right); - y1 = Bound(y1, top, bottom); - y2 = Bound(y2, top, bottom); - - source = XY_Coord(x1, y1); - dest = XY_Coord(x2, y2); - return(true); -} - - -/*********************************************************************************************** - * DisplayClass::Cell_Object -- Determines what has been clicked on. * - * * - * This routine is used to determine what the player has clicked on. * - * It is passed the cell that the click was on and it then examines * - * the cell and returns with a pointer to the object that is there. * - * * - * INPUT: cell -- The cell that has been clicked upon. * - * * - * x,y -- Optional offsets from the upper left corner of the cell to be used in * - * determining exactly which object in the cell is desired. * - * * - * OUTPUT: Returns with a pointer to the object that is "clickable" in * - * the specified cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * DisplayClass::Cell_Object(CELL cell, int x, int y) -{ - return(*this)[cell].Cell_Object(x, y); -} - - -/*********************************************************************************************** - * DisplayClass::Draw_It -- Draws the tactical map. * - * * - * This will draw the tactical map at the recorded position. This * - * routine is used whenever the tactical map moves or needs to be * - * completely redrawn. It will handle making the necessary adjustments * - * to accomodate a moving cursor. * - * * - * INPUT: forced -- bool; force redraw of the entire display? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/15/1991 JLB : Created. (benchmark = 292) * - * 04/15/1991 JLB : Added _cell2meta[] reference array (206) * - * 04/15/1991 JLB : Added actual map reference for terrain (207) * - * 04/16/1991 JLB : _cell2meta converted to int (194) * - * 04/16/1991 JLB : References actual CellIcon[] array (204) * - * 04/16/1991 JLB : Cell size increased to 16 x 16 (167) * - * 04/17/1991 JLB : Cell based tactical map rendering (165) * - * 04/22/1991 JLB : Uses Draw_Stamp() for icon rendering (426) * - * 04/22/1991 JLB : Draw_Stamp uses LogicPage now (276) * - * 04/23/1991 JLB : Map active location cursor (334) * - * 05/02/1991 JLB : Added smoothing and 3 icons sets (431) * - * 05/22/1991 JLB : Broken into Draw_Map() and Refresh_Map(). * - * 09/14/1991 JLB : Uses Refresh_Cell when new cells scroll onto display. * - * 05/12/1992 JLB : Destination page support. * - * 02/14/1994 JLB : Revamped. * - * 05/01/1994 JLB : Converted to member function. * - * 12/15/1994 JLB : Updated to work with display heirarchy. * - * 12/24/1994 JLB : Examines redraw bit intelligently. * - * 12/24/1994 JLB : Combined with old Refresh_Map() function. * - * 01/10/1995 JLB : Rubber band drawing. * - *=============================================================================================*/ - void DisplayClass::Draw_It(bool forced) -{ - int x,y; // Working cell index values. - - MapClass::Draw_It(forced); - - if (IsToRedraw || forced) { - IsToRedraw = false; - - /* - ** In rubber band mode, mark all cells under the "rubber band" to be - ** redrawn. - */ - Refresh_Band(); - - /* - ** If the multiplayer message system is displaying one or more messages, - ** flag all cells covered by the messages to redraw. This will prevent - ** messages from smearing the map if it scrolls. - */ - int num = Messages.Num_Messages(); - if (num) { - CELL cell; - for (cell = Coord_Cell(TacticalCoord); cell < Coord_Cell(TacticalCoord) + Lepton_To_Cell(TacLeptonWidth)+1; cell++) { - (*this)[cell].Redraw_Objects(); - } - for (cell = Coord_Cell(TacticalCoord) + MAP_CELL_W; - cell < Coord_Cell(TacticalCoord) + MAP_CELL_W + Lepton_To_Cell(TacLeptonWidth)+1; cell++) { - (*this)[cell].Redraw_Objects(); - } - if (num > 1) { - for (cell = Coord_Cell(TacticalCoord) + MAP_CELL_W*2; - cell < Coord_Cell(TacticalCoord) + MAP_CELL_W*2 + Lepton_To_Cell(TacLeptonWidth)+1; cell++) { - (*this)[cell].Redraw_Objects(); - } - } - if (num > 3) { - for (cell = Coord_Cell(TacticalCoord) + MAP_CELL_W*3; - cell < Coord_Cell(TacticalCoord) + MAP_CELL_W*3 + Lepton_To_Cell(TacLeptonWidth)+1; cell++) { - (*this)[cell].Redraw_Objects(); - } - } - if (num > 4) { - for (cell = Coord_Cell(TacticalCoord) + MAP_CELL_W*4; - cell < Coord_Cell(TacticalCoord) + MAP_CELL_W*4 + Lepton_To_Cell(TacLeptonWidth)+1; cell++) { - (*this)[cell].Redraw_Objects(); - } - } - } - - /* - ** Check for a movement of the tactical map. If there has been some - ** movement, then part (or all) of the icons must be redrawn. - */ - if (Lepton_To_Pixel(Coord_X(DesiredTacticalCoord)) != Lepton_To_Pixel(Coord_X(TacticalCoord)) || - Lepton_To_Pixel(Coord_Y(DesiredTacticalCoord)) != Lepton_To_Pixel(Coord_Y(TacticalCoord))) { - - int xmod = Lepton_To_Pixel(Coord_X(DesiredTacticalCoord)); - int ymod = Lepton_To_Pixel(Coord_Y(DesiredTacticalCoord)); - - int oldx = Lepton_To_Pixel(Coord_X(TacticalCoord))-xmod; // Old relative offset. - int oldy = Lepton_To_Pixel(Coord_Y(TacticalCoord))-ymod; - - int oldw = Lepton_To_Pixel(TacLeptonWidth)-ABS(oldx); // Replicable width. - int oldh = Lepton_To_Pixel(TacLeptonHeight)-ABS(oldy); // Replicable height. - - if (oldw < 1) forced = true; - if (oldh < 1) forced = true; - - /* - ** Work out which map edges need to be redrawn - */ - BOOL redraw_right = (oldx < 0) ? TRUE : FALSE; //Right hand edge - BOOL redraw_left = (oldx > 0) ? TRUE : FALSE; //Left hand edge - BOOL redraw_bottom= (oldy < 0) ? TRUE : FALSE; //Bottom edge - BOOL redraw_top = (oldy > 0) ? TRUE : FALSE; //Top edge - - -//Colour_Debug(2); - /* - ** Blit any replicable block to avoid having to drawstamp. - */ - CachedIconsDrawn=0; - UnCachedIconsDrawn=0; - if (!forced && (oldw != Lepton_To_Pixel(TacLeptonWidth) || oldh != Lepton_To_Pixel(TacLeptonHeight))) { - Set_Cursor_Pos(-1); - /* - ** If hid page is in video memory then we may nned to blit from the seen page to - ** avoid blitting an overlapped region. - */ - if (HidPage.Get_IsDirectDraw() && !OverlappedVideoBlits){ - Hide_Mouse(); - SeenBuff.Blit(HidPage, - ((oldx < 0) ? -oldx : 0) +TacPixelX, - ((oldy < 0) ? -oldy : 0) +TacPixelY, - ((oldx < 0) ? 0 : oldx) +TacPixelX, - ((oldy < 0) ? 0 : oldy) +TacPixelY, - oldw, - oldh); - Show_Mouse(); - }else{ - HidPage.Blit(HidPage, - ((oldx < 0) ? -oldx : 0) +TacPixelX, - ((oldy < 0) ? -oldy : 0) +TacPixelY, - ((oldx < 0) ? 0 : oldx) +TacPixelX, - ((oldy < 0) ? 0 : oldy) +TacPixelY, - oldw, - oldh); - } - } else { - forced = true; - } - - if (oldx < 0) oldx = 0; - if (oldy < 0) oldy = 0; - - /* - ** Record new map position for future reference. - */ - ScenarioInit++; - Set_Tactical_Position(DesiredTacticalCoord); - ScenarioInit--; - - if (!forced) { - - /* - ** - ** Set the 'redraw stamp' bit for any cells that could not be copied. - ** - */ - int startx = -Lepton_To_Pixel(Coord_XLepton(TacticalCoord)); - int starty = -Lepton_To_Pixel(Coord_YLepton(TacticalCoord)); - oldw -= 24; - oldh -= 24; - - if (abs(oldx) < 0x25 && abs(oldy) < 0x25){ - - /* - ** The width of the area we redraw depends on the scroll speed - */ - int extra_x = (abs(oldx)>=16) ? 2 : 1; - int extra_y = (abs(oldy)>=16) ? 2 : 1; - - /* - ** Flag the cells across the top of the visible area if required - */ - if (redraw_top){ - for (y = starty; y <= starty+CELL_PIXEL_H*extra_y; y += CELL_PIXEL_H) { - for (x = startx; x <= Lepton_To_Pixel(TacLeptonWidth)+((CELL_PIXEL_W*2)); x += CELL_PIXEL_W) { - CELL c = Click_Cell_Calc(Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1) + TacPixelX, - Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1) + TacPixelY); - - if (c > 0) (*this)[c].Redraw_Objects(true); - } - } - } - - /* - ** Flag the cells across the bottom of the visible area if required - */ - if (redraw_bottom){ - for (y = Lepton_To_Pixel(TacLeptonHeight)-CELL_PIXEL_H*(1+extra_y); y <= Lepton_To_Pixel(TacLeptonHeight)+CELL_PIXEL_H*3; y += CELL_PIXEL_H) { - for (x = startx; x <= Lepton_To_Pixel(TacLeptonWidth)+((CELL_PIXEL_W*2)); x += CELL_PIXEL_W) { - CELL c = Click_Cell_Calc(Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1) + TacPixelX, - Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1) + TacPixelY); - - if (c > 0) (*this)[c].Redraw_Objects(true); - } - } - } - - /* - ** Flag the cells down the left of the visible area if required - */ - if (redraw_left){ - for (x = startx; x <= startx + CELL_PIXEL_W*extra_x; x += CELL_PIXEL_W) { - for (y = starty; y <= Lepton_To_Pixel(TacLeptonHeight)+((CELL_PIXEL_H*2)); y += CELL_PIXEL_H) { - CELL c = Click_Cell_Calc(Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1) + TacPixelX, - Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1) + TacPixelY); - - if (c > 0) (*this)[c].Redraw_Objects(true); - } - } - } - - /* - ** Flag the cells down the right of the visible area if required - */ - if (redraw_right){ - for (x = Lepton_To_Pixel(TacLeptonWidth)-CELL_PIXEL_W*(extra_x+1); x <= Lepton_To_Pixel(TacLeptonWidth)+CELL_PIXEL_W*3; x += CELL_PIXEL_W) { - for (y = starty; y <= Lepton_To_Pixel(TacLeptonHeight)+((CELL_PIXEL_H*2)); y += CELL_PIXEL_H) { - CELL c = Click_Cell_Calc(Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1) + TacPixelX, - Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1) + TacPixelY); - - if (c > 0) (*this)[c].Redraw_Objects(true); - } - } - } - - }else{ - - /* - ** Set the 'redraw stamp' bit for any cells that could not be copied. - */ - int startx = -Lepton_To_Pixel(Coord_XLepton(TacticalCoord)); - int starty = -Lepton_To_Pixel(Coord_YLepton(TacticalCoord)); - oldw -= 24; - oldh -= 24; - for (y = starty; y <= Lepton_To_Pixel(TacLeptonHeight)+((CELL_PIXEL_H*2)); y += CELL_PIXEL_H) { - for (x = startx; x <= Lepton_To_Pixel(TacLeptonWidth)+((CELL_PIXEL_W*2)); x += CELL_PIXEL_W) { - if (x <= oldx || x >= oldx+oldw || y <= oldy || y >= oldy+oldh) { - CELL c = Click_Cell_Calc(Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1) + TacPixelX, - Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1) + TacPixelY); - - if (c > 0) { - (*this)[c].Redraw_Objects(true); - } - } - } - } - } - } - - } else { - - /* - ** Set the tactical coordinate just in case the desired tactical has changed but - ** not enough to result in any visible map change. This is likely to occur with very - ** slow scroll rates. - */ - ScenarioInit++; - if (DesiredTacticalCoord != TacticalCoord) { - Set_Tactical_Position(DesiredTacticalCoord); - } - ScenarioInit--; - } - - /* - ** If the entire tactical map is forced to be redrawn, then set all the redraw flags - ** and let the normal processing take care of the rest. - */ - if (forced) { - CellRedraw.Set(); - } - -//Colour_Debug(3); - /* - ** The first order of business is to redraw all the underlying icons that are - ** flagged to be redrawn. - */ - //Redraw_Icons(CELL_BLIT_ONLY); - Redraw_Icons(0); - - /* - ** Once the icons are drawn, duplicate the bottom line of the screen into the phantom - ** area one line below the screen. This causes the predator effect to work on any - ** shape drawn at the bottom of the screen. - */ -//Colour_Debug(4); -#ifdef FIX_ME_LATER -// HidPage.Blit(HidPage, 0, HidPage.Get_Height()-1, 0, HidPage.Get_Height(), HidPage.Get_Width(), 1, false); -#endif //FIX_ME_LATER - if (HidPage.Lock()){ - - //Redraw_Icons(CELL_DRAW_ONLY); - - /* - ** Redraw the game objects layer by layer. The layer drawing occurs on the ground layer - ** first and then followed by all the layers in increasing altituded. - */ - for (LayerType layer = LAYER_GROUND; layer < LAYER_COUNT; layer++) { - for (int index = 0; index < Layer[layer].Count(); index++) { - Layer[layer][index]->Render(forced); - } - } - - /* - ** Finally, redraw the shadow overlay as necessary. - */ -//Colour_Debug(5); - Redraw_Shadow(); - } - - Redraw_Shadow_Rects(); - - HidPage.Unlock(); - -//Colour_Debug(8); - /* - ** Draw the rubber band over the top of it all. - */ - if (IsRubberBand) { - LogicPage->Draw_Rect(BandX+TacPixelX, BandY+TacPixelY, NewX+TacPixelX, NewY+TacPixelY, WHITE); - } - /* - ** Clear the redraw flags so that normal redraw flag setting can resume. - */ - CellRedraw.Reset(); -//Colour_Debug(0); - -#ifdef SCENARIO_EDITOR - /* - ** If we're placing an object (PendingObject is non-NULL), and that object - ** is NOT an icon, smudge, or overlay, draw it here. - ** Terrain, Buildings & Aircraft aren't drawn at the cell's center coord; - ** they're drawn at the upper left coord, so I have to AND the coord value - ** with 0xFF00FF00 to strip off the lepton coordinates, but leave the - ** cell coordinates. - */ - if (Debug_Map && PendingObjectPtr) { - PendingObjectPtr->Coord = PendingObjectPtr->Class_Of().Coord_Fixup(Cell_Coord(ZoneCell + ZoneOffset)); - PendingObjectPtr->Render(true); - } -#endif - } -} - - -/*********************************************************************************************** - * DisplayClass::Redraw_Icons -- Draws all terrain icons necessary. * - * * - * This routine will redraw all of the terrain icons that are flagged * - * to be redrawn. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none. * - * * - * HISTORY: * - * 02/14/1994 JLB : Created. * - * 05/01/1994 JLB : Converted to member function. * - * 06/20/1994 JLB : Uses cell drawing support function. * - * 12/06/1994 JLB : Scans tactical view in separate row/colum loops * - * 12/24/1994 JLB : Uses the cell bit flag array to determine what to redraw. * - *=============================================================================================*/ -void DisplayClass::Redraw_Icons(int draw_flags) -{ - IsShadowPresent = false; - for (int y = -Coord_YLepton(TacticalCoord); y <= TacLeptonHeight; y += CELL_LEPTON_H) { - for (int x = -Coord_XLepton(TacticalCoord); x <= TacLeptonWidth; x += CELL_LEPTON_W) { - COORDINATE coord = Coord_Add(TacticalCoord, XY_Coord(x, y)); - CELL cell = Coord_Cell(coord); - coord = Cell_Coord(cell) & 0xFF00FF00L; - - /* - ** Only cells flagged to be redraw are examined. - */ - if (In_View(cell) && Is_Cell_Flagged(cell)) { - int xpixel; - int ypixel; - - if (Coord_To_Pixel(coord, xpixel, ypixel)) { - CellClass * cellptr = &(*this)[Coord_Cell(coord)]; - - /* - ** If there is a portion of the underlying icon that could be visible, - ** then draw it. Also draw the cell if the shroud is off. - */ - if (cellptr->Is_Visible(PlayerPtr) || Debug_Unshroud) { // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - cellptr->Draw_It(xpixel, ypixel, draw_flags); - } - - /* - ** If any cell is not fully mapped, then flag it so that the shadow drawing - ** process will occur. Only draw the shadow if Debug_Unshroud is false. - */ - if (!cellptr->Is_Mapped(PlayerPtr) && !Debug_Unshroud) { // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - IsShadowPresent = true; - } - } - } - } - } -} - - -/*********************************************************************************************** - * DisplayClass::Redraw_Shadow -- Draw the shadow overlay. * - * * - * This routine is called after all other tactical map rendering takes place. It draws * - * the shadow map over the tactical map. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - * 08/06/1995 JLB : Clips the fill rect if necessary. * - *=============================================================================================*/ -void DisplayClass::Redraw_Shadow(void) -{ - if (IsShadowPresent) { - for (int y = -Coord_YLepton(TacticalCoord); y <= TacLeptonHeight; y += CELL_LEPTON_H) { - for (int x = -Coord_XLepton(TacticalCoord); x <= TacLeptonWidth; x += CELL_LEPTON_W) { - COORDINATE coord = Coord_Add(TacticalCoord, XY_Coord(x, y)); - CELL cell = Coord_Cell(coord); - coord = Cell_Coord(cell) & 0xFF00FF00; - - /* - ** Only cells flagged to be redraw are examined. - */ - if (In_View(cell) && Is_Cell_Flagged(cell)) { - int xpixel; - int ypixel; - - if (Coord_To_Pixel(coord, xpixel, ypixel)) { - CellClass * cellptr = &(*this)[Coord_Cell(coord)]; - - if (!cellptr->Is_Mapped(PlayerPtr)) { // Pass player pointer since we will only be rendering in single player mode. ST - 3/6/2019 1:36PM - if (cellptr->Is_Visible(PlayerPtr)) { // Pass player pointer since we will only be rendering in single player mode. ST - 3/6/2019 1:36PM - int shadow = Cell_Shadow(cell, PlayerPtr); // Pass player pointer since we will only be rendering in single player mode. ST - 3/6/2019 1:36PM - if (shadow >= 0) { - CC_Draw_Shape(ShadowShapes, shadow, xpixel, ypixel, WINDOW_TACTICAL, SHAPE_GHOST, NULL, ShadowTrans); - } - } - } - } - } - } - } - } -} - -/*********************************************************************************************** - * DisplayClass::Redraw_Shadow -- Draw the shadow overlay. * - * * - * This routine is called after all other tactical map rendering takes place. It draws * - * the shadow map over the tactical map. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - * 08/06/1995 JLB : Clips the fill rect if necessary. * - *=============================================================================================*/ -void DisplayClass::Redraw_Shadow_Rects(void) -{ - if (IsShadowPresent) { - for (int y = -Coord_YLepton(TacticalCoord); y <= TacLeptonHeight; y += CELL_LEPTON_H) { - for (int x = -Coord_XLepton(TacticalCoord); x <= TacLeptonWidth; x += CELL_LEPTON_W) { - COORDINATE coord = Coord_Add(TacticalCoord, XY_Coord(x, y)); - CELL cell = Coord_Cell(coord); - coord = Cell_Coord(cell) & 0xFF00FF00; - - /* - ** Only cells flagged to be redraw are examined. - */ - if (In_View(cell) && Is_Cell_Flagged(cell)) { - int xpixel; - int ypixel; - - if (Coord_To_Pixel(coord, xpixel, ypixel)) { - CellClass * cellptr = &(*this)[Coord_Cell(coord)]; - - if (!cellptr->Is_Mapped(PlayerPtr)) { // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - if (!cellptr->Is_Visible(PlayerPtr)) { // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - int ww = CELL_PIXEL_W; - int hh = CELL_PIXEL_H; - - if (Clip_Rect(&xpixel, &ypixel, &ww, &hh, Lepton_To_Pixel(TacLeptonWidth), Lepton_To_Pixel(TacLeptonHeight)) >= 0) { - LogicPage->Fill_Rect(TacPixelX+xpixel, TacPixelY+ypixel, TacPixelX+xpixel+ww-1, TacPixelY+ypixel+hh-1, BLACK); - } - } - } - } - } - } - } - } -} - -/*********************************************************************************************** - * DisplayClass::Next_Object -- Searches for next object on display. * - * * - * This utility routine is used to find the "next" object from the object specified. This * - * is typically used when is pressed and the current object shifts. * - * * - * INPUT: object -- The current object to base the "next" calculation off of. * - * * - * OUTPUT: Returns with a pointer to the next object. If there is no objects available, * - * then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * DisplayClass::Next_Object(ObjectClass * object) -{ - ObjectClass * firstobj = 0; - bool foundmatch = false; - - if (!object) { - foundmatch = true; - } - for (unsigned uindex = 0; uindex < (unsigned)Layer[LAYER_GROUND].Count(); uindex++) { - ObjectClass * obj = Layer[LAYER_GROUND][uindex]; - - /* - ** Verify that the object can be selected by and is owned by the player. - */ - if (obj && obj->Is_Techno() && ((TechnoClass *)obj)->Is_Discovered_By_Player() && obj->Class_Of().IsSelectable && obj->Owner() == PlayerPtr->Class->House) { - if (!firstobj) firstobj = obj; - if (foundmatch) return(obj); - if (object == obj) foundmatch = true; - } - } - return(firstobj); -} - - -/*********************************************************************************************** - * DisplayClass::Prev_Object -- Searches for the previous object on the map. * - * * - * This routine will search for the previous object. Previous is defined as the one listed * - * before the specified object in the ground layer. If there is no specified object, then * - * the last object in the ground layer is returned. * - * * - * INPUT: object -- Pointer to the object that "previous" is to be defined from. * - * * - * OUTPUT: Returns with a pointer to the object previous to the specified one. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/24/1995 JLB : Created. * - *=============================================================================================*/ -ObjectClass * DisplayClass::Prev_Object(ObjectClass * object) -{ - ObjectClass * firstobj = 0; - bool foundmatch = false; - - if (!object) { - foundmatch = true; - } - for (int uindex = Layer[LAYER_GROUND].Count()-1; uindex >= 0; uindex--) { - ObjectClass * obj = Layer[LAYER_GROUND][uindex]; - - /* - ** Verify that the object can be selected by and is owned by the player. - */ - if (obj && obj->Is_Techno() && ((TechnoClass *)obj)->Is_Discovered_By_Player() && obj->Class_Of().IsSelectable && obj->Owner() == PlayerPtr->Class->House) { - if (!firstobj) firstobj = obj; - if (foundmatch) return(obj); - if (object == obj) foundmatch = true; - } - } - return(firstobj); -} - - -/*********************************************************************************************** - * DisplayClass::Pixel_To_Coord -- converts screen coord to COORDINATE * - * * - * INPUT: * - * x,y pixel coordinates to convert * - * * - * OUTPUT: * - * COORDINATE of pixel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/09/1994 BR : Created. * - * 12/06/1994 JLB : Uses map dimension variables in display class. * - * 12/10/1994 JLB : Uses union to speed building coordinate value. * - *=============================================================================================*/ -COORDINATE DisplayClass::Pixel_To_Coord(int x, int y) -{ - /* - ** Normalize the pixel coorindates to be relative to the upper left corner - ** of the tactical map. The coordinates are expressed in leptons. - */ - x -= TacPixelX; - x = Pixel_To_Lepton(x); - y -= TacPixelY; - y = Pixel_To_Lepton(y); - - /* - ** If pixel coordinate is over the tactical map, then translate it into a coordinate - ** value. If not, then just return with NULL. - */ - // Possibly ignore the view constraints if we aren't using the internal renderer. ST - 4/17/2019 9:06AM - //if (x < TacLeptonWidth && y < TacLeptonHeight) { - if (IgnoreViewConstraints || (x < TacLeptonWidth && y < TacLeptonHeight)) { - return(Coord_Add(TacticalCoord, XY_Coord(x, y))); - } - return(0); -} - - -/*********************************************************************************************** - * DisplayClass::Calculated_Cell -- Fetch a map cell based on specified method. * - * * - * Find a cell meeting the specified requirements. This function is * - * used for scenario reinforcements. * - * * - * INPUT: dir -- Method of picking a map cell. * - * * - * house -- The house to base calculation on. * - * * - * OUTPUT: Returns with the calculated cell. If 0, then this indicates * - * that no legal cell was found. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 04/11/1994 JLB : Revamped. * - * 05/18/1994 JLB : Converted to member function. * - *=============================================================================================*/ -CELL DisplayClass::Calculated_Cell(SourceType dir, HousesType house) -{ - CELL cell = 0; // Working cell number. - - while (cell == 0) { - int x,y; - int index; - - /* - ** Select a candidate cell based on the desired method. - */ - switch (dir) { - - /* - ** Looks for the northern most straight path shipping lane and returns - ** the cell of one of the ends. - */ - case SOURCE_SHIPPING: - for (y = 0; y < MapCellHeight; y++) { - for (x = 0; x < MapCellWidth; x++) { - if ((*this)[XY_Cell(MapCellX+x, MapCellY+y)].Land_Type() != LAND_WATER) break; - } - if (x == MapCellWidth) { - return(XY_Cell(MapCellX+MapCellWidth, MapCellY+y)); - } - } - return(0); - - /* - ** Select a map edge. - */ - case SOURCE_NORTH: - index = Random_Pick(1, MapCellWidth); - for (x = 0; x < MapCellWidth; x++) { - cell = XY_Cell(MapCellX+((x+index)%MapCellWidth), MapCellY-1); - if ((*this)[cell].Is_Generally_Clear() && (*this)[cell+MAP_CELL_W].Is_Generally_Clear()) break; - } - if (x == MapCellWidth) return(0); - break; - - case SOURCE_EAST: - index = Random_Pick(1, MapCellHeight); - for (y = 0; y < MapCellHeight; y++) { - cell = XY_Cell(MapCellX+MapCellWidth, MapCellY+((y+index)%MapCellHeight)); - if ((*this)[cell].Is_Generally_Clear() && (*this)[cell-1].Is_Generally_Clear()) break; - } - if (y == MapCellHeight) return(0); - break; - - case SOURCE_SOUTH: - index = Random_Pick(1, MapCellWidth); - for (x = 0; x < MapCellWidth; x++) { - cell = XY_Cell(MapCellX+((x+index)%MapCellWidth), MapCellY+MapCellHeight); - if ((*this)[cell].Is_Generally_Clear() && (*this)[cell-MAP_CELL_W].Is_Generally_Clear()) break; - } - if (x == MapCellWidth) return(0); - break; - - case SOURCE_WEST: - index = Random_Pick(1, MapCellHeight); - for (y = 0; y < MapCellHeight; y++) { - cell = XY_Cell(MapCellX-1, MapCellY+((y+index)%MapCellHeight)); - if ((*this)[cell].Is_Generally_Clear() && (*this)[cell+1].Is_Generally_Clear()) break; - } - if (y == MapCellHeight) return(0); - break; - - /* - ** Drop in at a random location. - */ - case SOURCE_AIR: - cell = Waypoint[WAYPT_REINF]; - if (cell < 1) { - cell = Coord_Cell(TacticalCoord); - return(cell); - } else { - if ((*this)[cell].Cell_Techno()) { - for (int radius = 1; radius < 7; radius++) { - CELL newcell = Coord_Cell(Coord_Scatter(Cell_Coord(cell), radius << 8, true)); - if (In_Radar(newcell) && !(*this)[newcell].Cell_Techno()) { - cell = newcell; - break; - } - } - } - } - break; - - /* - ** Dramatic entry point is somewhere on the visible screen as defined - ** by the current tactical map position. - */ - case SOURCE_VISIBLE: - cell = XY_Cell(Coord_XCell(TacticalCoord)+Random_Pick(0, Lepton_To_Cell(TacLeptonWidth)-1), Coord_YCell(TacticalCoord)+Random_Pick(0, Lepton_To_Cell(TacLeptonHeight)-1)); - if (house == PlayerPtr->Class->House && !In_Radar(cell)) { - cell = 0; - } - break; - - /* - ** Drop off near friendly base or near a friendly unit or - ** just randomly if all else fails. - */ - case SOURCE_ENEMYBASE: - case SOURCE_HOMEBASE: - return(0); - - /* - ** Find an unoccupied beach cell. - */ - case SOURCE_BEACH: { - CELL cells[MAP_CELL_W]; - CELL alternate[MAP_CELL_W]; - unsigned counter=0; - - for (x = 0; x < MapCellWidth; x++) { - CELL newcell = 0; - - if ((*this)[XY_Cell(x + MapCellX, MapCellHeight + MapCellY)].Land_Type() != LAND_WATER) continue; - if ((*this)[XY_Cell(x + MapCellX, MapCellHeight + MapCellY-1)].Land_Type() != LAND_WATER) continue; - for (y = MapCellHeight; y >= 0; y--) { - newcell = XY_Cell(x + MapCellX, y + MapCellY); - if ((*this)[newcell].Cell_Techno()) { - break; - } - if ((*this)[newcell].Land_Type() != LAND_WATER) { - break; - } - } - LandType land = (*this)[newcell].Land_Type(); - if (( land == LAND_BEACH || land == LAND_CLEAR || land == LAND_ROAD) && - !(*this)[newcell].Cell_Techno() && - !(*this)[newcell].Cell_Terrain() && - !(*this)[newcell-MAP_CELL_W].Cell_Techno() && - !(*this)[newcell-MAP_CELL_W].Cell_Terrain() && - !(*this)[newcell-(MAP_CELL_W*2)].Cell_Terrain() && - !(*this)[newcell-(MAP_CELL_W*2)].Cell_Techno()) { - - cells[counter++] = newcell; - if (counter >= (sizeof(cells) / sizeof(cells[0]))) { - break; - } - } - } - - /* - ** Fixup entry list so that it doesn't come close to blocking terrain or other - ** units. - */ - int counter2 = 0; - for (int index = 1; index < (int)counter-1; index++) { - if (Cell_X(cells[index-1])+1 == Cell_X(cells[index]) && Cell_X(cells[index+1])-1 == Cell_X(cells[index])) { - alternate[counter2++] = cells[index]; - } - } - - CELL cell = 0; - if (counter2) { - if (counter2 < 4) { - cell = alternate[counter2-1]; - } else { - cell = alternate[counter2 - (counter2 / 4)]; - } - } else { - if (counter) { - if (counter < 4) { - cell = cells[counter-1]; - } else { - cell = cells[counter - (counter / 4)]; - } - } - } - if (cell) { - if (Map.Theater == THEATER_DESERT) { - cell += MAP_CELL_W; - } - } - return(cell); - } - - case SOURCE_OCEAN: - cell = XY_Cell(Random_Pick(0, MapCellWidth-2)+MapCellX, MapCellHeight+MapCellY); - break; - - default: - return(0); - } - - /* - ** The selected edge cell must be unoccupied and if this is for - ** the player, then it must be on an accessible map cell. - */ - cell &= 0x0FFF; - if (cell && (*this)[cell].Cell_Techno()) { - cell = 0; - } - } - return(cell); -} - - -/*********************************************************************************************** - * DisplayClass::Select_These -- All selectable objects in region are selected. * - * * - * Use this routine to simultaneously select all objects within the coordinate region * - * specified. This routine is used by the multi-select rubber band handler. * - * * - * INPUT: coord1 -- Coordinate of one corner of the selection region. * - * * - * coord2 -- The opposite corner of the selection region. * - * * - * additive -- Does this add to the existing selection or replace it. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - * 04/25/1995 JLB : Limited to non-building type. * - *=============================================================================================*/ -static bool should_exclude_from_selection(ObjectClass* obj) -{ - return (obj->What_Am_I() == RTTI_UNIT) && - (((UnitClass *)obj)->Class->IsToHarvest || - *((UnitClass *)obj) == UNIT_MCV); -} - -void DisplayClass::Select_These(COORDINATE coord1, COORDINATE coord2, bool additive) -{ - COORDINATE tcoord = TacticalCoord; //Cell_Coord(TacticalCell) & 0xFF00FF00L; - - coord1 = Coord_Add(tcoord, coord1); - coord2 = Coord_Add(tcoord, coord2); - int x1 = Coord_X(coord1); - int x2 = Coord_X(coord2); - int y1 = Coord_Y(coord1); - int y2 = Coord_Y(coord2); - - /* - ** Ensure that coordinate number one represents the upper left corner - ** and coordinate number two represents the lower right corner. - */ - if (x1 > x2) { - int temp = x1; - x1 = x2; - x2 = temp; - } - if (y1 > y2) { - int temp = y1; - y1 = y2; - y2 = temp; - } - - /* - ** Sweep through all ground layer objects and select the ones within the - ** bounding box. - */ - if (!additive) { - Unselect_All(); - } - AllowVoice = true; - for (int index = 0; index < Layer[LAYER_GROUND].Count(); index++) { - ObjectClass * obj = Layer[LAYER_GROUND][index]; - COORDINATE ocoord = obj->Center_Coord(); - int x = Coord_X(ocoord); - int y = Coord_Y(ocoord); - - /* - ** Only try to select objects that are owned by the player, are allowed to be - ** selected, and are within the bouding box. - */ - if ( obj->Class_Of().IsSelectable && - obj->What_Am_I() != RTTI_BUILDING && - x >= x1 && x <= x2 && y >= y1 && y <= y2) { - bool old_allow_voice = AllowVoice; - bool is_player_controlled = obj->Owner() == PlayerPtr->Class->House; - AllowVoice &= is_player_controlled; - if (obj->Select(true)) { - if (is_player_controlled) { - old_allow_voice = false; - } - } - AllowVoice = old_allow_voice; - } - } - - /* - ** Select any aircraft with the bounding box. - */ - for (int air_index = 0; air_index < Aircraft.Count(); air_index++) { - AircraftClass * aircraft = Aircraft.Ptr(air_index); - COORDINATE ocoord = Coord_Add(aircraft->Center_Coord(), XY_Coord(0, -Pixel_To_Lepton(aircraft->Altitude))); - int x = Coord_X(ocoord); - int y = Coord_Y(ocoord); - - /* - ** Only try to select objects that are owned by the player, are allowed to be - ** selected, and are within the bounding box. - */ - if ( aircraft->Class_Of().IsSelectable && - !aircraft->Is_Selected_By_Player() && - x >= x1 && x <= x2 && y >= y1 && y <= y2) { - bool old_allow_voice = AllowVoice; - bool is_player_controlled = aircraft->Owner() == PlayerPtr->Class->House; - AllowVoice &= is_player_controlled; - if (aircraft->Select(true)) { - if (is_player_controlled) { - old_allow_voice = false; - } - } - AllowVoice = old_allow_voice; - } - } - - /* - ** If a mix of player and non-player controlled units were selected, make sure non-player controlled units are de-selected - */ - bool player_controlled_units = false, non_player_controlled_units = false; - for (int i = 0; (i < CurrentObject.Count()) && (!player_controlled_units || !non_player_controlled_units); ++i) { - HouseClass * hptr = HouseClass::As_Pointer(CurrentObject[i]->Owner()); - if (CurrentObject[i]->Owner() == PlayerPtr->Class->House) { - player_controlled_units = true; - } - else { - non_player_controlled_units = true; - } - } - if (player_controlled_units && non_player_controlled_units) { - for (int i = 0; i < CurrentObject.Count(); ++i) { - HouseClass * hptr = HouseClass::As_Pointer(CurrentObject[i]->Owner()); - if (CurrentObject[i]->Owner() != PlayerPtr->Class->House) { - int count_before = CurrentObject.Count(); - CurrentObject[i]->Unselect(); - if (count_before <= CurrentObject.Count()) { - GlyphX_Debug_Print("Select_These failed to remove an object"); - CurrentObject.Delete(CurrentObject[i]); - } - --i; - } - } - } - - /* - ** If player-controlled units are non-additively selected, remove harvesters and MCVs if they aren't the only types of units selected - */ - if (!additive && player_controlled_units) { - bool any_to_exclude = false, all_to_exclude = true; - for (int i = 0; i < CurrentObject.Count(); ++i) { - bool exclude = should_exclude_from_selection(CurrentObject[i]); - any_to_exclude |= exclude; - all_to_exclude &= exclude; - } - if (any_to_exclude && !all_to_exclude) { - for (int i = 0; i < CurrentObject.Count(); ++i) { - if (should_exclude_from_selection(CurrentObject[i])) { - int count_before = CurrentObject.Count(); - CurrentObject[i]->Unselect(); - if (count_before <= CurrentObject.Count()) { - GlyphX_Debug_Print("Select_These failed to remove an object"); - CurrentObject.Delete(CurrentObject[i]); - } - --i; - } - } - } - } - - AllowVoice = true; -} - - -/*********************************************************************************************** - * DisplayClass::Refresh_Band -- Causes all cells under the rubber band to be redrawn. * - * * - * Use this routine to flag all cells that are covered in some fashion by the multi-unit * - * select "rubber band" to be redrawn. This is necessary whenever the rubber band changes * - * size or is being removed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Refresh_Band(void) -{ - if (IsRubberBand) { - - /* - ** In rubber band mode, mark all cells under the "rubber band" to be - ** redrawn. - */ - int x1 = BandX+TacPixelX; - int y1 = BandY+TacPixelY; - int x2 = NewX+TacPixelX; - int y2 = NewY+TacPixelY; - - if (x1 > x2) { - int temp = x1; - x1 = x2; - x2 = temp; - } - if (y1 > y2) { - int temp = y1; - y1 = y2; - y2 = temp; - } - - CELL cell; - for (int y = y1; y <= y2+CELL_PIXEL_H; y += CELL_PIXEL_H) { - cell = Click_Cell_Calc(x1, Bound(y, 0, TacPixelY+Lepton_To_Pixel(TacLeptonHeight))); - if (cell != -1) (*this)[cell].Redraw_Objects(); - - cell = Click_Cell_Calc(x2, Bound(y, 0, TacPixelY+Lepton_To_Pixel(TacLeptonHeight))); - if (cell != -1) (*this)[cell].Redraw_Objects(); - } - - for (int x = x1; x <= x2+CELL_PIXEL_W; x += CELL_PIXEL_W) { - cell = Click_Cell_Calc(Bound(x, 0, TacPixelX+Lepton_To_Pixel(TacLeptonWidth)), y1); - if (cell != -1) (*this)[cell].Redraw_Objects(); - - cell = Click_Cell_Calc(Bound(x, 0, TacPixelX+Lepton_To_Pixel(TacLeptonWidth)), y2); - if (cell != -1) (*this)[cell].Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * DisplayClass::TacticalClass::Action -- Processes input for the tactical map. * - * * - * This routine handles the input directed at the tactical map. Since input, in this * - * regard, includes even the presence of the mouse over the tactical map, this routine * - * is called nearly every game frame. It handles adjusting the mouse shape as well as * - * giving orders to units. * - * * - * INPUT: flags -- The gadget event flags that triggered the call to this function. * - * * - * key -- A reference to the keyboard event (if any). * - * * - * OUTPUT: bool; Should processing be aborted on any succeeding buttons in the chain? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/17/1995 JLB : Created. * - *=============================================================================================*/ -int DisplayClass::TacticalClass::Action(unsigned flags, KeyNumType & key) -{ - int x,y; // Sub cell pixel coordinates. - bool shadow; - ObjectClass *object = 0; - ActionType action = ACTION_NONE; // Action possible with currently selected object. - - /* - ** Set some working variables that depend on the mouse position. For the press - ** or release event, special mouse queuing storage variables are used. Other - ** events must use the current mouse position globals. - */ - bool edge = false; - if (flags & (LEFTPRESS|LEFTRELEASE|RIGHTPRESS|RIGHTRELEASE)) { - x = _Kbd->MouseQX; - y = _Kbd->MouseQY; - } else { - x = Get_Mouse_X(); - y = Get_Mouse_Y(); - - if (x == 0 || y == 199 || x == 319) edge = true; - } - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); -// CELL cell = Map.Click_Cell_Calc(x, y); - if (coord) { - shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud); // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - x -= Map.TacPixelX; - y -= Map.TacPixelY; - - /* - ** Cause any displayed cursor to move along with the mouse cursor. - */ - if (cell != Map.ZoneCell) { - Map.Set_Cursor_Pos(cell); - } - - /* - ** Determine the object that the mouse is currently over. - */ - if (!shadow) { -// int xxx = x + Lepton_To_Pixel(Coord_XLepton(Map.TacticalCoord)); -// int yyy = y + Lepton_To_Pixel(Coord_YLepton(Map.TacticalCoord)); -// object = Map.Cell_Object(cell, xxx % CELL_PIXEL_W, yyy % CELL_PIXEL_H); - object = Map.Close_Object(coord); - - /* - ** Special case check to ignore cloaked object if not owned by the player. - */ -// if (object && object->Is_Techno() && !((TechnoClass *)object)->IsOwnedByPlayer && ((TechnoClass *)object)->Cloak == CLOAKED) { -// object = NULL; -// } - } - - /* - ** If there is a currently selected object, then the action to perform if - ** the left mouse button were clicked must be determined. - */ - if (CurrentObject.Count()) { - if (object) { - action = Best_Object_Action(object); - } else { - action = Best_Object_Action(cell); - } - } else { - if (object && object->Class_Of().IsSelectable) { - action = ACTION_SELECT; - } - - if (Map.IsRepairMode) { - if (object && object->Owner() == PlayerPtr->Class->House && object->Can_Repair()) { - action = ACTION_REPAIR; - } else { - action = ACTION_NO_REPAIR; - } - } - - if (Map.IsSellMode) { - if (object && object->Owner() == PlayerPtr->Class->House && object->Can_Demolish()) { - if (object->What_Am_I() == RTTI_BUILDING) { - action = ACTION_SELL; - } else { - action = ACTION_SELL_UNIT; - } - } else { - - /* - ** Check to see if the cursor is over an owned wall. - */ - if (Map[cell].Overlay != OVERLAY_NONE && - OverlayTypeClass::As_Reference(Map[cell].Overlay).IsWall && - Map[cell].Owner == PlayerPtr->Class->House) { - action = ACTION_SELL; - } else { - action = ACTION_NO_SELL; - } - } - } - - if (Map.IsTargettingMode == SPC_ION_CANNON) { - action = ACTION_ION; - } - - if (Map.IsTargettingMode == SPC_NUCLEAR_BOMB) { - action = ACTION_NUKE_BOMB; - } - - if (Map.IsTargettingMode == SPC_AIR_STRIKE) { - action = ACTION_AIR_STRIKE; - } - - if (Map.PendingObject) { - action = ACTION_NONE; - } - } - - /* - ** Move any cursor displayed. - */ - if (cell != Map.ZoneCell) { - Map.Set_Cursor_Pos(cell); - } - - /* - ** A right mouse button press cancels the current action or selection. - */ - if (flags & RIGHTPRESS) { - Map.Mouse_Right_Press(); - } - - /* - ** Make sure that if the mouse button has been released and the map doesn't know about it, - ** then it must be informed. Do this by faking a mouse release event. - */ - if ((flags & LEFTUP) && Map.IsRubberBand) { - flags |= LEFTRELEASE; - } - - /* - ** When the mouse buttons aren't pressed, only the mouse cursor shape is processed. - ** The shape changes depending on what object the mouse is currently over and what - ** object is currently selected. - */ - if (!edge) { - if (flags & LEFTUP) { - Map.Mouse_Left_Up(shadow, object, action); - } - } - - /* - ** Normal actions occur when the mouse button is released. The press event is - ** intercepted and possible rubber-band mode is flagged. - */ - if (flags & LEFTRELEASE) { - Map.Mouse_Left_Release(cell, x, y, object, action); - } - - /* - ** When the mouse is first pressed on the map, then record the mouse - ** position so that a proper check before going into rubber band - ** mode can be made. Rubber band mode starts when the mouse is - ** held down and moved a certain minimum distance. - */ - if (!edge && (flags & LEFTPRESS)) { - Map.Mouse_Left_Press(x, y); - } - - /* - ** While the mouse is being held down, determine if rubber band mode should - ** start. If rubber band mode is already active, then update the size - ** and flag the map to redraw it. - */ - if (flags & LEFTHELD) { - Map.Mouse_Left_Held(x, y); - } - } - - return(GadgetClass::Action(0, key)); -} - -/*********************************************************************************************** - * DisplayClass::TacticalClass::Selection_At_Mouse -- Object selection * - * * - * Selects any objects at the current mouse position. * - * * - * * - * INPUT: flags -- The gadget event flags that triggered the call to this function. * - * * - * key -- A reference to the keyboard event (if any). * - * * - * OUTPUT: bool; Should processing be aborted on any succeeding buttons in the chain? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 2019/09/17 JAS * - *=============================================================================================*/ -int DisplayClass::TacticalClass::Selection_At_Mouse(unsigned flags, KeyNumType & key) -{ - int x, y; // Sub cell pixel coordinates. - bool edge = false; - if (flags & (LEFTPRESS | LEFTRELEASE | RIGHTPRESS | RIGHTRELEASE)) { - x = _Kbd->MouseQX; - y = _Kbd->MouseQY; - } - else { - x = Get_Mouse_X(); - y = Get_Mouse_Y(); - - if (x == 0 || y == 199 || x == 319) edge = true; - } - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); - - if (coord) { - bool shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud); // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - x -= Map.TacPixelX; - y -= Map.TacPixelY; - - /* - ** Cause any displayed cursor to move along with the mouse cursor. - */ - if (cell != Map.ZoneCell) { - Map.Set_Cursor_Pos(cell); - } - - ObjectClass* object = nullptr; - - /* - ** Determine the object that the mouse is currently over. - */ - if (!shadow) { - object = Map.Close_Object(coord); - } - - if (object != nullptr) - { - bool shiftdown = DLL_Export_Get_Input_Key_State(KN_LSHIFT); - - if (shiftdown) - { - Map.Mouse_Left_Release(cell, x, y, object, ACTION_TOGGLE_SELECT); - } - else - { - Map.Mouse_Left_Release(cell, x, y, object, ACTION_SELECT); - } - - } - else - { - Unselect_All(); - } - } - - return 0; -} - -/*********************************************************************************************** - * DisplayClass::TacticalClass::Command_Object -- Commanding Units * - * * - * Issues a command to the currently selected unit. * - * * - * * - * INPUT: flags -- The gadget event flags that triggered the call to this function. * - * * - * key -- A reference to the keyboard event (if any). * - * * - * OUTPUT: bool; Should processing be aborted on any succeeding buttons in the chain? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 2019/09/17 JAS * - *=============================================================================================*/ -int DisplayClass::TacticalClass::Command_Object(unsigned flags, KeyNumType & key) -{ - int x, y; // Sub cell pixel coordinates. - bool edge = false; - if (flags & (LEFTPRESS | LEFTRELEASE | RIGHTPRESS | RIGHTRELEASE)) { - x = _Kbd->MouseQX; - y = _Kbd->MouseQY; - } - else { - x = Get_Mouse_X(); - y = Get_Mouse_Y(); - - if (x == 0 || y == 199 || x == 319) edge = true; - } - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); - - ActionType action = ACTION_NONE; - - if (coord) { - bool shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud); // Use PlayerPtr since we won't be rendering in MP. ST - 3/6/2019 2:49PM - x -= Map.TacPixelX; - y -= Map.TacPixelY; - - /* - ** Cause any displayed cursor to move along with the mouse cursor. - */ - if (cell != Map.ZoneCell) { - Map.Set_Cursor_Pos(cell); - } - - ObjectClass* object = nullptr; - - /* - ** Determine the object that the mouse is currently over. - */ - if (!shadow) { - object = Map.Close_Object(coord); - } - - if (CurrentObject.Count()) { - if (object) { - action = Best_Object_Action(object); - } - else { - action = Best_Object_Action(cell); - } - } - - if (action != ACTION_SELECT) - { - Map.Mouse_Left_Release(cell, x, y, object, action); - } - } - return 0; -} - - -/*********************************************************************************************** - * DisplayClass::Mouse_Right_Press -- Handles the right mouse button press. * - * * - * This routine is called when the right mouse button is pressed. This action is supposed * - * to cancel whatever mode or process is active. If there is nothing to cancel, then it * - * will default to unselecting any units that might be currently selected. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/24/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Mouse_Right_Press(void) -{ - if (PendingObjectPtr && PendingObjectPtr->Is_Techno()) { - //PendingObjectPtr->Transmit_Message(RADIO_OVER_OUT); - PendingObjectPtr = 0; - PendingObject = 0; - PendingHouse = HOUSE_NONE; - Set_Cursor_Shape(0); - } else { - if (IsRepairMode) { - IsRepairMode = false; - } else { - if (IsSellMode) { - IsSellMode = false; - } else { - if (IsTargettingMode) { - IsTargettingMode = false; - } else { - Unselect_All(); - } - } - } - } - Set_Default_Mouse(MOUSE_NORMAL, false); -} - - -/*********************************************************************************************** - * DisplayClass::Mouse_Left_Up -- Handles the left mouse "cruising" over the map. * - * * - * This routine is called continuously while the mouse is over the tactical map but there * - * are no mouse buttons pressed. Typically, this adjusts the mouse shape and the pop-up * - * help text. * - * * - * INPUT: shadow -- Is the mouse hovering over shadowed terrain? * - * * - * object -- Pointer to the object that the mouse is currently over (may be NULL). * - * * - * action -- This is the action that the currently selected object (if any) will * - * perform if the left mouse button were clicked at this location. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/24/1995 JLB : Created. * - * 07/05/1995 JLB : Removed pop up help text for shadow and terrain after #3. * - *=============================================================================================*/ -void DisplayClass::Mouse_Left_Up(bool shadow, ObjectClass * object, ActionType action, bool wwsmall) -{ - IsTentative = false; - - /* - ** Don't allow selection of an object that is located in shadowed terrain. - ** In fact, just show the normal move cursor in order to keep the shadowed - ** terrain a mystery. - */ - if (shadow) { - switch (action) { - case ACTION_GUARD_AREA: - Set_Default_Mouse(MOUSE_AREA_GUARD, wwsmall); - break; - - case ACTION_NONE: - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); - break; - - case ACTION_NO_SELL: - case ACTION_SELL: - case ACTION_SELL_UNIT: - Set_Default_Mouse(MOUSE_NO_SELL_BACK, wwsmall); - break; - - case ACTION_NO_REPAIR: - case ACTION_REPAIR: - Set_Default_Mouse(MOUSE_NO_REPAIR, wwsmall); - break; - - case ACTION_ION: - Set_Default_Mouse(MOUSE_ION_CANNON, wwsmall); - break; - - case ACTION_NUKE_BOMB: - Set_Default_Mouse(MOUSE_NUCLEAR_BOMB, wwsmall); - break; - - case ACTION_AIR_STRIKE: - Set_Default_Mouse(MOUSE_AIR_STRIKE, wwsmall); - break; - - case ACTION_NOMOVE: - if (CurrentObject.Count()) { - MouseType mouse_type = MOUSE_NO_MOVE; - for (int i = 0; i < CurrentObject.Count(); ++i) { - if (CurrentObject[i]->What_Am_I() != RTTI_AIRCRAFT) { - mouse_type = MOUSE_CAN_MOVE; - break; - } - } - Set_Default_Mouse(mouse_type, wwsmall); - break; - } - // Fall into next case for non aircraft object types. - - default: - Set_Default_Mouse(MOUSE_CAN_MOVE, wwsmall); - break; - - } - } else { - - /* - ** Change the mouse shape according to the default action that will occur - ** if the mouse button were clicked at this location. - */ - switch (action) { - case ACTION_TOGGLE_SELECT: - case ACTION_SELECT: - Set_Default_Mouse(MOUSE_CAN_SELECT, wwsmall); - break; - - case ACTION_MOVE: - Set_Default_Mouse(MOUSE_CAN_MOVE, wwsmall); - break; - - case ACTION_GUARD_AREA: - Set_Default_Mouse(MOUSE_AREA_GUARD, wwsmall); - break; - - case ACTION_HARVEST: - case ACTION_ATTACK: - Set_Default_Mouse(MOUSE_CAN_ATTACK, wwsmall); - break; - - case ACTION_SABOTAGE: - Set_Default_Mouse(MOUSE_DEMOLITIONS, wwsmall); - break; - - case ACTION_ENTER: - case ACTION_CAPTURE: - Set_Default_Mouse(MOUSE_ENTER, wwsmall); - break; - - case ACTION_NOMOVE: - Set_Default_Mouse(MOUSE_NO_MOVE, wwsmall); - break; - - case ACTION_NO_SELL: - Set_Default_Mouse(MOUSE_NO_SELL_BACK, wwsmall); - break; - - case ACTION_NO_REPAIR: - Set_Default_Mouse(MOUSE_NO_REPAIR, wwsmall); - break; - - case ACTION_SELF: - Set_Default_Mouse(MOUSE_DEPLOY, wwsmall); - break; - - case ACTION_REPAIR: - Set_Default_Mouse(MOUSE_REPAIR, wwsmall); - break; - - case ACTION_SELL_UNIT: - Set_Default_Mouse(MOUSE_SELL_UNIT, wwsmall); - break; - - case ACTION_SELL: - Set_Default_Mouse(MOUSE_SELL_BACK, wwsmall); - break; - - case ACTION_ION: - Set_Default_Mouse(MOUSE_ION_CANNON, wwsmall); - break; - - case ACTION_NUKE_BOMB: - Set_Default_Mouse(MOUSE_NUCLEAR_BOMB, wwsmall); - break; - - case ACTION_AIR_STRIKE: - Set_Default_Mouse(MOUSE_AIR_STRIKE, wwsmall); - break; - - case ACTION_TOGGLE_PRIMARY: - Set_Default_Mouse(MOUSE_DEPLOY, wwsmall); - break; - - default: - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); - break; - } - } -#if 0 - /* - ** Give a generic help message when over shadow terrain. - */ - if (shadow) { - if (Scenario < 4) { - Help_Text(TXT_SHADOW); - } else { - Help_Text(TXT_NONE); - } - } else { - - /* - ** If the mouse is held over objects on the map, then help text may - ** pop up that tells what the object is. This call informs the help - ** system of the text name for the object under the mouse. - */ - if (object) { - int text; - int color = LTGREY; - - /* - ** Fetch the appropriate background color for help text. - */ - if (PlayerPtr->Is_Ally(object)) { - color = CC_GREEN; - } else { - if (object->Owner() == HOUSE_NONE || object->Owner() == HOUSE_NEUTRAL) { - color = LTGREY; - } else { - color = PINK; - } - } - - /* - ** Fetch the name of the object. If it is an enemy object, then - ** the exact identity is glossed over with a generic text. - */ - text = object->Full_Name(); - if (object->Is_Techno() && !((TechnoTypeClass const &)object->Class_Of()).IsNominal) { - - if (!PlayerPtr->Is_Ally(object)) { - switch (object->What_Am_I()) { - case RTTI_INFANTRY: - text = TXT_ENEMY_SOLDIER; - break; - - case RTTI_UNIT: - text = TXT_ENEMY_VEHICLE; - break; - - case RTTI_BUILDING: - if ( *((BuildingClass*)object) != STRUCT_MISSION) { - text = TXT_ENEMY_STRUCTURE; - } - break; - } - } - } - - if (Scenario > 3 || object->What_Am_I() != RTTI_TERRAIN) { - Help_Text(text, -1, -1, color); - } else { - Help_Text(TXT_NONE); - } - } else { - Help_Text(TXT_NONE); - } - } -#endif -} - - -/*********************************************************************************************** - * DisplayClass::Mouse_Left_Release -- Handles the left mouse button release. * - * * - * This routine is called when the left mouse button is released over the tactical map. * - * The release event is the workhorse of the game. Most actions occur at the moment of * - * mouse release. * - * * - * INPUT: cell -- The cell that the mouse is over. * - * * - * x,y -- The mouse pixel coordinate. * - * * - * object -- Pointer to the object that the mouse is over. * - * * - * action -- The action that the currently selected object (if any) will * - * perform. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/24/1995 JLB : Created. * - * 03/27/1995 JLB : Handles sell and repair actions. * - *=============================================================================================*/ -void DisplayClass::Mouse_Left_Release(CELL cell, int x, int y, ObjectClass * object, ActionType action, bool wwsmall) -{ - if (PendingObjectPtr) { - - /* - ** Try to place the pending object onto the map. - */ - if (ProximityCheck) { - OutList.Add(EventClass(EventClass::PLACE, PendingObjectPtr->What_Am_I(), cell + ZoneOffset)); - } else { - Speak(VOX_DEPLOY); - } - - } else { - - if (IsRubberBand) { - Refresh_Band(); - Select_These(XYPixel_Coord(BandX, BandY), XYPixel_Coord(x, y)); - - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); -#ifdef NEVER - if (CurrentObject.Count()) { - if (CurrentObject[0]->Can_Player_Fire()) { - Set_Default_Mouse(MOUSE_CAN_ATTACK, wwsmall); - } else { - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); - } - } else { - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); - } -#endif - - IsRubberBand = false; - IsTentative = false; - Map.DisplayClass::IsToRedraw = true; - Map.Flag_To_Redraw(false); - - } else { - - /* - ** Toggle the select state of the object. - */ - if (action == ACTION_TOGGLE_SELECT) { - if (!object || !CurrentObject.Count()) { - action = ACTION_SELECT; - } else { - if (object->Is_Selected_By_Player()) { - object->Unselect(); - } else { - object->Select(); - } - } - } - - /* - ** Selection of other object action. - */ - if (action == ACTION_SELECT || (action == ACTION_NONE && object && object->Class_Of().IsSelectable && !object->Is_Selected_By_Player())) { - if (object->Is_Selected_By_Player()) { - object->Unselect(); - } - if (object->Select()) { - Unselect_All_Except(object); - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); - } -#ifdef NEVER - if (object->Can_Player_Fire()) { - Set_Default_Mouse(MOUSE_CAN_ATTACK, wwsmall); - } else { - Set_Default_Mouse(MOUSE_NORMAL, wwsmall); - } -#endif - } - - /* - ** If an action was detected as possible, then pass this action event - ** to all selected objects. - */ - if (action != ACTION_NONE && action != ACTION_SELECT && action != ACTION_TOGGLE_SELECT) { - - /* - ** Pass the action to all the selected objects. But first, redetermine - ** what action that object should perform. This, seemingly redundant - ** process, is necessary since multiple objects could be selected and each - ** might perform a different action when the click occurs. - */ - bool doflash = true; - AllowVoice = true; - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass * tobject = CurrentObject[index]; - if (object) { - tobject->Active_Click_With(tobject->What_Action(object), object); - } else { - tobject->Active_Click_With(tobject->What_Action(cell), cell); - } - AllowVoice = false; - } - AllowVoice = true; - - if (action == ACTION_REPAIR && object->What_Am_I() == RTTI_BUILDING) { - OutList.Add(EventClass(EventClass::REPAIR, object->As_Target())); - } - if (action == ACTION_SELL_UNIT && object) { - switch (object->What_Am_I()) { - case RTTI_AIRCRAFT: - case RTTI_UNIT: - OutList.Add(EventClass(EventClass::SELL, object->As_Target())); - break; - - default: - break; - } - - } - if (action == ACTION_SELL) { - if (object) { - OutList.Add(EventClass(EventClass::SELL, object->As_Target())); - } else { - OutList.Add(EventClass(EventClass::SELL, ::As_Target(cell))); - } - } - if (action == ACTION_ION) { - OutList.Add(EventClass(EventClass::SPECIAL_PLACE, SPC_ION_CANNON, cell)); - } - if (action == ACTION_NUKE_BOMB) { - OutList.Add(EventClass(EventClass::SPECIAL_PLACE, SPC_NUCLEAR_BOMB, cell)); - } - if (action == ACTION_AIR_STRIKE) { - OutList.Add(EventClass(EventClass::SPECIAL_PLACE, SPC_AIR_STRIKE, cell)); - } - } - - IsTentative = false; - } - } -} - - -/*********************************************************************************************** - * DisplayClass::Mouse_Left_Press -- Handles the left mouse button press. * - * * - * Handle the left mouse button press while over the tactical map. If it isn't is * - * repair or sell mode, then a tentative transition to rubber band mode is flagged. If the * - * mouse moves a sufficient distance from this recorded position, then rubber band mode * - * is officially started. * - * * - * INPUT: x,y -- The mouse coordinates at the time of the press. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/24/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Mouse_Left_Press(int x, int y) -{ - if (!IsRepairMode && !IsSellMode && !IsTargettingMode && !PendingObject) { - IsTentative = true; - BandX = x; - BandY = y; - NewX = x; - NewY = y; - } -} - - -/*********************************************************************************************** - * DisplayClass::Mouse_Left_Held -- Handles the left button held down. * - * * - * This routine is called continuously while the left mouse button is held down over * - * the tactical map. This handles the rubber band mode detection and dragging. * - * * - * INPUT: x,y -- The mouse coordinate. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/24/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Mouse_Left_Held(int x, int y) -{ - if (IsRubberBand) { - if (x != NewX || y != NewY) { - x = Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1); - y = Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1); - Refresh_Band(); - NewX = x; - NewY = y; - IsToRedraw = true; - Flag_To_Redraw(false); - } - } else { - - /* - ** If the mouse is still held down while a tentative extended select is possible, then - ** check to see if the mouse has moved a sufficient distance in order to activate - ** extended select mode. - */ - if (IsTentative) { - - /* - ** The mouse must have moved a minimum distance before rubber band mode can be - ** initiated. - */ - if (ABS(x - BandX) > 4 || ABS(y - BandY) > 4) { - IsRubberBand = true; - x = Bound(x, 0, Lepton_To_Pixel(TacLeptonWidth)-1); - y = Bound(y, 0, Lepton_To_Pixel(TacLeptonHeight)-1); - NewX = x; - NewY = y; - IsToRedraw = true; - Flag_To_Redraw(false); - } - } - } -} - - -// Needed to accomodate Glyphx client sidebar. ST - 4/12/2019 5:29PM -extern int GlyphXClientSidebarWidthInLeptons; - -/*********************************************************************************************** - * DisplayClass::Set_Tactical_Position -- Sets the tactical view position. * - * * - * This routine is used to set the tactical view position. The requested position is * - * clipped to the map dimensions as necessary. * - * * - * INPUT: coord -- The coordinate desired for the upper left corner. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Set_Tactical_Position(COORDINATE coord) -{ - /* - ** Bound the desired location to fit the legal map edges. - */ - int xx = 0;// Coord_X(coord) - Cell_To_Lepton(MapCellX); - int yy = 0;// Coord_Y(coord) - Cell_To_Lepton(MapCellY); - - Confine_Rect(&xx, &yy, TacLeptonWidth, TacLeptonHeight, Cell_To_Lepton(MapCellWidth) + GlyphXClientSidebarWidthInLeptons, Cell_To_Lepton(MapCellHeight)); // Needed to accomodate Glyphx client sidebar. ST - 4/12/2019 5:29PM - coord = XY_Coord(xx + Cell_To_Lepton(MapCellX), yy + Cell_To_Lepton(MapCellY)); - - if (ScenarioInit) { - TacticalCoord = coord; - } - DesiredTacticalCoord = coord; - IsToRedraw = true; - Flag_To_Redraw(false); -} - - -/*********************************************************************************************** - * DisplayClass::Compute_Start_Pos -- Computes player's start pos from unit coords. * - * * - * Use this function in multiplayer games, to compute the scenario starting Tactical Pos. * - * * - * INPUT: none * - * * - * OUTPUT: x, y -- Player starting location * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/28/1995 JLB : Commented. * - * 06/26/1995 JLB : Fixed building loop. * - *=============================================================================================*/ -void DisplayClass::Compute_Start_Pos(long& x, long& y) -{ - /* - ** Find the summation cell-x & cell-y for all the player's units, infantry, - ** and buildings. Buildings are weighted so that they count 16 times more - ** than units or infantry. - */ - x = 0; - y = 0; - long num = 0; - int i; - for (i = 0; i < Infantry.Count(); i++) { - InfantryClass * infp = Infantry.Ptr(i); - if (!infp->IsInLimbo && infp->House == PlayerPtr) { - x += (long)Coord_XCell (infp->Coord); - y += (long)Coord_YCell (infp->Coord); - num++; - } - } - - for (i = 0; i < Units.Count(); i++) { - UnitClass * unitp = Units.Ptr(i); - if (!unitp->IsInLimbo && unitp->House == PlayerPtr) { - x += (long)Coord_XCell (unitp->Coord); - y += (long)Coord_YCell (unitp->Coord); - num++; - } - } - - for (i = 0; i < Buildings.Count(); i++) { - BuildingClass * bldgp = Buildings.Ptr(i); - if (!bldgp->IsInLimbo && bldgp->House == PlayerPtr) { - x += (((long)Coord_XCell (bldgp->Coord)) << 4); - y += (((long)Coord_YCell (bldgp->Coord)) << 4); - num += 16; - } - } - - /* - ** Divide each coord by 'num' to compute the average value - */ - if (num > 0) { - x /= num; - } else { - x = 0; - } - - if (num > 0) { - y /= num; - } else { - y = 0; - } -} - - -/*********************************************************************************************** - * DisplayClass::Sell_Mode_Control -- Controls the sell mode. * - * * - * This routine will control the sell mode for the player. * - * * - * INPUT: control -- The mode to set the sell state to. * - * 0 = Turn sell mode off. * - * 1 = Turn sell mode on. * - * -1 = Toggle sell mode. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Sell_Mode_Control(int control) -{ - bool mode = IsSellMode; - switch (control) { - case 0: - mode = false; - break; - - case -1: - mode = (IsSellMode == false); - break; - - case 1: - mode = true; - break; - } - - if (mode != IsSellMode && !PendingObject) { - IsRepairMode = false; - if (mode && PlayerPtr->BScan) { - IsSellMode = true; - Unselect_All(); - } else { - IsSellMode = false; - Revert_Mouse_Shape(); - } - } -} - - -/*********************************************************************************************** - * DisplayClass::Repair_Mode_Control -- Controls the repair mode. * - * * - * This routine is used to control the repair mode for the player. * - * * - * INPUT: control -- The mode to set the repair to. * - * 0 = Turn repair off. * - * 1 = Turn repair on. * - * -1= Toggle repair state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void DisplayClass::Repair_Mode_Control(int control) -{ - bool mode = IsRepairMode; - switch (control) { - case 0: - mode = false; - break; - - case -1: - mode = (IsRepairMode == false); - break; - - case 1: - mode = true; - break; - } - - if (mode != IsRepairMode && !PendingObject) { - IsSellMode = false; - if (mode && PlayerPtr->BScan) { - IsRepairMode = true; - Unselect_All(); - } else { - IsRepairMode = false; - Revert_Mouse_Shape(); - } - } -} - - -/*********************************************************************************************** - * DisplayClass::In_View -- Determines if cell is visible on screen. * - * * - * Use this routine to determine if the specified cell is visible on * - * the display. This is a useful fact, since many display operations * - * can be skipped if the cell is not visible. * - * * - * INPUT: cell -- The cell number to check. * - * * - * OUTPUT: bool; Is this cell visible on the display? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/30/1994 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - *=============================================================================================*/ -bool DisplayClass::In_View(register CELL cell) -{ - COORDINATE coord = Cell_Coord(cell) & 0xFF00FF00L; - COORDINATE tcoord = TacticalCoord & 0xFF00FF00L; - - if ((Coord_X(coord) - Coord_X(tcoord)) > TacLeptonWidth+255) return(false); - if ((Coord_Y(coord) - Coord_Y(tcoord)) > TacLeptonHeight+255) return(false); - return(true); - -#ifdef OBSOLETE - int fudgex = Coord_XLepton(TacticalCoord) ? -1 : 0; - int fudgey = Coord_YLepton(TacticalCoord) ? -1 : 0; - if ((unsigned)(Cell_X(cell)-Coord_XCell(TacticalCoord)) > Lepton_To_Cell(TacLeptonWidth)+fudgex) return(false); - if ((unsigned)(Cell_Y(cell)-Coord_YCell(TacticalCoord)) > Lepton_To_Cell(TacLeptonHeight)+fudgey) return(false); - return(true); -#endif - -#ifdef OBSOLETE - cell -= TacticalCell; - - if (Cell_X(cell) >= TacWidth + (TacPartialX ? 1 : 0)) return(false); - if (Cell_Y(cell) >= TacHeight + (TacPartialY ? 1 : 0)) return(false); - return(true); -#endif -} - - -COORDINATE DisplayClass::Closest_Free_Spot(COORDINATE coord, bool any) const -{ - if (coord & 0xC000C000) { - return(0x00800080); - } - return (*this)[Coord_Cell(coord)].Closest_Free_Spot(coord, any); -} - - -bool DisplayClass::Is_Spot_Free(COORDINATE coord) const -{ - // This doesn't seem right... ST - 12/18/2018 10:09AM - //if (coord & 0xC000C000) { - // return(0x00800080); - //} - return (*this)[Coord_Cell(coord)].Is_Spot_Free(CellClass::Spot_Index(coord)); -} - - -/*********************************************************************************************** - * DisplayClass::Center_Map -- Centers the map about the currently selected objects * - * * - * This routine will average the position of all the selected objects and then center * - * the map about those objects. * - * * - * INPUT: none * - * * - * OUTPUT: The center coordinate. * - * * - * WARNINGS: The map position changes by this routine. * - * * - * HISTORY: * - * 08/22/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE DisplayClass::Center_Map(void) -{ - if (CurrentObject.Count()) { - unsigned x = 0; - unsigned y = 0; - - for (int index = 0; index < CurrentObject.Count(); index++) { - COORDINATE coord = CurrentObject[index]->Center_Coord(); - - x += Coord_X(coord); - y += Coord_Y(coord); - } - - x /= CurrentObject.Count(); - y /= CurrentObject.Count(); - Set_Tactical_Position(XY_Coord(x - (TacLeptonWidth/2), y - (TacLeptonHeight/2))); - - return XY_Coord(x, y); - } - - return 0; -} - -static ActionType _priority_actions[] = { - ACTION_ATTACK, - ACTION_ENTER, - ACTION_REPAIR, - ACTION_SABOTAGE, - ACTION_CAPTURE, - ACTION_MOVE -}; - -static int get_action_priority(ActionType action) -{ - for (int i = 0; i < sizeof(_priority_actions) / sizeof(_priority_actions[0]); ++i) { - if (_priority_actions[i] == action) { - return i; - } - } - return INT_MAX; -} - -template -static int index_of(const DynamicVectorClass& list, T* object) -{ - for (int i = 0; i < list.Count(); i++) { - if (list[i] == object) { - return i; - } - } - return -1; -} - -template -static ObjectClass* Best_Object_With_ActionT(DynamicVectorClass& objects, T subject) -{ - DynamicVectorClass checked_types; - - if (objects.Count()) { - int best_priority = INT_MAX; - ObjectClass* best_object = objects[0]; - for (int i = 0; i < objects.Count(); ++i) { - ObjectClass* object = objects[i]; - const ObjectTypeClass* type = &object->Class_Of(); - if (index_of(checked_types, type) != -1) { - continue; - } - checked_types.Add(type); - ActionType action = object->What_Action(subject); - int priority = get_action_priority(action); - if (priority < best_priority) { - best_priority = priority; - best_object = object; - if (best_priority == 0) { - break; - } - } - } - return best_object; - } - return NULL; -} - -ObjectClass* Best_Object_With_Action(DynamicVectorClass& objects, ObjectClass* object) -{ - return Best_Object_With_ActionT(objects, object); -} - -ObjectClass* Best_Object_With_Action(DynamicVectorClass& objects, CELL cell) -{ - return Best_Object_With_ActionT(objects, cell); -} - -ActionType Best_Object_Action(DynamicVectorClass& objects, ObjectClass* object) -{ - ObjectClass* obj = Best_Object_With_Action(objects, object); - return (obj != NULL) ? obj->What_Action(object) : ACTION_NONE; -} - -ActionType Best_Object_Action(DynamicVectorClass& objects, CELL cell) -{ - ObjectClass* obj = Best_Object_With_Action(objects, cell); - return (obj != NULL) ? obj->What_Action(cell) : ACTION_NONE; -} - -ObjectClass* Best_Object_With_Action(ObjectClass* object) -{ - return Best_Object_With_Action(CurrentObject.Raw(), object); -} - -ObjectClass* Best_Object_With_Action(CELL cell) -{ - return Best_Object_With_Action(CurrentObject.Raw(), cell); -} - -ActionType Best_Object_Action(ObjectClass* object) -{ - return Best_Object_Action(CurrentObject.Raw(), object); -} - -ActionType Best_Object_Action(CELL cell) -{ - return Best_Object_Action(CurrentObject.Raw(), cell); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/DISPLAY.H b/code/TIBERIANDAWN/DISPLAY.H deleted file mode 100644 index 9f85806..0000000 --- a/code/TIBERIANDAWN/DISPLAY.H +++ /dev/null @@ -1,341 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\display.h_v 2.15 16 Oct 1995 16:47:42 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DISPLAY.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 1, 1994 * - * * - * Last Update : May 1, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DISPLAY_H -#define DISPLAY_H - -#include "map.h" -#include "layer.h" - - -#define ICON_PIXEL_W 24 -#define ICON_PIXEL_H 24 -#define ICON_LEPTON_W 256 -#define ICON_LEPTON_H 256 -#define CELL_PIXEL_W ICON_PIXEL_W -#define CELL_PIXEL_H ICON_PIXEL_H -#define CELL_LEPTON_W ICON_LEPTON_W -#define CELL_LEPTON_H ICON_LEPTON_H - -// ----------------------------------------------------------- -#define PIXEL_LEPTON_W (ICON_LEPTON_W/ICON_PIXEL_W) -#define PIXEL_LEPTON_H (ICON_LEPTON_H/ICON_PIXEL_H) - - -extern COORDINATE Coord_Add(COORDINATE coord1, COORDINATE coord2); - -class DisplayClass: public MapClass -{ - // Need access to shadow shapes - friend class DLLExportClass; - - public: - - /* - ** This indicates the theater that the display is to represent. - */ - TheaterType Theater; - - /* - ** The tactical map display position is indicated by the cell of the - ** upper left hand corner. These should not be altered directly. Use - ** the Set_Tactical_Position function instead. - */ - COORDINATE TacticalCoord; - - /* - ** The dimensions (in cells) of the visible window onto the game map. This tactical - ** map is how the player interacts and views the game world. - */ - int TacLeptonWidth; - int TacLeptonHeight; - - /* - ** These layer control elements are used to group the displayable objects - ** so that proper overlap can be obtained. - */ - static LayerClass Layer[LAYER_COUNT]; - - /* - ** This records the position and shape of a placement cursor to display - ** over the map. This cursor is used when placing buildings and also used - ** extensively by the scenario editor. - */ - CELL ZoneCell; - short ZoneOffset; - short const *CursorSize; - short CursorShapeSave[256]; // For save/load - bool ProximityCheck; // Is proximity check ok? - - /* - ** This holds the building type that is about to be placed upon the map. - ** It is only valid during the building placement state. The PendingLegal - ** flag is updated as the cursor moves and it reflects the legality of - ** placing the building at the desired location. - */ - ObjectClass * PendingObjectPtr; - ObjectTypeClass const * PendingObject; - HousesType PendingHouse; - - static unsigned char FadingBrighten[256]; - static unsigned char FadingShade[256]; - static unsigned char FadingLight[256]; - static unsigned char RemapTables[HOUSE_COUNT][3][256]; - static unsigned char FadingGreen[256]; - static unsigned char FadingYellow[256]; - static unsigned char FadingRed[256]; - static unsigned char TranslucentTable[(MAGIC_COL_COUNT+1)*256]; - static unsigned char WhiteTranslucentTable[(1+1)*256]; - static unsigned char MouseTranslucentTable[(4+1)*256]; - static void const *TransIconset; - static unsigned char UnitShadow[(USHADOW_COL_COUNT+1)*256]; - static unsigned char SpecialGhost[2*256]; - - //------------------------------------------------------------------------- - DisplayClass(void); - - virtual void Read_INI(char *buffer); - void Write_INI(char *buffer); - - /* - ** Initialization - */ - virtual void One_Time(void); // One-time inits - virtual void Init_Clear(void); // Clears all to known state - virtual void Init_IO(void); // Inits button list - virtual void Init_Theater(TheaterType theater); // Theater-specific inits - - /* - ** General display/map/interface support functionality. - */ - virtual void AI(KeyNumType &input, int x, int y); - virtual void Draw_It(bool complete=false); - - /* - ** Added functionality. - */ - COORDINATE Center_Map(void); - virtual bool Map_Cell(CELL cell, HouseClass *house, bool and_for_allies); - - virtual CELL Click_Cell_Calc(int x, int y); - virtual void Help_Text(int , int =-1, int =-1, int =YELLOW, bool =false, int =0) {}; - virtual MouseType Get_Mouse_Shape(void) const = 0; - virtual bool Scroll_Map(DirType facing, int & distance, bool really); - virtual void Refresh_Cells(CELL cell, short const *list); - virtual void Set_View_Dimensions(int x, int y, int width=-1, int height=-1); - - /* - ** Pending object placement control. - */ - virtual void Put_Place_Back(TechnoClass * ) {}; // Affects 'pending' system. - void Cursor_Mark(CELL pos, bool on); - void Set_Cursor_Shape(short const * list); - CELL Set_Cursor_Pos(CELL pos = -1); - void Get_Occupy_Dimensions(int & w, int & h, short const *list); - - /* - ** Tactical map only functionality. - */ - virtual void Set_Tactical_Position(COORDINATE coord); - void Refresh_Band(void); - void Select_These(COORDINATE coord1, COORDINATE coord2, bool additive = false); - COORDINATE Pixel_To_Coord(int x, int y); - bool Coord_To_Pixel(COORDINATE coord, int &x, int &y); - bool Push_Onto_TacMap(COORDINATE &source, COORDINATE &dest); - void Remove(ObjectClass const *object, LayerType layer); - void Submit(ObjectClass const *object, LayerType layer); - CELL Calculated_Cell(SourceType dir, HousesType house); - bool In_View(register CELL cell); - bool Passes_Proximity_Check(ObjectTypeClass const *object); -#ifdef USE_RA_AI - bool Passes_Proximity_Check(ObjectTypeClass const * object, HousesType house, short const * list, CELL trycell) const; -#endif - ObjectClass * Cell_Object(CELL cell, int x=0, int y=0); - ObjectClass * Next_Object(ObjectClass * object); - ObjectClass * Prev_Object(ObjectClass * object); - int Cell_Shadow(CELL cell, HouseClass *house); - short const * Text_Overlap_List(char const * text, int x, int y, int lines = 1); - bool Is_Spot_Free(COORDINATE coord) const; - COORDINATE Closest_Free_Spot(COORDINATE coord, bool any=false) const; - void Sell_Mode_Control(int control); - void Repair_Mode_Control(int control); - - void Flag_Cell(CELL cell) { - Flag_To_Redraw(false); - IsToRedraw = true; - CellRedraw[cell] = true; - }; - bool Is_Cell_Flagged(CELL cell) const {return CellRedraw.Is_True(cell);}; - - /* - ** Computes starting position based on player's units' Coords. - */ - void Compute_Start_Pos(long& x, long& y); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - protected: - virtual void Mouse_Right_Press(void); - virtual void Mouse_Left_Press(int x, int y); - virtual void Mouse_Left_Up(bool shadow, ObjectClass * object, ActionType action, bool wwsmall = false); - virtual void Mouse_Left_Held(int x, int y); - virtual void Mouse_Left_Release(CELL cell, int x, int y, ObjectClass * object, ActionType action, bool wwsmall = false); - - public: - /* - ** This is the pixel offset for the upper left corner of the tactical map. - */ - int TacPixelX; - int TacPixelY; - - /* - ** This is the coordinate that the tactical map should be in at next available opportunity. - */ - COORDINATE DesiredTacticalCoord; - - /* - ** If something in the tactical map is to be redrawn, this flag is set to true. - */ - unsigned IsToRedraw:1; - - /* - ** If the player is currently wielding a wrench (to select buildings for repair), - ** then this flag is true. In such a state, normal movement and combat orders - ** are preempted. - */ - unsigned IsRepairMode:1; - - /* - ** If the player is currently in "sell back" mode, then this flag will be - ** true. While in this mode, anything clicked on will be sold back to the - ** "factory". - */ - unsigned IsSellMode:1; - - /* - ** If the player is currently in ion cannon targetting mode, then this - ** flag will be true. While in this mode, anything clicked on will be - ** be destroyed by the ION cannon. - */ - unsigned IsTargettingMode:2; - - protected: - - /* - ** If it is currently in rubber band mode (multi unit selection), then this - ** flag will be true. While in such a mode, normal input is prempted while - ** the extended selection is in progress. - */ - unsigned IsRubberBand:1; - - /* - ** The moment the mouse is held down, this flag gets set. If the mouse is dragged - ** a sufficient distance while held down, then true rubber band mode selection - ** can begin. Using a minimum distance prevents accidental rubber band selection - ** mode from being initiated. - */ - unsigned IsTentative:1; - - /* - ** This gadget class is used for capturing input to the tactical map. All mouse input - ** will be routed through this gadget. - */ - class TacticalClass : public GadgetClass { - public: - TacticalClass(void) : GadgetClass(0,0,0,0,LEFTPRESS|LEFTRELEASE|LEFTHELD|LEFTUP|RIGHTPRESS,true) {}; - - int Selection_At_Mouse(unsigned flags, KeyNumType & key); - int Command_Object(unsigned flags, KeyNumType & key); - - protected: - virtual int Action(unsigned flags, KeyNumType & key); - }; - friend class TacticalClass; - - /* - ** This is the "button" that tracks all input to the tactical map. - ** It must be available to derived classes, for Save/Load purposes. - */ -public: //ST - 1/21/2019 11:59AM - static TacticalClass TacButton; - - private: - - /* - ** This is a utility flag that is set during the icon draw process only if there - ** was at least one shadow icon detected that should be redrawn. When the shadow - ** drawing logic is to take place, but this flag is false, then the shadow drawing - ** will be skipped since it would perform no function. - */ - unsigned IsShadowPresent:1; - - /* - ** Rubber band mode consists of stretching a box from the anchor point (specified - ** here) to the current cursor position. - */ - int BandX,BandY; - int NewX,NewY; - - static void const *ShadowShapes; - static unsigned char ShadowTrans[(SHADOW_COL_COUNT+1)*256]; - - void Redraw_Icons(int draw_flags=0); - void Redraw_Shadow(void); - void Redraw_Shadow_Rects(void); - - /* - ** This bit array is used to flag cells to be redrawn. If the icon needs to - ** be redrawn for a cell, then the corresponding flag will be true. - */ - static BooleanVectorClass CellRedraw; - - // - // We need a way to bypass visible view checks when we are running in the context of GlyphX without using the - // internal C&C renderer. We shouldn't know or care what the user is actually looking at - // ST - 4/17/2019 9:01AM - // - static bool IgnoreViewConstraints; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[1024]; -}; - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/DLLInterface.cpp b/code/TIBERIANDAWN/DLLInterface.cpp deleted file mode 100644 index abbfabb..0000000 --- a/code/TIBERIANDAWN/DLLInterface.cpp +++ /dev/null @@ -1,7702 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/* -** DLLInterfac.cpp -** -** This is where we implement the API expected by the Instance Server. -** -** The Instance Server will pass in requests for loading and starting maps, control input from players, -** and requests for game simulation and rendering states. -** -** -*/ - - - -#include - -#include "function.h" -#include "externs.h" -#include "DLLInterface.h" -#include "Gadget.h" -#include "defines.h" // VOC_COUNT, VOX_COUNT -#include "SidebarGlyphx.h" - - - - -/* -** Externs -*/ -extern int DLL_Startup(const char * command_line); -extern void Reallocate_Big_Shape_Buffer(void); -extern bool ProgEndCalled; -extern int Write_PCX_File(char* name, GraphicViewPortClass& pic, unsigned char* palette ); -extern bool Color_Cycle(void); - - - - -/* -** Prototypes and constants -*/ -bool Debug_Write_Shape_Type(const ObjectTypeClass *type, int shapenum); -bool Debug_Write_Shape(const char *file_name, void const * shapefile, int shapenum, int flags = 0, void const * ghostdata = NULL); - -typedef void (__cdecl* CNC_Event_Callback_Type)(const EventCallbackStruct &event); -typedef unsigned __int64 uint64; -typedef __int64 int64; - - - - -/* -** Audio defines -** -** -** -** -** -*/ -// For compatibility with Watcom in audio enums -#pragma warning (disable : 4091) - -// From TiberianDawn\Audio.cpp -enum ContextType; -extern struct SoundEffectNameStruct { - char const *Name; // Digitized voice file name. - int Priority; // Playback priority of this sample. - ContextType Where; // In what game context does this sample exist. -} SoundEffectName[VOC_COUNT]; - -// From TiberianDawn\Audio.cpp -extern char const* Speech[VOX_COUNT]; - -// From TiberianDawn\Audio.cpp -typedef enum { - IN_NOVAR, // No variation or alterations allowed. - IN_JUV, // Juvenile sound effect alternate option. - IN_VAR, // Infantry variance response modification. -}; - - - - -/* -** Misc defines -** -** -** -** -** -*/ -#define RANDOM_START_POSITION 0x7f - -#define KILL_PLAYER_ON_DISCONNECT 1 - - - -/* -** DLL Interface -** -** -** -** -** -*/ -extern "C" __declspec(dllexport) unsigned int __cdecl CNC_Version(unsigned int version_in); -extern "C" __declspec(dllexport) void __cdecl CNC_Init(const char *command_line, CNC_Event_Callback_Type event_callback); -extern "C" __declspec(dllexport) void __cdecl CNC_Config(const CNCRulesDataStruct& rules); -extern "C" __declspec(dllexport) void __cdecl CNC_Add_Mod_Path(const char *mod_path); -extern "C" __declspec(dllexport) bool __cdecl CNC_Get_Visible_Page(unsigned char *buffer_in, unsigned int &width, unsigned int &height); -extern "C" __declspec(dllexport) bool __cdecl CNC_Get_Palette(unsigned char(&palette_in)[256][3]); -extern "C" __declspec(dllexport) bool __cdecl CNC_Start_Instance(int scenario_index, int build_level, const char *faction, const char *game_type, const char *content_directory, int sabotaged_structure, const char *override_map_name); -extern "C" __declspec(dllexport) bool __cdecl CNC_Start_Instance_Variation(int scenario_index, int scenario_variation, int scenario_direction, int build_level, const char *faction, const char *game_type, const char *content_directory, int sabotaged_structure, const char *override_map_name); -extern "C" __declspec(dllexport) bool __cdecl CNC_Start_Custom_Instance(const char* content_directory, const char* directory_path, const char* scenario_name, int build_level, bool multiplayer); -extern "C" __declspec(dllexport) bool __cdecl CNC_Advance_Instance(uint64 player_id); -extern "C" __declspec(dllexport) bool __cdecl CNC_Get_Game_State(GameStateRequestEnum state_type, uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); -extern "C" __declspec(dllexport) bool __cdecl CNC_Read_INI(int scenario_index, int scenario_variation, int scenario_direction, const char *content_directory, const char *override_map_name, char *ini_buffer, int _ini_buffer_size); -extern "C" __declspec(dllexport) void __cdecl CNC_Set_Home_Cell(int x, int y, uint64 player_id); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Game_Request(GameRequestEnum request_type); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Game_Settings_Request(int health_bar_display_mode, int resource_bar_display_mode); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Input(InputRequestEnum mouse_event, unsigned char special_key_flags, uint64 player_id, int x1, int y1, int x2, int y2); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Structure_Request(StructureRequestEnum request_type, uint64 player_id, int object_id); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Unit_Request(UnitRequestEnum request_type, uint64 player_id); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Sidebar_Request(SidebarRequestEnum request_type, uint64 player_id, int buildable_type, int buildable_id, short cell_x, short cell_y); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_SuperWeapon_Request(SuperWeaponRequestEnum request_type, uint64 player_id, int buildable_type, int buildable_id, int x1, int y1); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_ControlGroup_Request(ControlGroupRequestEnum request_type, uint64 player_id, unsigned char control_group_index); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Debug_Request(DebugRequestEnum debug_request_type, uint64 player_id, const char *object_name, int x, int y, bool unshroud, bool enemy); -extern "C" __declspec(dllexport) bool __cdecl CNC_Set_Multiplayer_Data(int scenario_index, CNCMultiplayerOptionsStruct &game_options, int num_players, CNCPlayerInfoStruct *player_list, int max_players); -extern "C" __declspec(dllexport) bool __cdecl CNC_Clear_Object_Selection(uint64 player_id); -extern "C" __declspec(dllexport) bool __cdecl CNC_Select_Object(uint64 player_id, int object_type_id, int object_to_select_id); -extern "C" __declspec(dllexport) bool __cdecl CNC_Save_Load(bool save, const char *file_path_and_name, const char *game_type); -extern "C" __declspec(dllexport) void __cdecl CNC_Set_Difficulty(int difficulty); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Player_Switch_To_AI(uint64 player_id); -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Human_Team_Wins(uint64 player_id); -extern "C" __declspec(dllexport) void __cdecl CNC_Start_Mission_Timer(int time); - - - -/* -** Class to implement the interface, and contain additional game state required by the conversion from peer/peer to client/server -** -** -** -** -** -*/ -class DLLExportClass { - public: - - static void Init(void); - static void Shutdown(void); - static void Config(const CNCRulesDataStruct& rules); - static void Add_Mod_Path(const char *mod_path); - static void Set_Home_Cell(int x, int y, uint64 player_id); - static void Set_Content_Directory(const char *dir); - - static bool Get_Layer_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - static bool Get_Sidebar_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - static bool Start_Construction(uint64 player_id, int buildable_type, int buildable_id); - static bool Hold_Construction(uint64 player_id, int buildable_type, int buildable_id); - static bool Cancel_Construction(uint64 player_id, int buildable_type, int buildable_id); - static bool Start_Placement(uint64 player_id, int buildable_type, int buildable_id); - static BuildingClass *Get_Pending_Placement_Object(uint64 player_id, int buildable_type, int buildable_id); - static bool Get_Placement_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - static void Convert_Type(const ObjectClass *object, CNCObjectStruct &object_out); - static void DLL_Draw_Intercept(int shape_number, int x, int y, int width, int height, int flags, ObjectClass *object, const char *shape_file_name = NULL, char override_owner = HOUSE_NONE, int scale = 0x100); - static void DLL_Draw_Pip_Intercept(const ObjectClass* object, int pip); - static void DLL_Draw_Line_Intercept(int x, int y, int x1, int y1, unsigned char color, int frame); - static bool Place(uint64 player_id, int buildable_type, int buildable_id, short cell_x, short cell_y); - static bool Cancel_Placement(uint64 player_id, int buildable_type, int buildable_id); - static bool Place_Super_Weapon(uint64 player_id, int buildable_type, int buildable_id, int x, int y); - static bool Create_Control_Group(unsigned char control_group_index); - static bool Add_To_Control_Group(unsigned char control_group_index); - static bool Toggle_Control_Group_Selection(unsigned char control_group_index); - static bool Construction_Action(SidebarRequestEnum construction_action, uint64 player_id, int buildable_type, int buildable_id); - static bool MP_Construction_Action(SidebarRequestEnum construction_action, uint64 player_id, int buildable_type, int buildable_id); - static bool Passes_Proximity_Check(CELL cell_in, BuildingTypeClass *placement_type, unsigned char* placement_distance); - static void Calculate_Start_Positions(void); - static void Computer_Message(bool last_player_taunt); - - static void Repair_Mode(uint64 player_id); - static void Repair(uint64 player_id, int object_id); - static void Sell_Mode(uint64 player_id); - static void Sell(uint64 player_id, int object_id); - static void Repair_Sell_Cancel(uint64 player_id); - - static void Scatter_Selected(uint64 player_id); - static void Select_Next_Unit(uint64 player_id); - static void Select_Previous_Unit(uint64 player_id); - static void Selected_Guard_Mode(uint64 player_id); - static void Selected_Stop(uint64 player_id); - static void Team_Units_Formation_Toggle_On(uint64 player_id); - static void Units_Queued_Movement_Toggle(uint64 player_id, bool toggle); - - static void Cell_Class_Draw_It(CNCDynamicMapStruct *dynamic_map, int &entry_index, CellClass *cell_ptr, int xpixel, int ypixel, bool debug_output); - static bool Get_Dynamic_Map_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - static bool Get_Shroud_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - static bool Get_Occupier_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - static bool Get_Player_Info_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size); - - - static void Set_Event_Callback(CNC_Event_Callback_Type event_callback) {EventCallback = event_callback;} - static void Debug_Spawn_Unit(const char *object_name, int x, int y, bool enemy = false); - static void Debug_Spawn_All(int x, int y); - static bool Try_Debug_Spawn_Unlimbo(TechnoClass *techno, int &cell_x, int &cell_y); - static void Debug_Kill_Unit(int x, int y); - static void Debug_Heal_Unit(int x, int y); - - static void On_Play_Movie(const char * movie_name, ThemeType theme, bool immediate); - static void On_Display_Briefing_Text(); - - static void On_Sound_Effect(const HouseClass* player_ptr, int sound_effect_index, const char* extension, int variation, COORDINATE coord); - static void On_Speech(const HouseClass* player_ptr, int speech_index); - - static void On_Game_Over(uint64 glyphx_player_id, bool player_wins); - static void On_Multiplayer_Game_Over(void); - - static void On_Message(const HouseClass* player_ptr, const char* message, float timeout_seconds, EventCallbackMessageEnum message_type, int64 message_id); - - static void On_Debug_Output(const char *debug_text); - - static void On_Achievement(const HouseClass* player_ptr, const char *achievement_type, const char *achievement_reason); - - static void On_Center_Camera(const HouseClass* player_ptr, int coord_x, int coord_y); - - static void On_Ping(const HouseClass* player_ptr, COORDINATE coord); - - static void Glyphx_Queue_AI(); - - static void Force_Human_Team_Wins(uint64 quitting_player_id); - - /* - ** Player context switching for input/output - */ - static bool Set_Player_Context(uint64 glyphx_player, bool force = false); - static void Reset_Player_Context(void); - static void Adjust_Internal_View(bool force_ignore_view_constraints = false); - static void Logic_Switch_Player_Context(ObjectClass *object); - static void Logic_Switch_Player_Context(HouseClass *house); - static __int64 Get_GlyphX_Player_ID(const HouseClass *house); - - static void Recalculate_Placement_Distances(); - - static void Reset_Sidebars(void); - - static SidebarGlyphxClass *Get_Current_Context_Sidebar(HouseClass *player_ptr = NULL); - - static uint64 GlyphxPlayerIDs[MAX_PLAYERS]; - - - - static const void *Get_Shadow_Shapes(void) {return Map.ShadowShapes;} - static const unsigned char *Get_Shadow_Trans(void) {return &Map.ShadowTrans[0];} - - static bool Legacy_Render_Enabled(void); - - static bool Get_Input_Key_State(KeyNumType key); - - static void Set_Special_Key_Flags(unsigned char special_key_flags); - static void Clear_Special_Key_Flags(); - - static bool Load(FileClass & file); - static bool Save(FileClass & file); - static void Code_Pointers(void); - static void Decode_Pointers(void); - - static bool Get_Game_Over() { return GameOver; } - - - private: - static void Calculate_Single_Player_Score(EventCallbackStruct&); - - static unsigned int TD_Calculate_Efficiency( unsigned int harvested_credits, unsigned int initial_credits, unsigned int available_credits ); - static unsigned int TD_Calculate_Leadership( int house, unsigned int units_lost, unsigned int buildings_lost ); - static unsigned int TD_Calculate_Score( unsigned int leadership, unsigned int efficiency, unsigned int build_level ); - - static void Convert_Action_Type(ActionType type, ObjectClass* object, TARGET target, DllActionTypeEnum& dll_type); - - static void Calculate_Placement_Distances(BuildingTypeClass* placement_type, unsigned char* placement_distance); - - static int CurrentDrawCount; - static int TotalObjectCount; - static int SortOrder; - static CNCObjectListStruct *ObjectList; - - static CNC_Event_Callback_Type EventCallback; - - - static int CurrentLocalPlayerIndex; - - static bool GameOver; - - /* - ** Pseudo sidebars for players in multiplayer - */ - static SidebarGlyphxClass MultiplayerSidebars[MAX_PLAYERS]; - - static CELL MultiplayerStartPositions[MAX_PLAYERS]; - - static BuildingTypeClass *PlacementType[MAX_PLAYERS]; - - static unsigned char PlacementDistance[MAX_PLAYERS][MAP_CELL_TOTAL]; - - static unsigned char SpecialKeyFlags[MAX_PLAYERS]; - - /* - ** Mod directories - */ - static DynamicVectorClass ModSearchPaths; - -}; - - -/* -** DLLExportClass static data -** -** -** -** -** -*/ -int DLLExportClass::CurrentDrawCount = 0; -int DLLExportClass::TotalObjectCount = 0; -int DLLExportClass::SortOrder = 0; -CNCObjectListStruct *DLLExportClass::ObjectList = NULL; -SidebarGlyphxClass DLLExportClass::MultiplayerSidebars [MAX_PLAYERS]; -uint64 DLLExportClass::GlyphxPlayerIDs[MAX_PLAYERS] = {0xffffffffl}; -int DLLExportClass::CurrentLocalPlayerIndex = -1; -CELL DLLExportClass::MultiplayerStartPositions[MAX_PLAYERS]; -BuildingTypeClass *DLLExportClass::PlacementType[MAX_PLAYERS]; -unsigned char DLLExportClass::PlacementDistance[MAX_PLAYERS][MAP_CELL_TOTAL]; -unsigned char DLLExportClass::SpecialKeyFlags[MAX_PLAYERS] = { 0U }; -DynamicVectorClass DLLExportClass::ModSearchPaths; -bool DLLExportClass::GameOver = false; - - -/* -** Global variables -** -** -** -** -** -*/ -int DLLForceMouseX = 0; -int DLLForceMouseY = 0; - -CNC_Event_Callback_Type DLLExportClass::EventCallback = NULL; - -// Needed to accomodate Glyphx client sidebar. ST - 4/12/2019 5:29PM -int GlyphXClientSidebarWidthInLeptons = 0; - -bool MPlayerIsHuman[MAX_PLAYERS]; -int MPlayerTeamIDs[MAX_PLAYERS]; -int MPlayerStartLocations[MAX_PLAYERS]; - -bool ShareAllyVisibility = true; - - - - - - -void Play_Movie_GlyphX(const char * movie_name, ThemeType theme) -{ - if ((movie_name[0] == 'x' || movie_name[0] == 'X') && movie_name[1] == 0) { - return; - } - - DLLExportClass::On_Play_Movie(movie_name, theme, false); -} - - -void On_Sound_Effect(int sound_index, int variation, COORDINATE coord) -{ - // MBL 02.26.2019 - int voc = sound_index; - if (voc == VOC_NONE) - { - return; - } - - // MBL 02.26.2019 - Borrowed from AUDIO.CPP Sound_Effect() - // - #if 1 - char const * ext = ""; // ".AUD"; - if (Special.IsJuvenile && SoundEffectName[voc].Where == IN_JUV) { - ext = ".JUV"; - } else { - if (SoundEffectName[voc].Where == IN_VAR) { - /* - ** For infantry, use a variation on the response. For vehicles, always - ** use the vehicle response table. - */ - if (variation < 0) { - if (ABS(variation) % 2) { - ext = ".V00"; - } else { - ext = ".V02"; - } - } else { - if (variation % 2) { - ext = ".V01"; - } else { - ext = ".V03"; - } - } - } - } - #endif - // END MBL - - DLLExportClass::On_Sound_Effect(PlayerPtr, sound_index, ext, variation, coord); -} - -// MBL 02.06.2020 -// void On_Speech(int speech_index) -void On_Speech(int speech_index, HouseClass *house) -{ - // DLLExportClass::On_Speech(PlayerPtr, speech_index); // MBL 02.06.2020 - if (house == NULL) { - DLLExportClass::On_Speech(PlayerPtr, speech_index); - } - else - { - DLLExportClass::On_Speech(house, speech_index); - } -} - - -void On_Ping(const HouseClass* player_ptr, COORDINATE coord) -{ - DLLExportClass::On_Ping(player_ptr, coord); -} - - -void GlyphX_Debug_Print(const char *debug_text) -{ - DLLExportClass::On_Debug_Output(debug_text); -} - - -void On_Achievement_Event(const HouseClass* player_ptr, const char *achievement_type, const char *achievement_reason) -{ - DLLExportClass::On_Achievement(player_ptr, achievement_type, achievement_reason); -} - - - - -/************************************************************************************************** -* CNC_Version -- Check DLL/Server version -* -* In: Version expected -* -* Out: Actual version -* -* -* -* History: 4/9/2020 2:12PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) unsigned int __cdecl CNC_Version(unsigned int version_in) -{ - // Unreferenced, but potentially useful to know which version the server is expecting - version_in; - - return CNC_DLL_API_VERSION; -} - - - - -/************************************************************************************************** -* CNC_Init -- Initialize the .DLL -* -* In: Command line -* -* Out: -* -* -* -* History: 1/3/2019 11:33AM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Init(const char *command_line, CNC_Event_Callback_Type event_callback) -{ - DLLExportClass::Set_Content_Directory(NULL); - - DLL_Startup(command_line); - - // MBL - DLLExportClass::Set_Event_Callback( event_callback ); - - DLLExportClass::Init(); -} - - - -/************************************************************************************************** -* DLL_Shutdown -- Shutdown the .DLL -* -* In: -* -* Out: -* -* -* -* History: 2/20/2020 1:58PM - ST -**************************************************************************************************/ -void DLL_Shutdown(void) -{ - DLLExportClass::Shutdown(); -} - - - - - -/************************************************************************************************** -* CNC_Config -- Configure the plugin -* -* In: Configuration data -* -* Out: -* -* -* -* History: 10/03/2019 - SKY -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Config(const CNCRulesDataStruct& rules) -{ - DLLExportClass::Config(rules); -} - - - - -/************************************************************************************************** -* CNC_Add_Mod_Path -- Add a path to load mod files from -* -* In: Path to load mods from -* -* Out: -* -* -* -* History: 2/20/2020 2:04PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Add_Mod_Path(const char *mod_path) -{ - DLLExportClass::Add_Mod_Path(mod_path); -} - - - - - -/************************************************************************************************** -* CNC_Get_Visible_Page -- Get the screen buffer 'SeenBuff' from the game -* -* In: If buffer_in is null, just return info about page -* -* Out: false if not changed since last call -* -* -* -* History: 1/3/2019 11:33AM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Get_Visible_Page(unsigned char *buffer_in, unsigned int &width, unsigned int &height) -{ - if (!DLLExportClass::Legacy_Render_Enabled() || (buffer_in == NULL)) { - return false; - } - - /* - ** Assume the seen page viewport is the same size as the page - */ - - GraphicBufferClass *gbuffer = HidPage.Get_Graphic_Buffer(); - if (gbuffer == NULL) { - return false; - } - - int view_port_width = Map.MapCellWidth * CELL_PIXEL_W; - int view_port_height = Map.MapCellHeight * CELL_PIXEL_H; - - if (view_port_width == 0 || view_port_height == 0) { - return false; - } - - unsigned char *raw_buffer = (unsigned char*) gbuffer->Get_Buffer(); - long raw_size = gbuffer->Get_Size(); - if (raw_buffer == NULL || gbuffer->Get_Width() < view_port_width || gbuffer->Get_Height() < view_port_height) { - return false; - } - - width = view_port_width; - height = view_port_height; - - int pitch = gbuffer->Get_Width(); - for (int i = 0; i < view_port_height; ++i, buffer_in += view_port_width, raw_buffer += pitch) { - memcpy(buffer_in, raw_buffer, view_port_width); - } - - return true; -} - - - - -extern "C" __declspec(dllexport) bool __cdecl CNC_Get_Palette(unsigned char(&palette_in)[256][3]) -{ - memcpy(palette_in, CurrentPalette, sizeof(palette_in)); - return true; -} - - - - -/************************************************************************************************** -* CNC_Set_Multiplayer_Data -- Set up for a multiplayer match -* -* In: Multiplayer data -* -* Out: false if data is bad -* -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Set_Multiplayer_Data(int scenario_index, CNCMultiplayerOptionsStruct &game_options, int num_players, CNCPlayerInfoStruct *player_list, int max_players) -{ - - if (num_players <= 0) { - return false; - } - - if (num_players > min(MAX_PLAYERS, max_players)) { - return false; - } - - DLLExportClass::Init(); - - //MPlayerPrefColor; // preferred color index for this player - //MPlayerColorIdx; // actual color index of this player - //MPlayerHouse; // House of this player (GDI/NOD) - //MPlayerLocalID; // ID of this player - MPlayerCount = num_players; // # of human players in this game - MPlayerBases = game_options.MPlayerBases; // 1 = bases are on for this scenario - MPlayerCredits = game_options.MPlayerCredits; // # credits everyone gets - MPlayerTiberium = game_options.MPlayerTiberium; // 1 = tiberium enabled for this scenario - MPlayerGoodies = game_options.MPlayerGoodies; // 1 = goodies enabled for this scenario - MPlayerGhosts = game_options.MPlayerGhosts; // 1 = houses with no players will still play - MPlayerSolo = game_options.MPlayerSolo; // 1 = allows a single-player net game - MPlayerUnitCount = game_options.MPlayerUnitCount; // # units for non-base multiplayer scenarios - - Special.IsMCVDeploy = game_options.IsMCVDeploy; - Special.IsVisceroids = game_options.SpawnVisceroids; - Special.IsCaptureTheFlag = game_options.CaptureTheFlag; - Special.IsEarlyWin = game_options.DestroyStructures; - - Rule.AllowSuperWeapons = game_options.EnableSuperweapons; // Are superweapons available - - if (MPlayerTiberium) { - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - } else { - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - } - - Scenario = scenario_index; - MPlayerCount = 0; - - for (int i=0 ; i 0 && MPlayerStartLocations[i] == 0 && MPlayerStartLocations[0] == 0) { - MPlayerStartLocations[i] = i; - } - - MPlayerCount++; - } - - /* - ** We need some default for the local ID in order to have a valid PlayerPtr during scenario load. ST - 4/24/2019 10:33AM - */ - MPlayerLocalID = MPlayerID[0]; - - return true; -} - -extern "C" __declspec(dllexport) bool __cdecl CNC_Clear_Object_Selection(uint64 player_id) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - Unselect_All(); - - return true; -} - -extern "C" __declspec(dllexport) bool __cdecl CNC_Select_Object(uint64 player_id, int object_type_id, int object_to_select_id) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - switch (object_type_id) - { - case INFANTRY: - { - for (int index = 0; index < Infantry.Count(); index++) { - InfantryClass * obj = Infantry.Ptr(index); - - if (obj - && !obj->IsInLimbo - && obj->House == PlayerPtr - && Infantry.ID((InfantryClass*)obj) == object_to_select_id) - { - if (!obj->Is_Selected_By_Player()) - { - obj->Select(); - AllowVoice = false; - } - return true; - } - } - } - break; - case UNIT: - { - for (int index = 0; index < Units.Count(); index++) { - UnitClass * obj = Units.Ptr(index); - - if (obj - && !obj->IsInLimbo - && obj->House == PlayerPtr - && Units.ID((UnitClass*)obj) == object_to_select_id) - { - if (!obj->Is_Selected_By_Player()) - { - obj->Select(); - AllowVoice = false; - } - return true; - } - } - } - break; - case AIRCRAFT: - { - for (int index = 0; index < Aircraft.Count(); index++) { - AircraftClass * obj = Aircraft.Ptr(index); - - if (obj - && !obj->IsInLimbo - && obj->House == PlayerPtr - && Aircraft.ID((AircraftClass*)obj) == object_to_select_id) - { - if (!obj->Is_Selected_By_Player()) - { - obj->Select(); - AllowVoice = false; - } - return true; - } - } - } - break; - case BUILDING: - { - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * obj = Buildings.Ptr(index); - if (obj - && !obj->IsInLimbo - && obj->House == PlayerPtr - && Buildings.ID((BuildingClass*)obj) == object_to_select_id) - { - if (!obj->Is_Selected_By_Player()) - { - obj->Select(); - AllowVoice = false; - } - return true; - } - } - } - break; - } - - return false; -} - - -/************************************************************************************************** -* GlyphX_Assign_Houses -- Replacement for Assign_Houses in INI.CPP -* -* In: -* -* Out: -* -* -* -* History: 6/25/2019 11:09AM - ST -**************************************************************************************************/ -void GlyphX_Assign_Houses(void) -{ - HousesType house; - HousesType pref_house; - HouseClass *housep; - bool house_used[MAX_PLAYERS]; // true = this house is in use - bool color_used[16]; // true = this color is in use. We have more than 6 color options now, so bumped this to 16. ST - 6/19/2019 5:18PM - bool preassigned; - int i,j,random_start_location; - PlayerColorType color; - HousesType house2; - HouseClass *housep2; - - srand(timeGetTime()); - - /* - ** Init the 'used' flag for all houses & colors to 0 - */ - for (i = 0; i < MAX_PLAYERS; i++) { - house_used[i] = false; - } - for (i = 0; i < 16; i++) { - color_used[i] = false; - } - - /* - ** Assign random start positions if needed. - */ - int random_start_locations[26]; - int num_start_locations = 0; - int num_random_start_locations = 0; - for (i = 0; i < 26; i++) { - if (Waypoint[i] != -1) { - preassigned = false; - for (j = 0; !preassigned && (j < MPlayerCount); j++) { - if (MPlayerStartLocations[j] == num_start_locations) { - preassigned = true; - } - } - if (!preassigned) { - random_start_locations[num_random_start_locations] = num_start_locations; - num_random_start_locations++; - } - num_start_locations++; - } - } - - if (num_random_start_locations > 1) { - for (i = 0; i < num_random_start_locations - 1; i++) { - j = i + rand() / (RAND_MAX / (num_random_start_locations - i) + 1); - int t = random_start_locations[j]; - random_start_locations[j] = random_start_locations[i]; - random_start_locations[i] = t; - } - } - - /* - ** For each player, randomly pick a house - */ - random_start_location = 0; - for (i = 0; i < MPlayerCount; i++) { - j = Random_Pick(0, MPlayerMax-1); - - /* - ** If this house was already selected, decrement 'i' & keep looping. - */ - if (house_used[j]) { - i--; - continue; - } - - /* - ** Set the house, preferred house (GDI/NOD), color, and actual house; - ** get a pointer to the house instance - */ - house = (HousesType)(j + (int)HOUSE_MULTI1); - pref_house = MPlayerID_To_HousesType(MPlayerID[i]); - color = MPlayerID_To_ColorIndex(MPlayerID[i]); - housep = HouseClass::As_Pointer(house); - MPlayerHouses[i] = house; - - /* - ** Mark this house & color as used - */ - house_used[j] = true; - color_used[color] = true; - - /* - ** Set the house's IsHuman, Credits, ActLike, & RemapTable - */ - memset((char *)housep->Name, 0, MPLAYER_NAME_MAX); - strncpy((char *)housep->Name, MPlayerNames[i], MPLAYER_NAME_MAX-1); - housep->IsHuman = MPlayerIsHuman[i]; - housep->Init_Data(color, pref_house, MPlayerCredits); - - /* - ** Set the start location override - */ - if (MPlayerStartLocations[i] != RANDOM_START_POSITION) { - housep->StartLocationOverride = MPlayerStartLocations[i]; - } else { - if (random_start_location < num_random_start_locations) { - housep->StartLocationOverride = random_start_locations[random_start_location++]; - } else { - housep->StartLocationOverride = -1; - } - } - - /* - ** If this ID is for myself, set up PlayerPtr - */ - if (MPlayerID[i] == MPlayerLocalID) { - PlayerPtr = housep; - } - } - - /* - ** From INI.CPP. Remove unused AI players. - */ - for (int i=0 ; iIsHuman == false) { - housep->Clobber_All(); - } - } - - for (i = 0; i < MPlayerCount; i++) { - - house = MPlayerHouses[i]; - housep = HouseClass::As_Pointer(house); - - if (housep) { - - int team = MPlayerTeamIDs[i]; - - for (int j=0 ; jMake_Ally(house2); - } - } - } - } - } - } -} - -/************************************************************************************************** -* CNC_Start_Instance -- Load and start a cnc map to use WITHOUT a sceanrio variation (SCEN_VAR) or scenarion direction (SCEN_DIR) -* -* In: Map initialization parameters -* -* Out: false if map load failed -* -* -* -* History: 7/10/2019 - LLL -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Start_Instance(int scenario_index, int build_level, const char *faction, const char *game_type, const char *content_directory, int sabotaged_structure, const char *override_map_name) -{ - return CNC_Start_Instance_Variation(scenario_index, (int)SCEN_VAR_NONE, (int)SCEN_DIR_EAST, build_level, faction, game_type, content_directory, sabotaged_structure, override_map_name); -} - - -/************************************************************************************************** -* HandleSabotagedStructure -* -* A port of the code from the original game code which is suppose to remove the main previously sabatoged building. -* From what I can tell since it only stores the type it might remove a different building of the same type. -* Watching the GDI longplay on YouTube the player destroys the refinery and yet it exists in the next level. Perhaps there are 2 refineries. -* -* History: 7/10/2019 - LLL -**************************************************************************************************/ -void HandleSabotagedStructure(int structure_type) -{ - SabotagedType = (StructType) structure_type; - - int index; - if (SabotagedType != STRUCT_NONE && Scenario == 7 && PlayerPtr->Class->House == HOUSE_GOOD) { - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && !building->IsInLimbo && building->House != PlayerPtr && building->Class->Type == SabotagedType) { - building->Limbo(); - delete building; - break; - } - } - - /* - ** Remove the building from the prebuild list. - */ - for (index = 0; index < Base.Nodes.Count(); index++) { - BaseNodeClass * node = Base.Get_Node(index); - - if (node && node->Type == SabotagedType) { - Base.Nodes.Delete(index); - break; - } - } - } - SabotagedType = STRUCT_NONE; -} - - - -/************************************************************************************************** -* CNC_Read_INI -- Load an ini file into the supplied buffer -* -* In: Map initialization parameters -* -* Out: false if ini load failed -* -* -* History: 12/16/2019 11:44AM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Read_INI(int scenario_index, int scenario_variation, int scenario_direction, const char *content_directory, const char *override_map_name, char *ini_buffer, int _ini_buffer_size) -{ - if (content_directory == NULL) { - return false; - } - - DLLExportClass::Set_Content_Directory(content_directory); - - // Hack a fix for scenario 21 since the same mission number is used in Covert Ops and N64 - Scenario = (scenario_index == 81) ? 21 : scenario_index; - - ScenVar = (ScenarioVarType)scenario_variation; - ScenDir = (ScenarioDirType)scenario_direction; - - GameToPlay = GAME_GLYPHX_MULTIPLAYER; - ScenPlayer = SCEN_PLAYER_MPLAYER; - - if (override_map_name && strlen(override_map_name)) { - strcpy(ScenarioName, override_map_name); - } else { - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, (ScenarioDirType)scenario_direction, (ScenarioVarType)scenario_variation); - } - - - if (_ini_buffer_size < _ShapeBufferSize) { - GlyphX_Debug_Print("INI file buffer may be too small"); - return false; - } - - if (!ini_buffer) { - GlyphX_Debug_Print("No INI file buffer"); - return false; - } - - memset(ini_buffer, _ini_buffer_size, 0); - - char fname[_MAX_PATH]; - - sprintf(fname,"%s.INI", ScenarioName); - CCFileClass file(fname); - if (!file.Is_Available()) { - GlyphX_Debug_Print("Failed to find scenario file"); - GlyphX_Debug_Print(fname); - return(false); - - } else { - - GlyphX_Debug_Print("Opened scenario file"); - GlyphX_Debug_Print(fname); - - int bytes_read = file.Read(ini_buffer, _ini_buffer_size-1); - if (bytes_read == _ini_buffer_size - 1) { - GlyphX_Debug_Print("INI file buffer is too small"); - return false; - } - } - - /* - ** Ini buffer should be zero terminated - */ - if ((int) strlen(ini_buffer) >= _ini_buffer_size) { - GlyphX_Debug_Print("INI file buffer overrun"); - return false; - } - - return true; -} - - -/************************************************************************************************** -* CNC_Set_Home_Cell -- Allows overriding the start position for the camera -* -* -* History: 2/14/2020 - LLL -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Set_Home_Cell(int x, int y, uint64 player_id) -{ - DLLExportClass::Set_Home_Cell(x, y, player_id); -} - - -/************************************************************************************************** -* CNC_Start_Instance -- Load and start a cnc map -* -* In: Map initialization parameters -* -* Out: false if map load failed -* -* -* Renamed and modified to accept a scenario variation 7/10/2019 - LLL -* Modified to accept a scenario direction 7/12/2019 - LLL -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Start_Instance_Variation(int scenario_index, int scenario_variation, int scenario_direction, int build_level, const char *faction, const char *game_type, const char *content_directory, int sabotaged_structure, const char *override_map_name) -{ - if (game_type == NULL) { - return false; - } - - if (faction == NULL) { - return false; - } - - if (content_directory == NULL) { - return false; - } - - if (stricmp(faction, "GDI") == 0) { - ScenPlayer = SCEN_PLAYER_GDI; - Whom = HOUSE_GOOD; - } - - if (stricmp(faction, "NOD") == 0) { - ScenPlayer = SCEN_PLAYER_NOD; - Whom = HOUSE_BAD; - } - - if (stricmp(faction, "Jurassic") == 0) { - ScenPlayer = SCEN_PLAYER_JP; - Whom = HOUSE_JP; - Special.IsJurassic = true; - AreThingiesEnabled = true; - } - - DLLExportClass::Set_Content_Directory(content_directory); - - // Hack a fix for scenario 21 since the same mission number is used in Covert Ops and N64 - Scenario = (scenario_index == 81) ? 21 : scenario_index; - BuildLevel = build_level; - - SabotagedType = (StructType)sabotaged_structure; - - ScenVar = (ScenarioVarType)scenario_variation; - ScenDir = (ScenarioDirType)scenario_direction; - - if (stricmp(game_type, "GAME_NORMAL") == 0) { - GameToPlay = GAME_NORMAL; - } else { - if (stricmp(game_type, "GAME_GLYPHX_MULTIPLAYER") == 0) { - GameToPlay = GAME_GLYPHX_MULTIPLAYER; - ScenPlayer = SCEN_PLAYER_MPLAYER; - } else { - return false; - } - } - - if (override_map_name && strlen(override_map_name)) { - strcpy(ScenarioName, override_map_name); - } else { - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, (ScenarioDirType)scenario_direction, (ScenarioVarType)scenario_variation); - } - - HiddenPage.Clear(); - VisiblePage.Clear(); - - /* - ** Set the mouse to some position where it's not going to scroll, or do something else wierd. - */ - DLLForceMouseX = 100; - DLLForceMouseY = 100; - _Kbd->MouseQX = 100; - _Kbd->MouseQY = 100; - - GlyphXClientSidebarWidthInLeptons = 0; - - Seed = timeGetTime(); - - if (!Start_Scenario(ScenarioName)) { - return(false); - } - - HandleSabotagedStructure(sabotaged_structure); - - DLLExportClass::Reset_Sidebars(); - DLLExportClass::Reset_Player_Context(); - - /* - ** Make sure the scroll constraints are applied. This is important for GDI 1 where the map isn't wide enough for the screen - */ - COORDINATE origin_coord = Coord_Add(Map.TacticalCoord, XY_Coord(1, 0)); - Map.Set_Tactical_Position(origin_coord); - origin_coord = Coord_Add(Map.TacticalCoord, XY_Coord(-1, 0)); - Map.Set_Tactical_Position(origin_coord); - - DLLExportClass::Calculate_Start_Positions(); - - /* - ** Hide the SeenBuff; force the map to render one frame. The caller can - ** then fade the palette in. - ** (If we loaded a game, this step will fade out the title screen. If we - ** started a scenario, Start_Scenario() will have played a couple of VQ - ** movies, which will have cleared the screen to black already.) - */ - - //Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - HiddenPage.Clear(); - VisiblePage.Clear(); - Set_Logic_Page(SeenBuff); - Map.Flag_To_Redraw(true); - Map.Render(); - - Set_Palette(GamePalette); - - return true; -} - - - - - -/************************************************************************************************** -* CNC_Start_Custom_Instance -- -* -* -* -* -* History: 2019/10/17 - JAS -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Start_Custom_Instance(const char* content_directory, const char* directory_path, - const char* scenario_name, int build_level, bool multiplayer) -{ - if (content_directory == NULL) { - return false; - } - - DLLExportClass::Set_Content_Directory(content_directory); - - if (multiplayer) { - GameToPlay = GAME_GLYPHX_MULTIPLAYER; - ScenPlayer = SCEN_PLAYER_MPLAYER; - } else { - GameToPlay = GAME_NORMAL; - ScenPlayer = SCEN_PLAYER_GDI; // Don't think it matters since we are specifying the exact file to load - } - - BuildLevel = build_level; - - const int MAX_FILE_PATH = 1024; - char scenario_file_name[MAX_FILE_PATH]; - char bin_file_name[MAX_FILE_PATH]; - snprintf(scenario_file_name, MAX_FILE_PATH, "%s%s.INI", directory_path, scenario_name); - snprintf(bin_file_name, MAX_FILE_PATH, "%s%s.BIN", directory_path, scenario_name); - - Seed = timeGetTime(); - - Clear_Scenario(); - - Read_Scenario_Ini_File(scenario_file_name, bin_file_name, scenario_name, true); - - HiddenPage.Clear(); - VisiblePage.Clear(); - - /* - ** Set the mouse to some position where it's not going to scroll, or do something else wierd. - */ - DLLForceMouseX = 100; - DLLForceMouseY = 100; - _Kbd->MouseQX = 100; - _Kbd->MouseQY = 100; - - GlyphXClientSidebarWidthInLeptons = 0; - - /* - if (!Start_Scenario(ScenarioName)) { - return(false); - } - */ - - DLLExportClass::Reset_Sidebars(); - DLLExportClass::Reset_Player_Context(); - - /* - ** Make sure the scroll constraints are applied. This is important for GDI 1 where the map isn't wide enough for the screen - */ - COORDINATE origin_coord = Coord_Add(Map.TacticalCoord, XY_Coord(1, 0)); - Map.Set_Tactical_Position(origin_coord); - origin_coord = Coord_Add(Map.TacticalCoord, XY_Coord(-1, 0)); - Map.Set_Tactical_Position(origin_coord); - - DLLExportClass::Calculate_Start_Positions(); - - /* - ** Hide the SeenBuff; force the map to render one frame. The caller can - ** then fade the palette in. - ** (If we loaded a game, this step will fade out the title screen. If we - ** started a scenario, Start_Scenario() will have played a couple of VQ - ** movies, which will have cleared the screen to black already.) - */ - - //Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - HiddenPage.Clear(); - VisiblePage.Clear(); - Set_Logic_Page(SeenBuff); - Map.Flag_To_Redraw(true); - Map.Render(); - - Set_Palette(GamePalette); - - return true; -} - - -bool Debug_Write_Shape_Type(const ObjectTypeClass *type, int shapenum) -{ - char fullname[_MAX_FNAME+_MAX_EXT]; - char buffer[_MAX_FNAME]; - CCFileClass file; - - if (type->ImageData != NULL) { - - sprintf(buffer, "%s_%d", type->IniName, shapenum); - _makepath(fullname, NULL, NULL, buffer, ".PCX"); - - return Debug_Write_Shape(fullname, type->ImageData, shapenum); - } - - return false; -} - - -bool Debug_Write_Shape(const char *file_name, void const * shapefile, int shapenum, int flags, void const * ghostdata) -{ - /* - ** Build frame returns a pointer now instead of the shapes length - */ - char *shape_pointer = (char*) Build_Frame(shapefile , shapenum , _ShapeBuffer); - if (shape_pointer == NULL) { - return false;; - } - if (Get_Last_Frame_Length() > _ShapeBufferSize) { - return false;; - } - - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); - - GraphicBufferClass temp_gbuffer(width, height); - GraphicViewPortClass temp_viewport(&temp_gbuffer, 0, 0, width, height); - - WindowList[WINDOW_CUSTOM][WINDOWX] = 0; - WindowList[WINDOW_CUSTOM][WINDOWY] = 0; - WindowList[WINDOW_CUSTOM][WINDOWWIDTH] = width; - WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = height; - - static const char _shape_trans = 0x40; - - if (flags == 0) { - Buffer_Frame_To_Page(0, 0, width, height, shape_pointer, temp_viewport, SHAPE_NORMAL|SHAPE_WIN_REL|_shape_trans); //, ghostdata, predoffset); - } else { - Buffer_Frame_To_Page(0, 0, width, height, shape_pointer, temp_viewport, flags, ghostdata); - } - Write_PCX_File((char*)file_name, temp_viewport, GamePalette); - - return true; -} - - - -/************************************************************************************************** -* CNC_Advance_Instance -- Process one logic frame -* -* In: -* -* Out: Is game still playing? -* -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Advance_Instance(uint64 player_id) -{ - //DLLExportClass::Set_Event_Callback(event_callback); - - InMainLoop = true; - - if (Frame <= 10) { // Don't spam forever, but useful to know that we actually started advancing - GlyphX_Debug_Print("CNC_Advance_Instance - TD"); - } - - /* - ** Shouldn't really need to do this, but I like the idea of always running the main loop in the context of the same player. - ** Might make tbe bugs more repeatable and consistent. ST - 3/15/2019 11:58AM - */ - if (player_id != 0) { - DLLExportClass::Set_Player_Context(player_id); - } else { - DLLExportClass::Set_Player_Context(DLLExportClass::GlyphxPlayerIDs[0]); - } - - /* - ** Allocate extra memory for uncompressed shapes as needed - */ - Reallocate_Big_Shape_Buffer(); - - /* - ** If there is no theme playing, but it looks like one is required, then start one - ** playing. This is usually the symptom of there being no transition score. - */ - //if (SampleType && Theme.What_Is_Playing() == THEME_NONE) { - // Theme.Queue_Song(THEME_PICK_ANOTHER); - //} - - /* - ** Update the display, unless we're inside a dialog. - */ - //if (SpecialDialog == SDLG_NONE && GameInFocus) { - - //WWMouse->Erase_Mouse(&HidPage, TRUE); - //Map.Input(input, x, y); - //if (input) { - // Keyboard_Process(input); - //} - /* - ** The main loop passes these in uninitialized. ST - 2/7/2019 4:36PM - */ - KeyNumType input = KN_NONE; // Player input. - int x = 0; - int y = 0; - Map.Input(input, x, y); - //if (input) { - // Keyboard_Process(input); - //} - - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - /* - ** Process the sidebar. ST - 4/18/2019 11:59AM - */ - HouseClass *old_player_ptr = PlayerPtr; - for (int i=0 ; iErase_Mouse(&HidPage, TRUE); - PlayerLoses = false; - PlayerWins = false; - PlayerRestarts = false; - Map.Help_Text(TXT_NONE); - - InMainLoop = false; - - GlyphX_Debug_Print("PlayerWins = true"); - - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - DLLExportClass::On_Multiplayer_Game_Over(); - } else { - DLLExportClass::On_Game_Over(player_id, true); - } - - return false; - } - if (PlayerLoses) { - - //WWMouse->Erase_Mouse(&HidPage, TRUE); - PlayerWins = false; - PlayerLoses = false; - PlayerRestarts = false; - Map.Help_Text(TXT_NONE); - - //Do_Lose(); //Old C&C code - GlyphX_Debug_Print("PlayerLoses = true"); - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - DLLExportClass::On_Multiplayer_Game_Over(); - } else { - DLLExportClass::On_Game_Over(player_id, false); - } - - InMainLoop = false; - - return false; - } - - /* - ** The frame logic has been completed. Increment the frame - ** counter. - */ - Frame++; - - /* - ** Very rarely, the human players will get a message from the computer. - */ - if (GameToPlay != GAME_NORMAL && MPlayerGhosts && IRandom(0,10000) == 1) { - DLLExportClass::Computer_Message(false); - } - - /* - ** The code is often leaving dangling pointers in overlappers. We can afford the CPU time to just clean them up. I suspect - ** the underlying cause was probably fixed in RA. - ** ST - 4/14/2020 11:45AM - */ - Map.Clean(); - -#ifndef NDEBUG - /* - ** Is there a memory trasher altering the map?? - */ - if (!Map.Validate()) { - GlyphX_Debug_Print("Map.Validate() failed"); - - //if (CCMessageBox().Process ("Map Error!","Stop","Continue")==0) { - // GameActive = false; - //} - Map.Validate(); // give debugger a chance to catch it - } -#endif NDEBUG - - InMainLoop = false; - - if (ProgEndCalled) { - GlyphX_Debug_Print("ProgEndCalled - GameActive = false"); - GameActive = false; - } - - if (DLLExportClass::Legacy_Render_Enabled()) { - Map.Render(); - } - - //Sync_Delay(); - Color_Cycle(); - //DLLExportClass::Set_Event_Callback(NULL); - return(GameActive); -} - - -/************************************************************************************************** -* CNC_Save_Load -- Process a save or load game action -* -* In: -* -* Out: Success? -* -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Save_Load(bool save, const char *file_path_and_name, const char *game_type) -{ - bool result = false; - - if (save) { - result = Save_Game(file_path_and_name, "internal"); - } else { - - if (game_type == NULL) { - return false; - } - - if (stricmp(game_type, "GAME_NORMAL") == 0) { - GameToPlay = GAME_NORMAL; - } else { - if (stricmp(game_type, "GAME_GLYPHX_MULTIPLAYER") == 0) { - GameToPlay = GAME_GLYPHX_MULTIPLAYER; - ScenPlayer = SCEN_PLAYER_MPLAYER; - } else { - return false; - } - } - - result = Load_Game(file_path_and_name); - - DLLExportClass::Set_Player_Context(DLLExportClass::GlyphxPlayerIDs[0], true); - Set_Logic_Page(SeenBuff); - VisiblePage.Clear(); - Map.Flag_To_Redraw(true); - if (DLLExportClass::Legacy_Render_Enabled()) { - Map.Render(); - } - Set_Palette(GamePalette); - } - - return result; -} - - - -/************************************************************************************************** -* CNC_Set_Difficulty -- Set game difficulty -* -* In: -* -* Out: -* -* -* -* History: 10/02/2019 - SKY -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Set_Difficulty(int difficulty) -{ - if (GameToPlay == GAME_NORMAL) { - Set_Scenario_Difficulty(difficulty); - } -} - - -/************************************************************************************************** -* CNC_Handle_Player_Switch_To_AI -- Renamed 3/9/20202 - LLL -* previously named: CNC_Handle_Player_Disconnect -- Handle player disconnected during multiplayuer game -* -* In: -* -* Out: -* -* -* -* History: 12/3/2019 1:46PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Player_Switch_To_AI(uint64 player_id) -{ - if (PlayerWins || PlayerLoses || DLLExportClass::Get_Game_Over()) { - return; - } - - GlyphX_Debug_Print("CNC_Handle_Player_Switch_To_AI"); - - if (GameToPlay == GAME_NORMAL) { - return; - } - -#ifdef KILL_PLAYER_ON_DISCONNECT - - /* - ** Kill player's units on disconnect. - */ - if (player_id != 0) { - DLLExportClass::Set_Player_Context(player_id); - - if (PlayerPtr) { - PlayerPtr->Flag_To_Die(); - } - } - -#else //KILL_PLAYER_ON_DISCONNECT - - if (player_id != 0) { - - HousesType house; - HouseClass *ptr; - - DLLExportClass::Set_Player_Context(player_id); - - if (PlayerPtr) { - PlayerPtr->WasHuman = true; - PlayerPtr->IsHuman = false; - PlayerPtr->IsStarted = true; - PlayerPtr->IQ = Rule.MaxIQ; - PlayerPtr->IsBaseBuilding = true; - - /* - ** Start the unload mission for MCVs - */ - for (int index = 0; index < Units.Count(); index++) { - UnitClass * obj = Units.Ptr(index); - - if (obj && !obj->IsInLimbo && obj->House == PlayerPtr) { - if (*obj == UNIT_MCV) { - obj->Assign_Mission(MISSION_GUARD); - obj->Assign_Target(TARGET_NONE); - obj->Assign_Destination(TARGET_NONE); - obj->Assign_Mission(MISSION_UNLOAD); - obj->Commence(); - } - } - } - - DLLExportClass::On_Message(PlayerPtr, "", 60.0f, MESSAGE_TYPE_PLAYER_DISCONNECTED, -1); - - /* - ** Send the disconnect taunt message - */ - int human_count = 0; - for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { - ptr = HouseClass::As_Pointer(house); - - if (ptr && ptr->IsHuman && !ptr->IsDefeated) { - human_count++; - } - } - - if (human_count == 1) { - DLLExportClass::Computer_Message(true); - } - } - } - -#endif //KILL_PLAYER_ON_DISCONNECT - -} - - -/************************************************************************************************** -* CNC_Handle_Human_Team_Wins -* -* History: 3/10/2020 - LLL -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Human_Team_Wins(uint64 quitting_player_id) -{ - GlyphX_Debug_Print("CNC_Handle_Human_Team_Wins"); - DLLExportClass::Force_Human_Team_Wins(quitting_player_id); -} - - -/************************************************************************************************** -* CNC_Start_Mission_Timer -* -* History: 11/25/2019 - LLL -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Start_Mission_Timer(int time) -{ - //Only implemented in Red Alert. -} - - - -/************************************************************************************************** -* DLLExportClass::Init -- Init the class -* -* In: -* -* Out: -* -* -* -* History: 3/12/2019 10:52AM - ST -**************************************************************************************************/ -void DLLExportClass::Init(void) -{ - for (int i=0 ; i= VOC_FIRST && sound_effect_index < VOC_COUNT ) - { - strncpy( new_event.SoundEffect.SoundEffectName, SoundEffectName[ sound_effect_index ].Name, CNC_OBJECT_ASSET_NAME_LENGTH); - new_event.SoundEffect.SoundEffectName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; // strncpy can leave strings unterminated - if ( extension != NULL ) - { - strncat( new_event.SoundEffect.SoundEffectName, extension, CNC_OBJECT_ASSET_NAME_LENGTH); - new_event.SoundEffect.SoundEffectName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; // strncat can leave strings unterminated - } - new_event.SoundEffect.SoundEffectPriority = SoundEffectName[ sound_effect_index ].Priority; - new_event.SoundEffect.SoundEffectContext = SoundEffectName[ sound_effect_index ].Where; - } - else - { - strncpy( new_event.SoundEffect.SoundEffectName, "BADINDEX", CNC_OBJECT_ASSET_NAME_LENGTH); - new_event.SoundEffect.SoundEffectPriority = -1; - new_event.SoundEffect.SoundEffectContext = -1; - } - - EventCallback(new_event); -} - - - -/************************************************************************************************** -* DLLExportClass::On_Speech -- Called when C&C wants to play a speech line -* -* In: -* -* Out: -* -* -* -* History: 2/20/2019 2:39PM - ST -**************************************************************************************************/ -void DLLExportClass::On_Speech(const HouseClass* player_ptr, int speech_index) -{ - // player_ptr could be NULL - - if (EventCallback == NULL) { - return; - } - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_SPEECH; - new_event.Speech.SpeechIndex = speech_index; - - new_event.GlyphXPlayerID = 0; - if ( player_ptr != NULL ) - { - new_event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - } - - if ( speech_index >= VOX_FIRST && speech_index < VOX_COUNT ) - { - strncpy( new_event.Speech.SpeechName, Speech[ speech_index ], CNC_OBJECT_ASSET_NAME_LENGTH); - new_event.Speech.SpeechName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; // strncpy can leave strings unterminated - } - else - { - strncpy( new_event.Speech.SpeechName, "BAD_SPEECH_INDEX", CNC_OBJECT_ASSET_NAME_LENGTH); - } - - EventCallback(new_event); -} - -/************************************************************************************************** -* DLLExportClass::TD_Calculate_Efficiency -- -* -* History: 10.29.2019 MBL (Based on LLL's Calculate_Single_Player_Score()) -**************************************************************************************************/ -unsigned int DLLExportClass::TD_Calculate_Efficiency( unsigned int harvested_credits, unsigned int initial_credits, unsigned int available_credits ) -{ - unsigned efficiency = Cardinal_To_Fixed( harvested_credits + (initial_credits + 1), (available_credits + 1) ); - if ( efficiency == 0 ) { - efficiency++; - } - - efficiency = Fixed_To_Cardinal(100, efficiency); - if (efficiency > 100) { - efficiency = 100; - } - - return efficiency; -} - -/************************************************************************************************** -* DLLExportClass::TD_Calculate_Leadership -- -* -* History: 10.29.2019 MBL (Based on LLL's Calculate_Single_Player_Score()) -**************************************************************************************************/ -unsigned int DLLExportClass::TD_Calculate_Leadership( int house, unsigned int units_lost, unsigned int buildings_lost ) -{ - unsigned int leadership = 0; - - for (int index = 0; index < Logic.Count(); index++) { - ObjectClass * object = Logic[index]; - if (object->Owner() == house) { - leadership++; - } - } - - if (leadership == 0) { - leadership = 1; - } - - leadership = Cardinal_To_Fixed(units_lost + buildings_lost + leadership, leadership); - - leadership = Fixed_To_Cardinal(100, leadership); - if (leadership > 100) { - leadership = 100; - } - - return leadership; -} - -/************************************************************************************************** -* DLLExportClass::TD_Calculate_Score -- -* -* History: 10.29.2019 MBL (Based on LLL's Calculate_Single_Player_Score()) -**************************************************************************************************/ -unsigned int DLLExportClass::TD_Calculate_Score( unsigned int leadership, unsigned int efficiency, unsigned int build_level ) -{ - long total = ((leadership * 40) + (4600) + (efficiency * 14)) / 100; - if (!total) total++; - total *= (build_level + 1); - - return total; -} - -void DLLExportClass::Calculate_Single_Player_Score(EventCallbackStruct& event) -{ - //Adapted from Tiberian Dawn SCORE.CPP Presentation() - LLL - int house = PlayerPtr->Class->House; // 0 or 1 - - HouseClass *houses[3]; - for (int index = 0; index < 3; index++) { - houses[index] = (HouseClass::As_Pointer((HousesType)(HOUSE_GOOD + index))); - } - - int gdi_units_lost = (HouseClass::As_Pointer(HOUSE_GOOD))->UnitsLost; - int nod_units_lost = (HouseClass::As_Pointer(HOUSE_BAD))->UnitsLost; - int civilians_killed = (HouseClass::As_Pointer(HOUSE_NEUTRAL))->UnitsLost; - int gdi_buildings_lost = (HouseClass::As_Pointer(HOUSE_GOOD))->BuildingsLost; - int nod_buildings_lost = (HouseClass::As_Pointer(HOUSE_BAD))->BuildingsLost; - int civilian_buildings_lost = (HouseClass::As_Pointer(HOUSE_NEUTRAL))->BuildingsLost; - int gdi_harvested = (HouseClass::As_Pointer(HOUSE_GOOD))->HarvestedCredits; - int nod_harvested = (HouseClass::As_Pointer(HOUSE_BAD))->HarvestedCredits; - - // unsigned leadership = 0; - // int index; - // for (index = 0; index < Logic.Count(); index++) { - // ObjectClass * object = Logic[index]; - // if (object->Owner() == house) { - // leadership++; - // } - // } - // - // if (leadership == 0) { - // leadership = 1; - // } - // - // leadership = Cardinal_To_Fixed(gdi_units_lost + gdi_buildings_lost + leadership, leadership); - // leadership = Fixed_To_Cardinal(100, leadership); - // if (leadership > 100) { - // leadership = 100; - // } - // - unsigned leadership = TD_Calculate_Leadership( house, (house == HOUSE_GOOD ? gdi_units_lost : nod_units_lost), (house == HOUSE_GOOD ? gdi_buildings_lost : nod_buildings_lost) ); - - /* - ** Determine efficiency rating. - */ - // int gharv = gdi_harvested; - // int init = PlayerPtr->InitialCredits; - // int cred = PlayerPtr->Available_Money(); - // - // unsigned efficiency = Cardinal_To_Fixed((house == HOUSE_GOOD ? gdi_harvested : nod_harvested) + (unsigned)PlayerPtr->InitialCredits + 1, (unsigned)PlayerPtr->Available_Money() + 1); - // if (!efficiency) efficiency++; - // efficiency = Fixed_To_Cardinal(100, efficiency); - // if (efficiency > 100) { - // efficiency = 100; - // } - // - unsigned efficiency = TD_Calculate_Efficiency((house == HOUSE_GOOD ? gdi_harvested : nod_harvested), PlayerPtr->InitialCredits, PlayerPtr->Available_Money()); - - /* - ** Calculate total score - */ - // long total_score = ((leadership * 40) + (4600) + (efficiency * 14)) / 100; - // if (!total_score) total_score++; - // total_score *= (BuildLevel + 1); - // - unsigned total_score = TD_Calculate_Score( leadership, efficiency, BuildLevel ); - - //Score Stats - event.GameOver.Leadership = leadership; - event.GameOver.Efficiency = efficiency; - event.GameOver.Score = total_score; - event.GameOver.CategoryTotal = 0; //Only used in Red Alert - event.GameOver.NODKilled = nod_units_lost; - event.GameOver.GDIKilled = gdi_units_lost; - event.GameOver.CiviliansKilled = civilians_killed; - event.GameOver.NODBuildingsDestroyed = nod_buildings_lost; - event.GameOver.GDIBuildingsDestroyed = gdi_buildings_lost; - event.GameOver.CiviliansBuildingsDestroyed = civilian_buildings_lost; - event.GameOver.RemainingCredits = PlayerPtr->Available_Money(); -} - -void DLLExportClass::Convert_Action_Type(ActionType type, ObjectClass* object, TARGET target, DllActionTypeEnum& dll_type) -{ - switch (type) - { - case ACTION_NONE: - default: - dll_type = DAT_NONE; - break; - case ACTION_MOVE: - dll_type = DAT_MOVE; - break; - case ACTION_NOMOVE: - dll_type = DAT_NOMOVE; - break; - case ACTION_ENTER: - dll_type = DAT_ENTER; - break; - case ACTION_SELF: - dll_type = DAT_SELF; - break; - case ACTION_ATTACK: - if (Target_Legal(target) && (object != NULL) && object->Is_Techno() && ((TechnoClass*)object)->In_Range(target, 0)) { - dll_type = DAT_ATTACK; - } - else { - dll_type = DAT_ATTACK_OUT_OF_RANGE; - } - break; - case ACTION_GUARD_AREA: - dll_type = DAT_GUARD; - break; - case ACTION_HARVEST: - dll_type = DAT_ATTACK; - break; - case ACTION_SELECT: - case ACTION_TOGGLE_SELECT: - dll_type = DAT_SELECT; - break; - case ACTION_CAPTURE: - dll_type = DAT_CAPTURE; - break; - case ACTION_SABOTAGE: - dll_type = DAT_SABOTAGE; - break; - case ACTION_TOGGLE_PRIMARY: - dll_type = DAT_TOGGLE_PRIMARY; - break; - case ACTION_NO_DEPLOY: - dll_type = DAT_CANT_DEPLOY; - break; - } -} - - - - -/************************************************************************************************** -* DLLExportClass::On_Game_Over -- Called when the C&C campaign game finishes -* -* -* History: 6/19/2019 - LLL -**************************************************************************************************/ -void DLLExportClass::On_Game_Over(uint64 glyphx_Player_id, bool player_wins) -{ - if (EventCallback == NULL) { - return; - } - - GameOver = true; - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_GAME_OVER; - new_event.GlyphXPlayerID = glyphx_Player_id; - new_event.GameOver.PlayerWins = player_wins; - new_event.GameOver.MovieName = player_wins ? WinMovie : LoseMovie; - new_event.GameOver.AfterScoreMovieName = ""; - new_event.GameOver.Multiplayer = false; - new_event.GameOver.MultiPlayerTotalPlayers = 0; - - Calculate_Single_Player_Score(new_event); - - if (player_wins) - { - if (PlayerPtr->Class->House == HOUSE_BAD && Scenario == 13) { - //TODO: Nod_Ending() Also looks like it plays some audio that might need to be integrated. - new_event.GameOver.MovieName = ""; - new_event.GameOver.AfterScoreMovieName = "NODFINAL"; - } - else if (PlayerPtr->Class->House == HOUSE_GOOD && Scenario == 15) { - if (TempleIoned) { - new_event.GameOver.MovieName = "GDIFINB"; - new_event.GameOver.AfterScoreMovieName = "GDIEND2"; - } - else { - new_event.GameOver.MovieName = "GDIFINA"; - new_event.GameOver.AfterScoreMovieName = "GDIEND1"; - } - } - } - - if (strcmp(new_event.GameOver.MovieName, "x") == 0 || strcmp(new_event.GameOver.MovieName, "X") == 0) { - new_event.GameOver.MovieName = ""; - } - - new_event.GameOver.MovieName2 = WinMovie2; - if (strcmp(new_event.GameOver.MovieName2, "x") == 0 || strcmp(new_event.GameOver.MovieName2, "X") == 0) { - new_event.GameOver.MovieName2 = ""; - } - - new_event.GameOver.MovieName3 = WinMovie3; - if (strcmp(new_event.GameOver.MovieName3, "x") == 0 || strcmp(new_event.GameOver.MovieName3, "X") == 0) { - new_event.GameOver.MovieName3 = ""; - } - - new_event.GameOver.MovieName4 = WinMovie4; - if (strcmp(new_event.GameOver.MovieName4, "x") == 0 || strcmp(new_event.GameOver.MovieName4, "X") == 0) { - new_event.GameOver.MovieName4 = ""; - } - - new_event.GameOver.SabotagedStructureType = SabotagedType; - new_event.GameOver.TimerRemaining = -1; //Used in RA - - EventCallback(new_event); -} - - -/************************************************************************************************** -* DLLExportClass::On_Multiplayer_Game_Over -- Called when the C&C multiplayer game finishes -* -* -* History: 6/19/2019 - LLL -* History: 10/25/2019 - MBL - Adding the multi-player score stats support for debrief -**************************************************************************************************/ -void DLLExportClass::On_Multiplayer_Game_Over(void) -{ - if (EventCallback == NULL) { - return; - } - - GameOver = true; - - EventCallbackStruct event; - - event.EventType = CALLBACK_EVENT_GAME_OVER; - - // Multiplayer players data for debrief stats - - event.GameOver.Multiplayer = true; - event.GameOver.MultiPlayerTotalPlayers = MPlayerCount; - - for ( int player_index = 0; player_index < MPlayerCount; player_index ++ ) - { - HouseClass* player_ptr = HouseClass::As_Pointer( MPlayerHouses[player_index] ); //HouseClass::As_Pointer(HOUSE_MULTI2); - if ( player_ptr != NULL ) - { - int house = player_ptr->Class->House; - unsigned int leadership = TD_Calculate_Leadership( house, player_ptr->UnitsLost, player_ptr->BuildingsLost ); - - unsigned int efficiency = TD_Calculate_Efficiency( player_ptr->HarvestedCredits, player_ptr->InitialCredits, player_ptr->Available_Money() ); - - unsigned int total_score = TD_Calculate_Score( leadership, efficiency, BuildLevel ); - - int units_killed = 0; - int structures_killed = 0; - for ( unsigned int house_index = 0; house_index < HOUSE_COUNT; house_index ++ ) - { - units_killed += player_ptr->UnitsKilled[ house_index ]; - structures_killed += player_ptr->BuildingsKilled[ house_index ]; - } - - // Populate and copy the multiplayer player data structure - - GameOverMultiPlayerStatsStruct multi_player_data; - - multi_player_data.GlyphXPlayerID = Get_GlyphX_Player_ID( player_ptr ); - multi_player_data.IsHuman = (player_ptr->IsHuman || player_ptr->WasHuman); - multi_player_data.WasHuman = player_ptr->WasHuman; - multi_player_data.IsWinner = !player_ptr->IsDefeated; - multi_player_data.Efficiency = efficiency; - multi_player_data.Score = total_score; - multi_player_data.ResourcesGathered = player_ptr->HarvestedCredits; - multi_player_data.TotalUnitsKilled = units_killed; - multi_player_data.TotalStructuresKilled = structures_killed; - - if ( player_index < GAME_OVER_MULTIPLAYER_MAX_PLAYERS_TRACKED ) - { - event.GameOver.MultiPlayerPlayersData[ player_index ] = multi_player_data; - } - } - } - for ( int player_index = MPlayerCount; player_index < GAME_OVER_MULTIPLAYER_MAX_PLAYERS_TRACKED; player_index ++ ) - { - memset( &event.GameOver.MultiPlayerPlayersData[ player_index ], 0, sizeof( GameOverMultiPlayerStatsStruct ) ); - } - - // Single-player N/A stuff - - event.GameOver.MovieName = ""; - event.GameOver.MovieName2 = ""; - event.GameOver.MovieName3 = ""; - event.GameOver.MovieName4 = ""; - event.GameOver.AfterScoreMovieName = ""; - event.GameOver.Leadership = 0; - event.GameOver.Efficiency = 0; - event.GameOver.Score = 0; - event.GameOver.NODKilled = 0; - event.GameOver.GDIKilled = 0; - event.GameOver.CiviliansKilled = 0; - event.GameOver.NODBuildingsDestroyed = 0; - event.GameOver.GDIBuildingsDestroyed = 0; - event.GameOver.CiviliansBuildingsDestroyed = 0; - event.GameOver.RemainingCredits = 0; - event.GameOver.SabotagedStructureType = 0; - event.GameOver.TimerRemaining = -1; - - // Trigger an event for each human player, winner first (even if it's an AI) - for (int i = 0; i < MPlayerCount; i++) { - HouseClass* player_ptr = HouseClass::As_Pointer(MPlayerHouses[i]); //HouseClass::As_Pointer(HOUSE_MULTI2); - if (player_ptr != NULL && !player_ptr->IsDefeated) { - event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - event.GameOver.IsHuman = player_ptr->IsHuman; - event.GameOver.PlayerWins = true; - event.GameOver.RemainingCredits = player_ptr->Available_Money(); - EventCallback(event); - } - } - - for (int i = 0; i < MPlayerCount; i++) { - HouseClass* player_ptr = HouseClass::As_Pointer(MPlayerHouses[i]); //HouseClass::As_Pointer(HOUSE_MULTI2); - if (player_ptr != NULL && player_ptr->IsHuman && player_ptr->IsDefeated) { - event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - event.GameOver.IsHuman = true; - event.GameOver.PlayerWins = false; - event.GameOver.RemainingCredits = player_ptr->Available_Money(); - EventCallback(event); - } - } -} - - -/************************************************************************************************** -* DLLExportClass::On_Message -- Called when the game wants to display a message (ex. tutorial text) -* -* In: -* -* Out: -* -* -* -* History: 10/16/2019 - SKY -**************************************************************************************************/ -void DLLExportClass::On_Message(const HouseClass* player_ptr, const char* message, float timeout_seconds, EventCallbackMessageEnum message_type, int64 message_id) -{ - if (EventCallback == NULL) - { - return; - } - - const char* p_msg = message; - if (message_id != -1) { - if (message_id == TXT_LOW_POWER) { - p_msg = "TEXT_LOW_POWER_MESSAGE_001"; - } - else if (message_id == TXT_INSUFFICIENT_FUNDS) { - p_msg = "TEXT_INSUFFICIENT_FUNDS_MESSAGE"; - } - } - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_MESSAGE; - new_event.Message.Message = p_msg; - new_event.Message.TimeoutSeconds = timeout_seconds; - new_event.Message.MessageType = message_type; - new_event.Message.MessageParam1 = message_id; - - new_event.GlyphXPlayerID = 0; - if (player_ptr != NULL) - { - new_event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - } - - EventCallback(new_event); -} - -void On_Message(const char* message, float timeout_seconds, EventCallbackMessageEnum message_type, int64 message_id) -{ - DLLExportClass::On_Message(PlayerPtr, message, timeout_seconds, message_type, message_id); -} - -void On_Message(const char* message, float timeout_seconds, int64 message_id) -{ - DLLExportClass::On_Message(PlayerPtr, message, timeout_seconds, MESSAGE_TYPE_DIRECT, message_id); -} - -void On_Defeated_Message(const char* message, float timeout_seconds) -{ - DLLExportClass::On_Message(PlayerPtr, message, timeout_seconds, MESSAGE_TYPE_PLAYER_DEFEATED, -1); -} - - - -/************************************************************************************************** -* DLLExportClass::On_Achievement -- Called when something achievement-related happens -* -* In: Type of achievement, reason this happened -* -* Out: -* -* -* -* History: 11/11/2019 11:37AM - ST -**************************************************************************************************/ -void DLLExportClass::On_Achievement(const HouseClass* player_ptr, const char *achievement_type, const char *achievement_reason) -{ - if (EventCallback == NULL) { - return; - } - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_ACHIEVEMENT; - new_event.Achievement.AchievementType = achievement_type; - new_event.Achievement.AchievementReason = achievement_reason; - - new_event.GlyphXPlayerID = 0; - if (player_ptr != NULL) { - new_event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - } - - EventCallback(new_event); -} - - -void DLLExportClass::On_Center_Camera(const HouseClass* player_ptr, int coord_x, int coord_y) -{ - if (EventCallback == NULL) { - return; - } - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_CENTER_CAMERA; - new_event.CenterCamera.CoordX = coord_x; - new_event.CenterCamera.CoordY = coord_y; - - new_event.GlyphXPlayerID = 0; - if (player_ptr != NULL) { - new_event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - } - - EventCallback(new_event); -} - - -void DLLExportClass::On_Ping(const HouseClass* player_ptr, COORDINATE coord) -{ - if (EventCallback == NULL) { - return; - } - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_PING; - new_event.Ping.CoordX = Coord_X(coord); - new_event.Ping.CoordY = Coord_Y(coord); - - new_event.GlyphXPlayerID = 0; - if (player_ptr != NULL) { - new_event.GlyphXPlayerID = Get_GlyphX_Player_ID(player_ptr); - } - - EventCallback(new_event); -} - - -/************************************************************************************************** -* DLLExportClass::On_Debug_Output -- Called when C&C wants to print debug output -* -* In: String to print to GlyphX log system -* -* Out: -* -* -* -* History: 2/20/2019 2:39PM - ST -**************************************************************************************************/ -void DLLExportClass::On_Debug_Output(const char *debug_text) -{ - if (EventCallback == NULL) { - return; - } - - EventCallbackStruct new_event; - new_event.EventType = CALLBACK_EVENT_DEBUG_PRINT; - new_event.DebugPrint.PrintString = debug_text; - EventCallback(new_event); -} - - -/************************************************************************************************** -* DLLExportClass::Force_Human_Team_Wins -* -* History: 3/10/2020 - LL -**************************************************************************************************/ -void DLLExportClass::Force_Human_Team_Wins(uint64 quitting_player_id) -{ - if (PlayerWins || PlayerLoses || GameOver) { - return; - } - - int winning_team = -1; - - //Find the first human's multiplayer team. - for (int i = 0; i < MPlayerCount; i++) - { - if (GlyphxPlayerIDs[i] != quitting_player_id) { - HousesType house_type = MPlayerHouses[i]; - HouseClass* house_class = HouseClass::As_Pointer(house_type); - if (house_class && house_class->IsHuman && !house_class->IsDefeated) { - winning_team = MPlayerTeamIDs[i]; - break; - } - } - } - - //Mark all players not on that team as defeated. - for (int i = 0; i < MPlayerCount; i++) - { - HousesType house_type = MPlayerHouses[i]; - HouseClass* house_class = HouseClass::As_Pointer(house_type); - if (house_class) { - house_class->IsDefeated = MPlayerTeamIDs[i] != winning_team; - } - } - - PlayerWins = true; -} - - -/************************************************************************************************** -* CNC_Get_Game_State -- Get game state -* -* In: Type of state requested -* Player perspective -* Buffer to contain game state -* Size of buffer -* -* Out: Game state returned in buffer -* -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) bool __cdecl CNC_Get_Game_State(GameStateRequestEnum state_type, uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - bool got_state = false; - - switch (state_type) { - - case GAME_STATE_LAYERS: - { - got_state = DLLExportClass::Get_Layer_State(player_id, buffer_in, buffer_size); - break; - } - - case GAME_STATE_SIDEBAR: - { - got_state = DLLExportClass::Get_Sidebar_State(player_id, buffer_in, buffer_size); - break; - } - - case GAME_STATE_PLACEMENT: - { - got_state = DLLExportClass::Get_Placement_State(player_id, buffer_in, buffer_size); - break; - } - - case GAME_STATE_DYNAMIC_MAP: - got_state = DLLExportClass::Get_Dynamic_Map_State(player_id, buffer_in, buffer_size); - break; - - case GAME_STATE_SHROUD: - got_state = DLLExportClass::Get_Shroud_State(player_id, buffer_in, buffer_size); - break; - - case GAME_STATE_OCCUPIER: - got_state = DLLExportClass::Get_Occupier_State(player_id, buffer_in, buffer_size); - break; - - case GAME_STATE_PLAYER_INFO: - got_state = DLLExportClass::Get_Player_Info_State(player_id, buffer_in, buffer_size); - break; - - case GAME_STATE_STATIC_MAP: - { - if (buffer_size < sizeof(CNCMapDataStruct)) { - got_state = false; - break; - } - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - CNCMapDataStruct *map_data = (CNCMapDataStruct *)buffer_in; - - map_data->OriginalMapCellX = map_cell_x; - map_data->OriginalMapCellY = map_cell_y; - map_data->OriginalMapCellWidth = map_cell_width; - map_data->OriginalMapCellHeight = map_cell_height; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - map_data->MapCellX = map_cell_x; - map_data->MapCellY = map_cell_y; - map_data->MapCellWidth = map_cell_width; - map_data->MapCellHeight = map_cell_height; - - map_data->Theater = (CnCTheaterType) Map.Theater; - - // Hack a fix for scenario 21 since the same mission number is used in Covert Ops and N64 - memset(map_data->ScenarioName, 0, sizeof(map_data->ScenarioName)); - if ((Map.Theater == CNC_THEATER_DESERT) && (Scenario == 21)) { - strncpy(map_data->ScenarioName, "SCB81EA", sizeof(map_data->ScenarioName) - 1); - } else { - strncpy(map_data->ScenarioName, ScenarioName, sizeof(map_data->ScenarioName) - 1); - } - - int cell_index = 0; - char cell_name[_MAX_PATH]; - char icon_number[32]; - - for (int y = 0 ; y < map_cell_height ; y++) { - for (int x = 0 ; x < map_cell_width ; x++) { - CELL cell = XY_Cell(map_cell_x+x, map_cell_y+y); - CellClass * cellptr = &Map[cell]; - - cell_name[0] = 0; - int icon = 0; - void *image_data = 0; - if (cellptr->Get_Template_Info(cell_name, icon, image_data)) { - itoa(icon, icon_number, 10); - strncat(cell_name, "_i", 32); - strncat(cell_name, icon_number, 32); - strncat(cell_name, ".tga", 32); - cell_name[31] = 0; - - CNCStaticCellStruct &cell_info = map_data->StaticCells[cell_index++]; - strncpy(cell_info.TemplateTypeName, cell_name, 32); - cell_info.TemplateTypeName[31] = 0; - cell_info.IconNumber = icon; - } - } - } - - got_state = true; - break; - } - - default: - { - got_state = false; - break; - } - } - - return got_state; -} - -/************************************************************************************************** -* CNC_Handle_Game_Request -* -* Callback for when the requested movie is done playing. -* -* 7/23/2019 - LLL -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Game_Request(GameRequestEnum request_type) -{ - switch (request_type) - { - case INPUT_GAME_MOVIE_DONE: - - InMainLoop = true; - break; - } -} - -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Game_Settings_Request(int health_bar_display_mode, int resource_bar_display_mode) -{ - if (!DLLExportClass::Legacy_Render_Enabled()) { - return; - } - - SpecialClass::eHealthBarDisplayMode new_hb_mode = (SpecialClass::eHealthBarDisplayMode)health_bar_display_mode; - if (new_hb_mode != Special.HealthBarDisplayMode) { - Special.HealthBarDisplayMode = new_hb_mode; - Map.Flag_To_Redraw(true); - } - - SpecialClass::eResourceBarDisplayMode new_rb_mode = (SpecialClass::eResourceBarDisplayMode)resource_bar_display_mode; - if (new_rb_mode != Special.ResourceBarDisplayMode) { - Special.ResourceBarDisplayMode = new_rb_mode; - Map.Flag_To_Redraw(true); - } -} - - - - - -void DLL_Draw_Intercept(int shape_number, int x, int y, int width, int height, int flags, ObjectClass *object, const char *shape_file_name = NULL, char override_owner = HOUSE_NONE, int scale = 0x100) -{ - DLLExportClass::DLL_Draw_Intercept(shape_number, x, y, width, height, flags, object, shape_file_name, override_owner, scale); -} - - -void DLL_Draw_Pip_Intercept(const ObjectClass* object, int pip) -{ - DLLExportClass::DLL_Draw_Pip_Intercept(object, pip); -} - - -void DLL_Draw_Line_Intercept(int x, int y, int x1, int y1, unsigned char color, int frame) -{ - DLLExportClass::DLL_Draw_Line_Intercept(x, y, x1, y1, color, frame); -} - - -void DLLExportClass::DLL_Draw_Intercept(int shape_number, int x, int y, int width, int height, int flags, ObjectClass *object, const char *shape_file_name, char override_owner, int scale) -{ - CNCObjectStruct& new_object = ObjectList->Objects[TotalObjectCount + CurrentDrawCount]; - Convert_Type(object, new_object); - if (new_object.Type == UNKNOWN) { - return; - } - - CNCObjectStruct* base_object = NULL; - for (int i = 0; i < CurrentDrawCount; ++i) { - CNCObjectStruct& draw_object = ObjectList->Objects[TotalObjectCount + i]; - if (draw_object.CNCInternalObjectPointer == object) { - base_object = &draw_object; - break; - } - } - - new_object.CNCInternalObjectPointer = (void*)object; - new_object.OccupyListLength = 0; - new_object.SortOrder = SortOrder++; - - strncpy(new_object.TypeName, object->Class_Of().IniName, CNC_OBJECT_ASSET_NAME_LENGTH); - - if (shape_file_name != NULL) { - strncpy(new_object.AssetName, shape_file_name, CNC_OBJECT_ASSET_NAME_LENGTH); - } - else { - strncpy(new_object.AssetName, object->Class_Of().IniName, CNC_OBJECT_ASSET_NAME_LENGTH); - } - - new_object.TypeName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - new_object.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - new_object.Owner = ((base_object != NULL) && (override_owner != HOUSE_NONE)) ? override_owner : (char)object->Owner(); - - HouseClass* owner_house = nullptr; - for (int i = 0; i < Houses.Count(); ++i) { - HouseClass* hptr = Houses.Ptr(i); - if ((hptr != nullptr) && (hptr->Class->House == new_object.Owner)) { - owner_house = hptr; - break; - } - } - - new_object.RemapColor = (owner_house != nullptr) ? owner_house->RemapColor : -1; - - if (base_object == NULL) { - CNCObjectStruct& root_object = ObjectList->Objects[TotalObjectCount]; - - if (new_object.Type == BUILDING) { - BuildingClass *building = (BuildingClass*)object; - if (building->BState == BSTATE_CONSTRUCTION) { - strncat(new_object.AssetName, "MAKE", CNC_OBJECT_ASSET_NAME_LENGTH); - new_object.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - } - const BuildingTypeClass *building_type = building->Class; - short const *occupy_list = building_type->Occupy_List(); - if (occupy_list) { - while (*occupy_list != REFRESH_EOL && new_object.OccupyListLength < MAX_OCCUPY_CELLS) { - new_object.OccupyList[new_object.OccupyListLength] = *occupy_list; - new_object.OccupyListLength++; - occupy_list++; - } - } - } - - COORDINATE coord = object->Render_Coord(); - CELL cell = Coord_Cell(coord); - int dimx, dimy; - object->Class_Of().Dimensions(dimx, dimy); - - short sim_lepton_x = 0; - short sim_lepton_y = 0; - - if (new_object.Type == UNIT) { - sim_lepton_x = ((DriveClass*)object)->SimLeptonX; - sim_lepton_y = ((DriveClass*)object)->SimLeptonY; - } - - new_object.PositionX = x; - new_object.PositionY = y; - new_object.Width = width; - new_object.Height = height; - new_object.Altitude = 0; - new_object.DrawFlags = flags; - new_object.SubObject = 0; - new_object.ShapeIndex = (unsigned short)shape_number; - new_object.IsTheaterSpecific = IsTheaterShape; - new_object.Scale = scale; - new_object.Rotation = 0; - new_object.FlashingFlags = 0; - new_object.Cloak = (CurrentDrawCount > 0) ? root_object.Cloak : UNCLOAKED; - new_object.VisibleFlags = CNCObjectStruct::VISIBLE_FLAGS_ALL; - new_object.SpiedByFlags = 0U; - - new_object.SortOrder = SortOrder++; - new_object.IsSelectable = object->Class_Of().IsSelectable; - new_object.IsSelectedMask = object->IsSelectedMask; - new_object.MaxStrength = object->Class_Of().MaxStrength; - new_object.Strength = object->Strength; - new_object.CellX = (CurrentDrawCount > 0) ? root_object.CellX : Cell_X(cell); - new_object.CellY = (CurrentDrawCount > 0) ? root_object.CellY : Cell_Y(cell); - new_object.CenterCoordX = Coord_X(object->Center_Coord()); - new_object.CenterCoordY = Coord_Y(object->Center_Coord()); - new_object.DimensionX = dimx; - new_object.DimensionY = dimy; - new_object.SimLeptonX = (CurrentDrawCount > 0) ? root_object.SimLeptonX : sim_lepton_x; - new_object.SimLeptonY = (CurrentDrawCount > 0) ? root_object.SimLeptonY : sim_lepton_y; - new_object.BaseObjectID = ((CurrentDrawCount > 0) && (root_object.Type != BUILDING)) ? root_object.ID : 0; - new_object.BaseObjectType = ((CurrentDrawCount > 0) && (root_object.Type != BUILDING)) ? root_object.Type : UNKNOWN; - new_object.NumLines = 0; - new_object.RecentlyCreated = object->IsRecentlyCreated; - new_object.NumPips = 0; - new_object.MaxPips = 0; - new_object.CanDemolish = object->Can_Demolish(); - new_object.CanDemolishUnit = object->Can_Demolish_Unit(); - new_object.CanRepair = object->Can_Repair(); - memset(new_object.CanMove, false, sizeof(new_object.CanMove)); - memset(new_object.CanFire, false, sizeof(new_object.CanFire)); - memset(new_object.ActionWithSelected, DAT_NONE, sizeof(new_object.ActionWithSelected)); - - HouseClass* old_player_ptr = PlayerPtr; - for (int i = 0; i < Houses.Count(); ++i) { - HouseClass* hptr = Houses.Ptr(i); - if ((hptr != nullptr) && hptr->IsActive && hptr->IsHuman) { - HousesType house = hptr->Class->House; - DynamicVectorClass& selected_objects = CurrentObject.Raw(house); - if (selected_objects.Count() > 0) { - Logic_Switch_Player_Context(hptr); - Convert_Action_Type(Best_Object_Action(selected_objects, object), (selected_objects.Count() == 1) ? selected_objects[0] : NULL, object->As_Target(), new_object.ActionWithSelected[house]); - } - } - } - Logic_Switch_Player_Context(old_player_ptr); - - RTTIType what_is_object = object->What_Am_I(); - - new_object.IsRepairing = false; - new_object.IsDumping = false; - new_object.IsALoaner = false; - new_object.IsFactory = false; - new_object.IsPrimaryFactory = false; - new_object.IsAntiGround = false; - new_object.IsAntiAircraft = false; - new_object.IsSubSurface = false; - new_object.IsNominal = false; - new_object.IsDog = false; - new_object.IsIronCurtain = false; - new_object.IsInFormation = false; - new_object.IsFake = false; - new_object.ProductionAssetName[0] = '\0'; - new_object.OverrideDisplayName = "\0"; - - bool is_building = what_is_object == RTTI_BUILDING; - if (is_building) { - BuildingClass* building = static_cast(object); - new_object.IsRepairing = building->IsRepairing; - new_object.IsFactory = building->Class->IsFactory; - new_object.IsPrimaryFactory = building->IsLeader; - } - - if (object->Is_Techno()) { - TechnoClass* techno_object = static_cast(object); - const TechnoTypeClass *ttype = techno_object->Techno_Type_Class(); - - new_object.MaxSpeed = (unsigned char)ttype->MaxSpeed; - new_object.IsALoaner = techno_object->IsALoaner; - new_object.IsNominal = ttype->IsNominal; - new_object.MaxPips = ttype->Max_Pips(); - new_object.IsAntiGround = ttype->Primary != WEAPON_NONE; - new_object.IsAntiAircraft = (ttype->Primary != WEAPON_NONE) && (Weapons[ttype->Primary].Fires != BULLET_NONE) && BulletTypeClass::As_Reference(Weapons[ttype->Primary].Fires).IsAntiAircraft; - - HouseClass* old_player_ptr = PlayerPtr; - for (int i = 0; i < Houses.Count(); ++i) { - HouseClass* hptr = Houses.Ptr(i); - if ((hptr != nullptr) && hptr->IsActive && hptr->IsHuman) { - Logic_Switch_Player_Context(hptr); - HousesType house = hptr->Class->House; - new_object.CanMove[house] = techno_object->Can_Player_Move(); - new_object.CanFire[house] = techno_object->Can_Player_Fire(); - } - } - Logic_Switch_Player_Context(old_player_ptr); - } - - new_object.ControlGroup = (unsigned char)(-1); - new_object.CanPlaceBombs = false; - bool is_infantry = what_is_object == RTTI_INFANTRY; - if (is_infantry) { - InfantryClass* infantry = static_cast(object); - new_object.ControlGroup = infantry->Group; - new_object.CanPlaceBombs = infantry->Class->Type == INFANTRY_RAMBO; - } - - new_object.CanHarvest = false; - bool is_unit = what_is_object == RTTI_UNIT; - if (is_unit) { - UnitClass* unit = static_cast(object); - if (unit->Class->Type == UNIT_HARVESTER) { - new_object.CanHarvest = true; - } - - new_object.ControlGroup = unit->Group; - } - - new_object.IsFixedWingedAircraft = false; - bool is_aircraft = what_is_object == RTTI_AIRCRAFT; - if (is_aircraft) { - AircraftClass* aircraft = static_cast(object); - new_object.Altitude = Pixel_To_Lepton(aircraft->Altitude); - new_object.IsFixedWingedAircraft = aircraft->Class->IsFixedWing; - new_object.ControlGroup = aircraft->Group; - } - - switch (what_is_object) - { - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - case RTTI_UNIT: - case RTTI_UNITTYPE: - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - { - TechnoClass* techno_object = static_cast(object); - new_object.FlashingFlags = techno_object->Get_Flashing_Flags(); - new_object.Cloak = techno_object->Cloak; - } - break; - - case RTTI_ANIM: - { - AnimClass* anim_object = static_cast(object); - new_object.VisibleFlags = anim_object->Get_Visible_Flags(); - } - break; - } - } - else { - new_object.MaxStrength = 0; - new_object.MaxSpeed = 0; - new_object.Strength = 0; - new_object.CellX = base_object->CellX; - new_object.CellY = base_object->CellY; - new_object.CenterCoordX = base_object->CenterCoordX; - new_object.CenterCoordY = base_object->CenterCoordY; - new_object.DimensionX = base_object->DimensionX; - new_object.DimensionY = base_object->DimensionY; - new_object.IsSelectable = false; - new_object.IsSelectedMask = 0U; - new_object.SimLeptonX = base_object->SimLeptonX; - new_object.SimLeptonY = base_object->SimLeptonY; - - new_object.PositionX = x; - new_object.PositionY = y; - new_object.Width = width; - new_object.Height = height; - new_object.Altitude = base_object->Altitude; - new_object.DrawFlags = flags; - new_object.ShapeIndex = (unsigned short)shape_number; - new_object.IsTheaterSpecific = IsTheaterShape; - new_object.Scale = scale; - new_object.Rotation = 0; - new_object.SubObject = CurrentDrawCount; - new_object.BaseObjectID = base_object->ID; - new_object.BaseObjectType = base_object->Type; - new_object.FlashingFlags = base_object->FlashingFlags; - new_object.Cloak = base_object->Cloak; - new_object.OccupyListLength = 0; - new_object.NumPips = 0; - new_object.MaxPips = 0; - new_object.IsRepairing = false; - new_object.IsDumping = false; - new_object.IsALoaner = base_object->IsALoaner; - new_object.NumLines = 0; - new_object.CanDemolish = base_object->CanDemolish; - new_object.CanDemolishUnit = base_object->CanDemolishUnit; - new_object.CanRepair = base_object->CanRepair; - new_object.RecentlyCreated = base_object->RecentlyCreated; - new_object.IsFactory = base_object->IsFactory; - new_object.IsPrimaryFactory = base_object->IsPrimaryFactory; - new_object.IsAntiGround = base_object->IsAntiGround; - new_object.IsAntiAircraft = base_object->IsAntiAircraft; - new_object.IsSubSurface = base_object->IsSubSurface; - new_object.IsNominal = base_object->IsNominal; - new_object.IsDog = base_object->IsDog; - new_object.IsIronCurtain = base_object->IsIronCurtain; - new_object.IsInFormation = false; - new_object.CanHarvest = base_object->CanHarvest; - new_object.CanPlaceBombs = base_object->CanPlaceBombs; - new_object.ControlGroup = base_object->ControlGroup; - new_object.VisibleFlags = base_object->VisibleFlags; - new_object.SpiedByFlags = base_object->SpiedByFlags; - new_object.IsFixedWingedAircraft = base_object->IsFixedWingedAircraft; - new_object.IsFake = base_object->IsFake; - new_object.ProductionAssetName[0] = '\0'; - new_object.OverrideDisplayName = "\0"; - memset(new_object.CanMove, false, sizeof(new_object.CanMove)); - memset(new_object.CanFire, false, sizeof(new_object.CanFire)); - memset(new_object.ActionWithSelected, DAT_NONE, sizeof(new_object.ActionWithSelected)); - } - - CurrentDrawCount++; -} - - - -void DLLExportClass::DLL_Draw_Pip_Intercept(const ObjectClass* object, int pip) -{ - CNCObjectStruct* base_object = NULL; - for (int i = 0; i < CurrentDrawCount; ++i) { - CNCObjectStruct& draw_object = ObjectList->Objects[TotalObjectCount + i]; - if (draw_object.CNCInternalObjectPointer == object) { - base_object = &draw_object; - break; - } - } - - if ((base_object != NULL) && (base_object->NumPips < MAX_OBJECT_PIPS)) { - base_object->Pips[base_object->NumPips] = pip; - base_object->NumPips++; - base_object->MaxPips = max(base_object->MaxPips, base_object->NumPips); - } -} - - - -void DLLExportClass::DLL_Draw_Line_Intercept(int x, int y, int x1, int y1, unsigned char color, int frame) -{ - CNCObjectStruct& root_object = ObjectList->Objects[TotalObjectCount]; - if (root_object.NumLines < MAX_OBJECT_LINES) { - root_object.Lines[root_object.NumLines].X = x; - root_object.Lines[root_object.NumLines].Y = y; - root_object.Lines[root_object.NumLines].X1 = x1; - root_object.Lines[root_object.NumLines].Y1 = y1; - root_object.Lines[root_object.NumLines].Frame = frame; - root_object.Lines[root_object.NumLines].Color = color; - - SortOrder++; - root_object.NumLines++; - } -} - - - -/************************************************************************************************** -* DLLExportClass::Get_Layer_State -- Get game objects from the layers -* -* In: -* -* Out: -* -* -* -* History: 1/29/2019 11:37AM - ST -**************************************************************************************************/ -bool DLLExportClass::Get_Layer_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - player_id; - - static int _export_count = 0; - - bool got_state = false; - - ObjectList = (CNCObjectListStruct*) buffer_in; - - TotalObjectCount = 0; - - /* - ** Get a reference draw coordinate for cells - */ - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - if (map_cell_x > 0) { - map_cell_x--; - } - if (map_cell_y > 0) { - map_cell_y--; - } - - SortOrder = 0; - - /* - ** Get the ground layer first and then followed by all the layers in increasing altitude. - */ - for (int layer = 0; layer < DLL_LAYER_COUNT; layer++) { - - for (int index = 0; index < Map.Layer[layer].Count(); index++) { - - ObjectClass *object = Map.Layer[layer][index]; - if (object->IsActive) { - - unsigned int memory_needed = sizeof(CNCObjectListStruct); - memory_needed += (TotalObjectCount + 10) * sizeof(CNCObjectStruct); - if (memory_needed >= buffer_size) { - return false; - } - - if (object->Is_Techno()) { - /* - ** Skip units tethered to buildings, since the building will draw them itself - */ - TechnoClass* techno_object = static_cast(object); - TechnoClass* contact_object = techno_object->In_Radio_Contact() ? techno_object->Contact_With_Whom() : nullptr; - if ((contact_object != nullptr) && (contact_object->What_Am_I() == RTTI_BUILDING) && contact_object->IsTethered && *((BuildingClass*)contact_object) == STRUCT_WEAP) { - continue; - } - } - - if (Debug_Map || Debug_Unshroud || (object->IsDown && !object->IsInLimbo)) { - int x, y; - Map.Coord_To_Pixel(object->Render_Coord(), x, y); - - /* - ** Call to Draw_It can result in multiple callbacks to the draw intercept - */ - CurrentDrawCount = 0; - object->Draw_It(x, y, WINDOW_VIRTUAL); - - /* - ** Shadows need to be rendered before the base object so they appear underneath, - ** even though they get drawn as sub-objects (after the base object) - */ - for (int i = 1; i < CurrentDrawCount; ++i) { - CNCObjectStruct& sub_object = ObjectList->Objects[TotalObjectCount + i]; - if (!sub_object.SubObject) { - continue; - } - static const int shadow_flags = SHAPE_PREDATOR | SHAPE_FADING; - if (((sub_object.DrawFlags & shadow_flags) == shadow_flags) || (strncmp(sub_object.AssetName, "WAKE", CNC_OBJECT_ASSET_NAME_LENGTH) == 0)) { - if ((strncmp(sub_object.AssetName, "RROTOR", CNC_OBJECT_ASSET_NAME_LENGTH) != 0) && - (strncmp(sub_object.AssetName, "LROTOR", CNC_OBJECT_ASSET_NAME_LENGTH) != 0)) { - for (int j = i - 1; j >= 0; --j) { - CNCObjectStruct& base_object = ObjectList->Objects[TotalObjectCount + j]; - if (!base_object.SubObject && (base_object.CNCInternalObjectPointer == sub_object.CNCInternalObjectPointer)) { - int sort_order = base_object.SortOrder; - base_object.SortOrder = sub_object.SortOrder; - sub_object.SortOrder = sort_order; - break; - } - } - } - } - } - - TotalObjectCount += CurrentDrawCount; - } - } - } - } - - ObjectList->Count = TotalObjectCount; - - if (ObjectList->Count) { - _export_count++; - return true; - } - - return false; -} - - - - -void DLLExportClass::Convert_Type(const ObjectClass *object, CNCObjectStruct &object_out) -{ - object_out.Type = UNKNOWN; - object_out.ID = -1; - - if (object == NULL) { - return; - } - - RTTIType type = object->What_Am_I(); - - switch (type) { - default: - break; - - case RTTI_INFANTRY: - object_out.Type = INFANTRY; - object_out.ID = Infantry.ID((InfantryClass*)object); - break; - - case RTTI_UNIT: - object_out.Type = UNIT; - object_out.ID = Units.ID((UnitClass*)object); - break; - - case RTTI_AIRCRAFT: - object_out.Type = AIRCRAFT; - object_out.ID = Aircraft.ID((AircraftClass*)object); - break; - - case RTTI_BUILDING: - object_out.Type = BUILDING; - object_out.ID = Buildings.ID((BuildingClass*)object); - break; - - case RTTI_BULLET: - object_out.Type = BULLET; - object_out.ID = Bullets.ID((BulletClass*)object); - break; - - case RTTI_ANIM: - object_out.Type = ANIM; - object_out.ID = Anims.ID((AnimClass*)object); - break; - - case RTTI_SMUDGE: - object_out.Type = SMUDGE; - object_out.ID = Smudges.ID((SmudgeClass*)object); - break; - - case RTTI_TERRAIN: - object_out.Type = TERRAIN; - object_out.ID = Terrains.ID((TerrainClass*)object); - break; - } -} - - - - - - -/************************************************************************************************** -* CNC_Handle_Input -- Process input to the game -* -* In: -* -* -* -* -* Out: Game state returned in buffer -* -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Input(InputRequestEnum input_event, unsigned char special_key_flags, uint64 player_id, int x1, int y1, int x2, int y2) -{ - - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (input_event) { - - /* - ** Special keys have changed - */ - case INPUT_REQUEST_SPECIAL_KEYS: - { - DLLExportClass::Set_Special_Key_Flags(special_key_flags); - break; - } - - /* - ** The mouse is moving - */ - case INPUT_REQUEST_MOUSE_MOVE: - { - if (!DLLExportClass::Legacy_Render_Enabled()) { - break; - } - - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - COORDINATE coord = Map.Pixel_To_Coord(x1, y1); - CELL cell = Coord_Cell(coord); - if (coord) { - //x -= Map.TacPixelX; - //y -= Map.TacPixelY; - - /* - ** Cause any displayed cursor to move along with the mouse cursor. - */ - if (cell != Map.ZoneCell) { - Map.Set_Cursor_Pos(cell); - } - } - break; - } - - /* - ** Player left-clicked - */ - case INPUT_REQUEST_MOUSE_LEFT_CLICK: - { - DLLExportClass::Adjust_Internal_View(); - - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - KeyNumType key = (KeyNumType)(KN_LMOUSE | KN_RLSE_BIT); - - if (Map.Pixel_To_Coord(x1, y1)) { - //DisplayClass::TacButton.Clicked_On(key, GadgetClass::LEFTRELEASE, x1, y1); - DisplayClass::TacButton.Clicked_On(key, GadgetClass::LEFTRELEASE, 100, 100); - } - break; - } - - /* - ** Player right-clicked (on up) - */ - case INPUT_REQUEST_MOUSE_RIGHT_CLICK: - { - DLLExportClass::Adjust_Internal_View(); - - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - KeyNumType key = (KeyNumType)(KN_RMOUSE | KN_RLSE_BIT); - - if (Map.Pixel_To_Coord(x1, y1)) { - //DisplayClass::TacButton.Clicked_On(key, GadgetClass::RIGHTRELEASE, x1, y1); - DisplayClass::TacButton.Clicked_On(key, GadgetClass::RIGHTRELEASE, 100, 100); - } - break; - } - - /* - ** Player right button down - */ - case INPUT_REQUEST_MOUSE_RIGHT_DOWN: - { - DLLExportClass::Adjust_Internal_View(); - - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - KeyNumType key = (KeyNumType)(KN_RMOUSE); - - if (Map.Pixel_To_Coord(x1, y1)) { - //DisplayClass::TacButton.Clicked_On(key, GadgetClass::RIGHTPRESS, x1, y1); - DisplayClass::TacButton.Clicked_On(key, GadgetClass::RIGHTPRESS, 100, 100); - } - break; - } - - - /* - ** Player drag selected - */ - case INPUT_REQUEST_MOUSE_AREA: - { - DLLExportClass::Adjust_Internal_View(); - Map.Select_These(XYPixel_Coord(x1, y1), XYPixel_Coord(x2, y2), false); - break; - } - - case INPUT_REQUEST_MOUSE_AREA_ADDITIVE: - { - DLLExportClass::Adjust_Internal_View(); - Map.Select_These(XYPixel_Coord(x1, y1), XYPixel_Coord(x2, y2), true); - break; - } - - case INPUT_REQUEST_SELL_AT_POSITION: - { - DLLExportClass::Adjust_Internal_View(); - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - COORDINATE coord = Map.Pixel_To_Coord(x1, y1); - CELL cell = Coord_Cell(coord); - - if (Map.Pixel_To_Coord(x1, y1)) - { - PlayerPtr->Sell_Wall(cell); - } - - break; - } - - case INPUT_REQUEST_SELECT_AT_POSITION: - { - DLLExportClass::Adjust_Internal_View(); - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - COORDINATE coord = Map.Pixel_To_Coord(x1, y1); - CELL cell = Coord_Cell(coord); - - if (Map.Pixel_To_Coord(x1, y1)) - { - KeyNumType key = (KeyNumType)(KN_LMOUSE | KN_RLSE_BIT); - - DisplayClass::TacButton.Selection_At_Mouse(GadgetClass::LEFTRELEASE, key); - } - - break; - } - - case INPUT_REQUEST_COMMAND_AT_POSITION: - { - DLLExportClass::Adjust_Internal_View(); - DLLForceMouseX = x1; - DLLForceMouseY = y1; - _Kbd->MouseQX = x1; - _Kbd->MouseQY = y1; - - COORDINATE coord = Map.Pixel_To_Coord(x1, y1); - CELL cell = Coord_Cell(coord); - - if (Map.Pixel_To_Coord(x1, y1)) - { - KeyNumType key = (KeyNumType)(KN_LMOUSE | KN_RLSE_BIT); - DisplayClass::TacButton.Command_Object(GadgetClass::LEFTRELEASE, key); - } - - break; - } - - default: - break; - } -} - - - - -/************************************************************************************************** -* CNC_Handle_Structure_Request -- Process requests to repair and sell structures. -* -* In: -* -* -* Out: -* -* -* -* History: 4/29/2019 - LLL -**************************************************************************************************/ - -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Structure_Request(StructureRequestEnum request_type, uint64 player_id, int object_id) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (request_type) - { - case INPUT_STRUCTURE_REPAIR_START: - DLLExportClass::Repair_Mode(player_id); - break; - case INPUT_STRUCTURE_REPAIR: - DLLExportClass::Repair(player_id, object_id); - break; - case INPUT_STRUCTURE_SELL_START: - DLLExportClass::Sell_Mode(player_id); - break; - case INPUT_STRUCTURE_SELL: - DLLExportClass::Sell(player_id, object_id); - break; - case INPUT_STRUCTURE_CANCEL: - DLLExportClass::Repair_Sell_Cancel(player_id); - break; - default: - break; - } -} - - - -/************************************************************************************************** -* CNC_Handle_Unit_Request -- Process requests on selected units. -* -* In: -* -* -* Out: -* -* -* -* History: 10/15/2019 - SKY -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Unit_Request(UnitRequestEnum request_type, uint64 player_id) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (request_type) - { - case INPUT_UNIT_SCATTER: - DLLExportClass::Scatter_Selected(player_id); - break; - case INPUT_UNIT_SELECT_NEXT: - DLLExportClass::Select_Next_Unit(player_id); - break; - case INPUT_UNIT_SELECT_PREVIOUS: - DLLExportClass::Select_Previous_Unit(player_id); - break; - case INPUT_UNIT_GUARD_MODE: - DLLExportClass::Selected_Guard_Mode(player_id); - break; - case INPUT_UNIT_STOP: - DLLExportClass::Selected_Stop(player_id); - break; - case INPUT_UNIT_FORMATION_TOGGLE: - DLLExportClass::Team_Units_Formation_Toggle_On(player_id); - break; - case INPUT_UNIT_QUEUED_MOVEMENT_ON: - // Red Alert Only - DLLExportClass::Units_Queued_Movement_Toggle(player_id, true); - break; - case INPUT_UNIT_QUEUED_MOVEMENT_OFF: - // Red Alert Only - DLLExportClass::Units_Queued_Movement_Toggle(player_id, false); - break; - default: - break; - } -} - - - -/************************************************************************************************** -* CNC_Handle_Sidebar_Request -- Process an input request to the sidebar -* -* In: -* -* -* Out: -* -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Sidebar_Request(SidebarRequestEnum request_type, uint64 player_id, int buildable_type, int buildable_id, short cell_x, short cell_y) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (request_type) { - - // MBL 06.02.2020 - Changing right-click support for first put building on hold, and then subsequenct right-clicks to decrement that queue count for 1x or 5x; Then, 1x or 5x Left click will resume from hold - // Handle and fall through to start construction (from hold state) below - case SIDEBAR_REQUEST_START_CONSTRUCTION_MULTI: - - case SIDEBAR_REQUEST_START_CONSTRUCTION: - DLLExportClass::Start_Construction(player_id, buildable_type, buildable_id); - break; - - case SIDEBAR_REQUEST_HOLD_CONSTRUCTION: - DLLExportClass::Hold_Construction(player_id, buildable_type, buildable_id); - break; - - case SIDEBAR_REQUEST_CANCEL_CONSTRUCTION: - DLLExportClass::Cancel_Construction(player_id, buildable_type, buildable_id); - break; - - case SIDEBAR_REQUEST_START_PLACEMENT: - DLLExportClass::Start_Placement(player_id, buildable_type, buildable_id); - break; - - case SIDEBAR_REQUEST_PLACE: - DLLExportClass::Place(player_id, buildable_type, buildable_id, cell_x, cell_y); - break; - - case SIDEBAR_CANCEL_PLACE: - DLLExportClass::Cancel_Placement(player_id, buildable_type, buildable_id); - break; - - default: - break; - } -} - -/************************************************************************************************** -* CNC_Handle_SuperWeapon_Request -* -* In: -* -* -* Out: -* -* -* -* History: -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_SuperWeapon_Request(SuperWeaponRequestEnum request_type, uint64 player_id, int buildable_type, int buildable_id, int x1, int y1) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (request_type) - { - case SUPERWEAPON_REQUEST_PLACE_SUPER_WEAPON: - DLLExportClass::Place_Super_Weapon(player_id, buildable_type, buildable_id, x1, y1); - break; - } -} - -/************************************************************************************************** -* CNC_Handle_ControlGroup_Request -* -* In: -* -* -* Out: -* -* -* -* History: -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_ControlGroup_Request(ControlGroupRequestEnum request_type, uint64 player_id, unsigned char control_group_index) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (request_type) - { - case CONTROL_GROUP_REQUEST_CREATE: - DLLExportClass::Create_Control_Group(control_group_index); - break; - case CONTROL_GROUP_REQUEST_TOGGLE: - DLLExportClass::Toggle_Control_Group_Selection(control_group_index); - break; - case CONTROL_GROUP_REQUEST_ADDITIVE_SELECTION: - DLLExportClass::Add_To_Control_Group(control_group_index); - break; - - } -} - - - - -/************************************************************************************************** -* DLLExportClass::Get_Layer_State -- Get a snapshot of the sidebar state -* -* In: -* -* Out: -* -* -* -* History: 1/29/2019 11:37AM - ST -**************************************************************************************************/ -bool DLLExportClass::Get_Sidebar_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - CNCSidebarStruct *sidebar = (CNCSidebarStruct*) buffer_in; - - unsigned int memory_needed = sizeof(*sidebar); // Base amount needed. Will need more depending on how many entries there are - - int entry_index = 0; - - sidebar->Credits = 0; - sidebar->CreditsCounter = 0; - sidebar->Tiberium = 0; - sidebar->MaxTiberium = 0; - sidebar->PowerProduced = 0; - sidebar->PowerDrained = 0; - sidebar->RepairBtnEnabled = false; - sidebar->SellBtnEnabled = false; - sidebar->RadarMapActive = false; - sidebar->MissionTimer = -1; - - sidebar->UnitsKilled = 0; - sidebar->BuildingsKilled = 0; - sidebar->UnitsLost = 0; - sidebar->BuildingsLost = 0; - sidebar->TotalHarvestedCredits = 0; - - if (PlayerPtr) { - sidebar->Credits = PlayerPtr->Credits; - sidebar->CreditsCounter = PlayerPtr->VisibleCredits.Current; // Timed display - // sidebar->CreditsCounter = PlayerPtr->VisibleCredits.Credits; // Actual - sidebar->Tiberium = PlayerPtr->Tiberium; - sidebar->MaxTiberium = PlayerPtr->Capacity; - sidebar->PowerProduced = PlayerPtr->Power; - sidebar->PowerDrained = PlayerPtr->Drain; - - sidebar->RepairBtnEnabled = PlayerPtr->BScan > 0; - sidebar->SellBtnEnabled = PlayerPtr->BScan > 0; - sidebar->RadarMapActive = PlayerPtr->Radar == RADAR_ON; - - - // A. Get the DestroyedBuildings and DestroyedInfantry stats if they are available at this point - if (PlayerPtr->DestroyedBuildings) { - for ( int index = 0; index < PlayerPtr->DestroyedBuildings->Get_Unit_Count(); index ++ ) - { - unsigned int count = (unsigned int) PlayerPtr->DestroyedBuildings->Get_Unit_Total( index ); - sidebar->BuildingsKilled += count; - } - } - if (PlayerPtr->DestroyedInfantry) { - for ( int index = 0; index < PlayerPtr->DestroyedInfantry->Get_Unit_Count(); index ++ ) - { - unsigned int count = (unsigned int) PlayerPtr->DestroyedInfantry->Get_Unit_Total( index ); - sidebar->UnitsKilled += count; // Includes Infantry, Vehicles, Aircraft - } - } - if (PlayerPtr->DestroyedUnits) { - for ( int index = 0; index < PlayerPtr->DestroyedUnits->Get_Unit_Count(); index ++ ) - { - unsigned int count = (unsigned int) PlayerPtr->DestroyedUnits->Get_Unit_Total( index ); - sidebar->UnitsKilled += count; // Includes Infantry, Vehicles, Aircraft - } - } - if (PlayerPtr->DestroyedAircraft) { - for ( int index = 0; index < PlayerPtr->DestroyedAircraft->Get_Unit_Count(); index ++ ) - { - unsigned int count = (unsigned int) PlayerPtr->DestroyedAircraft->Get_Unit_Total( index ); - sidebar->UnitsKilled += count; // Includes Infantry, Vehicles, Aircraft - } - } - - // B. If the DestroyedBuildings and DestroyedInfantry stats seemed to be unvailable, this is another way to do it - // Note that we need to do both of these depending on which type of match we are running, as well as for Replays/Observer and live stats reporting - // We can't just do it this way for everything, as it does not work for all cases - if (sidebar->BuildingsKilled == 0) - { - for (unsigned int house_index = 0; house_index < HOUSE_COUNT; house_index ++) - { - sidebar->BuildingsKilled += PlayerPtr->BuildingsKilled[ house_index ]; - } - } - if (sidebar->UnitsKilled == 0) - { - for (unsigned int house_index = 0; house_index < HOUSE_COUNT; house_index ++) - { - sidebar->UnitsKilled += PlayerPtr->UnitsKilled[ house_index ]; // Includes Infantry, Vehicles, Aircraft - } - } - - - sidebar->UnitsLost = PlayerPtr->UnitsLost; - sidebar->BuildingsLost = PlayerPtr->BuildingsLost; - sidebar->TotalHarvestedCredits = PlayerPtr->HarvestedCredits; - } - - if (GameToPlay == GAME_NORMAL) { - - /* - ** Get each sidebar column - */ - for (int c = 0 ; c < 2 ; c++) { - - sidebar->EntryCount[c] = Map.Column[c].BuildableCount; - - /* - ** Each production slot in the column - */ - for (int b=0 ; b < Map.Column[c].BuildableCount ; b++) { - - CNCSidebarEntryStruct &sidebar_entry = sidebar->Entries[entry_index++]; - if ((entry_index + 1) * sizeof(CNCSidebarEntryStruct) + memory_needed > buffer_size) { - return false; - } - - sidebar_entry.AssetName[0] = 0; - sidebar_entry.Type = UNKNOWN; - sidebar_entry.BuildableID = Map.Column[c].Buildables[b].BuildableID; - sidebar_entry.BuildableType = Map.Column[c].Buildables[b].BuildableType; - sidebar_entry.BuildableViaCapture = Map.Column[c].Buildables[b].BuildableViaCapture; - sidebar_entry.Fake = false; - - TechnoTypeClass const * tech = Fetch_Techno_Type(Map.Column[c].Buildables[b].BuildableType, Map.Column[c].Buildables[b].BuildableID); - - sidebar_entry.SuperWeaponType = SW_NONE; - - if (tech) { - sidebar_entry.Cost = tech->Cost * PlayerPtr->CostBias; - sidebar_entry.PowerProvided = 0; - sidebar_entry.BuildTime = tech->Time_To_Build(PlayerPtr->Class->House); - strncpy(sidebar_entry.AssetName, tech->IniName, CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - } else { - sidebar_entry.Cost = 0; - sidebar_entry.AssetName[0] = 0; - } - - SuperClass* super_weapon = nullptr; - - bool isbusy = false; - - switch (Map.Column[c].Buildables[b].BuildableType) { - case RTTI_INFANTRYTYPE: - sidebar_entry.Type = INFANTRY_TYPE; - isbusy = (PlayerPtr->InfantryFactory != -1); - isbusy |= Infantry.Avail() <= 0; - break; - - case RTTI_UNITTYPE: - isbusy = (PlayerPtr->UnitFactory != -1); - sidebar_entry.Type = UNIT_TYPE; - isbusy |= Units.Avail() <= 0; - break; - - case RTTI_AIRCRAFTTYPE: - isbusy = (PlayerPtr->AircraftFactory != -1); - sidebar_entry.Type = AIRCRAFT_TYPE; - isbusy |= Aircraft.Avail() <= 0; - break; - - case RTTI_BUILDINGTYPE: - { - isbusy = (PlayerPtr->BuildingFactory != -1); - isbusy |= Buildings.Avail() <= 0; - sidebar_entry.Type = BUILDING_TYPE; - - const BuildingTypeClass* build_type = static_cast(tech); - sidebar_entry.PowerProvided = build_type->Power - build_type->Drain; - } - break; - - default: - sidebar_entry.Type = UNKNOWN; - break; - - case RTTI_SPECIAL: - switch (Map.Column[c].Buildables[b].BuildableID) - { - case SPC_ION_CANNON: - sidebar_entry.SuperWeaponType = SW_ION_CANNON; - sidebar_entry.Type = SPECIAL; - strncpy(sidebar_entry.AssetName, "SW_Ion", CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - super_weapon = &PlayerPtr->IonCannon; - break; - - case SPC_NUCLEAR_BOMB: - sidebar_entry.SuperWeaponType = SW_NUKE; - sidebar_entry.Type = SPECIAL; - strncpy(sidebar_entry.AssetName, "SW_Nuke", CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - super_weapon = &PlayerPtr->NukeStrike; - break; - - case SPC_AIR_STRIKE: - sidebar_entry.SuperWeaponType = SW_AIR_STRIKE; - sidebar_entry.Type = SPECIAL; - strncpy(sidebar_entry.AssetName, "SW_AirStrike", CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - super_weapon = &PlayerPtr->AirStrike; - break; - - default: - sidebar_entry.SuperWeaponType = SW_UNKNOWN; - sidebar_entry.Type = SPECIAL; - break; - } - break; - } - - int fnumber = Map.Column[c].Buildables[b].Factory; - FactoryClass * factory = NULL; - if (tech && fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - if (super_weapon != nullptr) - { - sidebar_entry.Progress = (float)super_weapon->Anim_Stage() / (float)SuperClass::ANIMATION_STAGES; - sidebar_entry.Completed = super_weapon->Is_Ready(); - sidebar_entry.Constructing = super_weapon->Anim_Stage() != SuperClass::ANIMATION_STAGES; - sidebar_entry.ConstructionOnHold = false; - sidebar_entry.PlacementListLength = 0; - sidebar_entry.PowerProvided = 0; - sidebar_entry.BuildTime = super_weapon->Get_Recharge_Time(); - } - else - { - - sidebar_entry.Completed = false; - sidebar_entry.Constructing = false; - sidebar_entry.ConstructionOnHold = false; - sidebar_entry.Progress = 0.0f; - sidebar_entry.Busy = isbusy; - sidebar_entry.PlacementListLength = 0; - - if (factory) { - if (factory->Is_Building()) { - sidebar_entry.Constructing = true; - sidebar_entry.Progress = (float)factory->Completion() / (float)FactoryClass::STEP_COUNT; - sidebar_entry.Completed = factory->Has_Completed(); - } - else { - sidebar_entry.Completed = factory->Has_Completed(); - if (!sidebar_entry.Completed) - { - sidebar_entry.ConstructionOnHold = true; - sidebar_entry.Progress = (float)factory->Completion() / (float)FactoryClass::STEP_COUNT; - } - - if (sidebar_entry.Completed && sidebar_entry.Type == BUILDING_TYPE) { - if (tech) { - BuildingTypeClass *building_type = (BuildingTypeClass*)tech; - short const *occupy_list = building_type->Occupy_List(true); - if (occupy_list) { - while (*occupy_list != REFRESH_EOL && sidebar_entry.PlacementListLength < MAX_OCCUPY_CELLS) { - sidebar_entry.PlacementList[sidebar_entry.PlacementListLength] = *occupy_list; - sidebar_entry.PlacementListLength++; - occupy_list++; - } - } - } - } - } - } - } - } - } - - } else { - - - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - - SidebarGlyphxClass *context_sidebar = DLLExportClass::Get_Current_Context_Sidebar(); - - /* - ** Get each sidebar column - */ - for (int c = 0 ; c < 2 ; c++) { - - sidebar->EntryCount[c] = context_sidebar->Column[c].BuildableCount; - - /* - ** Each production slot in the column - */ - for (int b=0 ; b < context_sidebar->Column[c].BuildableCount ; b++) { - - CNCSidebarEntryStruct &sidebar_entry = sidebar->Entries[entry_index++]; - if ((entry_index + 1) * sizeof(CNCSidebarEntryStruct) + memory_needed > buffer_size) { - return false; - } - - sidebar_entry.AssetName[0] = 0; - sidebar_entry.Type = UNKNOWN; - sidebar_entry.BuildableID = context_sidebar->Column[c].Buildables[b].BuildableID; - sidebar_entry.BuildableType = context_sidebar->Column[c].Buildables[b].BuildableType; - sidebar_entry.BuildableViaCapture = context_sidebar->Column[c].Buildables[b].BuildableViaCapture; - sidebar_entry.Fake = false; - - TechnoTypeClass const * tech = Fetch_Techno_Type(context_sidebar->Column[c].Buildables[b].BuildableType, context_sidebar->Column[c].Buildables[b].BuildableID); - - sidebar_entry.SuperWeaponType = SW_NONE; - - if (tech) { - sidebar_entry.Cost = tech->Cost * PlayerPtr->CostBias; - sidebar_entry.PowerProvided = 0; - sidebar_entry.BuildTime = tech->Time_To_Build(PlayerPtr->Class->House); - strncpy(sidebar_entry.AssetName, tech->IniName, CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - } else { - sidebar_entry.Cost = 0; - sidebar_entry.AssetName[0] = 0; - } - - SuperClass* super_weapon = nullptr; - - bool isbusy = false; - - switch (context_sidebar->Column[c].Buildables[b].BuildableType) { - case RTTI_INFANTRYTYPE: - sidebar_entry.Type = INFANTRY_TYPE; - isbusy = (PlayerPtr->InfantryFactory != -1); - isbusy |= Infantry.Avail() <= 0; - break; - - case RTTI_UNITTYPE: - isbusy = (PlayerPtr->UnitFactory != -1); - isbusy |= Units.Avail() <= 0; - sidebar_entry.Type = UNIT_TYPE; - break; - - case RTTI_AIRCRAFTTYPE: - isbusy = (PlayerPtr->AircraftFactory != -1); - isbusy |= Aircraft.Avail() <= 0; - sidebar_entry.Type = AIRCRAFT_TYPE; - break; - - case RTTI_BUILDINGTYPE: - { - isbusy = (PlayerPtr->BuildingFactory != -1); - isbusy |= Buildings.Avail() <= 0; - sidebar_entry.Type = BUILDING_TYPE; - - const BuildingTypeClass* build_type = static_cast(tech); - sidebar_entry.PowerProvided = build_type->Power - build_type->Drain; - } - break; - - default: - sidebar_entry.Type = UNKNOWN; - break; - - case RTTI_SPECIAL: - switch (context_sidebar->Column[c].Buildables[b].BuildableID) { - case SPC_ION_CANNON: - sidebar_entry.SuperWeaponType = SW_ION_CANNON; - sidebar_entry.Type = SPECIAL; - strncpy(sidebar_entry.AssetName, "SW_Ion", CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - super_weapon = &PlayerPtr->IonCannon; - break; - - case SPC_NUCLEAR_BOMB: - sidebar_entry.SuperWeaponType = SW_NUKE; - sidebar_entry.Type = SPECIAL; - strncpy(sidebar_entry.AssetName, "SW_Nuke", CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - super_weapon = &PlayerPtr->NukeStrike; - break; - - case SPC_AIR_STRIKE: - sidebar_entry.SuperWeaponType = SW_AIR_STRIKE; - sidebar_entry.Type = SPECIAL; - strncpy(sidebar_entry.AssetName, "SW_AirStrike", CNC_OBJECT_ASSET_NAME_LENGTH); - sidebar_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - super_weapon = &PlayerPtr->AirStrike; - break; - - default: - sidebar_entry.SuperWeaponType = SW_UNKNOWN; - sidebar_entry.Type = SPECIAL; - break; - } - break; - } - - if (super_weapon != nullptr) - { - sidebar_entry.Progress = (float)super_weapon->Anim_Stage() / (float)SuperClass::ANIMATION_STAGES; - sidebar_entry.Completed = super_weapon->Is_Ready(); - sidebar_entry.Constructing = super_weapon->Anim_Stage() != SuperClass::ANIMATION_STAGES; - sidebar_entry.ConstructionOnHold = false; - sidebar_entry.PlacementListLength = 0; - sidebar_entry.PowerProvided = 0; - sidebar_entry.BuildTime = super_weapon->Get_Recharge_Time(); - } - else - { - - int fnumber = context_sidebar->Column[c].Buildables[b].Factory; - FactoryClass * factory = NULL; - if (tech && fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - sidebar_entry.Completed = false; - sidebar_entry.Constructing = false; - sidebar_entry.ConstructionOnHold = false; - sidebar_entry.Progress = 0.0f; - sidebar_entry.Busy = isbusy; - sidebar_entry.PlacementListLength = 0; - - if (factory) { - if (factory->Is_Building()) { - sidebar_entry.Constructing = true; - sidebar_entry.Progress = (float)factory->Completion() / (float)FactoryClass::STEP_COUNT; - sidebar_entry.Completed = factory->Has_Completed(); - } - else { - sidebar_entry.Completed = factory->Has_Completed(); - if (!sidebar_entry.Completed) - { - sidebar_entry.ConstructionOnHold = true; - sidebar_entry.Progress = (float)factory->Completion() / (float)FactoryClass::STEP_COUNT; - } - - if (sidebar_entry.Completed && sidebar_entry.Type == BUILDING_TYPE) { - if (tech) { - BuildingTypeClass *building_type = (BuildingTypeClass*)tech; - short const *occupy_list = building_type->Occupy_List(true); - if (occupy_list) { - while (*occupy_list != REFRESH_EOL && sidebar_entry.PlacementListLength < MAX_OCCUPY_CELLS) { - sidebar_entry.PlacementList[sidebar_entry.PlacementListLength] = *occupy_list; - sidebar_entry.PlacementListLength++; - occupy_list++; - } - } - } - } - } - } - } - } - } - } - } - - - - return true; -} - - -void DLLExportClass::Calculate_Placement_Distances(BuildingTypeClass* placement_type, unsigned char* placement_distance) -{ - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - memset(placement_distance, 255U, MAP_CELL_TOTAL); - for (int y = 0; y < map_cell_height; y++) { - for (int x = 0; x < map_cell_width; x++) { - CELL cell = (CELL)map_cell_x + x + ((map_cell_y + y) << 6); - BuildingClass* base = (BuildingClass*)Map[cell].Cell_Find_Object(RTTI_BUILDING); - if ((base && base->House->Class->House == PlayerPtr->Class->House) || (Map[cell].Owner == PlayerPtr->Class->House)) { - placement_distance[cell] = 0U; - for (FacingType facing = FACING_N; facing < FACING_COUNT; facing++) { - CELL adjcell = Adjacent_Cell(cell, facing); - if (Map.In_Radar(adjcell)) { - placement_distance[adjcell] = min(placement_distance[adjcell], 1U); - } - } - } - } - } -} - -void Recalculate_Placement_Distances() -{ - DLLExportClass::Recalculate_Placement_Distances(); -} - -void DLLExportClass::Recalculate_Placement_Distances() -{ - if (PlacementType[CurrentLocalPlayerIndex] != NULL) { - Calculate_Placement_Distances(PlacementType[CurrentLocalPlayerIndex], PlacementDistance[CurrentLocalPlayerIndex]); - } -} - - -/************************************************************************************************** -* DLLExportClass::Get_Placement_State -- Get a snapshot of legal validity of placing a structure on all map cells -* -* In: -* -* Out: -* -* -* -* History: 2/4/2019 3:11PM - ST -**************************************************************************************************/ -bool DLLExportClass::Get_Placement_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - if (PlacementType[CurrentLocalPlayerIndex] == NULL) { - return false; - } - - CNCPlacementInfoStruct *placement_info = (CNCPlacementInfoStruct*) buffer_in; - - unsigned int memory_needed = sizeof(*placement_info); // Base amount needed. Will need more depending on how many entries there are - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - memory_needed += map_cell_width * map_cell_height * sizeof(CNCPlacementCellInfoStruct); - - if (memory_needed + 128 >= buffer_size) { - return false; - } - - placement_info->Count = map_cell_width * map_cell_height; - - int index = 0; - for (int y=0 ; y < map_cell_height ; y++) { - for (int x=0 ; x < map_cell_width ; x++) { - - CELL cell = (CELL) map_cell_x + x + ((map_cell_y + y) << 6); - - bool pass = Passes_Proximity_Check(cell, PlacementType[CurrentLocalPlayerIndex], PlacementDistance[CurrentLocalPlayerIndex]); - - CellClass * cellptr = &Map[cell]; - bool clear = cellptr->Is_Generally_Clear(); - - CNCPlacementCellInfoStruct &placement_cell_info = placement_info->CellInfo[index++]; - placement_cell_info.PassesProximityCheck = pass; - placement_cell_info.GenerallyClear = clear; - } - } - - Map.ZoneOffset = 0; - - return true; -} - - -bool DLLExportClass::Passes_Proximity_Check(CELL cell_in, BuildingTypeClass *placement_type, unsigned char* placement_distance) -{ - - /* - ** Scan through all cells that the building foundation would cover. If any adjacent - ** cells to these are of friendly persuasion, then consider the proximity check to - ** have been a success. - */ - short const *occupy_list = placement_type->Occupy_List(true); - - while (*occupy_list != REFRESH_EOL) { - - CELL center_cell = cell_in + *occupy_list++; - - if (!Map.In_Radar(center_cell)) { - return false; - } - - if (placement_distance[center_cell] <= 1U) { - return true; - } - } - - return false; -} - - -/************************************************************************************************** -* DLLExportClass::Start_Construction -- Start sidebar construction -* -* In: -* -* Out: -* -* -* -* History: 1/29/2019 11:37AM - ST -**************************************************************************************************/ -bool DLLExportClass::Start_Construction(uint64 player_id, int buildable_type, int buildable_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - if (GameToPlay == GAME_NORMAL) { - return Construction_Action(SIDEBAR_REQUEST_START_CONSTRUCTION, player_id, buildable_type, buildable_id); - } - return MP_Construction_Action(SIDEBAR_REQUEST_START_CONSTRUCTION, player_id, buildable_type, buildable_id); -} - -/************************************************************************************************** -* DLLExportClass::Hold_Construction -- Pause sidebar construction -* -* In: -* -* Out: -* -* -* -* History: 6/12/2019 JAS -**************************************************************************************************/ -bool DLLExportClass::Hold_Construction(uint64 player_id, int buildable_type, int buildable_id) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) - { - return false; - } - - if (GameToPlay == GAME_NORMAL) { - return Construction_Action(SIDEBAR_REQUEST_HOLD_CONSTRUCTION, player_id, buildable_type, buildable_id); - } - return MP_Construction_Action(SIDEBAR_REQUEST_HOLD_CONSTRUCTION, player_id, buildable_type, buildable_id); -} - -/************************************************************************************************** -* DLLExportClass::Cancel_Construction -- Stop sidebar construction -* -* In: -* -* Out: -* -* -* -* History: 6/12/2019 JAS -**************************************************************************************************/ -bool DLLExportClass::Cancel_Construction(uint64 player_id, int buildable_type, int buildable_id) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) - { - return false; - } - - return Cancel_Placement(player_id, buildable_type, buildable_id) && - ((GameToPlay == GAME_NORMAL) ? - Construction_Action(SIDEBAR_REQUEST_CANCEL_CONSTRUCTION, player_id, buildable_type, buildable_id) : - MP_Construction_Action(SIDEBAR_REQUEST_CANCEL_CONSTRUCTION, player_id, buildable_type, buildable_id)); -} - -/************************************************************************************************** -* DLLExportClass::Construction_Action -- Reproduce actions on the sidebar -* -* In: -* -* Out: -* -* -* -* History: 1/29/2019 11:37AM - ST -**************************************************************************************************/ -bool DLLExportClass::Construction_Action(SidebarRequestEnum construction_action, uint64 player_id, int buildable_type, int buildable_id) -{ - - /* - ** - ** Based on SidebarClass::StripClass::SelectClass::Action - ** - ** Most of this code is validating that the game is in the correct state to be able to act on a sidebar icon - ** - */ - - for (int c = 0 ; c < 2 ; c++) { - - /* - ** Each production slot in the column - */ - for (int b=0 ; b < Map.Column[c].BuildableCount ; b++) { - if (Map.Column[c].Buildables[b].BuildableID == buildable_id) { - if (Map.Column[c].Buildables[b].BuildableType == buildable_type) { - - - int genfactory = -1; - switch (buildable_type) { - case RTTI_INFANTRYTYPE: - genfactory = PlayerPtr->InfantryFactory; - break; - - case RTTI_UNITTYPE: - genfactory = PlayerPtr->UnitFactory; - break; - - case RTTI_AIRCRAFTTYPE: - genfactory = PlayerPtr->AircraftFactory; - break; - - case RTTI_BUILDINGTYPE: - genfactory = PlayerPtr->BuildingFactory; - break; - - default: - genfactory = -1; - break; - } - - int fnumber = Map.Column[c].Buildables[b].Factory; - int spc = 0; - ObjectTypeClass const * choice = NULL; - - if (buildable_type != RTTI_SPECIAL) { - choice = Fetch_Techno_Type((RTTIType)buildable_type, buildable_id); - } else { - spc = buildable_id; - } - - FactoryClass * factory = NULL; - if (fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - if (spc == 0 && choice) { - if (fnumber == -1 && genfactory != -1) { - return(false); - } - - if (factory) { - - /* - ** If this object is currently being built, then give a scold sound and text and then - ** bail. - */ - switch (construction_action) - { - case SIDEBAR_REQUEST_CANCEL_CONSTRUCTION: - On_Speech(PlayerPtr, VOX_CANCELED); // Speak(VOX_CANCELED); - OutList.Add(EventClass(EventClass::ABANDON, (RTTIType)buildable_type, buildable_id)); - break; - case SIDEBAR_REQUEST_HOLD_CONSTRUCTION: - if (factory->Is_Building()) - { - On_Speech(PlayerPtr, VOX_SUSPENDED); // Speak(VOX_SUSPENDED); - OutList.Add(EventClass(EventClass::SUSPEND, (RTTIType)buildable_type, buildable_id)); - } - break; - - default: - if (factory->Is_Building()) { - On_Speech(PlayerPtr, VOX_NO_FACTORY); //Speak(VOX_NO_FACTORY); // "Cannot Comply" - return false; - } - else { - - /* - ** If production has completed, then attempt to have the object exit - ** the factory or go into placement mode. - */ - if (factory->Has_Completed()) { - - TechnoClass * pending = factory->Get_Object(); - if (!pending && factory->Get_Special_Item()) { - // TO_DO - //Map.IsTargettingMode = true; - } - else { - - BuildingClass * builder = pending->Who_Can_Build_Me(false, false); - if (!builder) { - OutList.Add(EventClass(EventClass::ABANDON, (RTTIType)buildable_type, buildable_id)); - On_Speech(PlayerPtr, VOX_NO_FACTORY); //Speak(VOX_NO_FACTORY); // "Cannot Comply" - } - else { - - /* - ** If the completed object is a building, then change the - ** game state into building placement mode. This fact is - ** not transmitted to any linked computers until the moment - ** the building is actually placed down. - */ - if (pending->What_Am_I() == RTTI_BUILDING) { - if (construction_action == SIDEBAR_REQUEST_START_PLACEMENT) { - PlayerPtr->Manual_Place(builder, (BuildingClass *)pending); - } - } - else { - - /* - ** For objects that can leave the factory under their own - ** power, queue this event and process through normal house - ** production channels. - */ - //OutList.Add(EventClass(EventClass::PLACE, otype, -1)); - } - } - } - - } - else { - - /* - ** The factory must have been in a suspended state. Resume construction - ** normally. - */ - if (construction_action == SIDEBAR_REQUEST_START_CONSTRUCTION) { - On_Speech(PlayerPtr, VOX_BUILDING); // Speak(VOX_BUILDING); - OutList.Add(EventClass(EventClass::PRODUCE, (RTTIType)buildable_type, buildable_id)); - return true; - } - } - } - break; - } - - } else { - - switch (construction_action) - { - case SIDEBAR_REQUEST_CANCEL_CONSTRUCTION: - case SIDEBAR_REQUEST_HOLD_CONSTRUCTION: - break; - - default: - /* - ** If this side strip is already busy with production, then ignore the - ** input and announce this fact. - */ - On_Speech(PlayerPtr, VOX_BUILDING); // Speak(VOX_BUILDING); - OutList.Add(EventClass(EventClass::PRODUCE, (RTTIType)buildable_type, buildable_id)); - - /* - ** Execute immediately so we get the sidebar feedback - */ - Queue_AI(); - return true; - } - } - } - } - } - } - } - return false; -} - - - - -/************************************************************************************************** -* DLLExportClass::MP_Construction_Action -- Reproduce actions on the sidebar -* -* In: -* -* Out: -* -* -* -* History: 3/26/2019 1:02PM - ST -**************************************************************************************************/ -bool DLLExportClass::MP_Construction_Action(SidebarRequestEnum construction_action, uint64 player_id, int buildable_type, int buildable_id) -{ - - /* - ** - ** Based on SidebarClass::StripClass::SelectClass::Action - ** - ** Most of this code is validating that the game is in the correct state to be able to act on a sidebar icon - ** - */ - - SidebarGlyphxClass *context_sidebar = DLLExportClass::Get_Current_Context_Sidebar(); - - for (int c = 0 ; c < 2 ; c++) { - - /* - ** Each production slot in the column - */ - for (int b=0 ; b < context_sidebar->Column[c].BuildableCount ; b++) { - if (context_sidebar->Column[c].Buildables[b].BuildableID == buildable_id) { - if (context_sidebar->Column[c].Buildables[b].BuildableType == buildable_type) { - - int genfactory = -1; - switch (buildable_type) { - case RTTI_INFANTRYTYPE: - genfactory = PlayerPtr->InfantryFactory; - break; - - case RTTI_UNITTYPE: - genfactory = PlayerPtr->UnitFactory; - break; - - case RTTI_AIRCRAFTTYPE: - genfactory = PlayerPtr->AircraftFactory; - break; - - case RTTI_BUILDINGTYPE: - genfactory = PlayerPtr->BuildingFactory; - break; - - default: - genfactory = -1; - break; - } - - int fnumber = context_sidebar->Column[c].Buildables[b].Factory; - int spc = 0; - ObjectTypeClass const * choice = NULL; - - if (buildable_type != RTTI_SPECIAL) { - choice = Fetch_Techno_Type((RTTIType)buildable_type, buildable_id); - } else { - spc = buildable_id; - } - - FactoryClass * factory = NULL; - if (fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - if (spc == 0 && choice) { - /* - ** If there is already a factory attached to this strip but the player didn't click - ** on the icon that has the attached factory, then say that the factory is busy and - ** ignore the click. - */ - if (fnumber == -1 && genfactory != -1) { - On_Speech(PlayerPtr, VOX_NO_FACTORY); //Speak(VOX_NO_FACTORY); // "Cannot Comply" - return(false); - } - - if (factory) { - switch (construction_action) - { - case SIDEBAR_REQUEST_CANCEL_CONSTRUCTION: - On_Speech(PlayerPtr, VOX_CANCELED); // Speak(VOX_CANCELED); - OutList.Add(EventClass(EventClass::ABANDON, (RTTIType)buildable_type, buildable_id)); - break; - case SIDEBAR_REQUEST_HOLD_CONSTRUCTION: - if (factory->Is_Building()) - { - On_Speech(PlayerPtr, VOX_SUSPENDED); // Speak(VOX_SUSPENDED); - OutList.Add(EventClass(EventClass::SUSPEND, (RTTIType)buildable_type, buildable_id)); - } - break; - - default: - /* - ** If this object is currently being built, then give a scold sound and text and then - ** bail. - */ - if (factory->Is_Building()) { - On_Speech(PlayerPtr, VOX_NO_FACTORY); //Speak(VOX_NO_FACTORY); // "Cannot Comply" - return false; - } - else { - - /* - ** If production has completed, then attempt to have the object exit - ** the factory or go into placement mode. - */ - if (factory->Has_Completed()) { - - TechnoClass * pending = factory->Get_Object(); - if (!pending && factory->Get_Special_Item()) { - // TO_DO - //Map.IsTargettingMode = true; - } - else { - - BuildingClass * builder = pending->Who_Can_Build_Me(false, false); - if (!builder) { - On_Speech(PlayerPtr, VOX_NO_FACTORY); //Speak(VOX_NO_FACTORY); // "Cannot Comply" - OutList.Add(EventClass(EventClass::ABANDON, (RTTIType)buildable_type, buildable_id)); - } - else { - - /* - ** If the completed object is a building, then change the - ** game state into building placement mode. This fact is - ** not transmitted to any linked computers until the moment - ** the building is actually placed down. - */ - if (pending->What_Am_I() == RTTI_BUILDING) { - if (construction_action == SIDEBAR_REQUEST_START_PLACEMENT) { - if (DLLExportClass::Legacy_Render_Enabled()) { - PlayerPtr->Manual_Place(builder, (BuildingClass *)pending); - } else { - Unselect_All(); - } - } - } - else { - - /* - ** For objects that can leave the factory under their own - ** power, queue this event and process through normal house - ** production channels. - */ - //OutList.Add(EventClass(EventClass::PLACE, otype, -1)); - } - } - } - - } - else { - - /* - ** The factory must have been in a suspended state. Resume construction - ** normally. - */ - if (construction_action == SIDEBAR_REQUEST_START_CONSTRUCTION) { - On_Speech(PlayerPtr, VOX_BUILDING); // Speak(VOX_BUILDING); - OutList.Add(EventClass(EventClass::PRODUCE, (RTTIType)buildable_type, buildable_id)); - return true; - } - } - } - break; - } - - } else { - - switch (construction_action) - { - case SIDEBAR_REQUEST_CANCEL_CONSTRUCTION: - case SIDEBAR_REQUEST_HOLD_CONSTRUCTION: - break; - - default: - /* - ** - */ - On_Speech(PlayerPtr, VOX_BUILDING); // Speak(VOX_BUILDING); - OutList.Add(EventClass(EventClass::PRODUCE, (RTTIType)buildable_type, buildable_id)); - - /* - ** Execute immediately so we get the sidebar feedback - */ - DLLExportClass::Glyphx_Queue_AI(); - return true; - } - } - } - } - } - } - } - return false; -} - - - - - -/************************************************************************************************** -* DLLExportClass::Start_Placement -- Start placing a completed structure -* -* In: -* -* Out: -* -* -* -* History: 1/29/2019 11:37AM - ST -**************************************************************************************************/ -bool DLLExportClass::Start_Placement(uint64 player_id, int buildable_type, int buildable_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - BuildingClass *building = Get_Pending_Placement_Object(player_id, buildable_type, buildable_id); - - if (building) { - - TechnoTypeClass const * tech = Fetch_Techno_Type((RTTIType)buildable_type, buildable_id); - - if (tech) { - BuildingTypeClass *building_type = (BuildingTypeClass*) tech; - //short const *occupy_list = building_type->Get_Occupy_List(true); - - PlacementType[CurrentLocalPlayerIndex] = building_type; - Recalculate_Placement_Distances(); - - if (GameToPlay == GAME_NORMAL) { - return Construction_Action(SIDEBAR_REQUEST_START_PLACEMENT, player_id, buildable_type, buildable_id); - } - return MP_Construction_Action(SIDEBAR_REQUEST_START_PLACEMENT, player_id, buildable_type, buildable_id); - } - } - return true; -} - - -/************************************************************************************************** -* DLLExportClass::Cancel_Placement -- Cancel placing a completed structure -* -* In: -* -* Out: -* -* -* -* History: 2/7/2019 10:52AM - ST -**************************************************************************************************/ -bool DLLExportClass::Cancel_Placement(uint64 player_id, int buildable_type, int buildable_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - PlacementType[CurrentLocalPlayerIndex] = NULL; - - Map.PendingObjectPtr = 0; - Map.PendingObject = 0; - Map.PendingHouse = HOUSE_NONE; - Map.Set_Cursor_Shape(0); - - return true; -} - - - -/************************************************************************************************** -* DLLExportClass::Place -- Place a completed structure down -* -* In: -* -* Out: -* -* -* -* History: 2/6/2019 11:51AM - ST -**************************************************************************************************/ -bool DLLExportClass::Place(uint64 player_id, int buildable_type, int buildable_id, short cell_x, short cell_y) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - /* - ** Need to check for proximity again here? - */ -#if (0) -Map.Passes_Proximity_Check - - Map.Set_Cursor_Shape(Map.PendingObject->Occupy_List()); - - - OutList.Add(EventClass(EventClass::PLACE, PendingObjectPtr->What_Am_I(), cell + ZoneOffset)); -#endif - - - BuildingClass *building = Get_Pending_Placement_Object(player_id, buildable_type, buildable_id); - - if (building) { - - TechnoTypeClass const * tech = Fetch_Techno_Type((RTTIType)buildable_type, buildable_id); - - if (tech) { - BuildingTypeClass *building_type = (BuildingTypeClass*) tech; - //short const *occupy_list = building_type->Get_Occupy_List(true); - - PlacementType[CurrentLocalPlayerIndex] = building_type; - - /* - ** The cell coordinates passed in will be relative to the playable area that the client knows about - */ - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - CELL cell = (CELL) (map_cell_x + cell_x) + ( (map_cell_y + cell_y) << 6 ); - - /* - ** Call the place directly instead of queueing it, so we can evaluate the return code. - */ - if (PlayerPtr->Place_Object(building->What_Am_I(), cell + Map.ZoneOffset)) { - PlacementType[CurrentLocalPlayerIndex] = NULL; - } - } - } - return true; - -} - - - - -BuildingClass *DLLExportClass::Get_Pending_Placement_Object(uint64 player_id, int buildable_type, int buildable_id) -{ - /* - ** - ** Based on SidebarClass::StripClass::SelectClass::Action - ** - ** - */ - if (GameToPlay == GAME_NORMAL) { - - for (int c = 0 ; c < 2 ; c++) { - - /* - ** Each production slot in the column - */ - for (int b=0 ; b < Map.Column[c].BuildableCount ; b++) { - if (Map.Column[c].Buildables[b].BuildableID == buildable_id) { - if (Map.Column[c].Buildables[b].BuildableType == buildable_type) { - - - int genfactory = -1; - switch (buildable_type) { - case RTTI_INFANTRYTYPE: - genfactory = PlayerPtr->InfantryFactory; - break; - - case RTTI_UNITTYPE: - genfactory = PlayerPtr->UnitFactory; - break; - - case RTTI_AIRCRAFTTYPE: - genfactory = PlayerPtr->AircraftFactory; - break; - - case RTTI_BUILDINGTYPE: - genfactory = PlayerPtr->BuildingFactory; - break; - - default: - genfactory = -1; - break; - } - - int fnumber = Map.Column[c].Buildables[b].Factory; - int spc = 0; - ObjectTypeClass const * choice = NULL; - - if (buildable_type != RTTI_SPECIAL) { - choice = Fetch_Techno_Type((RTTIType)buildable_type, buildable_id); - } else { - spc = buildable_id; - } - - FactoryClass * factory = NULL; - if (fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - if (spc == 0 && choice) { - if (fnumber == -1 && genfactory != -1) { - return(NULL); - } - - if (factory) { - - /* - ** If production has completed, then attempt to have the object exit - ** the factory or go into placement mode. - */ - if (factory->Has_Completed()) { - - TechnoClass * pending = factory->Get_Object(); - if (!pending && factory->Get_Special_Item()) { - //Map.IsTargettingMode = true; - } else { - BuildingClass * builder = pending->Who_Can_Build_Me(false, false); - if (!builder) { - OutList.Add(EventClass(EventClass::ABANDON, buildable_type, buildable_id)); - On_Speech(PlayerPtr, VOX_NO_FACTORY); // Speak(VOX_NO_FACTORY); - } else { - - /* - ** If the completed object is a building, then change the - ** game state into building placement mode. This fact is - ** not transmitted to any linked computers until the moment - ** the building is actually placed down. - */ - if (pending->What_Am_I() == RTTI_BUILDING) { - return (BuildingClass*)pending; - //PlayerPtr->Manual_Place(builder, (BuildingClass *)pending); - } - } - } - } - } - } - } - } - } - } - - } else { - - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - - - SidebarGlyphxClass *context_sidebar = DLLExportClass::Get_Current_Context_Sidebar(); - - for (int c = 0 ; c < 2 ; c++) { - - /* - ** Each production slot in the column - */ - for (int b=0 ; b < context_sidebar->Column[c].BuildableCount ; b++) { - if (context_sidebar->Column[c].Buildables[b].BuildableID == buildable_id) { - if (context_sidebar->Column[c].Buildables[b].BuildableType == buildable_type) { - - - int genfactory = -1; - switch (buildable_type) { - case RTTI_INFANTRYTYPE: - genfactory = PlayerPtr->InfantryFactory; - break; - - case RTTI_UNITTYPE: - genfactory = PlayerPtr->UnitFactory; - break; - - case RTTI_AIRCRAFTTYPE: - genfactory = PlayerPtr->AircraftFactory; - break; - - case RTTI_BUILDINGTYPE: - genfactory = PlayerPtr->BuildingFactory; - break; - - default: - genfactory = -1; - break; - } - - int fnumber = context_sidebar->Column[c].Buildables[b].Factory; - int spc = 0; - ObjectTypeClass const * choice = NULL; - - if (buildable_type != RTTI_SPECIAL) { - choice = Fetch_Techno_Type((RTTIType)buildable_type, buildable_id); - } else { - spc = buildable_id; - } - - FactoryClass * factory = NULL; - if (fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - if (spc == 0 && choice) { - if (fnumber == -1 && genfactory != -1) { - return(NULL); - } - - if (factory) { - - /* - ** If production has completed, then attempt to have the object exit - ** the factory or go into placement mode. - */ - if (factory->Has_Completed()) { - - TechnoClass * pending = factory->Get_Object(); - if (!pending && factory->Get_Special_Item()) { - //Map.IsTargettingMode = true; - } else { - BuildingClass * builder = pending->Who_Can_Build_Me(false, false); - if (!builder) { - OutList.Add(EventClass(EventClass::ABANDON, buildable_type, buildable_id)); - On_Speech(PlayerPtr, VOX_NO_FACTORY); // Speak(VOX_NO_FACTORY); - } else { - - /* - ** If the completed object is a building, then change the - ** game state into building placement mode. This fact is - ** not transmitted to any linked computers until the moment - ** the building is actually placed down. - */ - if (pending->What_Am_I() == RTTI_BUILDING) { - return (BuildingClass*)pending; - //PlayerPtr->Manual_Place(builder, (BuildingClass *)pending); - } - } - } - } - } - } - } - } - } - } - } - } - return NULL; -} - -/************************************************************************************************** -* DLLExportClass::Place_Super_Weapon -* -* History: -**************************************************************************************************/ -bool DLLExportClass::Place_Super_Weapon(uint64 player_id, int buildable_type, int buildable_id, int x, int y) -{ - if (buildable_type != RTTI_SPECIAL) - { - return false; - } - - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); - - SpecialWeaponType weapon_type = (SpecialWeaponType)buildable_id; - - OutList.Add(EventClass(EventClass::SPECIAL_PLACE, weapon_type, cell)); - - return true; -} - -/************************************************************************************************** -* DLLExportClass::Create_Control_Group -* -* History: -**************************************************************************************************/ -bool DLLExportClass::Create_Control_Group(unsigned char control_group_index) -{ - Handle_Team(control_group_index, 2); - - return true; -} - -/************************************************************************************************** -* DLLExportClass::Add_To_Control_Group -* -* History: -**************************************************************************************************/ -bool DLLExportClass::Add_To_Control_Group(unsigned char control_group_index) -{ - Handle_Team(control_group_index, 1); - - return true; -} - -/************************************************************************************************** -* DLLExportClass::Toggle_Control_Group_Selection -* -* History: -**************************************************************************************************/ -bool DLLExportClass::Toggle_Control_Group_Selection(unsigned char control_group_index) -{ - Handle_Team(control_group_index, 0); - - return true; -} - - - -/************************************************************************************************** -* DLLExportClass::Get_Shroud_State -- Get a snapshot of the shroud for the given player -* -* In: -* -* Out: -* -* -* -* History: 4/12/2019 3:44PM - ST -**************************************************************************************************/ -bool DLLExportClass::Get_Shroud_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - CNCShroudStruct *shroud = (CNCShroudStruct*) buffer_in; - - unsigned int memory_needed = sizeof(*shroud) + 256; // Base amount needed. Will need more depending on how many entries there are - - int entry_index = 0; - - /* - ** - ** Based loosely on DisplayClass::Redraw_Icons - ** - ** - */ - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - for (int y = 0 ; y < map_cell_height ; y++) { - for (int x = 0 ; x < map_cell_width ; x++) { - CELL cell = XY_Cell(map_cell_x+x, map_cell_y+y); - COORDINATE coord = Cell_Coord(cell) & 0xFF00FF00L; - - memory_needed += sizeof(CNCShroudEntryStruct); - if (memory_needed >= buffer_size) { - return false; - } - - int xpixel; - int ypixel; - - Map.Coord_To_Pixel(coord, xpixel, ypixel); - - CellClass * cellptr = &Map[Coord_Cell(coord)]; - - CNCShroudEntryStruct &shroud_entry = shroud->Entries[entry_index]; - - shroud_entry.IsVisible = cellptr->Is_Visible(PlayerPtr); - shroud_entry.IsMapped = cellptr->Is_Mapped(PlayerPtr); - shroud_entry.IsJamming = false; - shroud_entry.ShadowIndex = -1; - - if (!shroud_entry.IsMapped) { - if (shroud_entry.IsVisible) { - shroud_entry.ShadowIndex = (char) Map.Cell_Shadow(cell, PlayerPtr); - } - } - - entry_index++; - } - } - - shroud->Count = entry_index; - - return true; -} - - - - -/************************************************************************************************** -* DLLExportClass::Get_Occupier_State -- Get the occupier state for this player -* -* In: -* -* Out: -* -* -* -* History: 10/25/2019 - SKY -**************************************************************************************************/ -bool DLLExportClass::Get_Occupier_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - UNREFERENCED_PARAMETER(player_id); - - CNCOccupierHeaderStruct* occupiers = (CNCOccupierHeaderStruct*)buffer_in; - CNCOccupierEntryHeaderStruct* entry = reinterpret_cast(occupiers + 1U); - occupiers->Count = 0; - - unsigned int memory_needed = sizeof(CNCOccupierHeaderStruct); - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - for (int y = 0; y < map_cell_height; y++) { - for (int x = 0; x < map_cell_width; x++, occupiers->Count++) { - CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); - CellClass * cellptr = &Map[cell]; - - int occupier_count = 0; - ObjectClass* const cell_occupier = cellptr->Cell_Occupier(); - for (ObjectClass* optr = cell_occupier; optr != NULL; optr = optr->Next) { - if (optr->IsActive) { - occupier_count++; - } - } - - memory_needed += sizeof(CNCOccupierEntryHeaderStruct) + (sizeof(CNCOccupierObjectStruct) * occupier_count); - if (memory_needed >= buffer_size) { - return false; - } - - CNCOccupierObjectStruct* occupier = reinterpret_cast(entry + 1U); - entry->Count = occupier_count; - - for (ObjectClass* optr = cell_occupier; optr != NULL; optr = optr->Next) { - if (optr->IsActive) { - CNCObjectStruct object; - Convert_Type(optr, object); - occupier->Type = object.Type; - occupier->ID = object.ID; - occupier++; - } - } - - entry = reinterpret_cast(occupier + 1U); - } - } - - return true; -} - - - - -/************************************************************************************************** -* DLLExportClass::Get_Player_Info_State -- Get the multiplayer info for this player -* -* In: -* -* Out: -* -* -* -* History: 4/22/2019 10:33AM - ST -**************************************************************************************************/ -bool DLLExportClass::Get_Player_Info_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return false; - } - - CNCPlayerInfoStruct *player_info = (CNCPlayerInfoStruct*) buffer_in; - - unsigned int memory_needed = sizeof(*player_info) + 32; // A little extra for no reason - - if (memory_needed >= buffer_size) { - return false; - } - - player_info->GlyphxPlayerID = 0; - - if (PlayerPtr == NULL) { - return false;; - } - - strncpy(&player_info->Name[0], MPlayerNames[CurrentLocalPlayerIndex], MPLAYER_NAME_MAX); - player_info->Name[MPLAYER_NAME_MAX - 1] = 0; // Make sure it's terminated - player_info->House = PlayerPtr->Class->House; - player_info->AllyFlags = PlayerPtr->Get_Ally_Flags(); - player_info->ColorIndex = MPlayerID_To_ColorIndex(MPlayerID[CurrentLocalPlayerIndex]); - player_info->GlyphxPlayerID = player_id; - player_info->HomeCellX = Cell_X(MultiplayerStartPositions[CurrentLocalPlayerIndex]); - player_info->HomeCellY = Cell_Y(MultiplayerStartPositions[CurrentLocalPlayerIndex]); - player_info->IsDefeated = PlayerPtr->IsDefeated; - player_info->SpiedPowerFlags = 0U; - player_info->SpiedMoneyFlags = 0U; - player_info->IsRadarJammed = false; - - // Populate selection info - if (CurrentObject.Count() > 0) { - CNCObjectStruct object; - Convert_Type(CurrentObject[0], object); - player_info->SelectedID = object.ID; - player_info->SelectedType = object.Type; - - const int left = Map.MapCellX; - const int right = Map.MapCellX + Map.MapCellWidth - 1; - const int top = Map.MapCellY; - const int bottom = Map.MapCellY + Map.MapCellHeight - 1; - - // Use first object with a weapon, or first object if none - ObjectClass* action_object = nullptr; - for (int i = 0; i < CurrentObject.Count(); ++i) { - ObjectClass* object = CurrentObject[i]; - if (object->Is_Techno()) { - TechnoClass* techno = (TechnoClass*)object; - if (techno->Techno_Type_Class()->Primary != WEAPON_NONE || techno->Techno_Type_Class()->Secondary != WEAPON_NONE) { - action_object = object; - break; - } - } - } - if (action_object == nullptr) { - action_object = CurrentObject[0]; - } - - int index = 0; - for (int y = top; y <= bottom; ++y) { - for (int x = left; x <= right; ++x, ++index) { - Convert_Action_Type(action_object->What_Action(XY_Cell(x, y)), (CurrentObject.Count() == 1) ? action_object : NULL, As_Target(XY_Cell(x, y)), player_info->ActionWithSelected[index]); - } - } - - player_info->ActionWithSelectedCount = Map.MapCellWidth * Map.MapCellHeight; - } - else { - player_info->SelectedID = -1; - player_info->SelectedType = UNKNOWN; - player_info->ActionWithSelectedCount = 0U; - } - - // Screen shake - player_info->ScreenShake = PlayerPtr->ScreenShakeTime; - - return true; -}; - - - - -/************************************************************************************************** -* DLLExportClass::Get_Dynamic_Map_State -- Get a snapshot of the smudges and overlays on the terrain -* -* In: -* -* Out: -* -* -* -* History: 2/8/2019 10:45AM - ST -**************************************************************************************************/ -bool DLLExportClass::Get_Dynamic_Map_State(uint64 player_id, unsigned char *buffer_in, unsigned int buffer_size) -{ - /* - ** Get the player for this... - */ - player_id; - - static int _call_count = 0; - - CNCDynamicMapStruct *dynamic_map = (CNCDynamicMapStruct*) buffer_in; - - unsigned int memory_needed = sizeof(*dynamic_map) + 256; // Base amount needed. Will need more depending on how many entries there are - - int entry_index = 0; - - /* - ** - ** Based loosely on DisplayClass::Redraw_Icons - ** - ** - */ - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - int cell_index = 0; - - bool debug_output = false; - //if (_call_count == 20) { - //debug_output = true; - //} - - // Need to ignore view constraints for dynamic map updates, so the radar map - // has the latest tiberium state for cells outside the tactical view - DLLExportClass::Adjust_Internal_View(true); - - for (int y = 0 ; y < map_cell_height ; y++) { - for (int x = 0 ; x < map_cell_width ; x++) { - CELL cell = XY_Cell(map_cell_x+x, map_cell_y+y); - COORDINATE coord = Cell_Coord(cell) & 0xFF00FF00L; - - memory_needed += sizeof(CNCDynamicMapEntryStruct) * 2; - if (memory_needed >= buffer_size) { - return false; - } - - /* - ** Only cells flagged to be redraw are examined. - */ - //if (In_View(cell) && Is_Cell_Flagged(cell)) { - int xpixel; - int ypixel; - - if (Map.Coord_To_Pixel(coord, xpixel, ypixel)) { - CellClass * cellptr = &Map[Coord_Cell(coord)]; - - /* - ** If there is a portion of the underlying icon that could be visible, - ** then draw it. Also draw the cell if the shroud is off. - */ - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER || cellptr->IsVisible || Debug_Unshroud) { - Cell_Class_Draw_It(dynamic_map, entry_index, cellptr, xpixel, ypixel, debug_output); - } - - /* - ** If any cell is not fully mapped, then flag it so that the shadow drawing - ** process will occur. Only draw the shadow if Debug_Unshroud is false. - */ - //if (!cellptr->IsMapped && !Debug_Unshroud) { - // IsShadowPresent = true; - //} - } - //} - } - } - - if (entry_index) { - _call_count++; - } - - dynamic_map->Count = entry_index; - dynamic_map->VortexActive = false; - - return true; -} - - - - - - -/************************************************************************************************** -* DLLExportClass::Cell_Class_Draw_It -- Go through the motions of drawing a cell to get the smudge and overlay info -* -* In: -* -* Out: -* -* -* -* History: 2/8/2019 11:09AM - ST -**************************************************************************************************/ -void DLLExportClass::Cell_Class_Draw_It(CNCDynamicMapStruct *dynamic_map, int &entry_index, CellClass *cell_ptr, int xpixel, int ypixel, bool debug_output) -{ - /* - ** - ** Based on CellClass::Draw_It and SmudgeTypeClass::Draw_It - ** - ** - */ - - CELL cell = cell_ptr->Cell_Number(); - - /* - ** Redraw any smudge. - */ - if (cell_ptr->Smudge != SMUDGE_NONE) { - //SmudgeTypeClass::As_Reference(Smudge).Draw_It(x, y, SmudgeData); - - const SmudgeTypeClass &smudge_type = SmudgeTypeClass::As_Reference(cell_ptr->Smudge); - - if (smudge_type.Get_Image_Data() != NULL) { - - if (debug_output) { - IsTheaterShape = true; - Debug_Write_Shape_Type(&smudge_type, 0); - IsTheaterShape = false; - } - - CNCDynamicMapEntryStruct &smudge_entry = dynamic_map->Entries[entry_index++]; - - strncpy(smudge_entry.AssetName, smudge_type.IniName, CNC_OBJECT_ASSET_NAME_LENGTH); - smudge_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - smudge_entry.Type = (short) cell_ptr->Smudge; - smudge_entry.Owner = (char)cell_ptr->Owner; - smudge_entry.DrawFlags = SHAPE_WIN_REL; // Looks like smudges are drawn top left - smudge_entry.PositionX = xpixel; - smudge_entry.PositionY = ypixel; - smudge_entry.Width = Get_Build_Frame_Width(smudge_type.Get_Image_Data()); - smudge_entry.Height = Get_Build_Frame_Height(smudge_type.Get_Image_Data()); - smudge_entry.CellX = Cell_X(cell); - smudge_entry.CellY = Cell_Y(cell); - smudge_entry.ShapeIndex = cell_ptr->SmudgeData; - smudge_entry.IsSmudge = true; - smudge_entry.IsOverlay = false; - smudge_entry.IsResource = false; - smudge_entry.IsSellable = false; - smudge_entry.IsTheaterShape = true; // Smudges are always theater-specific - smudge_entry.IsFlag = false; - } - } - - /* - ** Draw the overlay object. - */ - if (cell_ptr->Overlay != OVERLAY_NONE) { - //OverlayTypeClass const & otype = OverlayTypeClass::As_Reference(Overlay); - //IsTheaterShape = (bool)otype.IsTheater; - //CC_Draw_Shape(otype.Get_Image_Data(), OverlayData, (x+(CELL_PIXEL_W>>1)), (y+(CELL_PIXEL_H>>1)), WINDOW_TACTICAL, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST, NULL, Map.UnitShadow); - //IsTheaterShape = false; - - const OverlayTypeClass &overlay_type = OverlayTypeClass::As_Reference(cell_ptr->Overlay); - - if (overlay_type.Get_Image_Data() != NULL) { - - CNCDynamicMapEntryStruct &overlay_entry = dynamic_map->Entries[entry_index++]; - - - if (debug_output) { - IsTheaterShape = (bool)overlay_type.IsTheater; - Debug_Write_Shape_Type(&overlay_type, 0); - IsTheaterShape = false; - } - - strncpy(overlay_entry.AssetName, overlay_type.IniName, CNC_OBJECT_ASSET_NAME_LENGTH); - overlay_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - overlay_entry.Type = (short)cell_ptr->Overlay; - overlay_entry.Owner = (char) cell_ptr->Owner; - overlay_entry.DrawFlags = SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST; // Looks like overlays are drawn centered and translucent - overlay_entry.PositionX = xpixel + (CELL_PIXEL_W>>1); - overlay_entry.PositionY = ypixel + (CELL_PIXEL_H>>1); - overlay_entry.Width = Get_Build_Frame_Width(overlay_type.Get_Image_Data()); - overlay_entry.Height = Get_Build_Frame_Height(overlay_type.Get_Image_Data()); - overlay_entry.CellX = Cell_X(cell); - overlay_entry.CellY = Cell_Y(cell); - overlay_entry.ShapeIndex = cell_ptr->OverlayData; - overlay_entry.IsSmudge = false; - overlay_entry.IsOverlay = true; - overlay_entry.IsResource = overlay_entry.Type >= OVERLAY_TIBERIUM1 && overlay_entry.Type <= OVERLAY_TIBERIUM12; - overlay_entry.IsSellable = overlay_entry.Type >= OVERLAY_SANDBAG_WALL && overlay_entry.Type <= OVERLAY_WOOD_WALL; - overlay_entry.IsTheaterShape = (bool)overlay_type.IsTheater; - overlay_entry.IsFlag = false; - } - } - - - if (cell_ptr->IsFlagged) { - - const void* image_data = MixFileClass::Retrieve("FLAGFLY.SHP"); - if (image_data != NULL) { - - CNCDynamicMapEntryStruct &flag_entry = dynamic_map->Entries[entry_index++]; - - strncpy(flag_entry.AssetName, "FLAGFLY", CNC_OBJECT_ASSET_NAME_LENGTH); - flag_entry.AssetName[CNC_OBJECT_ASSET_NAME_LENGTH - 1] = 0; - flag_entry.Type = -1; - flag_entry.Owner = cell_ptr->Owner; - flag_entry.DrawFlags = SHAPE_CENTER|SHAPE_GHOST|SHAPE_FADING; - flag_entry.PositionX = xpixel + (ICON_PIXEL_W / 2); - flag_entry.PositionY = ypixel + (ICON_PIXEL_H / 2); - flag_entry.Width = Get_Build_Frame_Width(image_data); - flag_entry.Height = Get_Build_Frame_Height(image_data); - flag_entry.CellX = Cell_X(cell); - flag_entry.CellY = Cell_Y(cell); - flag_entry.ShapeIndex = Frame % 14; - flag_entry.IsSmudge = false; - flag_entry.IsOverlay = false; - flag_entry.IsResource = false; - flag_entry.IsSellable = false; - flag_entry.IsTheaterShape = false; - flag_entry.IsFlag = true; - } - - } - -} - - - - -/************************************************************************************************** -* DLLExportClass::Glyphx_Queue_AI -- Special queue processing for Glyphx multiplayer mode -* -* In: -* -* Out: -* -* -* -* History: 3/12/2019 10:52AM - ST -**************************************************************************************************/ -void DLLExportClass::Glyphx_Queue_AI(void) -{ - - //------------------------------------------------------------------------ - // Move events from the OutList (events generated by this player) into the - // DoList (the list of events to execute). - //------------------------------------------------------------------------ - while (OutList.Count) { - OutList.First().IsExecuted = false; - if (!DoList.Add(OutList.First())) { - ; - } - OutList.Next(); - } - - /* - ** Based on Execute_DoList in queue.cpp - ** - ** The events have the ID of the player encoded in them, so no special per-player processing should be needed. - ** When the event is created, the 'local player' is assumed to be the originator of the event, so PlayerPtr will need - ** to be swapped out to represent the real originating player prior to any events being created as a result of GlyphX input - ** - ** ST - 3/12/2019 10:51AM - */ - - for (int i = 0; i < MPlayerCount; i++) { - - HousesType house; - HouseClass *housep; - - house = MPlayerHouses [i]; - housep= HouseClass::As_Pointer (house); - - //..................................................................... - // If for some reason this house doesn't exist, skip it. - // Also, if this house has exited the game, skip it. (The user can - // generate events after he exits, because the exit event is scheduled - // at least FrameSendRate*3 frames ahead. If one system gets these - // packets & another system doesn't, they'll go out of sync because - // they aren't checking the CommandCount for that house, since that - // house isn't connected any more.) - //..................................................................... - if (!housep){ - continue; - } - - if (!housep->IsHuman){ - continue; - } - - //..................................................................... - // Loop through all events - //..................................................................... - for (int j = 0; j < DoList.Count; j++) { - - if (!DoList[j].IsExecuted && (unsigned)Frame >= DoList[j].Frame) { - DoList[j].Execute(); - - //............................................................... - // Mark this event as executed. - //............................................................... - DoList[j].IsExecuted = 1; - } - } - } - - - - - //------------------------------------------------------------------------ - // Clean out the DoList - //------------------------------------------------------------------------ - while (DoList.Count) { - - //..................................................................... - // Discard events that have been executed, OR it's too late to execute. - // (This happens if another player exits the game; he'll leave FRAMEINFO - // events lying around in my queue. They won't have been "executed", - // because his IPX connection was destroyed.) - //..................................................................... - if ( (DoList.First().IsExecuted) || ((unsigned)Frame > DoList.First().Frame) ) { - DoList.Next(); - } - else { - break; - } - } - -} - - - - - -/************************************************************************************************** -* DLLExportClass::Reset_Sidebars -- Init the multiplayer sidebars -* -* In: -* -* Out: -* -* -* -* History: 3/14/2019 3:10PM - ST -**************************************************************************************************/ -void DLLExportClass::Reset_Sidebars(void) -{ - for (int i=0 ; iClass->House); - } - return true; - } - - /* - ** C&C relies a lot on PlayerPtr, which is a pointer to the 'local' player's house. Historically, in a peer-to-peer - ** multiplayer game, each player's PlayerPtr pointed to their own local player. - ** - ** Since much of the IO logic depends on PlayerPtr being the player performing the action, we need to set PlayerPtr - ** correctly depending on which player generated input or needs output - */ - - for (int i=0 ; iClass->House); - CurrentLocalPlayerIndex = i; - - return true; - } - } - - return false; -} - - - -/************************************************************************************************** -* DLLExportClass::Reset_Player_Context -- Clear out old player context data -* -* In: -* -* Out: -* -* -* -* History: 4/16/2019 10:36AM - ST -**************************************************************************************************/ -void DLLExportClass::Reset_Player_Context(void) -{ - for (int i=0 ; iIs_Techno()) { - return; - } - - TechnoClass *tech = static_cast(object); - - //HousesType house = tech->House->Class->House; - DLLExportClass::Logic_Switch_Player_Context(tech->House); -} - - - -/************************************************************************************************** -* Logic_Switch_Player_Context -- Called when the internal game locic needs to switch player context -* -* In: -* -* Out: -* -* -* -* History: 4/17/2019 9:45AM - ST -**************************************************************************************************/ -void Logic_Switch_Player_Context(HouseClass *object) -{ - DLLExportClass::Logic_Switch_Player_Context(object); -} - - -/************************************************************************************************** -* DLLExportClass::Logic_Switch_Player_Context -- Called when the internal game locic needs to switch player context -* -* In: -* -* Out: -* -* -* -* History: 4/17/2019 9:45AM - ST -**************************************************************************************************/ -void DLLExportClass::Logic_Switch_Player_Context(HouseClass *house) -{ - if (GameToPlay == GAME_NORMAL) { - CurrentObject.Set_Active_Context(PlayerPtr->Class->House); - return; - } - - if (house == NULL) { - return; - } - - /* - ** C&C relies a lot on PlayerPtr, which is a pointer to the 'local' player's house. Historically, in a peer-to-peer - ** multiplayer game, each player's PlayerPtr pointed to their own local player. - ** - ** Since much of the IO logic depends on PlayerPtr being the player performing the action, we need to set PlayerPtr - ** correctly depending on which player generated input or needs output - */ - - HousesType house_type = house->Class->House; - - for (int i=0 ; iClass->House); - CurrentLocalPlayerIndex = i; - - return; - } - } -} - - -/************************************************************************************************** -* DLLExportClass::Calculate_Start_Positions -- Calculate the initial view positions for the players -* -* In: -* -* Out: -* -* -* -* History: 4/16/2019 6/12/2019 3:00PM - ST -**************************************************************************************************/ -void DLLExportClass::Calculate_Start_Positions(void) -{ - if (GameToPlay == GAME_NORMAL) { - MultiplayerStartPositions[0] = Views[0]; - return; - } - - HouseClass *player_ptr = PlayerPtr; - - ScenarioInit++; - COORDINATE old_tac = Map.TacticalCoord; - for (int i=0 ; iClass->House; - - for (int i=0 ; iIsActive) { - GlyphX_Debug_Print("DLLExportClass::Repair -- trying to repair a non-active building"); - } else { - - if (building && building->Can_Repair() && building->House && building->House->Class->House == PlayerPtr->Class->House) - { - building->Repair(-1); - } - } - } - } -} - -/************************************************************************************************** -* DLLExportClass::Sell_Mode -- Starts the player's sell mode. All it does here is unselect all units. -* -* In: -* -* Out: -* -* -* -* History: 5/1/2019 - LLL -**************************************************************************************************/ -void DLLExportClass::Sell_Mode(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - Unselect_All(); -} - -/************************************************************************************************** -* DLLExportClass::Sell -- Sell's a player's speceific building. -* -* In: -* -* Out: -* -* -* -* History: 5/1/2019 - LLL -**************************************************************************************************/ -void DLLExportClass::Sell(uint64 player_id, int object_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - TARGET target = Build_Target(KIND_BUILDING, object_id); - if (target != TARGET_NONE) - { - BuildingClass* building = As_Building(target); - if (building) { - if (!building->IsActive) { - GlyphX_Debug_Print("DLLExportClass::Sell -- trying to sell a non-active building"); - } else { - if (building->House && building->House->Class->House == PlayerPtr->Class->House) - { - building->Sell_Back(1); - } - } - } - } -} - - - -/************************************************************************************************** -* DLLExportClass::Repair_Sell_Cancel -- Ends the player's repair or sell mode. Doesn't do anything right now. -* -* In: -* -* Out: -* -* -* -* History: 5/1/2019 - LLL -**************************************************************************************************/ -void DLLExportClass::Repair_Sell_Cancel(uint64 player_id) -{ - //OutputDebugString("Repair_Sell_Cancel\n"); -} - -/************************************************************************************************** -* DLLExportClass::Scatter_Selected -- Scatter the selected units -* -* In: -* -* Out: -* -* -* -* History: 10/15/2019 - SKY -**************************************************************************************************/ -void DLLExportClass::Scatter_Selected(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - if (CurrentObject.Count()) { - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass const * tech = CurrentObject[index]; - - if (tech && tech->Can_Player_Move()) { - OutList.Add(EventClass(EventClass::SCATTER, tech->As_Target())); - } - } - } -} - -/************************************************************************************************** -* DLLExportClass::Select_Next_Unit -* -* History: 03.02.2020 MBL -**************************************************************************************************/ -void DLLExportClass::Select_Next_Unit(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - ObjectClass* obj = Map.Next_Object(CurrentObject.Count() ? CurrentObject[0] : NULL); - if (obj) { - Unselect_All(); - obj->Select(); - - COORDINATE center = Map.Center_Map(); - Map.Flag_To_Redraw(true); - if (center) { - On_Center_Camera(PlayerPtr, Coord_X(center), Coord_Y(center)); - } - } -} - -/************************************************************************************************** -* DLLExportClass::Select_Previous_Unit -* -* History: 03.02.2020 MBL -**************************************************************************************************/ -void DLLExportClass::Select_Previous_Unit(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - ObjectClass* obj = Map.Prev_Object(CurrentObject.Count() ? CurrentObject[0] : NULL); - if (obj) { - Unselect_All(); - obj->Select(); - - COORDINATE center = Map.Center_Map(); - Map.Flag_To_Redraw(true); - if (center) { - On_Center_Camera(PlayerPtr, Coord_X(center), Coord_Y(center)); - } - } -} - -/************************************************************************************************** -* DLLExportClass::Selected_Guard_Mode -* -* History: 03.03.2020 MBL -**************************************************************************************************/ -void DLLExportClass::Selected_Guard_Mode(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - if (CurrentObject.Count()) { - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass const * tech = CurrentObject[index]; - - if (tech && tech->Can_Player_Fire()) { - if (tech->Can_Player_Move()) { - OutList.Add(EventClass(tech->As_Target(), MISSION_GUARD_AREA)); - } else { - OutList.Add(EventClass(tech->As_Target(), MISSION_GUARD)); - } - } - } - } -} - -/************************************************************************************************** -* DLLExportClass::Selected_Stop -* -* History: 03.03.2020 MBL -**************************************************************************************************/ -void DLLExportClass::Selected_Stop(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - // Copied from TiberianDawn/Conquer.cpp - Keyboard_Process() with VK_S - if (CurrentObject.Count()) { - for (int index = 0; index < CurrentObject.Count(); index++) { - ObjectClass const * tech = CurrentObject[index]; - - if (tech && (tech->Can_Player_Move() || (tech->Can_Player_Fire() && - tech->What_Am_I() != RTTI_BUILDING))) { - OutList.Add(EventClass(EventClass::IDLE, tech->As_Target())); - } - } - } -} - - -/************************************************************************************************** -* DLLExportClass::Units_Queued_Movement_Toggle -* -* History: 03.03.2020 MBL -**************************************************************************************************/ -void DLLExportClass::Units_Queued_Movement_Toggle(uint64 /*player_id*/, bool /*toggle*/) -{ - // Currently Red Alert only but stubbed in support in case we add to Tiberian Dawn later -} - -/************************************************************************************************** -* DLLExportClass::Team_Units_Formation_Toggle_On -* -* History: 03.03.2020 MBL -**************************************************************************************************/ -void DLLExportClass::Team_Units_Formation_Toggle_On(uint64 player_id) -{ - /* - ** Get the player for this... - */ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - // Red Alert only at this time, unless we do some updates to support in Tiberian Dawn - #if 0 - Toggle_Formation(); // Conquer.cpp - #endif -} - - -/************************************************************************************************** -* CNC_Handle_Debug_Request -- Process a debug input request -* -* In: -* -* -* Out: -* -* -* History: 1/7/2019 5:20PM - ST -**************************************************************************************************/ -extern "C" __declspec(dllexport) void __cdecl CNC_Handle_Debug_Request(DebugRequestEnum debug_request_type, uint64 player_id, const char *object_name, int x, int y, bool unshroud, bool enemy) -{ - if (!DLLExportClass::Set_Player_Context(player_id)) { - return; - } - - switch (debug_request_type) { - - case DEBUG_REQUEST_SPAWN_OBJECT: - { - DLLExportClass::Debug_Spawn_Unit(object_name, x, y, enemy); - } - break; - - case DEBUG_REQUEST_FORCE_CRASH: - Debug_Force_Crash = true; - break; - - case DEBUG_REQUEST_KILL_OBJECT: - if (strcmp(object_name, "HEAL") == 0) { - DLLExportClass::Debug_Heal_Unit(x, y); - } - else { - DLLExportClass::Debug_Kill_Unit(x, y); - } - break; - - case DEBUG_REQUEST_END_GAME: - { - bool win = true; - - const char lose[] = "LOSE"; - if (strcmp(lose, object_name) == 0) { - win = false; - } - - PlayerWins = win; - PlayerLoses = !win; - } - break; - - case DEBUG_REQUEST_UNSHROUD: - Debug_Unshroud = unshroud; - Map.Flag_To_Redraw(true); - break; - - case DEBUG_REQUEST_SUPERWEAPON_RECHARGE: - PlayerPtr->IonCannon.Forced_Charge(true); - PlayerPtr->NukeStrike.Forced_Charge(true); - PlayerPtr->AirStrike.Forced_Charge(true); - break; - - case DEBUG_REQUEST_END_PRODUCTION: - { - for (int index = 0; index < Factories.Count(); index++) { - FactoryClass* factory = Factories.Ptr(index); - if (factory->Get_House()->IsHuman) { - Factories.Ptr(index)->Force_Complete(); - } - } - } - break; - - case DEBUG_REQUEST_ADD_RESOURCES: - { - if (object_name) { - int amount = atoi(object_name); - PlayerPtr->Credits += amount; - if (PlayerPtr->Credits < 0) { - PlayerPtr->Credits = 0; - } - } - } - break; - - case DEBUG_REQUEST_UNLOCK_BUILDABLES: - PlayerPtr->DebugUnlockBuildables = !PlayerPtr->DebugUnlockBuildables; - PlayerPtr->IsRecalcNeeded = true; - break; - - default: - break; - } - - -} - - -/************************************************************************************************** -* DLLExportClass::Debug_Spawn_All -- Debug spawn all buildable units and structures -* -* In: Object to unlimbo , x & y cell positions -* -* -* Out: True if unlimbo succeeded -* -* -* -* History: 1/22/2020 2:57PM - ST -**************************************************************************************************/ -bool DLLExportClass::Try_Debug_Spawn_Unlimbo(TechnoClass *techno, int &cell_x, int &cell_y) -{ - if (techno) { - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_right = map_cell_x + Map.MapCellWidth; - int map_cell_bottom = map_cell_y + Map.MapCellHeight; - - map_cell_right = min(map_cell_right, cell_x + 26); // Generally try to prevent the objects from spawing off the right of the screen - - int try_x = cell_x; - int try_y = cell_y; - - while (try_y < map_cell_bottom) { - - CELL cell = XY_Cell(try_x, try_y); - - if (techno->Unlimbo(Cell_Coord(cell))) { - - try_x++; - if (try_x > map_cell_right - 2) { - try_x = cell_x; //map_cell_x + 2; - try_y++; - } - - cell_x = try_x; - cell_y = try_y; - return true; - } - - try_x++; - if (try_x > map_cell_right - 2) { - try_x = cell_x; //map_cell_x + 2; - try_y++; - } - } - - cell_x = try_x; - cell_y = try_y; - } - - return false; -} - - -/************************************************************************************************** -* DLLExportClass::Debug_Spawn_All -- Debug spawn all buildable units and structures -* -* In: -* -* Out: -* -* -* -* History: 1/22/2020 2:57PM - ST -**************************************************************************************************/ -void DLLExportClass::Debug_Spawn_All(int x, int y) -{ - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - - int map_cell_bottom = map_cell_y + Map.MapCellHeight; - - int origin_x = map_cell_x + 2; - int origin_y = map_cell_y + 2; - - if (x != 0 || y != 0) { - CELL screen_cell = Coord_Cell(Map.Pixel_To_Coord(x, y)); - origin_x = Cell_X(screen_cell); - origin_y = Cell_Y(screen_cell); - } - - int try_x = origin_x; - int try_y = origin_y; - - HousesType house = PlayerPtr->Class->House; - - for (StructType sindex = STRUCT_FIRST; sindex < STRUCT_COUNT; sindex++) { - BuildingTypeClass const & building_type = BuildingTypeClass::As_Reference(sindex); - - if (building_type.IsBuildable) { - - BuildingClass * building = new BuildingClass(building_type, house); - if (building) { - - try_x = origin_x; - try_y = origin_y; - - while (try_y < map_cell_bottom) { - if (Try_Debug_Spawn_Unlimbo(building, try_x, try_y)) { - break; - } - } - } - } - } - - - for (UnitType index = UNIT_FIRST; index < UNIT_COUNT; index++) { - UnitTypeClass const & unit_type = UnitTypeClass::As_Reference(index); - - /* - ** Fetch the sidebar cameo image for this building. - */ - if (unit_type.IsBuildable) { - - UnitClass * unit = (UnitClass*) unit_type.Create_One_Of(PlayerPtr); - if (unit) { - - try_x = origin_x; - try_y = origin_y; - - while (try_y < map_cell_bottom) { - if (Try_Debug_Spawn_Unlimbo(unit, try_x, try_y)) { - break; - } - } - } - } - } - - - for (InfantryType index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - InfantryTypeClass const &infantry_type = InfantryTypeClass::As_Reference(index); - - /* - ** Fetch the sidebar cameo image for this building. - */ - if (infantry_type.IsBuildable) { - - InfantryClass * inf = (InfantryClass*) infantry_type.Create_One_Of(PlayerPtr); - if (inf) { - - try_x = origin_x; - try_y = origin_y; - - while (try_y < map_cell_bottom) { - if (Try_Debug_Spawn_Unlimbo(inf, try_x, try_y)) { - break; - } - } - } - } - } - - for (AircraftType index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) { - AircraftTypeClass const &aircraft_type = AircraftTypeClass::As_Reference(index); - - /* - ** Fetch the sidebar cameo image for this building. - */ - if (aircraft_type.IsBuildable) { - - AircraftClass * air = (AircraftClass*) aircraft_type.Create_One_Of(PlayerPtr); - if (air) { - - try_x = origin_x; - try_y = origin_y; - - while (try_y < map_cell_bottom) { - if (Try_Debug_Spawn_Unlimbo(air, try_x, try_y)) { - break; - } - } - } - } - } - -} - - - - - -/************************************************************************************************** -* DLLExportClass::Debug_Spawn_Unit -- Debug spawn a unit at the specified location -* -* In: -* -* Out: -* -* -* -* History: 3/14/2019 3:20PM - ST -**************************************************************************************************/ -void DLLExportClass::Debug_Spawn_Unit(const char *object_name, int x, int y, bool enemy) -{ - if (object_name == NULL) { - return; - } - - if (strlen(object_name) == 0) { - return; - } - - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); - - HousesType house = PlayerPtr->Class->House; - - /* - ** Place all? - */ - if (stricmp(object_name, "ALLOBJECTS") == 0) { - Debug_Spawn_All(x, y); - return; - } - - /* - ** If this is for the enemy, find the enemy with the most stuff - */ - - if (enemy) { - unsigned max_count = 0; - for (int i = 0; i < Houses.Count(); ++i) { - const HouseClass* player = Houses.Ptr(i); - const unsigned count = player->CurUnits + player->CurBuildings + player->CurInfantry + player->CurAircraft; - if (!PlayerPtr->Is_Ally(player) && (count >= max_count)) { - house = player->Class->House; - max_count = count; - } - } - } - - /* - ** What is this thing? - */ - - StructType structure_type = BuildingTypeClass::From_Name(object_name); - if (structure_type != STRUCT_NONE) { - - BuildingClass * building = new BuildingClass(structure_type, house); - if (building) { - if (!building->Unlimbo(Cell_Coord(cell))) { - delete building; - } - } - -#if (0) - Map.PendingObject = &BuildingTypeClass::As_Reference(structure_type); - Map.PendingHouse = PlayerPtr->ActLike; - Map.PendingObjectPtr = Map.PendingObject->Create_One_Of(PlayerPtr); - if (Map.PendingObjectPtr) { - Map.Set_Cursor_Pos(); - Map.Set_Cursor_Shape(Map.PendingObject->Occupy_List()); - - //OutList.Add(EventClass(EventClass::PLACE, RTTI_BUILDING, (CELL)(cell + Map.ZoneOffset))); - } -#endif - return; - } - - - UnitType unit_type = UnitTypeClass::From_Name(object_name); - if (unit_type != UNIT_NONE) { - - UnitClass * unit = new UnitClass(unit_type, house); - if (unit) { - unit->Unlimbo(Map.Pixel_To_Coord(x, y), DIR_N); - } - - return; - } - - - InfantryType infantry_type = InfantryTypeClass::From_Name(object_name); - if (infantry_type != INFANTRY_NONE) { - - InfantryClass * inf = new InfantryClass(infantry_type, house); - if (inf) { - inf->Unlimbo(Map.Pixel_To_Coord(x, y), DIR_N); - } - return; - } - - AircraftType aircraft_type = AircraftTypeClass::From_Name(object_name); - if (aircraft_type != AIRCRAFT_NONE) { - - AircraftClass * air = new AircraftClass(aircraft_type, house); - if (air) { - air->Altitude = 0; - air->Unlimbo(Map.Pixel_To_Coord(x, y), DIR_N); - } - return; - } - - OverlayType overlay_type = OverlayTypeClass::From_Name(object_name); - if (overlay_type != OVERLAY_NONE) - { - new OverlayClass(overlay_type, cell); - return; - } -} - - -/************************************************************************************************** -* DLLExportClass::Debug_Kill_Unit -- Kill a unit at the specified location -* -* In: -* -* Out: -* -* -* -* History: 8/19/2019 3:09PM - ST -**************************************************************************************************/ -void DLLExportClass::Debug_Kill_Unit(int x, int y) -{ - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); - - CellClass * cellptr = &Map[cell]; - - if (cellptr) { - ObjectClass *obj = cellptr->Cell_Object(); - static const int debug_damage = 1000; - if (obj) { - int damage = debug_damage; - obj->Take_Damage(damage, 0, WARHEAD_HE, 0); - } else { - if (cellptr->Overlay != OVERLAY_NONE) { - OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay); - if (optr->IsTiberium) { - cellptr->Reduce_Tiberium(1); - } - if (optr->IsWall) { - Map[cell].Reduce_Wall(debug_damage); - } - } - } - } -} - -void DLLExportClass::Debug_Heal_Unit(int x, int y) -{ - COORDINATE coord = Map.Pixel_To_Coord(x, y); - CELL cell = Coord_Cell(coord); - - CellClass * cellptr = &Map[cell]; - - if (cellptr) { - ObjectClass *obj = cellptr->Cell_Object(); - if (obj) { - obj->Strength = obj->Class_Of().MaxStrength; - } - else { - if (cellptr->Overlay != OVERLAY_NONE) { - OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay); - if (optr->IsTiberium) { - const int cellcount = (int)FACING_COUNT + 1; - CellClass* cells[cellcount]; - cells[0] = cellptr; - for (FacingType index = FACING_N; index < FACING_COUNT; index++) { - cells[(int)index + 1] = cellptr->Adjacent_Cell(index); - } - - for (int index = 0; index < cellcount; index++) { - CellClass *newcell = cells[index]; - - if (newcell && newcell->Cell_Object() == NULL) { - if (newcell->Land_Type() == LAND_CLEAR && newcell->Overlay == OVERLAY_NONE) { - switch (newcell->TType) { - case TEMPLATE_BRIDGE1: - case TEMPLATE_BRIDGE2: - case TEMPLATE_BRIDGE3: - case TEMPLATE_BRIDGE4: - break; - - default: - new OverlayClass(Random_Pick(OVERLAY_TIBERIUM1, OVERLAY_TIBERIUM12), newcell->Cell_Number()); - newcell->OverlayData = 1; - break; - - } - } - else if (newcell->Land_Type() == LAND_TIBERIUM) { - newcell->OverlayData = MIN(newcell->OverlayData + 1, 11); - newcell->Recalc_Attributes(); - newcell->Redraw_Objects(); - } - } - } - } - } - } - } -} - - - - -/************************************************************************************************** -* DLLExportClass::Legacy_Render_Enabled -- Is the legacy rendering enabled? -* -* In: -* -* Out: -* -* -* -* History: 4/15/2019 5:46PM - ST -**************************************************************************************************/ -bool DLLExportClass::Legacy_Render_Enabled(void) -{ - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - unsigned int num_humans = 0U; - for (int i = 0; i < MPlayerCount; ++i) { - HouseClass *player_ptr = HouseClass::As_Pointer(MPlayerHouses[i]); - if (player_ptr && player_ptr->IsHuman) { - if (++num_humans > 1) break; - } - } - return num_humans < 2; - } - - //return false; - return true; -} - - -/************************************************************************************************** -* DLLExportClass::Computer_Message -- Replacement for original Computer_Message function -* -* In: -* -* Out: -* -* -* -* History: 1/27/2020 1:42PM - ST -**************************************************************************************************/ -void DLLExportClass::Computer_Message(bool last_player_taunt) -{ - HousesType house; - HouseClass *ptr; - - HouseClass *ai_players[MAX_PLAYERS]; - int ai_player_count = 0; - - /*------------------------------------------------------------------------ - Find the computer house that the message will be from - ------------------------------------------------------------------------*/ - for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { - ptr = HouseClass::As_Pointer(house); - - if (!ptr || ptr->IsHuman || ptr->IsDefeated) { - continue; - } - - ai_players[ai_player_count++] = ptr; - } - - if (ai_player_count) { - int ai_player_index = 0; - if (ai_player_count > 1) { - ai_player_index = IRandom(0, ai_player_count - 1); - } - - int taunt_index; - if (last_player_taunt) { - taunt_index = 13; - } else { - taunt_index = IRandom(0,12); - } - - On_Message(ai_players[ai_player_index], "", 15.0f, MESSAGE_TYPE_COMPUTER_TAUNT, taunt_index); - } -} - - -/************************************************************************************************** -* DLLExportClass::Set_Special_Key_Flags -- -* -* In: -* -* Out: -* -* -* -* History: 6/27/2019 - JAS -**************************************************************************************************/ -void DLLExportClass::Set_Special_Key_Flags(unsigned char special_key_flags) -{ - SpecialKeyFlags[CurrentLocalPlayerIndex] = special_key_flags; -} - -/************************************************************************************************** -* DLLExportClass::Clear_Special_Key_Flags -- -* -* In: -* -* Out: -* -* -* -* History: 6/27/2019 - JAS -**************************************************************************************************/ -void DLLExportClass::Clear_Special_Key_Flags() -{ - SpecialKeyFlags[CurrentLocalPlayerIndex] = 0; -} - -/************************************************************************************************** -* DLLExportClass::Get_Input_Key_State -- -* -* In: -* -* Out: -* -* -* -* History: 6/27/2019 - JAS -**************************************************************************************************/ -bool DLLExportClass::Get_Input_Key_State(KeyNumType key) -{ - switch (key) - { - case KN_LCTRL: - return (SpecialKeyFlags[CurrentLocalPlayerIndex] & INPUT_SPECIAL_KEY_CTRL) != 0; - break; - case KN_LSHIFT: - return (SpecialKeyFlags[CurrentLocalPlayerIndex] & INPUT_SPECIAL_KEY_SHIFT) != 0; - break; - case KN_LALT: - return (SpecialKeyFlags[CurrentLocalPlayerIndex] & INPUT_SPECIAL_KEY_ALT) != 0; - break; - default: - break; - }; - - return false; - -} - - -/************************************************************************************************** -* Get_Input_Key_State -* -* History: 6/27/2019 - JAS -**************************************************************************************************/ -bool DLL_Export_Get_Input_Key_State(KeyNumType key) -{ - return DLLExportClass::Get_Input_Key_State(key); -} - - - -bool DLLSave(FileClass &file) -{ - return DLLExportClass::Save(file); -} - -bool DLLLoad(FileClass &file) -{ - return DLLExportClass::Load(file); -} - - -/************************************************************************************************** -* DLLExportClass::Save -- -* -* In: -* -* Out: -* -* -* -* History: 9/10/2019 10:24AM - ST -**************************************************************************************************/ -bool DLLExportClass::Save(FileClass & file) -{ - /* - ** Version first - */ - unsigned int version = CNC_DLL_API_VERSION; - if (file.Write(&version, sizeof(version)) != sizeof(version)) { - return false; - } - - if (file.Write(MultiplayerStartPositions, sizeof(MultiplayerStartPositions)) != sizeof(MultiplayerStartPositions)) { - return false; - } - - if (file.Write(GlyphxPlayerIDs, sizeof(GlyphxPlayerIDs)) != sizeof(GlyphxPlayerIDs)) { - return false; - } - - if (file.Write(&GlyphXClientSidebarWidthInLeptons, sizeof(GlyphXClientSidebarWidthInLeptons)) != sizeof(GlyphXClientSidebarWidthInLeptons)) { - return false; - } - - if (file.Write(MPlayerIsHuman, sizeof(MPlayerIsHuman)) != sizeof(MPlayerIsHuman)) { - return false; - } - - if (file.Write(MultiplayerStartPositions, sizeof(MultiplayerStartPositions)) != sizeof(MultiplayerStartPositions)) { - return false; - } - - if (file.Write(PlacementType, sizeof(PlacementType)) != sizeof(PlacementType)) { - return false; - } - - if (file.Write(&MPlayerCount, sizeof(MPlayerCount)) != sizeof(MPlayerCount)) { - return false; - } - - if (file.Write(&MPlayerBases, sizeof(MPlayerBases)) != sizeof(MPlayerBases)) { - return false; - } - - if (file.Write(&MPlayerCredits, sizeof(MPlayerCredits)) != sizeof(MPlayerCredits)) { - return false; - } - - if (file.Write(&MPlayerTiberium, sizeof(MPlayerTiberium)) != sizeof(MPlayerTiberium)) { - return false; - } - - if (file.Write(&MPlayerGoodies, sizeof(MPlayerGoodies)) != sizeof(MPlayerGoodies)) { - return false; - } - - if (file.Write(&MPlayerGhosts, sizeof(MPlayerGhosts)) != sizeof(MPlayerGhosts)) { - return false; - } - - if (file.Write(&MPlayerSolo, sizeof(MPlayerSolo)) != sizeof(MPlayerSolo)) { - return false; - } - - if (file.Write(&MPlayerUnitCount, sizeof(MPlayerUnitCount)) != sizeof(MPlayerUnitCount)) { - return false; - } - - if (file.Write(&MPlayerLocalID, sizeof(MPlayerLocalID)) != sizeof(MPlayerLocalID)) { - return false; - } - - if (file.Write(MPlayerHouses, sizeof(MPlayerHouses)) != sizeof(MPlayerHouses)) { - return false; - } - - if (file.Write(MPlayerNames, sizeof(MPlayerNames)) != sizeof(MPlayerNames)) { - return false; - } - - if (file.Write(MPlayerID, sizeof(MPlayerID)) != sizeof(MPlayerID)) { - return false; - } - - if (file.Write(MPlayerIsHuman, sizeof(MPlayerIsHuman)) != sizeof(MPlayerIsHuman)) { - return false; - } - - for (int i=0 ; iType; - } - } -} - - - -/************************************************************************************************** -* DLLExportClass::Decode_Pointers -- -* -* In: -* -* Out: -* -* -* -* History: 9/10/2019 10:24AM - ST -**************************************************************************************************/ -void DLLExportClass::Decode_Pointers(void) -{ - for (int i=0 ; i(PlacementType[i]); - PlacementType[i] = NULL; - if (type >= STRUCT_FIRST && type < STRUCT_COUNT) { - - TechnoTypeClass const * tech = Fetch_Techno_Type(RTTI_BUILDINGTYPE, type); - if (tech) { - BuildingTypeClass* build_type = (BuildingTypeClass*)(tech); - if (build_type) { - PlacementType[i] = build_type; - } - } - } - } - } -} - - -void DLL_Code_Pointers(void) -{ - DLLExportClass::Code_Pointers(); -} - -void DLL_Decode_Pointers(void) -{ - DLLExportClass::Decode_Pointers(); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/DLLInterface.h b/code/TIBERIANDAWN/DLLInterface.h deleted file mode 100644 index a52c00c..0000000 --- a/code/TIBERIANDAWN/DLLInterface.h +++ /dev/null @@ -1,928 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -#pragma once - -#ifndef DLL_INTERFACE_H -#define DLL_INTERFACE_H - -struct CarryoverObjectStruct; - - -/* -** DLL Interface version -** -** -** -*/ -#define CNC_DLL_API_VERSION 0x101 - - - -#define MAX_EXPORT_CELLS (128 * 128) - -#ifdef TIBERIAN_DAWN -#define MAP_MAX_CELL_WIDTH 64 -#define MAP_MAX_CELL_HEIGHT 64 -#else -#define MAP_MAX_CELL_WIDTH 128 -#define MAP_MAX_CELL_HEIGHT 128 -#endif - - -/* -** Interface structs require stricter packing -** -** -*/ -#pragma pack(push) -#pragma pack(1) - - - - -/************************************************************************************** -** -** Game state request types -** -** -*/ -enum GameStateRequestEnum { - GAME_STATE_NONE, - GAME_STATE_STATIC_MAP, - GAME_STATE_DYNAMIC_MAP, - GAME_STATE_LAYERS, - GAME_STATE_SIDEBAR, - GAME_STATE_PLACEMENT, - GAME_STATE_SHROUD, - GAME_STATE_OCCUPIER, - GAME_STATE_PLAYER_INFO -}; - - - - -/************************************************************************************** -** -** Static map data (tiles) -** -** -*/ -struct CNCStaticCellStruct { - char TemplateTypeName[32]; - int IconNumber; -}; - - - -enum CnCTheaterType { - CNC_THEATER_NONE=-1, - CNC_THEATER_DESERT, - CNC_THEATER_JUNGLE, - CNC_THEATER_TEMPERATE, - CNC_THEATER_WINTER, - - CNC_THEATER_COUNT, - CNC_THEATER_FIRST=0 -}; - - -struct CNCMapDataStruct { - int MapCellX; - int MapCellY; - int MapCellWidth; - int MapCellHeight; - int OriginalMapCellX; - int OriginalMapCellY; - int OriginalMapCellWidth; - int OriginalMapCellHeight; - - CnCTheaterType Theater; - char ScenarioName[_MAX_FNAME+_MAX_EXT]; - - CNCStaticCellStruct StaticCells[MAX_EXPORT_CELLS]; -}; - - - - -/************************************************************************************** -** -** Object type enum -** -** -*/ -#define DLL_LAYER_COUNT 3 - -enum DllObjectTypeEnum { - UNKNOWN, - INFANTRY, - UNIT, - AIRCRAFT, - BUILDING, - TERRAIN, - ANIM, - BULLET, - OVERLAY, - SMUDGE, - OBJECT, - SPECIAL, - INFANTRY_TYPE, - UNIT_TYPE, - AIRCRAFT_TYPE, - BUILDING_TYPE, - VESSEL, - VESSEL_TYPE -}; - - - -/************************************************************************************** -** -** Object action types -** -** -*/ -enum DllActionTypeEnum : unsigned char { - DAT_NONE, - DAT_MOVE, - DAT_NOMOVE, - DAT_ENTER, - DAT_SELF, - DAT_ATTACK, - DAT_ATTACK_OUT_OF_RANGE, - DAT_GUARD, - DAT_SELECT, - DAT_CAPTURE, - DAT_SABOTAGE, - DAT_HEAL, - DAT_DAMAGE, - DAT_TOGGLE_PRIMARY, - DAT_CANT_DEPLOY, - DAT_REPAIR, - DAT_CANT_REPAIR -}; - - - - - - -/************************************************************************************** -** -** Object state data -** -** -*/ -#define MAX_OCCUPY_CELLS 36 -#define MAX_OBJECT_PIPS 18 -#define MAX_OBJECT_LINES 3 -#define MAX_HOUSES 32 - -struct CNCObjectLineStruct { - int X; - int Y; - int X1; - int Y1; - int Frame; - unsigned char Color; -}; - -#define CNC_OBJECT_ASSET_NAME_LENGTH 16 -struct CNCObjectStruct { - void *CNCInternalObjectPointer; - char TypeName[CNC_OBJECT_ASSET_NAME_LENGTH]; - char AssetName[CNC_OBJECT_ASSET_NAME_LENGTH]; // CNC uses 8.3 filenames, so it shouldn't need to be bigger than 9 - DllObjectTypeEnum Type; - int ID; - int BaseObjectID; - DllObjectTypeEnum BaseObjectType; - int PositionX; - int PositionY; - int Width; - int Height; - int Altitude; - int SortOrder; - int Scale; - int DrawFlags; - short MaxStrength; - short Strength; - unsigned short ShapeIndex; - unsigned short CellX; - unsigned short CellY; - unsigned short CenterCoordX; - unsigned short CenterCoordY; - short SimLeptonX; - short SimLeptonY; - unsigned char DimensionX; - unsigned char DimensionY; - unsigned char Rotation; - unsigned char MaxSpeed; - char Owner; - char RemapColor; - char SubObject; - bool IsSelectable; - unsigned int IsSelectedMask; - bool IsRepairing; - bool IsDumping; - bool IsTheaterSpecific; - unsigned int FlashingFlags; - unsigned char Cloak; - bool CanRepair; - bool CanDemolish; - bool CanDemolishUnit; - short OccupyList[MAX_OCCUPY_CELLS]; - int OccupyListLength; - int Pips[MAX_OBJECT_PIPS]; - int NumPips; - int MaxPips; - CNCObjectLineStruct Lines[MAX_OBJECT_LINES]; - int NumLines; - bool RecentlyCreated; - bool IsALoaner; - bool IsFactory; - bool IsPrimaryFactory; - bool IsDeployable; - bool IsAntiGround; - bool IsAntiAircraft; - bool IsSubSurface; - bool IsNominal; - bool IsDog; - bool IsIronCurtain; - bool IsInFormation; - bool CanMove[MAX_HOUSES]; - bool CanFire[MAX_HOUSES]; - bool CanDeploy; - bool CanHarvest; - bool CanPlaceBombs; - bool IsFixedWingedAircraft; - bool IsFake; - unsigned char ControlGroup; - unsigned int VisibleFlags; - unsigned int SpiedByFlags; - char ProductionAssetName[CNC_OBJECT_ASSET_NAME_LENGTH]; - const char* OverrideDisplayName; - DllActionTypeEnum ActionWithSelected[MAX_HOUSES]; - - static const unsigned int VISIBLE_FLAGS_ALL = 0xffffffff; -}; - -struct CNCObjectListStruct { - int Count; - CNCObjectStruct Objects[1]; // Variable length -}; - - - - -/************************************************************************************** -** -** Placement validity data -** -** Used to pass back info about tructure placement validity -*/ -struct CNCPlacementCellInfoStruct { - bool PassesProximityCheck; // If the structure was placed in this cell, does that satisfy the proximity check for the whole structure? - bool GenerallyClear; // Is this cell generally clear of obstructions that would prevent placement? -}; - -struct CNCPlacementInfoStruct { - int Count; - CNCPlacementCellInfoStruct CellInfo[1]; // Variable length -}; - - - - - -/************************************************************************************** -** -** Sidebar/construction state data -** -** -*/ -enum DllSuperweaponTypeEnum { - SW_NONE, - SW_UNKNOWN, - - //TD values - SW_NUKE, - SW_AIR_STRIKE, - SW_ION_CANNON, - - //RA values - SW_SONAR_PULSE, - SW_CHRONOSPHERE, - SW_PARA_BOMB, - SW_PARA_INFANTRY, - SW_SPY_MISSION, - SW_IRON_CURTAIN, - SW_GPS, - SW_CHRONOSPHERE_DESTINATION -}; - -struct CNCSidebarEntryStruct { - char AssetName[16]; // CNC uses 8.3 filenames, so it shouldn't need to be bigger than 9 - int BuildableType; // This is the original buildable type that should be passed back if we want to start/cancel construction - int BuildableID; // This is the original buildable id that should be passed back if we want to start/cancel construction - DllObjectTypeEnum Type; // Type converted to shared enum - DllSuperweaponTypeEnum SuperWeaponType; - int Cost; // Cost to construct - int PowerProvided; // Power cost to construct - int BuildTime; // Cost to construct - float Progress; // Construction progress (0.0 - 1.0) - short PlacementList[MAX_OCCUPY_CELLS]; // Which cells this structure occupies for placement (if structure) - int PlacementListLength; // How many cells - bool Completed; // Construction has completed - bool Constructing; // Is it currently constructing - bool ConstructionOnHold; // Is the current construction on hold - bool Busy; // Is the associated factory busy - bool BuildableViaCapture; // Is this buildable due to the capture of a structure of a different faction. This will be false for captured structures of the same faction (ActLike) - bool Fake; // Is this a fake structure? -}; - - -struct CNCSidebarStruct { - int EntryCount[2]; // Counts for the left and right columns - int Credits; // Amount of currency available (excluding Tiberium) - int CreditsCounter; // Visible credits to display in the sidebar (includes count up/down logic) - int Tiberium; // Amount of Tiberium in reserve - int MaxTiberium; // Maximum amount of Tiberium storage available - int PowerProduced; - int PowerDrained; - int MissionTimer; - unsigned int UnitsKilled; // Total count of enemy units killed by this player; Includes Infantry, Vehicles, Aircraft - unsigned int BuildingsKilled; // Total count of enemy structures killed by this player - unsigned int UnitsLost; // Total count player-owned units killed/lost - unsigned int BuildingsLost; // Total count player-owned structures killed/lost - unsigned int TotalHarvestedCredits; // Complete total of gained credits over the match (does not include starting credits) - bool RepairBtnEnabled; - bool SellBtnEnabled; - bool RadarMapActive; - - CNCSidebarEntryStruct Entries[1]; // Variable length column entries -}; - - - -enum SidebarRequestEnum { - SIDEBAR_REQUEST_START_CONSTRUCTION, - SIDEBAR_REQUEST_HOLD_CONSTRUCTION, - SIDEBAR_REQUEST_CANCEL_CONSTRUCTION, - SIDEBAR_REQUEST_START_PLACEMENT, - SIDEBAR_REQUEST_PLACE, - SIDEBAR_CANCEL_PLACE, - SIDEBAR_CLICK_REPAIR, - SIDEBAR_REQUEST_ENABLE_QUEUE, - SIDEBAR_REQUEST_DISABLE_QUEUE, - SIDEBAR_REQUEST_START_CONSTRUCTION_MULTI, - SIDEBAR_REQUEST_CANCEL_CONSTRUCTION_MULTI -}; - -enum SuperWeaponRequestEnum { - SUPERWEAPON_REQUEST_PLACE_SUPER_WEAPON -}; - -enum ControlGroupRequestEnum { - CONTROL_GROUP_REQUEST_CREATE, - CONTROL_GROUP_REQUEST_TOGGLE, - CONTROL_GROUP_REQUEST_ADDITIVE_SELECTION, -}; - - - -/************************************************************************************** -** -** Input events sent into the DLL -** -** -*/ -enum InputRequestEnum { - INPUT_REQUEST_NONE, - INPUT_REQUEST_MOUSE_MOVE, - INPUT_REQUEST_MOUSE_LEFT_CLICK, - INPUT_REQUEST_MOUSE_RIGHT_DOWN, - INPUT_REQUEST_MOUSE_RIGHT_CLICK, - INPUT_REQUEST_MOUSE_AREA, - INPUT_REQUEST_MOUSE_AREA_ADDITIVE, - INPUT_REQUEST_SELL_AT_POSITION, - INPUT_REQUEST_SELECT_AT_POSITION, - INPUT_REQUEST_COMMAND_AT_POSITION, - INPUT_REQUEST_SPECIAL_KEYS -}; - - -/************************************************************************************** -** -** Structure Requests Repair, Sell -** -** -*/ -enum StructureRequestEnum { - INPUT_STRUCTURE_NONE, - INPUT_STRUCTURE_REPAIR_START, - INPUT_STRUCTURE_REPAIR, - INPUT_STRUCTURE_SELL_START, - INPUT_STRUCTURE_SELL, - INPUT_STRUCTURE_CANCEL, -}; - - -/************************************************************************************** -** -** Unit Requests Scatter, Select Next, Select Previous, Guard Mode, Stop -** -** -*/ -enum UnitRequestEnum { - INPUT_UNIT_NONE, - INPUT_UNIT_SCATTER, - INPUT_UNIT_SELECT_NEXT, - INPUT_UNIT_SELECT_PREVIOUS, - INPUT_UNIT_GUARD_MODE, - INPUT_UNIT_STOP, - INPUT_UNIT_FORMATION_TOGGLE, // RA Only - INPUT_UNIT_QUEUED_MOVEMENT_ON, // RA Only - INPUT_UNIT_QUEUED_MOVEMENT_OFF, // RA Only -}; - - -/************************************************************************************** -** -** Game Action Requests -** -** -*/ -enum GameRequestEnum { - INPUT_GAME_MOVIE_DONE, - INPUT_GAME_LOADING_DONE, -}; - - - -/************************************************************************************** -** -** Special Keys -** -** -*/ -enum SpecialKeyRequestEnum { - INPUT_SPECIAL_KEY_CTRL = 0b00000001, - INPUT_SPECIAL_KEY_ALT = 0b00000010, - INPUT_SPECIAL_KEY_SHIFT = 0b00000100, -}; - - - -/************************************************************************************** -** -** Non-static map data. -** -** Per-cell smudges and overlays. Smudges are used for things like craters and structure bibs that draw under units. -** Overlays are things like walls and tiberium that can't move from the cell but aren't flat like smudges. -** -** -*/ -struct CNCDynamicMapEntryStruct { - char AssetName[16]; - int PositionX; - int PositionY; - int Width; - int Height; - short Type; - char Owner; - int DrawFlags; - unsigned char CellX; - unsigned char CellY; - unsigned char ShapeIndex; - bool IsSmudge; - bool IsOverlay; - bool IsResource; - bool IsSellable; - bool IsTheaterShape; - bool IsFlag; -}; - -struct CNCDynamicMapStruct { - bool VortexActive; - int VortexX; - int VortexY; - int VortexWidth; - int VortexHeight; - int Count; - CNCDynamicMapEntryStruct Entries[1]; // Variable length -}; - - - - - -/************************************************************************************** -** -** Event data -** -** Used to call back into the GlyphX engine for one-time events like sound effect triggers -** -** -*/ -enum EventCallbackType { - CALLBACK_EVENT_INVALID = -1, - CALLBACK_EVENT_SOUND_EFFECT = 0, - CALLBACK_EVENT_SPEECH, - CALLBACK_EVENT_GAME_OVER, - CALLBACK_EVENT_DEBUG_PRINT, - CALLBACK_EVENT_MOVIE, - CALLBACK_EVENT_MESSAGE, - CALLBACK_EVENT_UPDATE_MAP_CELL, - CALLBACK_EVENT_ACHIEVEMENT, - CALLBACK_EVENT_STORE_CARRYOVER_OBJECTS, - CALLBACK_EVENT_SPECIAL_WEAPON_TARGETTING, - CALLBACK_EVENT_BRIEFING_SCREEN, - CALLBACK_EVENT_CENTER_CAMERA, - CALLBACK_EVENT_PING -}; - - -struct GameOverMultiPlayerStatsStruct -{ - GameOverMultiPlayerStatsStruct() - : - GlyphXPlayerID( 0 ), - IsHuman( false ), - WasHuman( false ), - IsWinner( false ), - ResourcesGathered( 0 ), - TotalUnitsKilled( 0 ), - TotalStructuresKilled( 0 ), - Efficiency( 0 ), - Score( 0 ) - { - } - __int64 GlyphXPlayerID; - bool IsHuman; - bool WasHuman; - bool IsWinner; - int ResourcesGathered; - int TotalUnitsKilled; - int TotalStructuresKilled; - int Efficiency; // AKA Economy - int Score; -}; - -#define GAME_OVER_MULTIPLAYER_MAX_PLAYERS_TRACKED 8 - -enum EventCallbackMessageEnum { - MESSAGE_TYPE_DIRECT = 0, - MESSAGE_TYPE_PLAYER_DEFEATED, - MESSAGE_TYPE_COMPUTER_TAUNT, - MESSAGE_TYPE_PLAYER_DISCONNECTED -}; - -struct EventCallbackStruct { - - EventCallbackStruct::EventCallbackStruct(void) : EventType(CALLBACK_EVENT_INVALID), GlyphXPlayerID(0) { } - - EventCallbackType EventType; - - __int64 GlyphXPlayerID; - - union { - - struct SoundEffectEvent { - int SFXIndex; - int Variation; - int PixelX; - int PixelY; - int PlayerID; //TO_FIX - char SoundEffectName[ 16 ]; - int SoundEffectPriority; - int SoundEffectContext; - } SoundEffect; - - struct SpeechEvent { - int SpeechIndex; - int PlayerID; //TO_FIX - char SpeechName[ 16 ]; - } Speech; - - struct GameOverEvent { - bool Multiplayer; - // - // Single-player data - // - bool IsHuman; - bool PlayerWins; - const char* MovieName; - const char* MovieName2; - const char* MovieName3; - const char* MovieName4; - const char* AfterScoreMovieName; - int Score; - int Leadership; - int Efficiency; - int CategoryTotal; - int NODKilled; - int GDIKilled; - int CiviliansKilled; - int NODBuildingsDestroyed; - int GDIBuildingsDestroyed; - int CiviliansBuildingsDestroyed; - int RemainingCredits; - int SabotagedStructureType; - int TimerRemaining; - // - // Multi-player data - // - int MultiPlayerTotalPlayers; - GameOverMultiPlayerStatsStruct MultiPlayerPlayersData[ GAME_OVER_MULTIPLAYER_MAX_PLAYERS_TRACKED ]; - } GameOver; - - struct DebugPrintEvent { - const char *PrintString; - } DebugPrint; - - struct MovieEvent { - const char* MovieName; - int Theme; - bool Immediate; - } Movie; - - struct MessageEvent { - const char* Message; - float TimeoutSeconds; - EventCallbackMessageEnum MessageType; - __int64 MessageParam1; - } Message; - - struct UpdateMapCellEvent { - int CellX; - int CellY; - char TemplateTypeName[32]; - } UpdateMapCell; - - struct AchievementEvent { - const char* AchievementType; - const char* AchievementReason; - } Achievement; - - struct StoreCarryoverObjectsEvent { - CarryoverObjectStruct* CarryoverList; - } StoreCarryoverObjects; - - struct SpecialWeaponTargettingEvent { - int Type; - int ID; - char Name[16]; - DllSuperweaponTypeEnum WeaponType; - } SpecialWeaponTargetting; - - struct CenterCameraEvent { - int CoordX; - int CoordY; - } CenterCamera; - - struct PingEvent { - int CoordX; - int CoordY; - } Ping; - }; - -}; - - - - - - - - -/************************************************************************************** -** -** Multiplayer setup data -** -** Used to pass multiplayer setup info into the C&C code from the GlyphX engine -** -** -*/ - - - -struct CNCMultiplayerOptionsStruct { - //int MPlayerPrefColor; // preferred color index for this player - //int MPlayerColorIdx; // actual color index of this player - //CnCHousesType MPlayerHouse; // House of this player (GDI/NOD) - //unsigned char MPlayerLocalID; // ID of this player - int MPlayerCount; // # of human players in this game - int MPlayerBases; // 1 = bases are on for this scenario - int MPlayerCredits; // # credits everyone gets - int MPlayerTiberium; // 1 = tiberium enabled for this scenario - int MPlayerGoodies; // 1 = goodies enabled for this scenario - int MPlayerGhosts; // 1 = houses with no players will still play - int MPlayerSolo; // 1 = allows a single-player net game - int MPlayerUnitCount; // # units for non-base multiplayer scenarios - bool IsMCVDeploy; // MCV undeploys instead of selling - bool SpawnVisceroids; // Do visceroids spawn - bool EnableSuperweapons; // Are superweapons available - bool MPlayerShadowRegrow; - bool MPlayerAftermathUnits; - bool CaptureTheFlag; - bool DestroyStructures; // New early win condition via destroying all a player's structures -}; - - - -struct CNCSpiedInfoStruct { - int Power; - int Drain; - int Money; -}; - - -struct CNCPlayerInfoStruct { - char Name[64]; - unsigned char House; - int ColorIndex; - unsigned __int64 GlyphxPlayerID; - int Team; - int StartLocationIndex; - unsigned char HomeCellX; - unsigned char HomeCellY; - bool IsAI; - unsigned int AllyFlags; - bool IsDefeated; - unsigned int SpiedPowerFlags; - unsigned int SpiedMoneyFlags; - CNCSpiedInfoStruct SpiedInfo[MAX_HOUSES]; - int SelectedID; - DllObjectTypeEnum SelectedType; - DllActionTypeEnum ActionWithSelected[MAX_EXPORT_CELLS]; - unsigned int ActionWithSelectedCount; - unsigned int ScreenShake; - bool IsRadarJammed; -}; - - - - -// -enum GameRequestType { - GAME_REQUEST_MOVIE_DONE, -}; - - - - -/************************************************************************************** -** -** Rules configuration data -** -** -*/ -struct CNCDifficultyDataStruct -{ - float FirepowerBias; - float GroundspeedBias; - float AirspeedBias; - float ArmorBias; - float ROFBias; - float CostBias; - float BuildSpeedBias; - - float RepairDelay; - float BuildDelay; - - bool IsBuildSlowdown; - bool IsWallDestroyer; - bool IsContentScan; -}; - -struct CNCRulesDataStruct -{ - CNCDifficultyDataStruct Difficulties[3]; -}; - - - - -/************************************************************************************** -** -** Debug input interface -** -** -*/ - -enum DebugRequestEnum { - DEBUG_REQUEST_SPAWN_OBJECT, - DEBUG_REQUEST_END_GAME, - DEBUG_REQUEST_UNSHROUD, - DEBUG_REQUEST_SUPERWEAPON_RECHARGE, - DEBUG_REQUEST_KILL_OBJECT, - DEBUG_REQUEST_END_PRODUCTION, - DEBUG_REQUEST_ADD_RESOURCES, - DEBUG_REQUEST_UNLOCK_BUILDABLES, - DEBUG_REQUEST_FORCE_CRASH, - DEBUG_REQUEST_SET_GLOBAL_FLAG, -}; - - - - - - -/************************************************************************************** -** -** Shroud data. -** -** Per-cell shroud info -** -** -*/ -struct CNCShroudEntryStruct { - char ShadowIndex; - bool IsVisible; - bool IsMapped; - bool IsJamming; -}; - -struct CNCShroudStruct { - int Count; - CNCShroudEntryStruct Entries[1]; // Variable length -}; - - - - - - -/************************************************************************************** -** -** Occupier data. -** -** Per-cell occupier info -** -** -*/ -struct CNCOccupierObjectStruct { - DllObjectTypeEnum Type; - int ID; -}; - -struct CNCOccupierEntryHeaderStruct { - int Count; -}; - -struct CNCOccupierHeaderStruct { - int Count; -}; - - - - -/************************************************************************************** -** -** Carryover object. -** -** Used to store object data that persists between missions -** -** -*/ -struct CarryoverObjectStruct -{ - CarryoverObjectStruct() : Next(0) {} - - CarryoverObjectStruct* Next; - - int RTTI; - int Type; - int Cell; - int Strength; - int House; -}; - - - - - -/* -** End of strict structure packing -** -** -*/ -#pragma pack(pop) - - - -#endif //DLL_INTERFACE_H \ No newline at end of file diff --git a/code/TIBERIANDAWN/DLLInterfaceEditor.cpp b/code/TIBERIANDAWN/DLLInterfaceEditor.cpp deleted file mode 100644 index cb205a5..0000000 --- a/code/TIBERIANDAWN/DLLInterfaceEditor.cpp +++ /dev/null @@ -1,741 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -#include -//#include -//#include - -#include "function.h" -#include "externs.h" -#include "DLLInterface.h" -#include "Gadget.h" -#include "defines.h" // VOC_COUNT, VOX_COUNT -#include "SidebarGlyphx.h" -#include "TEMPLATE.H" - -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup(); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup(); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map(char* cncdata_directory, char* house_name, int scenario_index, char* east_west, char* variant); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name(char* cncdata_directory, char* scenario_name); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map(); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data_By_Index(int cell_index, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data(int x, int y, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Texture_Buffer(int x, int y, int& out_width, int& out_height, SAFEARRAY*& out_texture_array); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory, int CD); -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points); - -char EditorMapINIBuffer[SHAPE_BUFFER_SIZE]; -bool EditorMapInitialized = false; - -const static int EDITOR_COMMMAND_SUCCESS = 0; -const static int EDITOR_COMMMAND_FAILURE = 1; - -const static char* MixFileNames[] = -{ - "GENERAL.MIX", - "SC-000.MIX", - "SC-001.MIX", - "DESERT.MIX", - "TEMPERAT.MIX", - "WINTER.MIX" -}; - -extern MixFileClass *TheaterIcons; -extern bool Read_Movies_From_Scenario_Ini(char *root, bool fresh); - -/************************************************************************************************** -* CNC_Editor_Startup -* Initializes the system to allow map loading for the editor -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup() -{ - BlackPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; - GamePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; - OriginalPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; - WhitePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; - memset(WhitePalette, 63, 768); - - - Set_Palette(GamePalette); - - TheaterData = 0; - TheaterIcons = 0; - LowTheaterData = 0; - - return EDITOR_COMMMAND_SUCCESS; -} - -/************************************************************************************************** -* CNC_Editor_Cleanup -* Cleans up systems initialized by the editor -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup() -{ - if (BlackPalette) - { - delete[] BlackPalette; - } - - if (GamePalette) - { - delete[] GamePalette; - } - - if (OriginalPalette) - { - delete[] OriginalPalette; - } - if (WhitePalette) - { - delete[] WhitePalette; - } - - return EDITOR_COMMMAND_SUCCESS; -} -/************************************************************************************************** -* CNC_Editor_Load_Mix_Files -* Loads all the Mix files for Tiberian Dawn -**************************************************************************************************/ -void CNC_Editor_Load_Mix_Files() -{ - int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]); - - for (int i = count - 1; i >= 0; --i) - { - MixFileClass::Free(MixFileNames[i]); - } - - for (int i = 0; i < count; ++i) - { - new MixFileClass(MixFileNames[i]); - MixFileClass::Cache(MixFileNames[i]); - } -} - -/************************************************************************************************** -* CNC_Editor_Setup_Content_Directory -* Sets up where the system should load map data from. -**************************************************************************************************/ -void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, char* cd_directory) -{ - char content_directory[_MAX_PATH]; - - sprintf(content_directory, "%s\\TIBERIAN_DAWN\\%s\\", cncdata_directory, cd_directory); - - if (strlen(content_directory) != 0) { - CCFileClass::Clear_Search_Drives(); - CCFileClass::Reset_Raw_Path(); - char *dll_dir = strdup(content_directory); - CCFileClass::Set_Search_Drives(dll_dir); - free(dll_dir); - } -} - -void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, int CD_index) -{ - char cd_name[_MAX_PATH]; - sprintf(cd_name, "CD%i", CD_index); - CNC_Editor_Setup_Content_Directory(cncdata_directory, cd_name); -} - - - - -/************************************************************************************************** -* CNC_Editor_Load_Map -* Loads the map with the given parameters. -* -* cncdata_directory: path of the base CNC data directory -* faction: the name of the faction we are loading the map for -* scenario_index: int scenario index -* east_west: -* variant: -* -* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map( - char* cncdata_directory, - char* house_name, - int scenario_index, - char* east_west, - char* variant) -{ - CNC_Editor_Clear_Map(); - - int CD = 1; - if (stricmp(house_name, "GDI") == 0) { - ScenPlayer = SCEN_PLAYER_GDI; - GameToPlay = GAME_NORMAL; - - if (scenario_index == 30 || scenario_index == 90) { - CD = 5; - } - else if (scenario_index >= 60 && scenario_index <= 72) { - CD = 4; - } - else if (scenario_index >= 20 && scenario_index < 60) { - CD = 3; - } - } - - if (stricmp(house_name, "NOD") == 0) { - ScenPlayer = SCEN_PLAYER_NOD; - GameToPlay = GAME_NORMAL; - CD = 2; - - // Hack a fix for scenario 21 since the same mission number is used in Covert Ops and N64 - if (scenario_index == 81 || scenario_index == 22) { - CD = 5; - if (scenario_index == 81) { - scenario_index = 21; - } - } - else if (scenario_index >= 60 && scenario_index <= 61) { - CD = 4; - } - else if (scenario_index >= 20 && scenario_index < 60) { - CD = 3; - } - } - - if (stricmp(house_name, "MULTI") == 0) - { - ScenPlayer = SCEN_PLAYER_MPLAYER; - GameToPlay = GAME_GLYPHX_MULTIPLAYER; - } - - if (stricmp(house_name, "JUR") == 0) - { - ScenPlayer = SCEN_PLAYER_JP; - GameToPlay = GAME_NORMAL; - } - - switch (CD) - { - case 4: - CNC_Editor_Setup_Content_Directory(cncdata_directory, "CONSOLE_1"); - break; - case 5: - CNC_Editor_Setup_Content_Directory(cncdata_directory, "CONSOLE_2"); - break; - default: - CNC_Editor_Setup_Content_Directory(cncdata_directory, CD); - break; - } - - CNC_Editor_Load_Mix_Files(); - - Scenario = scenario_index; - BuildLevel = 7; - - if (stricmp(east_west, "w") == 0) - { - ScenDir = SCEN_DIR_WEST; - } - else - { - ScenDir = SCEN_DIR_EAST; - } - - ScenarioVarType variant_enum; - - if (stricmp(variant, "b") == 0) - { - variant_enum = SCEN_VAR_B; - } - else if (stricmp(variant, "c") == 0) - { - variant_enum = SCEN_VAR_C; - } - else if (stricmp(variant, "d") == 0) - { - variant_enum = SCEN_VAR_D; - } - else - { - variant_enum = SCEN_VAR_A; - } - - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir, variant_enum); - - char fname[_MAX_FNAME + _MAX_EXT]; - sprintf(fname, "%s.INI", ScenarioName); - CCFileClass file(fname); - if (!file.Is_Available()) - { - return(EDITOR_COMMMAND_FAILURE); - } - else - { - memset(EditorMapINIBuffer, 0, SHAPE_BUFFER_SIZE); - file.Read(EditorMapINIBuffer, SHAPE_BUFFER_SIZE - 1); - } - - Map.One_Time_Editor(); - Map.Read_INI(EditorMapINIBuffer); - if (Map.Read_Binary(ScenarioName, &ScenarioCRC)) - { - EditorMapInitialized = true; - return EDITOR_COMMMAND_SUCCESS; - } - else - { - return EDITOR_COMMMAND_FAILURE; - } -} - - -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name(char* cncdata_directory, char* scenario_name) -{ - return EDITOR_COMMMAND_FAILURE; -} - -/************************************************************************************************** -* CNC_Editor_Clear_Map -* Deletes the data for the currently loaded map. -* -* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map() -{ - if (EditorMapInitialized) - { - Map.Init_Clear(); - - int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]); - for (int i = count - 1; i >= 0; --i) - { - MixFileClass::Free(MixFileNames[i]); - } - - EditorMapInitialized = false; - TheaterData = nullptr; - TheaterIcons = nullptr; - - return EDITOR_COMMMAND_SUCCESS; - } - else - { - return EDITOR_COMMMAND_FAILURE; - } - -} - -/************************************************************************************************** -* CNC_Editor_Get_Map_Stats -* Gets the stats for the currently loaded map -* -* map_width: out parameter storing the width of the map -* map_height: out parameter storing the height of the map -* theater: out paramter storing the theater of the map -* -* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater) -{ - if (EditorMapInitialized) - { - map_width = Map.MapCellWidth + 1; - map_height = Map.MapCellHeight + 1; - theater = Map.Theater; - return EDITOR_COMMMAND_SUCCESS; - } - - map_width = -1; - map_height = -1; - theater = -1; - return EDITOR_COMMMAND_FAILURE; -} - -/************************************************************************************************** -* CNC_Editor_Get_Cell_Data_By_Index -* Get the data from the given cell. -* -* cell_index: The index of the desired cell. -* cell_name: out buffer to be filled with the name of the given cell. -* cell_name_size: the size of the cell name buffer. -* -* -* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data_By_Index(int cell_index, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index) -{ - CellClass * cellptr = &Map[cell_index]; - - cell_name[0] = 0; - int icon = 0; - void *image_data = 0; - - char template_name[10]; - if (cellptr->Get_Template_Info(template_name, icon, image_data)) - { - snprintf(cell_name, cell_name_size, "%s-%04d", template_name, icon); - - template_type = cellptr->TType; - template_icon_index = icon; - - return EDITOR_COMMMAND_SUCCESS; - } - - return EDITOR_COMMMAND_FAILURE; -} - -/************************************************************************************************** -* CNC_Editor_Get_Cell_Data -* Get the data from the given cell. -* -* x,y: The corrdinates of the desired cell. -* cell_name: out buffer to be filled with the name of the given cell. -* cell_name_size: the size of the cell name buffer. -* -* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure -**************************************************************************************************/ - -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data(int x, int y, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index) -{ - if (!EditorMapInitialized) - { - return EDITOR_COMMMAND_FAILURE; - } - - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); - - return CNC_Editor_Get_Cell_Data_By_Index((int)cell, cell_name, cell_name_size, template_type, template_icon_index); -} - -/************************************************************************************************** -* CNC_Editor_Get_Cell_Texture_Buffer -* -* x,y: -* out_width, out_height: dimensions of the outputed texture array -* out_texture_array: output array of unsigned chars storing the color data for the requested object, -* every 3 chars is a set of RGB values -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Texture_Buffer(int x, int y, int& out_width, int& out_height, SAFEARRAY*& out_texture_array) -{ - - int map_cell_x = Map.MapCellX; - int map_cell_y = Map.MapCellY; - int map_cell_width = Map.MapCellWidth; - int map_cell_height = Map.MapCellHeight; - - if (map_cell_x > 0) { - map_cell_x--; - map_cell_width++; - } - - if (map_cell_width < MAP_MAX_CELL_WIDTH) { - map_cell_width++; - } - - if (map_cell_y > 0) { - map_cell_y--; - map_cell_height++; - } - - if (map_cell_height < MAP_MAX_CELL_HEIGHT) { - map_cell_height++; - } - - CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); - CellClass * cellptr = &Map[cell]; - - char cell_name[_MAX_PATH]; - - int icon = 0; - void *image_data = 0; - if (cellptr->Get_Template_Info(cell_name, icon, image_data)) - { - GraphicBufferClass temp_gbuffer(24, 24); - GraphicViewPortClass temp_viewport(&temp_gbuffer, 0, 0, 24, 24); - - WindowList[WINDOW_CUSTOM][WINDOWX] = 0; - WindowList[WINDOW_CUSTOM][WINDOWY] = 0; - WindowList[WINDOW_CUSTOM][WINDOWWIDTH] = 24; - WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = 24; - - temp_viewport.Draw_Stamp(image_data, icon, 0, 0, NULL, WINDOW_CUSTOM); - - out_width = temp_viewport.Get_Width(); - out_height = temp_viewport.Get_Height(); - - const int COLOR_SIZE = 3; - - SAFEARRAYBOUND Bound; - Bound.lLbound = 0; - Bound.cElements = out_width * out_height * COLOR_SIZE; - - out_texture_array = SafeArrayCreate(VT_UI1, 1, &Bound); - - unsigned char* out_buffer; - - HRESULT hr = SafeArrayAccessData(out_texture_array, (void **)&out_buffer); - if (SUCCEEDED(hr)) - { - GraphicBufferClass* Graphic_Buffer = temp_viewport.Get_Graphic_Buffer(); - - int VP_Scan_Line = temp_viewport.Get_Width() + temp_viewport.Get_XAdd(); - - char * start_ptr; - start_ptr = (char *)Graphic_Buffer->Get_Buffer(); - start_ptr += ((temp_viewport.Get_YPos() * VP_Scan_Line) + temp_viewport.Get_XPos()); - - for (int y = 0; y < out_height; ++y) - { - unsigned char* scanline_ptr = (unsigned char*)start_ptr + y * VP_Scan_Line; - unsigned char* out_buffer_y_ptr = out_buffer + (y * out_width * COLOR_SIZE); - for (int x = 0; x < out_width; ++x) - { - unsigned char* pallete_index_ptr = scanline_ptr + x; - unsigned char* out_buffer_ptr = out_buffer_y_ptr + (x * COLOR_SIZE); - - int red_palette_index = (*pallete_index_ptr) * COLOR_SIZE; - out_buffer_ptr[0] = GamePalette[red_palette_index] << 2; - out_buffer_ptr[1] = GamePalette[red_palette_index + 1] << 2; - out_buffer_ptr[2] = GamePalette[red_palette_index + 2] << 2; - } - } - - SafeArrayUnaccessData(out_texture_array); - - return EDITOR_COMMMAND_SUCCESS; - } - } - - return EDITOR_COMMMAND_FAILURE; -} - -/************************************************************************************************** -* CNC_Editor_Get_Template_Data -* Get the data from the given tile template type. -* -* template_type_index: The index of the template type to use. should come from the Get_Cell_Data function. -* template_points: Out buffer to be filled with the list of positions of the tiles as offsets from the origin of the template. -* This data is store is an X, Y, X, Y, X, Y format. -* -* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points) -{ - if (template_type_index >= TEMPLATE_COUNT || template_type_index == TEMPLATE_NONE) - { - return EDITOR_COMMMAND_FAILURE; - } - - const TemplateTypeClass& template_type = TemplateTypeClass::As_Reference((TemplateType)template_type_index); - if (template_type.Get_Image_Data() == nullptr) - { - return EDITOR_COMMMAND_FAILURE; - } - - short const * occupy_list = template_type.Occupy_List(); - - short const * counter = occupy_list; - while (counter && *counter != REFRESH_EOL) - { - counter++; - } - - int occupy_list_size = counter - occupy_list; - - - SAFEARRAYBOUND bounds; - bounds.lLbound = 0; - bounds.cElements = occupy_list_size * 2; - template_points = SafeArrayCreate(VT_I4, 1, &bounds); - - int *pData; - HRESULT hr = SafeArrayAccessData(template_points, (void **)&pData); - if (SUCCEEDED(hr)) - { - for (int i = 0; i < occupy_list_size; i++) - { - CELL cell = occupy_list[i]; - - int x = Cell_X(cell); - int y = Cell_Y(cell); - - pData[i * 2] = x; - pData[i * 2 + 1] = y; - } - - SafeArrayUnaccessData(template_points); - - return EDITOR_COMMMAND_SUCCESS; - } - - return EDITOR_COMMMAND_FAILURE; -} - - -/************************************************************************************************** -* CNC_Editor_Get_Scenario_Names -* -**************************************************************************************************/ -extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory, int CD) -{ - unsigned char read_buffer[SHAPE_BUFFER_SIZE]; - Set_Shape_Buffer(read_buffer, SHAPE_BUFFER_SIZE); - - char team_ids[] = - { - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - }; - /* - { - 'g', - 'b', - 'm', - 'j' - }; - */ - const int team_count = sizeof(team_ids) / sizeof(char); - - char direction_ids[] = - { - 'e', - 'w' - }; - const int direction_count = sizeof(direction_ids) / sizeof(char); - - char variant_ids[] = - { - 'a', - 'b', - 'c', - 'd' - }; - - const int variant_count = sizeof(variant_ids) / sizeof(char); - - const int min_scenario_index = 1; - const int max_scenario_index = 99; - - char scenario_name[_MAX_FNAME + _MAX_EXT]; - char file_name[_MAX_FNAME + _MAX_EXT]; - - CNC_Editor_Setup_Content_Directory(cncdata_directory, CD); - CNC_Editor_Load_Mix_Files(); - - char output_file_name[256]; - snprintf(output_file_name, 256, "d:\\TD_Disk%d_Names.txt", CD); - - FILE * names_file = fopen(output_file_name, "w+"); - - for (int team_index = 0; team_index < team_count; team_index++) - { - for (int scenario_index = min_scenario_index; scenario_index <= max_scenario_index; ++scenario_index) - { - for (int direction_index = 0; direction_index < direction_count; direction_index++) - { - for (int variant_index = 0; variant_index < variant_count; variant_index++) - { - sprintf(scenario_name, "sc%c%.2d%c%c", - team_ids[team_index], - scenario_index, - direction_ids[direction_index], - variant_ids[variant_index]); - - sprintf(file_name, "%s.INI", scenario_name); - CCFileClass file(file_name); - if (file.Is_Available()) - { - if (Read_Movies_From_Scenario_Ini(scenario_name, false)) - { - //fprintf(names_file, "%s - \t$Intro:%s \t\t$Brief:%s \t\t$Win:%s \t\t$Lose:%s \t\t$Action:%s \t\t$Theme:%s", scenario_name, IntroMovie, BriefMovie, WinMovie, LoseMovie, ActionMovie, MovieThemeName); - fprintf(names_file, "------------------%s-------------- %s \n", scenario_name, MovieThemeName); - - if (stricmp("x", IntroMovie) != 0) - { - fprintf(names_file, "%s\n", IntroMovie); - } - if (stricmp("x", BriefMovie) != 0) - { - fprintf(names_file, "%s\n", BriefMovie); - } - if (stricmp("x", ActionMovie) != 0) - { - fprintf(names_file, "%s\n", ActionMovie); - } - if (stricmp("x", WinMovie) != 0) - { - fprintf(names_file, "%s\n", WinMovie); - } - } - - fprintf(names_file, "\n"); - } - - - - } - } - } - } - - fclose(names_file); - - return EDITOR_COMMMAND_SUCCESS; -} diff --git a/code/TIBERIANDAWN/DOOR.CPP b/code/TIBERIANDAWN/DOOR.CPP deleted file mode 100644 index 2c795fb..0000000 --- a/code/TIBERIANDAWN/DOOR.CPP +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\door.cpv 1.4 16 Oct 1995 16:49:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DOOR.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 06/11/95 * - * * - * Last Update : June 14, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * DoorClass::AI -- Handles the door processing logic. * - * DoorClass::Close_Door -- Try to close the unit's door. * - * DoorClass::DoorClass -- Constructor for the DoorClass object. * - * DoorClass::Door_Stage -- Fetches the current door animation frame. * - * DoorClass::Open_Door -- Opens the door for this unit. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" - - -/*********************************************************************************************** - * DoorClass::DoorClass -- Constructor for the DoorClass object. * - * * - * This constructor sets the door to an initial closed state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/14/1995 JLB : Created. * - *=============================================================================================*/ -DoorClass::DoorClass(void) -{ - State = IS_CLOSED; - IsToRedraw = false; - Stages = 0; -} - - -/*********************************************************************************************** - * DoorClass::AI -- Handles the door processing logic. * - * * - * This routine should be called every game frame. It handles the door closing and opening * - * logic. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/13/1995 JLB : Created. * - *=============================================================================================*/ -void DoorClass::AI(void) -{ - if (Control.Graphic_Logic()) { - if (Control.Fetch_Stage() >= Stages) { - Control.Set_Rate(0); - switch (State) { - case IS_OPENING: - State = IS_OPEN; - break; - - case IS_CLOSING: - State = IS_CLOSED; - break; - } - } - IsToRedraw = true; - } -} - - -/*********************************************************************************************** - * DoorClass::Open_Door -- Opens the door for this unit. * - * * - * This routine will perform the door open operation for this unit. It will control vehicle * - * rotation if necessary. * - * * - * INPUT: rate -- The animation rate (delay) to use for the door animation logic. * - * * - * stages -- The number of animations stages that this door must pass through. * - * * - * OUTPUT: Was action initiated to open the door? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -bool DoorClass::Open_Door(int rate, int stages) -{ - switch (State) { - case IS_CLOSED: - case IS_CLOSING: - State = IS_OPENING; - Stages = stages-1; - Control.Set_Stage(0); - Control.Set_Rate(rate); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * DoorClass::Close_Door -- Try to close the unit's door. * - * * - * This routine will attempt to close the unit's door. If the door is already closed or * - * in the process of closing, then no action is performed. * - * * - * INPUT: rate -- The animation rate (delay) to use for the door animation logic. * - * * - * stages -- The number of animations stages that this door must pass through. * - * * - * OUTPUT: Action was initiated to close the door? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -bool DoorClass::Close_Door(int rate, int stages) -{ - switch (State) { - case IS_OPEN: - case IS_OPENING: - State = IS_CLOSING; - Stages = stages-1; - Control.Set_Stage(0); - Control.Set_Rate(rate); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * DoorClass::Door_Stage -- Fetches the current door animation frame. * - * * - * Use this routine to fetch the current door animation frame number. Frame zero is the * - * closed frame and frame 'N' is the open frame. If the door is in the process of opening * - * or closing, the appropriate frame number is used. 'N' is defined as the number of * - * stages in the animation minus 1 (e.g., a four frame animation will return a door stage * - * number between 0 and 3, inclusive). * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the door animation frame number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/14/1995 JLB : Created. * - *=============================================================================================*/ -int DoorClass::Door_Stage(void) const -{ - switch (State) { - case IS_CLOSING: - return((Stages-1) - Control.Fetch_Stage()); - - case IS_CLOSED: - return(0); - - case IS_OPENING: - return(Control.Fetch_Stage()); - - case IS_OPEN: - return(Stages-1); - } - return(0); -} diff --git a/code/TIBERIANDAWN/DOOR.H b/code/TIBERIANDAWN/DOOR.H deleted file mode 100644 index c743e0d..0000000 --- a/code/TIBERIANDAWN/DOOR.H +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\door.h_v 1.8 16 Oct 1995 16:47:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DOOR.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 06/11/95 * - * * - * Last Update : June 11, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DOOR_H -#define DOOR_H - -class DoorClass -{ - private: - - /* - ** This is the animation control handler. - */ - StageClass Control; - - /* - ** This is the recorded number of stages of the current - ** door animation process. - */ - unsigned char Stages; - - /* - ** This is the door state. - */ - enum { - IS_CLOSED, // Door is closed. - IS_OPENING, // Door is in the process of opening. - IS_OPEN, // Door is fully open. - IS_CLOSING // Door is in the process of closing. - } State; - - /* - ** If the animation for this door indicates that the object it is - ** attached to should be redrawn, then this flag will be true. - */ - unsigned IsToRedraw:1; - - public: - DoorClass(void); - - bool Time_To_Redraw(void) {return(IsToRedraw);}; - void Clear_Redraw_Flag(void) {IsToRedraw = false;}; - void AI(void); - int Door_Stage(void) const; - bool Is_Door_Opening(void) {return(State == IS_OPENING);}; - bool Is_Door_Closing(void) {return(State == IS_CLOSING);}; - bool Open_Door(int rate, int stages); - bool Close_Door(int rate, int stages); - bool Is_Door_Open(void) {return(State == IS_OPEN);}; - bool Is_Door_Closed(void) {return(State == IS_CLOSED);}; - bool Is_Ready_To_Open(void); - - /* - ** File I/O. - */ - void Code_Pointers(void) { return; } - void Decode_Pointers(void) { return; } -}; - -#endif diff --git a/code/TIBERIANDAWN/DPMI.CPP b/code/TIBERIANDAWN/DPMI.CPP deleted file mode 100644 index f24b152..0000000 --- a/code/TIBERIANDAWN/DPMI.CPP +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\dpmi.cpv 2.17 16 Oct 1995 16:49:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DPMI.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 2, 1994 * - * * - * Last Update : July 2, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -//PG_TO_FIX -#if (0) - -#ifdef __FLAT__ -#pragma inline -#endif - -#include "function.h" -#include "dpmi.h" - -#ifndef __FLAT__ - -void DOSSegmentClass::Swap(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size) -{ - if (!size) return; - - unsigned short ssel = src.Selector; - unsigned short dsel = dest.Selector; - - asm { - push es - push ds - - mov si,soffset - mov di,doffset - mov cx,size - mov ax,ssel - mov dx,dsel - mov ds,ax - mov es,dx - } -again: - asm { - mov al,ds:[si] - mov ah,es:[di] - mov ds:[si],ah - mov es:[di],al - inc di - inc si - dec cx - jnz again - - pop ds - pop es - } -} -#endif - - -void DOSSegmentClass::Swap(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size) -{ - extern void dss_swap(char *src, char *dest, int size); - - #pragma aux dss_swap = \ - "again: mov al,[esi]" \ - "mov ah,[edi]" \ - "mov [esi],ah" \ - "stosb" \ - "inc esi" \ - "loop again" \ - parm [esi] [edi] [ecx] \ - modify [ax]; - - if (!size) return; - dss_swap((char *)(src.Selector + soffset), (char *)(dest.Selector + doffset), size); -} - -#ifdef OBSOLETE -void DOSSegmentClass::Copy(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size) -{ - extern void dss_copy(char *src, char *dest, int size); - #pragma aux dss_copy = \ - "mov ebx,ecx" \ - "shr ecx,2" \ - "jecxz copskip1" \ - "rep movsd" \ -"copskip1: mov ecx,ebx" \ - "and ecx,3" \ - "jecxz copskip2" \ - "rep movsb" \ -"copskip2:" \ - parm [esi edi ecx] \ - modify [ebx]; - - if (!size) return; - dss_copy((char *)(src.Selector + soffset), (char *)(dest.Selector + doffset), size); -} -#endif - -#ifdef OBSOLETE -void DOSSegmentClass::Copy_To(void *source, int dest, int size) -{ - extern void dss_copy_to(void *src, (void *)dest, int size); - - #pragma aux dss_copy_to = \ - "mov ebx,ecx" \ - "shr ecx,2" \ - "jecxz cop2skip1" \ - "rep movsd" \ -"cop2skip1: mov ecx,ebx" \ - "and ecx,3" \ - "jecxz cop2skip2" \ - "rep movsb" \ -"cop2skip2:" \ - parm [esi edi ecx] \ - modify [ebx]; - - if (!size) return; - dss_copy_to(src, (void *)(Selector + dest), size); - -} -#endif - -#ifdef OBSOLETE -void DOSSegmentClass::Copy_From(void *dest, int source, int size) -{ - extern void dss_copy_from(void *dest, (void *)source, int size); - - #pragma aux dss_copy_from = \ - "mov ebx,ecx" \ - "shr ecx,2" \ - "jecxz copfskip1" \ - "rep movsd" \ -"copfskip1: mov ecx,ebx" \ - "and ecx,3" \ - "jecxz copfskip2" \ - "rep movsb" \ -"copfskip2:" \ - parm [edi esi ecx] \ - modify [ebx]; - - if (!size) return; - dss_copy_from(dest, (void *)(Selector + source), size); -} -#endif - - -#endif //PG_TO_FIX \ No newline at end of file diff --git a/code/TIBERIANDAWN/DPMI.H b/code/TIBERIANDAWN/DPMI.H deleted file mode 100644 index bcf710b..0000000 --- a/code/TIBERIANDAWN/DPMI.H +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\dpmi.h_v 2.17 16 Oct 1995 16:44:52 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DPMI.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 2, 1994 * - * * - * Last Update : July 2, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DPMI_H -#define DPMI_H -#include -#include -#include -#include - - -extern void output(short port, short data); - - -class DOSSegmentClass { - /* - ** This is the selector/segment value. In real mode it is the segment, in protected - ** mode it is the selector (also 16 bits). This value is moved into DS or ES when - ** accessing memory. - ** Note: in Watcom flat addressing, Selector == Segment<<4 (ex: 0A0000h) - */ - unsigned int Selector; - - /* - ** These are C equivalents for pushing and popping the DS segment register. By using - ** these, it is possible to create very small code that uses a segment and - ** offset without damaging the DS register. These are especially useful in protected - ** mode, but they are legal in real mode as well. - */ - void Push_DS(void) {/*__emit__(0x1E);*/}; - void Pop_DS(void) {/*__emit__(0x1F);*/}; - - public: - DOSSegmentClass(void); - ~DOSSegmentClass(void); - DOSSegmentClass(unsigned short segment, long size=(1024L*64L)); - - unsigned int Get_Selector(void); - - /* - ** This routine is used to assign where the descriptor actually points to in - ** low DOS memory. In real mode, this is a simple segment assignment and the size - ** is always 64K regardless of what is specified. In protected mode, the segment - ** is used to update the selector and the size can be any length. - ** In Watcom flat mode, it sets Selector == segment<<4 - */ - void Assign(unsigned short segment, long size=(1024L*64L)); - - /* - ** These routines will move the data to/from regular memory and the segment/descriptor - ** memory. - */ - void Copy_To(void *source, int dest, int size); - void Copy_From(void *dest, int source, int size); - void Copy_Word_To(short data, int dest); - void Copy_Byte_To(char data, int dest); - void Copy_DWord_To(long data, int dest); - short Copy_Word_From(int source); - char Copy_Byte_From(int source); - long Copy_DWord_From(int source); - - /* - ** These routines move data around between sections of segmented (descriptor) memory. - ** Typically, this is used when accessing DOS memory in protected mode or when dealing - ** with hard memory areas such as the screen. - */ - static void Copy(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size); - static void Swap(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size); -}; - - -inline DOSSegmentClass::DOSSegmentClass(void) -{ - Selector = 0xB0000; -} - -inline DOSSegmentClass::~DOSSegmentClass(void) -{ -} - -inline void DOSSegmentClass::Copy_Word_To(short data, int dest) -{ - *(short *)(Selector+dest) = data; -} - -inline void DOSSegmentClass::Copy_Byte_To(char data, int dest) -{ - *(char *)(Selector+dest) = data; -} - -inline void DOSSegmentClass::Copy_DWord_To(long data, int dest) -{ - *(long *)(Selector+dest) = data; -} - -inline DOSSegmentClass::DOSSegmentClass(unsigned short segment, long) -{ - Assign(segment); -} - -inline void DOSSegmentClass::Assign(unsigned short segment, long) -{ - Selector = (long)(segment)<<4L; -} - -inline void DOSSegmentClass::Copy_To(void *source, int dest, int size) -{ - memmove((void*)(Selector+dest), source, size); -} - -inline void DOSSegmentClass::Copy_From(void *dest, int source, int size) -{ - memmove(dest, (void*)(Selector+source), size); -} - -inline void DOSSegmentClass::Copy(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size) { - memmove((void*)(dest.Selector+doffset), (void*)(src.Selector+soffset), size); -} - -inline short DOSSegmentClass::Copy_Word_From(int source) -{ - return *(short*)(Selector+source); -} - -inline char DOSSegmentClass::Copy_Byte_From(int source) -{ - return *(char*)(Selector+source); -} - -inline long DOSSegmentClass::Copy_DWord_From(int source) -{ - return *(long*)(Selector+source); -} - -inline unsigned int DOSSegmentClass::Get_Selector(void) -{ - return Selector; -} -#endif - - diff --git a/code/TIBERIANDAWN/DRIVE.CPP b/code/TIBERIANDAWN/DRIVE.CPP deleted file mode 100644 index dfd1cda..0000000 --- a/code/TIBERIANDAWN/DRIVE.CPP +++ /dev/null @@ -1,2290 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\drive.cpv 2.17 16 Oct 1995 16:51:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DRIVE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 22, 1994 * - * * - * Last Update : July 30, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * DriveClass::AI -- Processes unit movement and rotation. * - * DriveClass::Approach_Target -- Handles approaching the target in order to attack it. * - * DriveClass::Assign_Destination -- Set the unit's NavCom. * - * DriveClass::Class_Of -- Fetches a reference to the class type for this object. * - * DriveClass::Debug_Dump -- Displays status information to monochrome screen. * - * DriveClass::Do_Turn -- Tries to turn the vehicle to the specified direction. * - * DriveClass::DriveClass -- Constructor for drive class object. * - * DriveClass::Exit_Map -- Give the unit a movement order to exit the map. * - * DriveClass::Fixup_Path -- Adds smooth start path to normal movement path. * - * DriveClass::Force_Track -- Forces the unit to use the indicated track. * - * DriveClass::Lay_Track -- Handles track laying logic for the unit. * - * DriveClass::Offload_Tiberium_Bail -- Offloads one Tiberium quantum from the object. * - * DriveClass::Ok_To_Move -- Checks to see if this object can begin moving. * - * DriveClass::Overrun_Square -- Handles vehicle overrun of a cell. * - * DriveClass::Per_Cell_Process -- Handles when unit finishes movement into a cell. * - * DriveClass::Smooth_Turn -- Handles the low level coord calc for smooth turn logic. * - * DriveClass::Start_Of_Move -- Tries to get a unit to advance toward cell. * - * DriveClass::Tiberium_Load -- Determine the Tiberium load as a percentage. * - * DriveClass::While_Moving -- Processes unit movement. * - * DriveClass::Mark_Track -- Marks the midpoint of the track as occupied. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -DriveClass::DriveClass(void) : Class(0), SimLeptonX(0), SimLeptonY(0) {}; // Added SimLeptonX and Y. ST - 4/30/2019 8:06AM - - -/*********************************************************************************************** - * DriveClass::Do_Turn -- Tries to turn the vehicle to the specified direction. * - * * - * This routine will set the vehicle to rotate to the direction specified. For tracked * - * vehicles, it is just a simple rotation. For wheeled vehicles, it performs a series * - * of short drives (three point turn) to face the desired direction. * - * * - * INPUT: dir -- The direction that this vehicle should face. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/29/1995 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Do_Turn(DirType dir) -{ - if (dir != PrimaryFacing) { - - /* - ** Special rotation track is needed for units that - ** cannot rotate in place. - */ - if (Special.IsThreePoint && TrackNumber == -1 && Class->Speed == SPEED_WHEEL) { - int facediff; // Signed difference between current and desired facing. - FacingType face; // Current facing (ordinal value). - - facediff = PrimaryFacing.Difference(dir) >> 5; - facediff = Bound(facediff, -2, 2); - if (facediff) { - face = Dir_Facing(PrimaryFacing); - - IsOnShortTrack = true; - Force_Track(face*FACING_COUNT + (face + facediff), Coord); - - Path[0] = FACING_NONE; - Set_Speed(0xFF); // Full speed. - } - } else { - PrimaryFacing.Set_Desired(dir); - //if (Special.IsJurassic && AreThingiesEnabled && What_Am_I() == RTTI_UNIT && ((UnitClass *)this)->Class->IsPieceOfEight) PrimaryFacing.Set_Current(dir); - if (What_Am_I() == RTTI_UNIT && ((UnitClass *)this)->Class->IsPieceOfEight) PrimaryFacing.Set_Current(dir); - } - } -} - - -/*********************************************************************************************** - * DriveClass::Force_Track -- Forces the unit to use the indicated track. * - * * - * This override (nuclear bomb) style routine is to be used when a unit needs to start * - * on a movement track but is outside the normal movement system. This occurs when a * - * harvester starts driving off of a refinery. * - * * - * INPUT: track -- The track number to start on. * - * * - * coord -- The coordinate that the unit will end up at when the movement track * - * is completed. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/17/1995 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Force_Track(int track, COORDINATE coord) -{ - TrackNumber = track; - TrackIndex = 0; - Start_Driver(coord); -} - - -/*********************************************************************************************** - * DriveClass::Tiberium_Load -- Determine the Tiberium load as a percentage. * - * * - * Use this routine to determine what the Tiberium load is (as a fixed point percentage). * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current "fullness" rating for the object. This will be 0x0000 for * - * empty and 0x0100 for full. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/17/1995 JLB : Created. * - *=============================================================================================*/ -int DriveClass::Tiberium_Load(void) const -{ - if (*this == UNIT_HARVESTER) { - return(Cardinal_To_Fixed(UnitTypeClass::STEP_COUNT, Tiberium)); - } - return(0x0000); -} - - -/*********************************************************************************************** - * DriveClass::Approach_Target -- Handles approaching the target in order to attack it. * - * * - * This routine will check to see if the target is infantry and it can be overrun. It will * - * try to overrun the infantry rather than attack it. This only applies to computer * - * controlled vehicles. If it isn't the infantry overrun case, then it falls into the * - * base class for normal (complex) approach algorithm. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/17/1995 JLB : Created. * - * 07/12/1995 JLB : Flamethrower tanks don't overrun -- their weapon is better. * - *=============================================================================================*/ -void DriveClass::Approach_Target(void) -{ - /* - ** Only if there is a legal target should the approach check occur. - */ - if (!House->IsHuman && Target_Legal(TarCom) && !Target_Legal(NavCom)) { - - /* - ** Special case: - ** If this is for a unit that can crush infantry, and the target is - ** infantry, AND the infantry is pretty darn close, then just try - ** to drive over the infantry instead of firing on it. - */ - TechnoClass * target = As_Techno(TarCom); - if (Class->Primary != WEAPON_FLAME_TONGUE && Class->IsCrusher && Distance(TarCom) < 0x0180 && target && ((TechnoTypeClass const &)(target->Class_Of())).IsCrushable) { - Assign_Destination(TarCom); - return; - } - } - - /* - ** In the other cases, uses the more complex "get to just within weapon range" - ** algorithm. - */ - FootClass::Approach_Target(); -} - - -/*********************************************************************************************** - * DriveClass::Overrun_Square -- Handles vehicle overrun of a cell. * - * * - * This routine is called when a vehicle enters a square or when it is about to enter a * - * square (controlled by parameter). When a vehicle that can crush infantry enters a * - * cell that contains infantry, then the infantry will be destroyed (regardless of * - * affiliation). When a vehicle threatens to overrun a square, all occupying infantry * - * will attempt to get out of the way. * - * * - * INPUT: cell -- The cell that is, or soon will be, entered by a vehicle. * - * * - * threaten -- Don't kill, but just threaten to enter the cell. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Overrun_Square(CELL cell, bool threaten) -{ - CellClass * cellptr = &Map[cell]; - - if (Class->IsCrusher) { - if (threaten) { - - /* - ** If the cell contains infantry, then they will panic when a vehicle tries - ** drive over them. Have the infantry run away instead. - */ - if (cellptr->Flag.Composite & 0x1F) { - - /* - ** Scattering is controlled by the game difficulty level. - */ - if (((GameToPlay == GAME_NORMAL && PlayerPtr->Difficulty == DIFF_HARD) || Special.IsScatter || Scenario > 8) && - !(GameToPlay == GAME_NORMAL && PlayerPtr->Difficulty == DIFF_EASY)) { - cellptr->Incoming(0, true); - } - } - } else { - ObjectClass * object = cellptr->Cell_Occupier(); - int crushed = false; - while (object) { - if (object->Class_Of().IsCrushable && !House->Is_Ally(object) && Distance(object->Center_Coord()) < 0x80) { - ObjectClass * next = object->Next; - crushed = true; - - /* - ** Record credit for the kill(s) - */ - Sound_Effect(VOC_SQUISH2, Coord); - object->Record_The_Kill(this); - object->Mark(MARK_UP); - object->Limbo(); - delete object; - new OverlayClass(OVERLAY_SQUISH, Coord_Cell(Coord)); - - object = next; - } else { - object = object->Next; - } - } - if (crushed) Do_Uncloak(); - } - } -} - - -/*********************************************************************************************** - * DriveClass::DriveClass -- Constructor for drive class object. * - * * - * This will initialize the drive class to its default state. It is called as a result * - * of creating a unit. * - * * - * INPUT: classid -- The unit's ID class. It is passed on to the foot class constructor. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/13/1994 JLB : Created. * - *=============================================================================================*/ -DriveClass::DriveClass(UnitType classid, HousesType house) : - Class(&UnitTypeClass::As_Reference(classid)), - FootClass(house) -{ - /* - ** For two shooters, clear out the second shot flag -- it will be set the first time - ** the object fires. For non two shooters, set the flag since it will never be cleared - ** and the second shot flag tells the system that normal rearm times apply -- this is - ** what is desired for non two shooters. - */ - if (Class->IsTwoShooter) { - IsSecondShot = false; - } else { - IsSecondShot = true; - } - IsHarvesting = false; - IsTurretLockedDown = false; - IsOnShortTrack = false; - IsReturning = false; - TrackNumber = -1; - TrackIndex = 0; - SpeedAccum = 0; - Tiberium = 0; - Strength = Class->MaxStrength; -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * DriveClass::Debug_Dump -- Displays status information to monochrome screen. * - * * - * This debug utility function will display the status of the drive class to the mono * - * screen. It is through this information that bugs can be tracked down. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Debug_Dump(MonoClass *mono) const -{ - mono->Set_Cursor(33, 7); - mono->Printf("%2d:%2d", TrackNumber, TrackIndex); - mono->Text_Print("X", 16 + (IsTurretLockedDown?2:0), 10); -// mono->Text_Print("X", 16 + (IsOnShortTrack?2:0), 11); - mono->Set_Cursor(41, 7);mono->Printf("%d", Fixed_To_Cardinal(100, Tiberium_Load())); - FootClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * DriveClass::Exit_Map -- Give the unit a movement order to exit the map. * - * * - * This routine is used to assign an appropriate movement destination for the unit so that * - * it will leave the map. The scripts are usually the one to call this routine when it * - * is determined that the unit has fulfilled its mission and must "depart". * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Exit_Map(void) -{ - CELL cell; // Map exit cell number. - - if (*this == UNIT_HOVER && !Target_Legal(NavCom)) { - - /* - ** Scan a swath of cells from current position to the edge of the map and if - ** there is any blocking object, just wait so to try again later. - */ - Mark(MARK_UP); - for (int x = Cell_X(Coord_Cell(Center_Coord()))-1; x <= Cell_X(Coord_Cell(Center_Coord()))+1; x++) { - for (int y = Cell_Y(Coord_Cell(Center_Coord()))+1; y < Map.MapCellY+Map.MapCellHeight; y++) { - cell = XY_Cell(x, y); - if (Map[cell].Cell_Techno()) { - Mark(MARK_DOWN); - return; - } - } - } - Mark(MARK_DOWN); - - /* - ** A clear path to the map edge exists. Assign it as the navigation computer - ** destination and let the transport move. - */ - cell = XY_Cell(Cell_X(Coord_Cell(Coord)), Map.MapCellY+Map.MapCellHeight); - IsReturning = true; - Assign_Destination(::As_Target(cell)); - } -} - - -/*********************************************************************************************** - * DriveClass::Smooth_Turn -- Handles the low level coord calc for smooth turn logic. * - * * - * This routine calculates the new coordinate value needed for the * - * smooth turn logic. The adjustment and flag values must be * - * determined prior to entering this routine. * - * * - * INPUT: adj -- The adjustment coordinate as lifted from the * - * correct smooth turn table. * - * * - * dir -- Pointer to dir for possible modification * - * according to the flag bits. * - * * - * OUTPUT: Returns with the coordinate the unit should positioned to. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/14/1994 JLB : Created. * - * 07/13/1994 JLB : Converted to member function. * - *=============================================================================================*/ -COORDINATE DriveClass::Smooth_Turn(COORDINATE adj, DirType *dir) -{ - DirType workdir = *dir; - int x,y; - int temp; - TrackControlType flags = TrackControl[TrackNumber].Flag; - - x = Coord_X(adj); - y = Coord_Y(adj); - - if (flags & F_T) { - temp = x; - x = y; - y = temp; - workdir = (DirType)(DIR_W - workdir); - } - - if (flags & F_X) { - x = -x; - workdir = (DirType)-workdir; - } - - if (flags & F_Y) { - y = -y; - workdir = (DirType)(DIR_S - workdir); - } - - *dir = workdir; - - return(XY_Coord( Coord_X(Head_To_Coord()) + x, Coord_Y(Head_To_Coord()) + y)); -} - - -/*********************************************************************************************** - * DriveClass::Assign_Destination -- Set the unit's NavCom. * - * * - * This routine is used to set the unit's navigation computer to the * - * specified target. Once the navigation computer is set, the unit * - * will start planning and moving toward the destination. * - * * - * INPUT: target -- The destination target for the unit to head to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/07/1992 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void DriveClass::Assign_Destination(TARGET target) -{ - - /* - ** Abort early if there is anything wrong with the parameters - ** or the unit already is assigned the specified destination. - */ - if (target == NavCom) return; - -#ifdef NEVER - UnitClass *tunit; // Destination unit pointer. - - /* - ** When in move mode, a map position may really indicate - ** a unit to guard. - */ - if (Is_Target_Cell(target)) { - cell = As_Cell(target); - - tunit = Map[cell].Cell_Unit(); - if (tunit) { - - /* - ** Prevent targeting of itself. - */ - if (tunit != this) { - target = tunit->As_Target(); - } - } else { - - tbuilding = Map[cell].Cell_Building(); - if (tbuilding) { - target = tbuilding->As_Target(); - } - } - } -#endif - - /* - ** For harvesting type vehicles, it might go into a dock and unload procedure - ** when the harvester is full and an empty refinery is selected as a target. - */ - BuildingClass * b = As_Building(target); - - /* - ** Transport vehicles must tell all passengers that are about to load, that they - ** cannot proceed. This is accomplished with a radio message to this effect. - */ - //if (tunit && In_Radio_Contact() && Class->IsTransporter && Contact_With_Whom()->Is_Infantry()) { - if (In_Radio_Contact() && Class->IsTransporter && Contact_With_Whom()->Is_Infantry()) { - Transmit_Message(RADIO_OVER_OUT); - } - - /* - ** If the player clicked on a friendly repair facility and the repair - ** facility is currently not involved with some other unit (radio or unloading). - */ - if (b && *b == STRUCT_REPAIR) { - if (b->In_Radio_Contact() && (b->Contact_With_Whom() != this)) { - ArchiveTarget = target; - } else { - - /* - ** Establish radio contact protocol. If the facility responds correctly, - ** then remain in radio contact and proceed toward the desired destination. - */ - if (Transmit_Message(RADIO_HELLO, b) == RADIO_ROGER) { - - /* - ** Last check to make sure that the loading square is free from permanent - ** occupation (such as a building). - */ - CELL cell = Coord_Cell(b->Center_Coord()) + (MAP_CELL_W-1); - if (Ground[Map[cell].Land_Type()].Cost[Class->Speed] ) { - if (Transmit_Message(RADIO_DOCKING) == RADIO_ROGER) { - FootClass::Assign_Destination(target); - Path[0] = FACING_NONE; - return; - } - - /* - ** Failure to establish a docking relationship with the refinery. - ** Bail & await further instructions. - */ - Transmit_Message(RADIO_OVER_OUT); - } - } - } - } - - /* - ** Set the unit's navigation computer. - */ - FootClass::Assign_Destination(target); - Path[0] = FACING_NONE; // Force recalculation of path. - if (!IsDriving) { - Start_Of_Move(); - } -} - - -/*********************************************************************************************** - * DriveClass::While_Moving -- Processes unit movement. * - * * - * This routine is used to process movement for the units as they move. * - * It is called many times for each cell's worth of movement. This * - * routine only applies after the next cell HeadTo has been determined. * - * * - * INPUT: none * - * * - * OUTPUT: true/false; Should this routine be called again? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/02/1992 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -bool DriveClass::While_Moving(void) -{ - int actual; // Working movement addition value. - - /* - ** Perform quick legality checks. - */ - if (!IsDriving || TrackNumber == -1 || (IsRotating && !Class->IsTurretEquipped)) { - SpeedAccum = 0; // Kludge? No speed should accumulate if movement is on hold. - return(false); - } - - /* - ** If enough movement has accumulated so that the unit can - ** visibly move on the map, then process accordingly. - ** Slow the unit down if he's carrying a flag. - */ - MPHType maxspeed = MPHType(min((int)(Class->MaxSpeed * House->GroundspeedBias), (int)MPH_LIGHT_SPEED)); - if (((UnitClass *)this)->Flagged != HOUSE_NONE) { - actual = SpeedAccum + Fixed_To_Cardinal(maxspeed /2, Speed); - } else { - actual = SpeedAccum + Fixed_To_Cardinal(maxspeed, Speed); - } - - if (actual > PIXEL_LEPTON_W) { - TurnTrackType const *track; // Track control pointer. - TrackType const *ptr; // Pointer to coord offset values. - int tracknum; // The track number being processed. - FacingType nextface; // Next facing queued in path. - bool adj; // Is a turn coming up? - - track = &TrackControl[TrackNumber]; - if (IsOnShortTrack) { - tracknum = track->StartTrack; - } else { - tracknum = track->Track; - } - ptr = RawTracks[tracknum-1].Track; - nextface = Path[0]; - - /* - ** Determine if there is a turn coming up. If there is - ** a turn, then track jumping might occur. - */ - adj = false; - if (nextface != FACING_NONE && Dir_Facing(track->Facing) != nextface) { - adj = true; - } - - /* - ** Skip ahead the number of track steps required (limited only - ** by track length). Set the unit to the new position and - ** flag the unit accordingly. - */ - Mark(MARK_UP); - while (actual > PIXEL_LEPTON_W) { - COORDINATE offset; - DirType dir; - - actual -= PIXEL_LEPTON_W; - - offset = ptr[TrackIndex].Offset; - if (offset || !TrackIndex) { - dir = ptr[TrackIndex].Facing; - Coord = Smooth_Turn(offset, &dir); - - PrimaryFacing.Set(dir); - - /* - ** See if "per cell" processing is necessary. - */ - if (TrackIndex && RawTracks[tracknum-1].Cell == TrackIndex) { - Per_Cell_Process(false); - if (!IsActive) { - return(false); - } - } - - /* - ** The unit could "jump tracks". Check to see if the unit should - ** do so. - */ - if (*this != UNIT_GUNBOAT && nextface != FACING_NONE && adj && RawTracks[tracknum-1].Jump == TrackIndex && TrackIndex) { - TurnTrackType const *newtrack; // Proposed jump-to track. - int tnum; - - tnum = Dir_Facing(track->Facing)*FACING_COUNT + nextface; - newtrack = &TrackControl[tnum]; - if (newtrack->Track && RawTracks[newtrack->Track-1].Entry) { - COORDINATE c = Head_To_Coord(); - int oldspeed = Speed; - - c = Adjacent_Cell(c, nextface); - - switch(Can_Enter_Cell(Coord_Cell(c), nextface)) { - case MOVE_OK: - IsOnShortTrack = false; // Shouldn't be necessary, but... - TrackNumber = tnum; - track = newtrack; - - // Mono_Printf("**Jumping from track %d to track %d. **\n", tracknum, track->Track);Keyboard::Get(); - - tracknum = track->Track; - TrackIndex = RawTracks[tracknum-1].Entry-1; // Anticipate increment. - ptr = RawTracks[tracknum-1].Track; - adj = false; - - Stop_Driver(); - Per_Cell_Process(true); - if (Start_Driver(c)) { - Set_Speed(oldspeed); - memcpy(&Path[0], &Path[1], CONQUER_PATH_MAX-1); - Path[CONQUER_PATH_MAX-1] = FACING_NONE; - } else { - Path[0] = FACING_NONE; - TrackNumber = -1; - actual = 0; - } - break; - - case MOVE_CLOAK: - Map[Coord_Cell(c)].Shimmer(); - break; - - case MOVE_TEMP: - if (*this == UNIT_HARVESTER || !House->IsHuman) { - bool old = Special.IsScatter; - Special.IsScatter = true; - Map[Coord_Cell(c)].Incoming(0, true); - Special.IsScatter = old; - } - break; - } - } - } - TrackIndex++; - - } else { - actual = 0; - Coord = Head_To_Coord(); - Stop_Driver(); - TrackNumber = -1; - TrackIndex = NULL; - - /* - ** Perform "per cell" activities. - */ - Per_Cell_Process(true); - - break; - } - } - if (IsActive) { - Mark(MARK_DOWN); - } - } - - - - /* - ** NEW 4/30/2019 7:59AM - ** - ** When we don't have enough speed accumulated to move another pixel, it would be good to know at a sub-pixel (lepton) level - ** how far we would move if we could. It didn't matter in the original when it was 320x200 pixels, but on a 3840x2160 - ** screen, what was half a pixel could now be several pixels. - ** - ** ST - ** - */ - if (actual && actual <= PIXEL_LEPTON_W) { - TurnTrackType const *track; // Track control pointer. - TrackType const *ptr; // Pointer to coord offset values. - int tracknum; // The track number being processed. - FacingType nextface; // Next facing queued in path. - bool adj; // Is a turn coming up? - - track = &TrackControl[TrackNumber]; - if (IsOnShortTrack) { - tracknum = track->StartTrack; - } else { - tracknum = track->Track; - } - ptr = RawTracks[tracknum-1].Track; - nextface = Path[0]; - - /* - ** Determine if there is a turn coming up. If there is - ** a turn, then track jumping might occur. - */ - adj = false; - if (nextface != FACING_NONE && Dir_Facing(track->Facing) != nextface) { - adj = true; - } - - COORDINATE simulated_pos = Coord; - - COORDINATE offset; - DirType dir; - - offset = ptr[TrackIndex].Offset; - if (offset || !TrackIndex) { - dir = ptr[TrackIndex].Facing; - simulated_pos = Smooth_Turn(offset, &dir); - } - - int x_diff = Coord_X(simulated_pos) - Coord_X(Coord); - int y_diff = Coord_Y(simulated_pos) - Coord_Y(Coord); - - SimLeptonX = (x_diff * actual) / PIXEL_LEPTON_W; - SimLeptonY = (y_diff * actual) / PIXEL_LEPTON_W; - } else { - SimLeptonX = 0; - SimLeptonY = 0; - } - - - - /* - ** Replace any remainder back into the unit's movement - ** accumulator to be processed next pass. - */ - SpeedAccum = actual; - return(true); -} - - -/*********************************************************************************************** - * DriveClass::Per_Cell_Process -- Handles when unit finishes movement into a cell. * - * * - * This routine is called when a unit has mostly or completely * - * entered a cell. The unit might be in the middle of a movement track * - * when this routine is called. It's primary purpose is to perform * - * sighting and other "per cell" activities. * - * * - * INPUT: center -- Is the unit safely at the center of a cell? If it is merely "close" * - * to the center, then this parameter will be false. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/03/1993 JLB : Created. * - * 03/30/1994 JLB : Revamped for track system. * - * 04/15/1994 JLB : Converted to member function. * - * 06/18/1994 JLB : Converted to virtual function. * - * 06/18/1994 JLB : Distinguishes between center and near-center conditions. * - *=============================================================================================*/ -void DriveClass::Per_Cell_Process(bool center) -{ - CELL cell = Coord_Cell(Coord); - - /* - ** Check to see if it has reached its destination. If so, then clear the NavCom - ** regardless of the remaining path list. - */ - if (center && As_Cell(NavCom) == cell) { - IsTurretLockedDown = false; - NavCom = TARGET_NONE; - Path[0] = FACING_NONE; - } - -#ifdef NEVER - /* - ** A "lemon" vehicle will have a tendency to break down as - ** it moves about the terrain. - */ - if (Is_A_Lemon) { - if (Random_Pick(1, 4) == 1) { - Take_Damage(1); - } - } -#endif - - Lay_Track(); - - FootClass::Per_Cell_Process(center); -} - - -/*********************************************************************************************** - * DriveClass::Start_Of_Move -- Tries to get a unit to advance toward cell. * - * * - * This will try to start a unit advancing toward the cell it is * - * facing. It will check for and handle legality and reserving of the * - * necessary cell. * - * * - * INPUT: none * - * * - * OUTPUT: true/false; Should this routine be called again because * - * initial start operation is temporarily delayed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/02/1992 JLB : Created. * - * 10/18/1993 JLB : This should be called repeatedly until HeadTo is not NULL. * - * 03/16/1994 JLB : Revamped for track logic. * - * 04/15/1994 JLB : Converted to member function. * - * 06/19/1995 JLB : Fixed so that it won't fire on ground unnecessarily. * - * 07/13/1995 JLB : Handles bumping into cloaked objects. * - *=============================================================================================*/ -bool DriveClass::Start_Of_Move(void) -{ - FacingType facing; // Direction movement will commence. - DirType dir; // Desired actual facing toward destination. - int facediff; // Difference between current and desired facing. - int speed; // Speed of unit. - CELL destcell; // Cell of destination. - LandType ground; // Ground unit is entering. - COORDINATE dest; // Destination coordinate. - - facing = Path[0]; - - if (!Target_Legal(NavCom) && facing == FACING_NONE) { - IsTurretLockedDown = false; - Stop_Driver(); - if (Mission == MISSION_MOVE) { - Enter_Idle_Mode(); - } - return(false); // Why is it calling this routine!?! - } - -#ifdef NEVER - /* - ** Movement start logic can't begin until a unit that requires - ** a locked down turret gets to a locked down state (i.e., the - ** turret rotation stops. - */ - if (ClassF & CLASSF_LOCKTURRET) { - Set_Secondary_Facing(facing<<5); - if (Is_Rotating) { - return(true); - } - } -#endif - - /* - ** Reduce the path length if the target is a unit and the - ** range to the unit is less than the precalculated path steps. - */ - if (facing != FACING_NONE) { - int dist; - - if (Is_Target_Unit(NavCom) || Is_Target_Infantry(NavCom)) { - dist = Lepton_To_Cell(Distance(NavCom)); - -// if (dist > CELL_LEPTON_W || -// !As_Techno(NavCom)->Techno_Type_Class()->IsCrushable || -// !Class->IsCrusher) { - - if (dist < CONQUER_PATH_MAX) { - Path[dist] = FACING_NONE; - facing = Path[0]; // Maybe needed. - } -// } - } - } - - /* - ** If the path is invalid at this point, then generate one. If - ** generating a new path fails, then abort NavCom. - */ - if (facing == FACING_NONE) { - - /* - ** If after a path search, there is still no valid path, then set the - ** NavCom to null and let the script take care of assigning a new - ** navigation target. - */ - if (!PathDelay.Expired()) { - return(false); - } - if (!Basic_Path()) { - if (Distance(NavCom) < 0x0280 && (Mission == MISSION_MOVE || Mission == MISSION_GUARD_AREA)) { - Assign_Destination(TARGET_NONE); - } else { - - /* - ** If a basic path could be found, but the immediate move destination is - ** blocked by a friendly temporary blockage, then cause that blockage - ** to scatter. - */ - CELL cell = Adjacent_Cell(Coord_Cell(Center_Coord()), PrimaryFacing.Current()); - if (Map.In_Radar(cell)) { - if (Can_Enter_Cell(cell) == MOVE_TEMP) { - CellClass * cellptr = &Map[cell]; - TechnoClass * blockage = cellptr->Cell_Techno(); - if (blockage && House->Is_Ally(blockage)) { - bool old = Special.IsScatter; - Special.IsScatter = true; - cellptr->Incoming(0, true); - Special.IsScatter = old; - } - } - } - - if (TryTryAgain) { - TryTryAgain--; - } else { - Assign_Destination(TARGET_NONE); - if (IsNewNavCom) Sound_Effect(VOC_SCOLD); - IsNewNavCom = false; - } - } - Stop_Driver(); - TrackNumber = -1; - IsTurretLockedDown = false; - return(false); - } - - /* - ** If a basic path could be found, but the immediate move destination is - ** blocked by a friendly temporary blockage, then cause that blockage - ** to scatter. - */ - CELL cell = Adjacent_Cell(Coord_Cell(Center_Coord()), Path[0]); - if (Map.In_Radar(cell)) { - if (Can_Enter_Cell(cell) == MOVE_TEMP) { - CellClass * cellptr = &Map[cell]; - TechnoClass * blockage = cellptr->Cell_Techno(); - if (blockage && House->Is_Ally(blockage)) { - bool old = Special.IsScatter; - Special.IsScatter = true; - cellptr->Incoming(0, true); - Special.IsScatter = old; - } - } - } - - TryTryAgain = PATH_RETRY; - facing = Path[0]; - } - - if (Class->IsLockTurret || !Class->IsTurretEquipped) { - IsTurretLockedDown = true; - } - -#ifdef NEVER - /* - ** If the turret needs to match the body's facing before - ** movement can occur, then start it's rotation and - ** don't start a movement track until it is aligned. - */ - if (!Ok_To_Move(BodyFacing)) { - return(true); - } -#endif - - /* - ** Determine the coordinate of the next cell to move into. - */ - dest = Adjacent_Cell(Coord, facing); - dir = Facing_Dir(facing); - - /* - ** Set the facing correctly if it isn't already correct. This - ** means starting a rotation track if necessary. - */ - facediff = PrimaryFacing.Difference(dir); - if (facediff) { - - /* - ** Request a change of facing. - */ - Do_Turn(dir); - return(true); - - } else { - - /* NOTE: Beyond this point, actual track assignment can begin. - ** - ** If the cell to move into is impassable (probably for some unexpected - ** reason), then abort the path list and set the speed to zero. The - ** next time this routine is called, a new path will be generated. - */ - destcell = Coord_Cell(dest); - Mark(MARK_UP); - MoveType cando = Can_Enter_Cell(destcell, facing); - Mark(MARK_DOWN); - - if (cando != MOVE_OK) { - - if (Mission == MISSION_MOVE && House->IsHuman && Distance(NavCom) < 0x0200) { - Assign_Destination(TARGET_NONE); - } - - /* - ** If a temporary friendly object is blocking the path, then cause it to - ** get out of the way. - */ - if (cando == MOVE_TEMP) { - bool old = Special.IsScatter; - Special.IsScatter = true; - Map[destcell].Incoming(0, true); - Special.IsScatter = old; - } - - /* - ** If a cloaked object is blocking, then shimmer the cell. - */ - if (cando == MOVE_CLOAK) { - Map[destcell].Shimmer(); - } - - Stop_Driver(); - if (cando != MOVE_MOVING_BLOCK) { - Path[0] = FACING_NONE; // Path is blocked! - } - - /* - ** If blocked by a moving block then just exit start of move and - ** try again next tick. - */ - if (cando == MOVE_DESTROYABLE) { - if (Map[destcell].Cell_Object()) { - if (!House->Is_Ally(Map[destcell].Cell_Object())) { - Override_Mission(MISSION_ATTACK, Map[destcell].Cell_Object()->As_Target(), TARGET_NONE); - } - } else { - if (Map[destcell].Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(Map[destcell].Overlay).IsWall) { - Override_Mission(MISSION_ATTACK, ::As_Target(destcell), TARGET_NONE); - } - } - } else { - if (IsNewNavCom) Sound_Effect(VOC_SCOLD); - } - IsNewNavCom = false; - TrackNumber = -1; - return(true); - } - - /* - ** Determine the speed that the unit can travel to the desired square. - */ - ground = Map[destcell].Land_Type(); - speed = Ground[ground].Cost[Class->Speed]; - if (!speed) speed = 128; - -#ifdef NEVER - /* - ** Set the jiggle flag if the terrain would cause the unit - ** to jiggle when travelled over. - */ - BaseF &= ~BASEF_JIGGLE; - if (Ground[ground].Jiggle) { - BaseF |= BASEF_JIGGLE; - } -#endif - - /* - ** A damaged unit has a reduced speed. - */ - if ((Class->MaxStrength>>1) > Strength) { - speed -= (speed>>2); // Three quarters speed. - } - if ((speed != Speed)/* || !SpeedAdd*/) { - Set_Speed(speed); // Full speed. - } - - /* - ** Adjust speed depending on distance to ultimate movement target. The - ** further away the target is, the faster the vehicle will travel. - */ - int dist = Distance(NavCom); - if (dist < 0x0200) { - speed = Fixed_To_Cardinal(speed, 0x00A0); - } else { - if (dist < 0x0700) { - speed = Fixed_To_Cardinal(speed, 0x00D0); - } - } - - /* - ** Reserve the destination cell so that it won't become - ** occupied AS this unit is moving into it. - */ - if (cando != MOVE_OK) { - Path[0] = FACING_NONE; // Path is blocked! - TrackNumber = -1; - dest = NULL; - } else { - - Overrun_Square(Coord_Cell(dest), true); - - /* - ** Determine which track to use (based on recorded path). - */ - FacingType nextface = Path[1]; - if (nextface == FACING_NONE) nextface = facing; - - IsOnShortTrack = false; - TrackNumber = facing * FACING_COUNT + nextface; - if (TrackControl[TrackNumber].Track == 0) { - Path[0] = FACING_NONE; - TrackNumber = -1; - return(true); - } else { - if (TrackControl[TrackNumber].Flag & F_D) { - /* - ** If the middle cell of a two cell track contains a crate, - ** the check for goodies before movement starts. - */ - if (!Map[destcell].Goodie_Check(this)) { - cando = MOVE_NO; - } else { - - dest = Adjacent_Cell(dest, nextface); - destcell = Coord_Cell(dest); - cando = Can_Enter_Cell(destcell); - } - - if (cando != MOVE_OK) { - - /* - ** If a temporary friendly object is blocking the path, then cause it to - ** get out of the way. - */ - if (cando == MOVE_TEMP) { - bool old = Special.IsScatter; - Special.IsScatter = true; - Map[destcell].Incoming(0, true); - Special.IsScatter = old; - } - - /* - ** If a cloaked object is blocking, then shimmer the cell. - */ - if (cando == MOVE_CLOAK) { - Map[destcell].Shimmer(); - } - - Path[0] = FACING_NONE; // Path is blocked! - TrackNumber = -1; - dest = NULL; - if (cando == MOVE_DESTROYABLE) { - - if (Map[destcell].Cell_Object()) { - if (!House->Is_Ally(Map[destcell].Cell_Object())) { - Override_Mission(MISSION_ATTACK, Map[destcell].Cell_Object()->As_Target(), TARGET_NONE); - } - } else { - if (Map[destcell].Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(Map[destcell].Overlay).IsWall) { - Override_Mission(MISSION_ATTACK, ::As_Target(destcell), TARGET_NONE); - } - } - IsNewNavCom = false; - TrackIndex = 0; - return(true); - } - } else { - memcpy(&Path[0], &Path[2], CONQUER_PATH_MAX-2); - Path[CONQUER_PATH_MAX-2] = FACING_NONE; - IsPlanningToLook = true; - } - } else { - memcpy(&Path[0], &Path[1], CONQUER_PATH_MAX-1); - } - Path[CONQUER_PATH_MAX-1] = FACING_NONE; - } - } - - IsNewNavCom = false; - TrackIndex = 0; - if (!Start_Driver(dest)) { - TrackNumber = -1; - Path[0] = FACING_NONE; - Set_Speed(0); - } - } - return(false); -} - - -/*********************************************************************************************** - * DriveClass::AI -- Processes unit movement and rotation. * - * * - * This routine is used to process unit movement and rotation. It * - * functions autonomously from the script system. Thus, once a unit * - * is give rotation command or movement path, it will follow this * - * until specifically instructed to stop. The advantage of this * - * method is that it allows smooth movement of units, faster game * - * execution, and reduced script complexity (since actual movement * - * dynamics need not be controlled directly by the scripts). * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine relies on the process control bits for the * - * specified unit (for speed reasons). Thus, only setting * - * movement, rotation, or path list will the unit perform * - * any physics. * - * * - * HISTORY: * - * 09/26/1993 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void DriveClass::AI(void) -{ - FootClass::AI(); - - /* - ** If the unit is following a track, then continue - ** to do so -- mindlessly. - */ - if (TrackNumber != -1) { - - /* - ** Perform the movement accumulation. - */ - While_Moving(); - if (!IsActive) return; - if (TrackNumber == -1 && (Target_Legal(NavCom) || Path[0] != FACING_NONE)) { - Start_Of_Move(); - While_Moving(); - if (!IsActive) return; - } - - } else { - - /* - ** For tracked units that are rotating in place, perform the rotation now. - */ - if ((Class->Speed == SPEED_FLOAT || Class->Speed == SPEED_HOVER || Class->Speed == SPEED_TRACK || (Class->Speed == SPEED_WHEEL && !Special.IsThreePoint)) && PrimaryFacing.Is_Rotating()) { - if (PrimaryFacing.Rotation_Adjust((int)(Class->ROT * House->GroundspeedBias))) { - Mark(MARK_CHANGE); - } - if (!IsRotating) { - Per_Cell_Process(true); - if (!IsActive) return; - } - - } else { - - /* - ** The unit has no track to follow, but if there - ** is a navigation target or a remaining path, - ** then start on a new track. - */ - if (Mission != MISSION_GUARD || NavCom != TARGET_NONE) { - if (Target_Legal(NavCom) || Path[0] != FACING_NONE) { - Start_Of_Move(); - While_Moving(); - if (!IsActive) return; - } else { - Stop_Driver(); - } - } - } - } -} - - -/*********************************************************************************************** - * DriveClass::Fixup_Path -- Adds smooth start path to normal movement path. * - * * - * This routine modifies the path of the specified unit so that it * - * will not start out with a rotation. This is necessary for those * - * vehicles that have difficulty with rotating in place. Typically, * - * this includes wheeled vehicles. * - * * - * INPUT: unit -- Pointer to the unit to adjust. * - * * - * path -- Pointer to path structure. * - * * - * OUTPUT: none * - * * - * WARNINGS: Only units that require a fixup get modified. The * - * modification only occurs, if there is a legal path to * - * do so. * - * * - * HISTORY: * - * 04/03/1994 JLB : Created. * - * 04/06/1994 JLB : Uses path structure. * - * 04/10/1994 JLB : Diagonal smooth turn added. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void DriveClass::Fixup_Path(PathType *path) -{ - FacingType stage[6]={FACING_N,FACING_N,FACING_N,FACING_N,FACING_N,FACING_N}; // Prefix path elements. - int facediff; // The facing difference value (0..4 | 0..-4). - static FacingType _path[4][6] = { - {(FacingType)2,(FacingType)0,(FacingType)2,(FacingType)0,(FacingType)0,(FacingType)0}, - {(FacingType)3,(FacingType)0,(FacingType)2,(FacingType)2,(FacingType)0,(FacingType)0}, - {(FacingType)4,(FacingType)0,(FacingType)2,(FacingType)2,(FacingType)0,(FacingType)0}, - {(FacingType)4,(FacingType)0,(FacingType)2,(FacingType)2,(FacingType)1,(FacingType)0} - }; - static FacingType _dpath[4][6] = { - {(FacingType)0,(FacingType)0,(FacingType)0,(FacingType)0,(FacingType)0,(FacingType)0}, - {(FacingType)3,(FacingType)0,(FacingType)2,(FacingType)2,(FacingType)0,(FacingType)0}, - {(FacingType)4,(FacingType)0,(FacingType)2,(FacingType)2,(FacingType)1,(FacingType)0}, - {(FacingType)5,(FacingType)0,(FacingType)2,(FacingType)2,(FacingType)1,(FacingType)0} - }; - - int index; - int counter; // Path addition - FacingType *ptr; // Path list pointer. - FacingType *ptr2; // Copy of new path list pointer. - FacingType nextpath; // Next path value. - CELL cell; // Working cell value. - bool ok; - - /* - ** Verify that the unit is valid and there is a path problem to resolve. - */ - if (!path || path->Command[0] == FACING_NONE) { - return; - } - - /* - ** Only wheeled vehicles need a path fixup -- to avoid 3 point turns. - */ - if (!Special.IsThreePoint || Class->Speed != SPEED_WHEEL) { - return; - } - - /* - ** If the original path starts in the same direction as the unit, then - ** there is no problem to resolve -- abort. - */ - facediff = PrimaryFacing.Difference((DirType)(path->Command[0]<<5)) >> 5; - - if (!facediff) return; - - if (Dir_Facing(PrimaryFacing) & FACING_NE) { - ptr = &_dpath[(FacingType)ABS((int)facediff)-FACING_NE][1]; // Pointer to path adjust list. - counter = (int)_dpath[(FacingType)ABS((int)facediff)-FACING_NE][0]; // Number of path adjusts. - } else { - ptr = &_path[(FacingType)ABS((int)facediff)-FACING_NE][1]; // Pointer to path adjust list. - counter = (int)_path[(FacingType)ABS((int)facediff)-FACING_NE][0]; // Number of path adjusts. - } - ptr2 = ptr; - - ok = true; // Presume adjustment is all ok. - cell = Coord_Cell(Coord); // Starting cell. - nextpath = Dir_Facing(PrimaryFacing); // Starting path. - for (index = 0; index < counter; index++) { - - /* - ** Determine next path element and add it to the - ** working path list. - */ - if (facediff > 0) { - nextpath = nextpath + *ptr++; - } else { - nextpath = nextpath - *ptr++; - } - stage[index] = nextpath; - cell = Adjacent_Cell(cell, nextpath); - //cell = Coord_Cell(Adjacent_Cell(Cell_Coord(cell), nextpath)); - - /* - ** If it can't enter this cell, then abort the path - ** building operation without adjusting the unit's - ** path. - */ - if (Can_Enter_Cell(cell, nextpath) != MOVE_OK) { - ok = false; - break; - } - } - - /* - ** If veering to the left was not successful, then try veering - ** to the right. This only makes sense if the vehicle is trying - ** to turn 180 degrees. - */ - if (!ok && ABS(facediff) == 4) { - ptr = ptr2; // Pointer to path adjust list. - facediff = -facediff; - ok = true; // Presume adjustment is all ok. - cell = Coord_Cell(Coord); // Starting cell. - nextpath = Dir_Facing(PrimaryFacing); // Starting path. - for (index = 0; index < counter; index++) { - - /* - ** Determine next path element and add it to the - ** working path list. - */ - if (facediff > 0) { - nextpath = nextpath + *ptr++; - } else { - nextpath = nextpath - *ptr++; - } - stage[index] = nextpath; - cell = Coord_Cell(Adjacent_Cell(Cell_Coord(cell), nextpath)); - - /* - ** If it can't enter this cell, then abort the path - ** building operation without adjusting the unit's - ** path. - */ - if (Can_Enter_Cell(cell, nextpath) != MOVE_OK) { - ok = false; - break; - } - } - } - - /* - ** If a legal path addition was created, then install it in place - ** of the first path value. The initial path entry is to be replaced - ** with a sequence of path entries that create smooth turning. - */ - if (ok) { - if (path->Length <= 1) { - movmem(&stage[0], path->Command, MAX(counter, 1)); - path->Length = counter; - } else { - - /* - ** Optimize the transition path step from the smooth turn - ** first part as it joins with the rest of the normal - ** path. The normal prefix path steps are NOT to be optimized. - */ - if (counter) { - counter--; - path->Command[0] = stage[counter]; - Optimize_Moves(path, MOVE_OK); - } - - /* - ** If there is more than one prefix path element, then - ** insert the rest now. - */ - if (counter) { - movmem(&path->Command[0], &path->Command[counter], 40-counter); - movmem(&stage[0], &path->Command[0], counter); - path->Length += counter; - } - } - path->Command[path->Length] = FACING_NONE; - } -} - - -/*********************************************************************************************** - * DriveClass::Lay_Track -- Handles track laying logic for the unit. * - * * - * This routine handles the track laying for the unit. This entails examining the unit's * - * current location as well as the direction and whether this unit is allowed to lay * - * tracks in the first place. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Lay_Track(void) -{ -#ifdef NEVER - static IconCommandType *_trackdirs[8] = { - TrackN_S, - TrackNE_SW, - TrackE_W, - TrackNW_SE, - TrackN_S, - TrackNE_SW, - TrackE_W, - TrackNW_SE - }; - - if (!(ClassF & CLASSF_TRACKS)) return; - - Icon_Install(Coord_Cell(Coord), _trackdirs[Facing_To_8(BodyFacing)]); -#endif -} - - -/*********************************************************************************************** - * DriveClass::Mark_Track -- Marks the midpoint of the track as occupied. * - * * - * This routine will ensure that the midpoint (if any) of the track that the unit is * - * following, will be marked according to the mark type specified. * - * * - * INPUT: headto -- The head to coordinate. * - * * - * type -- The type of marking to perform. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/30/1995 JLB : Created. * - *=============================================================================================*/ -void DriveClass::Mark_Track(COORDINATE headto, MarkType type) -{ - int value; - - if (type == MARK_UP) { - value = false; - } else { - value = true; - } - - if (headto) { - if (!IsOnShortTrack && TrackNumber != -1) { - - /* - ** If we have not passed the per cell process point we need - ** to deal with it. - */ - int tracknum = TrackControl[TrackNumber].Track; - if (tracknum) { - TrackType const * ptr = RawTracks[tracknum - 1].Track; - int cellidx = RawTracks[tracknum - 1].Cell; - if (cellidx > -1) { - DirType dir = ptr[cellidx].Facing; - - if (TrackIndex < cellidx && cellidx != -1) { - COORDINATE offset = Smooth_Turn(ptr[cellidx].Offset, &dir); - CELL cell = Coord_Cell(offset); - if ((unsigned)cell < MAP_CELL_TOTAL) { - Map[cell].Flag.Occupy.Vehicle = value; - } - } - } - } - } - CELL cell = Coord_Cell(headto); - if ((unsigned)cell < MAP_CELL_TOTAL) { - Map[cell].Flag.Occupy.Vehicle = value; - } - } -} - - -/*********************************************************************************************** - * DriveClass::Offload_Tiberium_Bail -- Offloads one Tiberium quantum from the object. * - * * - * This routine will offload one Tiberium packet/quantum/bail from the object. Multiple * - * calls to this routine are needed in order to fully offload all Tiberium. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of credits offloaded for the one call. If zero is returned,* - * then this indicates that all Tiberium has been offloaded. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -int DriveClass::Offload_Tiberium_Bail(void) -{ - if (Tiberium) { - Tiberium--; - if (House->IsHuman) { - return(UnitTypeClass::FULL_LOAD_CREDITS/UnitTypeClass::STEP_COUNT); // 25 in debugger - } - - // MBL 05.14.2020: AI harvested credits fix for multiplayer, since they are miscalculated, and it's noticed - // - // return(UnitTypeClass::FULL_LOAD_CREDITS+(UnitTypeClass::FULL_LOAD_CREDITS/3)/UnitTypeClass::STEP_COUNT); 708 in debugger - // - if (GameToPlay == GAME_NORMAL) // Non-multiplayer game, keep the original calculation; 708 in debugger - { - return(UnitTypeClass::FULL_LOAD_CREDITS+(UnitTypeClass::FULL_LOAD_CREDITS/3)/UnitTypeClass::STEP_COUNT); // Original (708), wrong calcualation but preserving to not break missions - } - else // Multiplayer game, apply the 1/3 bonus credits correction, so not be as extreme; 33 in debugger - { - return((UnitTypeClass::FULL_LOAD_CREDITS+(UnitTypeClass::FULL_LOAD_CREDITS/3))/UnitTypeClass::STEP_COUNT); // Corrected calculation - } - } - return(0); -} - - -/*********************************************************************************************** - * DriveClass::Ok_To_Move -- Checks to see if this object can begin moving. * - * * - * This routine is used to verify that this object is allowed to move. Some objects can * - * be temporarily occupied and thus cannot move until the situation permits. * - * * - * INPUT: direction -- The direction that movement would be desired. * - * * - * OUTPUT: Can the unit move in the direction specified? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -bool DriveClass::Ok_To_Move(DirType ) const -{ - return true; -} - - -/*********************************************************************************************** - * DriveClass::Class_Of -- Fetches a reference to the class type for this object. * - * * - * This routine will fetch a reference to the TypeClass of this object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with reference to the type class of this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -ObjectTypeClass const & DriveClass::Class_Of(void) const -{ - return *Class; -} - - -/*************************************************************************** -** Smooth turn track tables. These are coordinate offsets from the center -** of the destination cell. These are the raw tracks that are modified -** by negating the X and Y portions as necessary. Also for reverse travelling -** direction, the track list can be processed backward. -** -** Track 1 = N -** Track 2 = NE -** Track 3 = N->NE 45 deg (double path consumption) -** Track 4 = N->E 90 deg (double path consumption) -** Track 5 = NE->SE 90 deg (double path consumption) -** Track 6 = NE->N 45 deg (double path consumption) -** Track 7 = N->NE (facing change only) -** Track 8 = NE->E (facing change only) -** Track 9 = N->E (facing change only) -** Track 10= NE->SE (facing change only) -** Track 11= back up into refinery -** Track 12= drive out of refinery -*/ -//#pragma warn -ias -DriveClass::TrackType const DriveClass::Track1[24] = { - {0x00F50000L,(DirType)0}, - {0x00EA0000L,(DirType)0}, - {0x00DF0000L,(DirType)0}, - {0x00D40000L,(DirType)0}, - {0x00C90000L,(DirType)0}, - {0x00BE0000L,(DirType)0}, - {0x00B30000L,(DirType)0}, - {0x00A80000L,(DirType)0}, - {0x009D0000L,(DirType)0}, - {0x00920000L,(DirType)0}, - {0x00870000L,(DirType)0}, - {0x007C0000L,(DirType)0}, // Track jump check here. - {0x00710000L,(DirType)0}, - {0x00660000L,(DirType)0}, - {0x005B0000L,(DirType)0}, - {0x00500000L,(DirType)0}, - {0x00450000L,(DirType)0}, - {0x003A0000L,(DirType)0}, - {0x002F0000L,(DirType)0}, - {0x00240000L,(DirType)0}, - {0x00190000L,(DirType)0}, - {0x000E0000L,(DirType)0}, - {0x00030000L,(DirType)0}, - {0x00000000L,(DirType)0} -}; - -DriveClass::TrackType const DriveClass::Track2[] = { - {0x00F8FF08L,(DirType)32}, - {0x00F0FF10L,(DirType)32}, - {0x00E8FF18L,(DirType)32}, - {0x00E0FF20L,(DirType)32}, - {0x00D8FF28L,(DirType)32}, - {0x00D0FF30L,(DirType)32}, - {0x00C8FF38L,(DirType)32}, - {0x00C0FF40L,(DirType)32}, - {0x00B8FF48L,(DirType)32}, - {0x00B0FF50L,(DirType)32}, - {0x00A8FF58L,(DirType)32}, - {0x00A0FF60L,(DirType)32}, - {0x0098FF68L,(DirType)32}, - {0x0090FF70L,(DirType)32}, - {0x0088FF78L,(DirType)32}, - {0x0080FF80L,(DirType)32}, // Track jump check here. - {0x0078FF88L,(DirType)32}, - {0x0070FF90L,(DirType)32}, - {0x0068FF98L,(DirType)32}, - {0x0060FFA0L,(DirType)32}, - {0x0058FFA8L,(DirType)32}, - {0x0050FFB0L,(DirType)32}, - {0x0048FFB8L,(DirType)32}, - {0x0040FFC0L,(DirType)32}, - {0x0038FFC8L,(DirType)32}, - {0x0030FFD0L,(DirType)32}, - {0x0028FFD8L,(DirType)32}, - {0x0020FFE0L,(DirType)32}, - {0x0018FFE8L,(DirType)32}, - {0x0010FFF0L,(DirType)32}, - {0x0008FFF8L,(DirType)32}, - {0x00000000L,(DirType)32} -}; - -DriveClass::TrackType const DriveClass::Track3[] = { - {0x01F5FF00L,(DirType)0}, - {0x01EAFF00L,(DirType)0}, - {0x01DFFF00L,(DirType)0}, - {0x01D4FF00L,(DirType)0}, - {0x01C9FF00L,(DirType)0}, - {0x01BEFF00L,(DirType)0}, - {0x01B3FF00L,(DirType)0}, - {0x01A8FF00L,(DirType)0}, - {0x019DFF00L,(DirType)0}, - {0x0192FF00L,(DirType)0}, - {0x0187FF00L,(DirType)0}, - {0x0180FF00L,(DirType)0}, - {0x0175FF00L,(DirType)0}, // Jump entry point here. - {0x016BFF00L,(DirType)0}, - {0x0160FF02L,(DirType)1}, - {0x0155FF04L,(DirType)3}, - {0x014CFF06L,(DirType)4}, - {0x0141FF08L,(DirType)5}, - {0x0137FF0BL,(DirType)7}, - {0x012EFF0FL,(DirType)8}, - {0x0124FF13L,(DirType)9}, - {0x011AFF17L,(DirType)11}, - {0x0110FF1BL,(DirType)12}, - {0x0107FF1FL,(DirType)13}, // Center cell processing here. - {0x00FCFF24L,(DirType)15}, - {0x00F3FF28L,(DirType)16}, - {0x00ECFF2CL,(DirType)17}, - {0x00E0FF32L,(DirType)19}, - {0x00D7FF36L,(DirType)20}, - {0x00CFFF3DL,(DirType)21}, - {0x00C6FF42L,(DirType)23}, - {0x00BAFF49L,(DirType)24}, - {0x00B0FF4DL,(DirType)25}, - {0x00A8FF58L,(DirType)27}, - {0x00A0FF60L,(DirType)28}, - {0x0098FF68L,(DirType)29}, - {0x0090FF70L,(DirType)31}, - {0x0088FF78L,(DirType)32}, - {0x0080FF80L,(DirType)32}, // Track jump check here. - {0x0078FF88L,(DirType)32}, - {0x0070FF90L,(DirType)32}, - {0x0068FF98L,(DirType)32}, - {0x0060FFA0L,(DirType)32}, - {0x0058FFA8L,(DirType)32}, - {0x0050FFB0L,(DirType)32}, - {0x0048FFB8L,(DirType)32}, - {0x0040FFC0L,(DirType)32}, - {0x0038FFC8L,(DirType)32}, - {0x0030FFD0L,(DirType)32}, - {0x0028FFD8L,(DirType)32}, - {0x0020FFE0L,(DirType)32}, - {0x0018FFE8L,(DirType)32}, - {0x0010FFF0L,(DirType)32}, - {0x0008FFF8L,(DirType)32}, - {0x00000000L,(DirType)32} -}; - -DriveClass::TrackType const DriveClass::Track4[] = { - {0x00F5FF00L,(DirType)0}, - {0x00EBFF00L,(DirType)0}, - {0x00E0FF00L,(DirType)0}, - {0x00D5FF00L,(DirType)0}, - {0x00CBFF01L,(DirType)0}, - {0x00C0FF03L,(DirType)0}, - {0x00B5FF05L,(DirType)1}, - {0x00ABFF07L,(DirType)1}, - {0x00A0FF0AL,(DirType)2}, - {0x0095FF0DL,(DirType)3}, - {0x008BFF10L,(DirType)4}, - {0x0080FF14L,(DirType)5}, // Track entry here. - {0x0075FF18L,(DirType)8}, - {0x006DFF1CL,(DirType)12}, - {0x0063FF22L,(DirType)16}, - {0x005AFF25L,(DirType)20}, - {0x0052FF2BL,(DirType)23}, - {0x0048FF32L,(DirType)27}, - {0x0040FF37L,(DirType)32}, - {0x0038FF3DL,(DirType)36}, - {0x0030FF46L,(DirType)39}, - {0x002BFF4FL,(DirType)43}, - {0x0024FF58L,(DirType)47}, - {0x0020FF60L,(DirType)51}, - {0x001BFF6DL,(DirType)54}, - {0x0017FF79L,(DirType)57}, - {0x0014FF82L,(DirType)60}, // Track jump here. - {0x0011FF8FL,(DirType)62}, - {0x000DFF98L,(DirType)63}, - {0x0009FFA2L,(DirType)64}, - {0x0006FFACL,(DirType)64}, - {0x0004FFB5L,(DirType)66}, - {0x0003FFC0L,(DirType)64}, - {0x0002FFCBL,(DirType)64}, - {0x0001FFD5L,(DirType)64}, - {0x0000FFE0L,(DirType)64}, - {0x0000FFEBL,(DirType)64}, - {0x0000FFF5L,(DirType)64}, - {0x00000000L,(DirType)64} -}; - -DriveClass::TrackType const DriveClass::Track5[] = { - {0xFFF8FE08L,(DirType)32}, - {0xFFF0FE10L,(DirType)32}, - {0xFFE8FE18L,(DirType)32}, - {0xFFE0FE20L,(DirType)32}, - {0xFFD8FE28L,(DirType)32}, - {0xFFD0FE30L,(DirType)32}, - {0xFFC8FE38L,(DirType)32}, - {0xFFC0FE40L,(DirType)32}, - {0xFFB8FE48L,(DirType)32}, - {0xFFB0FE50L,(DirType)32}, - {0xFFA8FE58L,(DirType)32}, - {0xFFA0FE60L,(DirType)32}, - {0xFF98FE68L,(DirType)32}, - {0xFF90FE70L,(DirType)32}, - {0xFF88FE78L,(DirType)32}, - {0xFF80FE80L,(DirType)32}, // Track entry here. - {0xFF78FE88L,(DirType)32}, - {0xFF71FE90L,(DirType)32}, - {0xFF6AFE97L,(DirType)32}, - {0xFF62FE9FL,(DirType)32}, - {0xFF5AFEA8L,(DirType)32}, - {0xFF53FEB0L,(DirType)35}, - {0xFF4BFEB7L,(DirType)38}, - {0xFF44FEBEL,(DirType)41}, - {0xFF3EFEC4L,(DirType)44}, - {0xFF39FECEL,(DirType)47}, - {0xFF34FED8L,(DirType)50}, - {0xFF30FEE0L,(DirType)53}, - {0xFF2DFEEBL,(DirType)56}, - {0xFF2CFEF5L,(DirType)59}, - {0xFF2BFF00L,(DirType)62}, - {0xFF2CFF0BL,(DirType)66}, - {0xFF2DFF15L,(DirType)69}, - {0xFF30FF1FL,(DirType)72}, - {0xFF34FF28L,(DirType)75}, - {0xFF39FF30L,(DirType)78}, - {0xFF3EFF3AL,(DirType)81}, - {0xFF44FF44L,(DirType)84}, - {0xFF4BFF4BL,(DirType)87}, - {0xFF53FF50L,(DirType)90}, - {0xFF5AFF58L,(DirType)93}, - {0xFF62FF60L,(DirType)96}, - {0xFF6AFF68L,(DirType)96}, - {0xFF71FF70L,(DirType)96}, - {0xFF78FF78L,(DirType)96}, - {0xFF80FF80L,(DirType)96}, // Track jump check here. - {0xFF88FF88L,(DirType)96}, - {0xFF90FF90L,(DirType)96}, - {0xFF98FF98L,(DirType)96}, - {0xFFA0FFA0L,(DirType)96}, - {0xFFA8FFA8L,(DirType)96}, - {0xFFB0FFB0L,(DirType)96}, - {0xFFB8FFB8L,(DirType)96}, - {0xFFC0FFC0L,(DirType)96}, - {0xFFC8FFC8L,(DirType)96}, - {0xFFD0FFD0L,(DirType)96}, - {0xFFD8FFD8L,(DirType)96}, - {0xFFE0FFE0L,(DirType)96}, - {0xFFE8FFE8L,(DirType)96}, - {0xFFF0FFF0L,(DirType)96}, - {0xFFF8FFF8L,(DirType)96}, - {0x00000000L,(DirType)96} -}; - -DriveClass::TrackType const DriveClass::Track6[] = { - {0x0100FE00L,(DirType)32}, - {0x00F8FE08L,(DirType)32}, - {0x00F0FE10L,(DirType)32}, - {0x00E8FE18L,(DirType)32}, - {0x00E0FE20L,(DirType)32}, - {0x00D8FE28L,(DirType)32}, - {0x00D0FE30L,(DirType)32}, - {0x00C8FE38L,(DirType)32}, - {0x00C0FE40L,(DirType)32}, - {0x00B8FE48L,(DirType)32}, - {0x00B0FE50L,(DirType)32}, - {0x00A8FE58L,(DirType)32}, - {0x00A0FE60L,(DirType)32}, - {0x0098FE68L,(DirType)32}, - {0x0090FE70L,(DirType)32}, - {0x0088FE78L,(DirType)32}, - {0x0080FE80L,(DirType)32}, // Jump entry point here. - {0x0078FE88L,(DirType)32}, - {0x0070FE90L,(DirType)32}, - {0x0068FE98L,(DirType)32}, - {0x0060FEA0L,(DirType)32}, - {0x0058FEA8L,(DirType)32}, - {0x0055FEAEL,(DirType)32}, - {0x004EFEB8L,(DirType)35}, - {0x0048FEC0L,(DirType)37}, - {0x0042FEC9L,(DirType)40}, - {0x003BFED2L,(DirType)43}, - {0x0037FEDAL,(DirType)45}, - {0x0032FEE3L,(DirType)48}, - {0x002BFEEBL,(DirType)51}, - {0x0026FEF5L,(DirType)53}, - {0x0022FEFEL,(DirType)56}, - {0x001CFF08L,(DirType)59}, - {0x0019FF12L,(DirType)61}, - {0x0015FF1BL,(DirType)64}, - {0x0011FF26L,(DirType)64}, - {0x000EFF30L,(DirType)64}, - {0x000BFF39L,(DirType)64}, - {0x0009FF43L,(DirType)64}, - {0x0007FF4EL,(DirType)64}, - {0x0005FF57L,(DirType)64}, - {0x0003FF62L,(DirType)64}, - {0x0001FF6DL,(DirType)64}, - {0x0000FF77L,(DirType)64}, - {0x0000FF80L,(DirType)64}, // Track jump check here. - {0x0000FF8BL,(DirType)64}, - {0x0000FF95L,(DirType)64}, - {0x0000FFA0L,(DirType)64}, - {0x0000FFABL,(DirType)64}, - {0x0000FFB5L,(DirType)64}, - {0x0000FFC0L,(DirType)64}, - {0x0000FFCBL,(DirType)64}, - {0x0000FFD5L,(DirType)64}, - {0x0000FFE0L,(DirType)64}, - {0x0000FFEBL,(DirType)64}, - {0x0000FFF5L,(DirType)64}, - {0x00000000L,(DirType)64} -}; - -DriveClass::TrackType const DriveClass::Track7[] = { - {0x0006FFFFL,(DirType)0}, - {0x000CFFFEL,(DirType)4}, - {0x0011FFFCL,(DirType)8}, - {0x0018FFFAL,(DirType)12}, - {0x001FFFF6L,(DirType)16}, - {0x0024FFF3L,(DirType)19}, - {0x002BFFF0L,(DirType)22}, - {0x0030FFFDL,(DirType)23}, - {0x0035FFEBL,(DirType)24}, - {0x0038FFE8L,(DirType)25}, - {0x003CFFE6L,(DirType)26}, - {0x0040FFE3L,(DirType)27}, - {0x0043FFE0L,(DirType)28}, - {0x0046FFDDL,(DirType)29}, - {0x0043FFDFL,(DirType)30}, - {0x0040FFE1L,(DirType)30}, - {0x003CFFE3L,(DirType)30}, - {0x0038FFE5L,(DirType)30}, - {0x0035FFE7L,(DirType)31}, - {0x0030FFE9L,(DirType)31}, - {0x002BFFEBL,(DirType)31}, - {0x0024FFEDL,(DirType)31}, - {0x001FFFF1L,(DirType)31}, - {0x0018FFF4L,(DirType)32}, - {0x0011FFF7L,(DirType)32}, - {0x000CFFFAL,(DirType)32}, - {0x0006FFFDL,(DirType)32}, - {0x00000000L,(DirType)32} -}; - -DriveClass::TrackType const DriveClass::Track8[] = { - {0x0003FFFCL,(DirType)32}, - {0x0006FFF7L,(DirType)36}, - {0x000AFFF1L,(DirType)40}, - {0x000CFFEBL,(DirType)44}, - {0x000DFFE4L,(DirType)46}, - {0x000EFFDCL,(DirType)48}, - {0x000FFFD5L,(DirType)50}, - {0x0010FFD0L,(DirType)52}, - {0x0011FFC9L,(DirType)54}, - {0x0012FFC2L,(DirType)56}, - {0x0011FFC0L,(DirType)58}, - {0x0010FFC2L,(DirType)60}, - {0x000EFFC9L,(DirType)62}, - {0x000CFFCFL,(DirType)64}, - {0x000AFFD5L,(DirType)64}, - {0x0008FFDAL,(DirType)64}, - {0x0006FFE2L,(DirType)64}, - {0x0004FFE9L,(DirType)64}, - {0x0002FFEFL,(DirType)64}, - {0x0001FFF5L,(DirType)64}, - {0x0000FFF9L,(DirType)64}, - {0x00000000L,(DirType)64} -}; - -DriveClass::TrackType const DriveClass::Track9[] = { - {0xFFF50002L,(DirType)0}, - {0xFFEB0004L,(DirType)2}, - {0xFFE00006L,(DirType)4}, - {0xFFD50009L,(DirType)6}, - {0xFFCE000CL,(DirType)9}, - {0xFFC8000FL,(DirType)11}, - {0xFFC00012L,(DirType)13}, - {0xFFB80015L,(DirType)16}, - {0xFFC00012L,(DirType)18}, - {0xFFC8000EL,(DirType)20}, - {0xFFCE000AL,(DirType)22}, - {0xFFD50004L,(DirType)24}, - {0xFFDE0000L,(DirType)26}, - {0xFFE9FFF8L,(DirType)28}, - {0xFFEEFFF2L,(DirType)30}, - {0xFFF5FFEBL,(DirType)32}, - {0xFFFDFFE1L,(DirType)34}, - {0x0002FFD8L,(DirType)36}, - {0x0007FFD2L,(DirType)39}, - {0x000BFFCBL,(DirType)41}, - {0x0010FFC5L,(DirType)43}, - {0x0013FFBEL,(DirType)45}, - {0x0015FFB7L,(DirType)48}, - {0x0013FFBEL,(DirType)50}, - {0x0011FFC5L,(DirType)52}, - {0x000BFFCCL,(DirType)54}, - {0x0008FFD4L,(DirType)56}, - {0x0005FFDFL,(DirType)58}, - {0x0003FFEBL,(DirType)62}, - {0x0001FFF5L,(DirType)64}, - {0x00000000L,(DirType)64} -}; - -DriveClass::TrackType const DriveClass::Track10[] = { - {0xFFF6000BL,(DirType)32}, - {0xFFF00015L,(DirType)37}, - {0xFFEB0020L,(DirType)42}, - {0xFFE9002BL,(DirType)47}, - {0xFFE50032L,(DirType)52}, - {0xFFE30038L,(DirType)57}, - {0xFFE00040L,(DirType)60}, - {0xFFE20038L,(DirType)62}, - {0xFFE40032L,(DirType)64}, - {0xFFE5002AL,(DirType)68}, - {0xFFE6001EL,(DirType)70}, - {0xFFE70015L,(DirType)72}, - {0xFFE8000BL,(DirType)74}, - {0xFFE90000L,(DirType)76}, - {0xFFE8FFF5L,(DirType)78}, - {0xFFE7FFEBL,(DirType)80}, - {0xFFE6FFE0L,(DirType)82}, - {0xFFE5FFD5L,(DirType)84}, - {0xFFE4FFCEL,(DirType)86}, - {0xFFE2FFC5L,(DirType)88}, - {0xFFE0FFC0L,(DirType)90}, - {0xFFE3FFC5L,(DirType)92}, - {0xFFE5FFCEL,(DirType)94}, - {0xFFE9FFD5L,(DirType)95}, - {0xFFEBFFE0L,(DirType)96}, - {0xFFF0FFEBL,(DirType)96}, - {0xFFF6FFF5L,(DirType)96}, - {0x00000000L,(DirType)96} -}; - -DriveClass::TrackType const DriveClass::Track11[] = { - {0x01000000L,DIR_SW}, - {0x00F30008L,DIR_SW}, - {0x00E50010L,DIR_SW_X1}, - {0x00D60018L,DIR_SW_X1}, - {0x00C80020L,DIR_SW_X1}, - {0x00B90028L,DIR_SW_X1}, - {0x00AB0030L,DIR_SW_X2}, - {0x009C0038L,DIR_SW_X2}, - {0x008D0040L,DIR_SW_X2}, - {0x007F0048L,DIR_SW_X2}, - {0x00710050L,DIR_SW_X2}, - {0x00640058L,DIR_SW_X2}, - {0x00550060L,DIR_SW_X2}, - - {0x00000000L,DIR_SW_X2} -}; - -DriveClass::TrackType const DriveClass::Track12[] = { - {0xFF550060L,DIR_SW_X2}, - {0xFF640058L,DIR_SW_X2}, - {0xFF710050L,DIR_SW_X2}, - {0xFF7F0048L,DIR_SW_X2}, - {0xFF8D0040L,DIR_SW_X2}, - {0xFF9C0038L,DIR_SW_X2}, - {0xFFAB0030L,DIR_SW_X2}, - {0xFFB90028L,DIR_SW_X1}, - {0xFFC80020L,DIR_SW_X1}, - {0xFFD60018L,DIR_SW_X1}, - {0xFFE50010L,DIR_SW_X1}, - {0xFFF30008L,DIR_SW}, - - {0x00000000L,DIR_SW} -}; - -/* -** Drive out of weapon's factory. -*/ -DriveClass::TrackType const DriveClass::Track13[] = { - {XYP_COORD(10,-21),(DirType)(DIR_SW-10)}, - {XYP_COORD(10,-21),(DirType)(DIR_SW-10)}, - {XYP_COORD(10,-20),(DirType)(DIR_SW-10)}, - {XYP_COORD(10,-20),(DirType)(DIR_SW-10)}, - {XYP_COORD(9,-18),(DirType)(DIR_SW-10)}, - {XYP_COORD(9,-18),(DirType)(DIR_SW-10)}, - {XYP_COORD(9,-17),(DirType)(DIR_SW-10)}, - {XYP_COORD(8,-16),(DirType)(DIR_SW-10)}, - {XYP_COORD(8,-15),(DirType)(DIR_SW-10)}, - {XYP_COORD(7,-14),(DirType)(DIR_SW-10)}, - {XYP_COORD(7,-13),(DirType)(DIR_SW-10)}, - {XYP_COORD(6,-12),(DirType)(DIR_SW-10)}, - {XYP_COORD(6,-11),(DirType)(DIR_SW-10)}, - {XYP_COORD(5,-10),(DirType)(DIR_SW-10)}, - {XYP_COORD(5,-9),(DirType)(DIR_SW-10)}, - {XYP_COORD(4,-8),(DirType)(DIR_SW-10)}, - {XYP_COORD(4,-7),(DirType)(DIR_SW-10)}, - {XYP_COORD(3,-6),(DirType)(DIR_SW-10)}, - {XYP_COORD(3,-5),(DirType)(DIR_SW-9)}, - {XYP_COORD(2,-4),(DirType)(DIR_SW-7)}, - {XYP_COORD(2,-3),(DirType)(DIR_SW-5)}, - {XYP_COORD(1,-2),(DirType)(DIR_SW-3)}, - {XYP_COORD(1,-1),(DirType)(DIR_SW-1)}, - - {0x00000000L,DIR_SW} -}; - - -/* -** There are a limited basic number of tracks that a vehicle can follow. These -** are they. Each track can be interpreted differently but this is controlled -** by the TrackControl structure elaborated elsewhere. -*/ -DriveClass::RawTrackType const DriveClass::RawTracks[13] = { - {Track1, -1, 0, -1}, - {Track2, -1, 0, -1}, - {Track3, 37, 12, 22}, - {Track4, 26, 11, 19}, - {Track5, 45, 15, 31}, - {Track6, 44, 16, 27}, - {Track7, -1, 0, -1}, - {Track8, -1, 0, -1}, - {Track9, -1, 0, -1}, - {Track10, -1, 0, -1}, - {Track11, -1, 0, -1}, - {Track12, -1, 0, -1}, - {Track13, -1, 0, -1} -}; - - -/*************************************************************************** -** Smooth turning control table. Given two directions in a path list, this -** table determines which track to use and what modifying operations need -** be performed on the track data. -*/ -DriveClass::TurnTrackType const DriveClass::TrackControl[67] = { - {1, 0, DIR_N, F_}, // 0-0 - {3, 7, DIR_NE, F_D}, // 0-1 (raw chart) - {4, 9, DIR_E, F_D}, // 0-2 (raw chart) - {0, 0, DIR_SE, F_}, // 0-3 ! - {0, 0, DIR_S, F_}, // 0-4 ! - {0, 0, DIR_SW, F_}, // 0-5 ! - {4, 9, DIR_W, (DriveClass::TrackControlType)(F_X|F_D)}, // 0-6 - {3, 7, DIR_NW, (DriveClass::TrackControlType)(F_X|F_D)}, // 0-7 - {6, 8, DIR_N, (DriveClass::TrackControlType)(F_T|F_X|F_Y|F_D)}, // 1-0 - {2, 0, DIR_NE, F_}, // 1-1 (raw chart) - {6, 8, DIR_E, F_D}, // 1-2 (raw chart) - {5, 10, DIR_SE, F_D}, // 1-3 (raw chart) - {0, 0, DIR_S, F_}, // 1-4 ! - {0, 0, DIR_SW, F_}, // 1-5 ! - {0, 0, DIR_W, F_}, // 1-6 ! - {5, 10, DIR_NW, (DriveClass::TrackControlType)(F_T|F_X|F_Y|F_D)}, // 1-7 - {4, 9, DIR_N, (DriveClass::TrackControlType)(F_T|F_X|F_Y|F_D)}, // 2-0 - {3, 7, DIR_NE, (DriveClass::TrackControlType)(F_T|F_X|F_Y|F_D)}, // 2-1 - {1, 0, DIR_E, (DriveClass::TrackControlType)(F_T|F_X)}, // 2-2 - {3, 7, DIR_SE, (DriveClass::TrackControlType)(F_T|F_X|F_D)}, // 2-3 - {4, 9, DIR_S, (DriveClass::TrackControlType)(F_T|F_X|F_D)}, // 2-4 - {0, 0, DIR_SW, F_}, // 2-5 ! - {0, 0, DIR_W, F_}, // 2-6 ! - {0, 0, DIR_NW, F_}, // 2-7 ! - {0, 0, DIR_N, F_}, // 3-0 ! - {5, 10, DIR_NE, (DriveClass::TrackControlType)(F_Y|F_D)}, // 3-1 - {6, 8, DIR_E, (DriveClass::TrackControlType)(F_Y|F_D)}, // 3-2 - {2, 0, DIR_SE, F_Y}, // 3-3 - {6, 8, DIR_S, (DriveClass::TrackControlType)(F_T|F_X|F_D)}, // 3-4 - {5, 10, DIR_SW, (DriveClass::TrackControlType)(F_T|F_X|F_D)}, // 3-5 - {0, 0, DIR_W, F_}, // 3-6 ! - {0, 0, DIR_NW, F_}, // 3-7 ! - {0, 0, DIR_N, F_}, // 4-0 ! - {0, 0, DIR_NE, F_}, // 4-1 ! - {4, 9, DIR_E, (DriveClass::TrackControlType)(F_Y|F_D)}, // 4-2 - {3, 7, DIR_SE, (DriveClass::TrackControlType)(F_Y|F_D)}, // 4-3 - {1, 0, DIR_S, F_Y}, // 4-4 - {3, 7, DIR_SW, (DriveClass::TrackControlType)(F_X|F_Y|F_D)}, // 4-5 - {4, 9, DIR_W, (DriveClass::TrackControlType)(F_X|F_Y|F_D)}, // 4-6 - {0, 0, DIR_NW, F_}, // 4-7 ! - {0, 0, DIR_N, F_}, // 5-0 ! - {0, 0, DIR_NE, F_}, // 5-1 ! - {0, 0, DIR_E, F_}, // 5-2 ! - {5, 10, DIR_SE, (DriveClass::TrackControlType)(F_T|F_D)}, // 5-3 - {6, 8, DIR_S, (DriveClass::TrackControlType)(F_T|F_D)}, // 5-4 - {2, 0, DIR_SW, F_T}, // 5-5 - {6, 8, DIR_W, (DriveClass::TrackControlType)(F_X|F_Y|F_D)}, // 5-6 - {5, 10, DIR_NW, (DriveClass::TrackControlType)(F_X|F_Y|F_D)}, // 5-7 - {4, 9, DIR_N, (DriveClass::TrackControlType)(F_T|F_Y|F_D)}, // 6-0 - {0, 0, DIR_NE, F_}, // 6-1 ! - {0, 0, DIR_E, F_}, // 6-2 ! - {0, 0, DIR_SE, F_}, // 6-3 ! - {4, 9, DIR_S, (DriveClass::TrackControlType)(F_T|F_D)}, // 6-4 - {3, 7, DIR_SW, (DriveClass::TrackControlType)(F_T|F_D)}, // 6-5 - {1, 0, DIR_W, F_T}, // 6-6 - {3, 7, DIR_NW, (DriveClass::TrackControlType)(F_T|F_Y|F_D)}, // 6-7 - {6, 8, DIR_N, (DriveClass::TrackControlType)(F_T|F_Y|F_D)}, // 7-0 - {5, 10, DIR_NE, (DriveClass::TrackControlType)(F_T|F_Y|F_D)}, // 7-1 - {0, 0, DIR_E, F_}, // 7-2 ! - {0, 0, DIR_SE, F_}, // 7-3 ! - {0, 0, DIR_S, F_}, // 7-4 ! - {5, 10, DIR_SW, (DriveClass::TrackControlType)(F_X|F_D)}, // 7-5 - {6, 8, DIR_W, (DriveClass::TrackControlType)(F_X|F_D)}, // 7-6 - {2, 0, DIR_NW, F_X}, // 7-7 - - {11, 11, DIR_SW, F_}, // Backup harvester into refinery. - {12, 12, DIR_SW_X2, F_}, // Drive back into refinery. - {13, 13, DIR_SW, F_} // Drive out of weapons factory. -}; \ No newline at end of file diff --git a/code/TIBERIANDAWN/DRIVE.H b/code/TIBERIANDAWN/DRIVE.H deleted file mode 100644 index dc66aa0..0000000 --- a/code/TIBERIANDAWN/DRIVE.H +++ /dev/null @@ -1,223 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\drive.h_v 2.19 16 Oct 1995 16:47:44 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : DRIVE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 14, 1994 * - * * - * Last Update : April 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DRIVE_H -#define DRIVE_H - -#include "foot.h" - -/**************************************************************************** -** Movable objects are handled by this class definition. Moveable objects -** cover everything except buildings. -*/ -class DriveClass : public FootClass -{ - public: - /* - ** This points to the static control data that gives 'this' unit its characteristics. - */ - UnitTypeClass const * const Class; - - - /* - ** Simulated sub-pixel offset to find out where the object would be if it could make a sub-pixel move. Only used by - ** GlyphX client for more accurate positioning. - ** - ** ST - 4/30/2019 8:05AM - */ - short SimLeptonX; - short SimLeptonY; - - /* - ** This records the number of "loads" of Tiberium the unit is carrying. Only - ** harvesters use this field. - */ - unsigned char Tiberium; - - /* - ** If this unit performing harvesting action, then this flag is true. The flag - ** is located here because the other bit flags here give it a free place to - ** reside. - */ - unsigned IsHarvesting:1; - - /* - ** This flags when a transport vehicle could not unload at its designated location - ** and is heading off the map to try again later. When this flag is true, the - ** transport unit is allowed to disappear when it reaches the edge of the map. - */ - unsigned IsReturning:1; - - /* - ** Some units must have their turret locked down to face their body direction. - ** When this flag is set, this condition is in effect. This flag is a more - ** accurate check than examining the TrackNumber since the turret may be - ** rotating into position so that a pending track may start. During this process - ** the track number does not indicate anything. - */ - unsigned IsTurretLockedDown:1; - - /* - ** This vehicle could be processing a "short track". A short track is one that - ** doesn't actually go anywhere. Kind of like turning in place. - */ - unsigned IsOnShortTrack:1; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - DriveClass(void); - DriveClass(UnitType classid, HousesType house); - virtual ~DriveClass(void) {}; - operator UnitType(void) const {return Class->Type;}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - virtual int Offload_Tiberium_Bail(void); - void Do_Turn(DirType dir); - virtual void Approach_Target(void); - virtual ObjectTypeClass const & Class_Of(void) const; - virtual void Overrun_Square(CELL cell, bool threaten=true); - virtual void Assign_Destination(TARGET target); - virtual void Per_Cell_Process(bool center); - virtual bool Ok_To_Move(DirType ) const; - virtual void AI(void); - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - void Force_Track(int track, COORDINATE coord); - virtual int Tiberium_Load(void) const; - - void Exit_Map(void); - void Mark_Track(COORDINATE headto, MarkType type); - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /********************************************************************** - ** These enumerations are used as working constants that exist only - ** in the DriveClass namespace. - */ - enum DriveClassEnum { - BACKUP_INTO_REFINERY=64, // Track to backup into refinery. - OUT_OF_REFINERY, // Track to leave refinery. - OUT_OF_WEAPON_FACTORY // Track to leave weapons factory. - }; - - private: - - /**************************************************************************** - ** Smooth turning tracks are controlled by this structure and these - ** processing bits. - */ - typedef enum TrackControlType : unsigned char { - F_=0x00, // No translation necessary? - F_T=0x01, // Transpose X and Y components? - F_X=0x02, // Reverse X component sign? - F_Y=0x04, // Reverse Y component sign? - F_D=0x08 // Two cell consumption? - } TrackControlType; - //#define F_S 0x10 // Is this a 90 degree turn? - - typedef struct { - char Track; // Which track to use. - char StartTrack; // Track when starting from stand-still. - DirType Facing; // Facing when track has been completed. - DriveClass::TrackControlType Flag; // List processing flag bits. - } TurnTrackType; - - typedef struct { - COORDINATE Offset; // Offset to origin coordinate. - DirType Facing; // Facing (primary track). - } TrackType; - - typedef struct { - DriveClass::TrackType const * Track; // Pointer to track list. - int Jump; // Index where track jumping is allowed. - int Entry; // Entry point if jumping to this track. - int Cell; // Per cell process should occur at this index. - } RawTrackType; - - /* - ** These speed values are used to accumulate movement and then - ** convert them into pixel "steps" that are then translated through - ** the currently running track so that the unit will move. - */ - unsigned char SpeedAccum; - - /* - ** This the track control logic (used for ground vehicles only). The 'Track' - ** variable holds the track being followed (0 == not following track). The - ** 'TrackIndex' variable holds the current index into the specified track - ** (starts at 0). - */ - char TrackNumber; - char TrackIndex; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - virtual void Fixup_Path(PathType *path); - bool While_Moving(void); - bool Start_Of_Move(void); - void Lay_Track(void); - COORDINATE Smooth_Turn(COORDINATE adj, DirType *dir); - - static TurnTrackType const TrackControl[67]; - static RawTrackType const RawTracks[13]; - static TrackType const Track13[]; - static TrackType const Track12[]; - static TrackType const Track11[]; - static TrackType const Track10[]; - static TrackType const Track9[]; - static TrackType const Track8[]; - static TrackType const Track7[]; - static TrackType const Track6[]; - static TrackType const Track5[]; - static TrackType const Track4[]; - static TrackType const Track3[]; - static TrackType const Track2[]; - static TrackType const Track1[24]; -}; - -//PG_TO_FIX -//inline DriveClass::TrackControlType operator |(DriveClass::TrackControlType, DriveClass::TrackControlType); -//inline DriveClass::TrackControlType operator &(DriveClass::TrackControlType, DriveClass::TrackControlType); -//inline DriveClass::TrackControlType operator ~(DriveClass::TrackControlType); - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/EDIT.CPP b/code/TIBERIANDAWN/EDIT.CPP deleted file mode 100644 index 6771013..0000000 --- a/code/TIBERIANDAWN/EDIT.CPP +++ /dev/null @@ -1,468 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\edit.cpv 2.18 16 Oct 1995 16:48:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : EDIT.CPP * - * * - * Programmer : Joe L. Bostic, Maria del Mar McCready Legg * - * * - * Start Date : 01/15/95 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * EditClass::Action -- Handles input events. * - * EditClass::Draw_Background -- Draw the background to the edit gadget. * - * EditClass::Draw_Me -- Draws the edit box and embedded text. * - * EditClass::Draw_Text -- Draws the edit gadget text. * - * EditClass::EditClass -- Normal constructor for edit class object. * - * EditClass::Handle_Key -- Handles keyboard input to edit gadget. * - * EditClass::Set_Text -- Sets the text to the edit gadget. * - * EditClass::~EditClass -- Default destructor for the edit gadget. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * EditClass::EditClass -- Normal constructor for edit class object. * - * * - * This is the normal constructor used to create an edit object. * - * * - * INPUT: id -- The ID number for this edit object. This is the ID number that will be * - * returned by the Input() function when the key is pressed if this * - * gadget has the keyboard input focus. * - * * - * text -- Referenct to the text buffer that the edit gadget will modify as keyboard * - * input is processed. The value that this buffer contains is the default * - * text displayed. * - * * - * maxlen-- The maximum size of the text buffer specified. This length INCLUDES the * - * trailing null character so a simple sizeof() function call can be used. * - * * - * flags -- These are the text print control flags. It is used to control how the * - * text looks in the edit box. Use the normal TPF_??? flags. * - * * - * x,y -- The pixel coordinates of the upper left corner of the edit gadget area. * - * * - * w,h -- The pixel dimensions of the edit box. If either of these are no provided, * - * or set to -1, then the dimension is determined from the string itself. * - * * - * sytle -- This style flag parameter control what kind of characters are allowed in * - * the edit box. The initial string in the text buffer may contain illegal * - * characters, but they are NOT removed regardless of this parameter. * - * * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: * - * 01/05/1995 MML : Created. * - * 01/21/1995 JLB : Modified. * - *=============================================================================================*/ -EditClass::EditClass(int id, char * text, int max_len, TextPrintType flags, int x, int y, int w, int h, EditStyle style) : - ControlClass (id, x, y, w, h, LEFTPRESS), String(text) -{ - TextFlags = flags; - EditFlags = style; - Color = CC_GREEN; - Set_Text(text, max_len); - - if (w == -1 || h == -1) { - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TextFlags); - - if (h == -1) { - Height = FontHeight+2; - } - if (w == -1) { - if (strlen(String) > 0) { - Width = String_Pixel_Width(String) + 6; - } else { - Width = ((Char_Pixel_Width('X')+FontXSpacing) * (MaxLength+1)) + 2; - } - } - } - IsReadOnly = 0; -} - - -/*********************************************************************************************** - * EditClass::~EditClass -- Default destructor for the edit gadget. * - * * - * This default destructor removes the focus setting if it currently has it. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/24/1995 JLB : Created. * - *=============================================================================================*/ -EditClass::~EditClass(void) -{ - if (Has_Focus()) { - Clear_Focus(); - } -} - - -/*********************************************************************************************** - * EditClass::Set_Text -- Sets the text to the edit gadget. * - * * - * Use this routine to change the text that this edit gadget refers to. * - * * - * INPUT: text -- Reference to the character array that this edit gadget will be * - * modifying. * - * max_len -- The maximum size of the buffer that will be modified. * - * * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -void EditClass::Set_Text(char * text, int max_len) -{ - String = text; - MaxLength = max_len-1; - Length = strlen(String); - Flag_To_Redraw(); -} - - -/*********************************************************************************************** - * EditClass::Draw_Me -- Draws the edit box and embedded text. * - * * - * This routine will render the edit box. This will show the box outline as well as any * - * text it may contain. * - * * - * INPUT: forced -- Should the edit box be drawn even if it thinks it doesn't have to? * - * * - * OUTPUT: Was the edit box drawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int EditClass::Draw_Me(int forced) -{ - if (ControlClass::Draw_Me(forced)) { - /* - ** Hide the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); - } - - /* - ** Draw the body & set text color. - */ - Draw_Background(); - - /* - ** Display the text. - */ - Draw_Text(String); - - /* - ** Display the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * EditClass::Action -- Handles input events. * - * * - * This routine will handle all mouse and keyboard events directed at this edit box * - * gadget. For keyboard events, this will insert the characters into the edit box. * - * * - * INPUT: flags -- The event flag that triggered this function call. * - * * - * key -- Reference to the keyboard/mouse event that triggered this function call. * - * * - * OUTPUT: Should the list be processed further? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int EditClass::Action(unsigned flags, KeyNumType & key) -{ - - /* - ** If this is a read-only edit box, it's a display-only device - */ - if (IsReadOnly) { - return(false); - } - - /* - ** If the left mouse button is pressed over this gadget, then set the focus to - ** this gadget. The event flag is cleared so that no button ID number is returned. - */ - if ((flags & LEFTPRESS)) { - flags &= ~LEFTPRESS; - Set_Focus(); - Flag_To_Redraw(); // force to draw cursor - } - - /* - ** Handle keyboard events here. Normally, the key is added to the string, but if the - ** RETURN key is pressed, then the button ID number is returned from the Input() - ** function. - */ - if ((flags & KEYBOARD) && Has_Focus()) { - - /* - ** Process the keyboard character. If indicated, consume this keyboard event - ** so that the edit gadget ID number is not returned. - */ - if (key == KN_ESC) { - - Clear_Focus(); - flags = 0; - - } else { - - KeyASCIIType ascii = (KeyASCIIType)(Keyboard::To_ASCII(key) & 0x00ff); - - /* - ** Allow numeric keypad presses to map to ascii numbers - */ - if ((key & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9'){ - key &= ~WWKEY_VK_BIT; - - if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){ - if (Handle_Key (ascii) ) { - flags &= ~KEYBOARD; - key = KN_NONE; - } - } - - }else{ - - /* - ** Filter out all special keys except return and backspace - */ - if ((!(key & WWKEY_VK_BIT) && ascii >= ' ' && ascii <= 127) - || key == KN_RETURN || key == KN_BACKSPACE){ - - - if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){ - if (Handle_Key(Keyboard::To_ASCII(key))) { - flags &= ~KEYBOARD; - key = KN_NONE; - } - } - }else{ - //if (key & WWKEY_RLS_BIT){ - // if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){ - flags &= ~KEYBOARD; - key = KN_NONE; - // } - //} - } - } - } - } - - return(ControlClass::Action(flags, key)); -} - - -/*********************************************************************************************** - * EditClass::Draw_Background -- Draw the background to the edit gadget. * - * * - * This routine will redraw the edit gadget background. The overlaying text is handled by * - * a different routine. The mouse is guaranteed to be hidden when this routine is called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -void EditClass::Draw_Background(void) -{ - Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_BOX, true); -} - - -/*********************************************************************************************** - * EditClass::Draw_Text -- Draws the edit gadget text. * - * * - * This routine is called when the edit gadget text needs to be drawn. The background has * - * already been drawn by the time this function is called. The mouse is guaranteed to be * - * hidden as well. * - * * - * INPUT: text -- The text to draw in the edit gadget. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -void EditClass::Draw_Text(char const * text) -{ - if (FontPtr == GradFont6Ptr) { - TextPrintType flags; - - if (Has_Focus()) { - flags = TPF_BRIGHT_COLOR; - } else { - flags = (TextPrintType)0; - } - - Conquer_Clip_Text_Print(text, X+1, Y+1, Color, TBLACK, TextFlags | flags, Width-2); - - if (Has_Focus() && (int)strlen(text) < MaxLength && - ((int)String_Pixel_Width(text) + (int)String_Pixel_Width ("_") < Width-2) ) { - Conquer_Clip_Text_Print( "_", X+1+String_Pixel_Width(text), Y+1, Color, TBLACK, TextFlags | flags); - } - } else { - Conquer_Clip_Text_Print(text, X+1, Y+1, Has_Focus() ? BLUE : WHITE, TBLACK, TextFlags, Width-2); - - if (Has_Focus() && (int)strlen(text) < MaxLength && - ((int)String_Pixel_Width(text) + (int)String_Pixel_Width ("_") < Width-2) ) { - Conquer_Clip_Text_Print("_",X+1+String_Pixel_Width(text),Y+1,BLUE,TBLACK, TextFlags); - } - } - -} - - -/*********************************************************************************************** - * EditClass::Handle_Key -- Handles keyboard input to edit gadget. * - * * - * This is the gruntwork routine that processes keyboard input to the edit gadget. This * - * routine will be called when keyboard input has been detected and this gadget has the * - * current focus. * - * * - * INPUT: ascii -- The ASCII key code that was fetched from the keyboard buffer. * - * * - * OUTPUT: bool; Should this keyboard input NOT cause the gadget ID number to be returned * - * from the controlling Input() routine? Typically, the return value would be * - * true unless the focus is lost due to the key being pressed. * - * * - * WARNINGS: none * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -bool EditClass::Handle_Key(KeyASCIIType ascii) -{ - switch (ascii) { - /* - ** Handle the special case of a non-keyboard event. It is possible that this - ** key code might be passed to this routine if this routine has been overridden - ** and the key event was consumed. - */ - case 0: - break; - - /* - ** If the return key is pressed, then remove the focus from this edit - ** gadget but otherwise let the normal gadget processing proceed. This - ** causes the gadget ID number to be returned from the Input() function - ** so that the controlling program will know that the text can be - ** processed. - */ - case KA_RETURN: - Clear_Focus(); - return(false); - - /* - ** When the BACKSPACE key is pressed, remove the last character in the edit string. - */ - case KA_BACKSPACE: - if (Length) { - Length--; - String[Length] = '\0'; - Flag_To_Redraw(); - } - break; - - /* - ** If the keyboard event was not a recognized special key, then examine to see - ** if it can legally be added to the edit string and do so if possible. - */ - default: - - /* - ** Don't add a character if the length is greater than edit width. - */ - if (((int)String_Pixel_Width(String) + (int)Char_Pixel_Width(ascii) ) >= (Width-2)) { - break; - } - - /* - ** Don't add a character if the length is already at maximum. - */ - if (Length >= MaxLength) break; - - /* - ** Invisible characters are never added to the string. This is - ** especially true for spaces at the beginning of the string. - */ - if (!isgraph(ascii) && ascii != ' ') break; - if (ascii == ' ' && Length == 0) break; - - /* - ** If this is an upper case only edit gadget, then force the alphabetic - ** character to upper case. - */ - if ((EditFlags & UPPERCASE) && isalpha(ascii)) { - ascii = (KeyASCIIType)toupper(ascii); - } - - if ((!(EditFlags & NUMERIC) || !isdigit(ascii)) && - (!(EditFlags & ALPHA) || !isalpha(ascii)) && - (!(EditFlags & MISC) || isalnum(ascii)) && - ascii != ' ') { - break; - } - - /* - ** The character passed all legality checks, so add it to the edit string - ** and flag this gadget to be redrawn. The manual flag to redraw is needed - ** because the event flag has been cleared. This prevents the gadget's ID - ** number from being returned just because the gadget has been edited. - */ - String[Length++] = ascii; - String[Length] = '\0'; - Flag_To_Redraw(); - break; - } - return(true); -} diff --git a/code/TIBERIANDAWN/EDIT.H b/code/TIBERIANDAWN/EDIT.H deleted file mode 100644 index ff01911..0000000 --- a/code/TIBERIANDAWN/EDIT.H +++ /dev/null @@ -1,113 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\edit.h_v 2.17 16 Oct 1995 16:46:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : EDIT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef EDIT_H -#define EDIT_H - -class EditClass : public ControlClass -{ - public: - typedef enum EditStyle { - ALPHA =0x0001, // Edit accepts alphabetic characters. - NUMERIC =0x0002, // Edit accepts numbers. - MISC =0x0004, // Edit accepts misc graphic characters. - UPPERCASE =0x0008, // Force to upper case. - ALPHANUMERIC=(int)ALPHA|(int)NUMERIC|(int)MISC, - } EditStyle; - - EditClass (int id, char * text, int max_len, TextPrintType flags, int x, int y, int w=-1, int h=-1, EditStyle style=ALPHANUMERIC); - virtual ~EditClass(void); - - virtual int Draw_Me(int forced); - virtual void Set_Text(char * text, int max_len); - void Set_Color (int color) { Color = color; } - - void Set_Read_Only(int rdonly) {IsReadOnly = rdonly;} - - protected: - - /* - ** These are the text size and style flags to be used when displaying the text - ** of the edit gadget. - */ - TextPrintType TextFlags; - - /* - ** Input flags that control what characters are allowed in the string. - */ - EditStyle EditFlags; - - /* - ** Pointer to text staging buffer and the maximum length of the string it - ** can contain. - */ - char *String; - int MaxLength; - - /* - ** This is the current length of the string. This length will never exceed the - ** MaxLength allowed. - */ - int Length; - - /* - ** This is the desired color of the edit control. - */ - int Color; - - virtual int Action (unsigned flags, KeyNumType &key); - virtual void Draw_Background(void); - virtual void Draw_Text(char const * text); - virtual bool Handle_Key(KeyASCIIType ascii); - - private: - int IsReadOnly; - -}; - -//inline EditClass::EditStyle operator |(EditClass::EditStyle, EditClass::EditStyle); -//inline EditClass::EditStyle operator &(EditClass::EditStyle, EditClass::EditStyle); -//inline EditClass::EditStyle operator ~(EditClass::EditStyle); - -inline EditClass::EditStyle operator|(EditClass::EditStyle a, EditClass::EditStyle b) -{return static_cast(static_cast(a) | static_cast(b));} - -inline EditClass::EditStyle operator&(EditClass::EditStyle a, EditClass::EditStyle b) -{return static_cast(static_cast(a) & static_cast(b));} - -inline EditClass::EditStyle operator~(EditClass::EditStyle a) -{return static_cast(~static_cast(a));} - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/ENDING.CPP b/code/TIBERIANDAWN/ENDING.CPP deleted file mode 100644 index 68265ae..0000000 --- a/code/TIBERIANDAWN/ENDING.CPP +++ /dev/null @@ -1,258 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ending.cpv 1.5 16 Oct 1995 16:50:30 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ENDING.H * - * * - * Programmer : Barry W. Green * - * * - * Start Date : July 10, 1995 * - * * - * Last Update : July 10, 1995 [BWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "textblit.h" - -void GDI_Ending(void) -{ -#ifdef DEMO - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Load_Title_Screen("DEMOPIC.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); - Get_Key_Num(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - VisiblePage.Clear(); - -#else - if (TempleIoned) { - Play_Movie("GDIFINB"); - } else { - Play_Movie("GDIFINA"); - } - - Score.Presentation(); - - if (TempleIoned) { - Play_Movie("GDIEND2"); - } else { - Play_Movie("GDIEND1"); - } - - CountDownTimerClass count; - if (CCFileClass("TRAILER.VQA").Is_Available()) { - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("TRAILER"); // Red Alert teaser. - } - - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); -// CountDownTimerClass count; - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("CC2TEASE"); -#endif -} - - -#ifndef DEMO -/*********************************************************************************************** - * Nod_Ending -- play ending movies for Nod players * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 7/10/1995 BWG : Created. * - *=============================================================================================*/ -void Nod_Ending(void) -{ - static unsigned char const _tanpal[]={0x0,0xED,0xED,0x2C,0x2C,0xFB,0xFB,0xFD,0xFD,0x0,0x0,0x0,0x0,0x0,0x52,0x0}; - - char fname[12]; -#ifdef NOT_FOR_WIN95 - char *satpic = new char[64000]; -#endif //NOT_FOR_WIN95 - int oldfontxspacing = FontXSpacing; - void const *oldfont; - - Score.Presentation(); - - oldfont = Set_Font(ScoreFontPtr); - - PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL); - TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height(), (void*)NULL); - TextPrintBuffer->Clear(); - BlitList.Clear(); - SeenBuff.Clear(); - HidPage.Clear(); - PseudoSeenBuff->Clear(); - - void * localpal = Load_Alloc_Data(CCFileClass("SATSEL.PAL")); - Load_Uncompress(CCFileClass("SATSEL.CPS"), SysMemPage, SysMemPage); -#ifdef NOT_FOR_WIN95 - memcpy(satpic, HidPage.Get_Buffer(), 64000); -#else - SysMemPage.Blit(*PseudoSeenBuff); -#endif //NOT_FOR_WIN95 - void *kanefinl = Load_Sample("KANEFINL.AUD"); - void *loopie6m = Load_Sample("LOOPIE6M.AUD"); - - Play_Movie("NODFINAL", THEME_NONE, false); - - Hide_Mouse(); - Wait_Vert_Blank(); - Set_Palette(localpal); -#ifdef NOT_FOR_WIN95 - memcpy(SeenBuff.Get_Buffer(), satpic, 64000); -#endif //NOT_FOR_WIN95 - Show_Mouse(); - - InterpolationPaletteChanged = TRUE; - InterpolationPalette = (unsigned char*)localpal; - Increase_Palette_Luminance(InterpolationPalette , 30,30,30,63); - Read_Interpolation_Palette("SATSELIN.PAL"); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff,"SATSELIN.PAL"); - - Keyboard::Clear(); - Play_Sample(kanefinl,255,128); - Play_Sample(loopie6m,255,128); - - bool mouseshown = false; - bool done = false; - int selection = 1; - bool printedtext = false; - while (!done) { - if (!printedtext && !Is_Sample_Playing(kanefinl)) { - printedtext++; - Alloc_Object(new ScorePrintClass(Text_String(TXT_SEL_TARGET), 0, 180,_tanpal)); - mouseshown = true; - Show_Mouse(); - } - Call_Back_Delay(1); - if (!Keyboard::Check()) { - if (!Is_Sample_Playing(loopie6m)) Play_Sample(loopie6m,255,128); - } else { - if (Is_Sample_Playing(kanefinl)) { - Clear_KeyBuffer(); - } else { - int key = Keyboard::Get(); - if ((key & 0x10FF) == KN_LMOUSE && !(key & KN_RLSE_BIT)) { - int mousex = _Kbd->MouseQX; - int mousey = _Kbd->MouseQY; - if (mousey >= 22*2 && mousey <= 177*2) { - done++; - if (mousex < 160*2 && mousey < 100*2) selection = 2; - if (mousex < 160*2 && mousey >= 100*2) selection = 3; - if (mousex >= 160*2 && mousey >= 100*2) selection = 4; - } - } - } - } - } - if (mouseshown) Hide_Mouse(); -#ifdef NOT_FOR_WIN95 - delete satpic; -#else - delete PseudoSeenBuff; -#endif //NOT_FOR_WIN95 - -/* get rid of all the animating objects */ - for (int i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) { - delete ScoreObjs[i]; - ScoreObjs[i] = 0; - } - // erase the "choose a target" text - SeenBuff.Fill_Rect(0,180*2,319*2,199*2,0); - TextPrintBuffer->Fill_Rect(0,180*2,319*2,199*2,0); - - Hide_Mouse(); - Keyboard::Clear(); - - Set_Font(oldfont); - FontXSpacing = oldfontxspacing; - Free_Sample(kanefinl); - Free_Sample(loopie6m); - - sprintf(fname,"NODEND%d",selection); - PreserveVQAScreen = 1; - Play_Movie(fname); - - CountDownTimerClass count; - if (CCFileClass("TRAILER.VQA").Is_Available()) { - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("TRAILER"); // Red Alert teaser. - } - - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); -// CountDownTimerClass count; - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("CC2TEASE"); - - delete [] localpal; - delete TextPrintBuffer; - BlitList.Clear(); -} -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/ENDING.H b/code/TIBERIANDAWN/ENDING.H deleted file mode 100644 index 0d67f44..0000000 --- a/code/TIBERIANDAWN/ENDING.H +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ENDING.H * - * * - * Programmer : Barry W. Green * - * * - * Start Date : July 10, 1995 * - * * - * Last Update : July 10, 1995 [BWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef ENDING_H -#define ENDING_H - -void Nod_Ending(void); - -#endif diff --git a/code/TIBERIANDAWN/EVENT.CPP b/code/TIBERIANDAWN/EVENT.CPP deleted file mode 100644 index fe3dd46..0000000 --- a/code/TIBERIANDAWN/EVENT.CPP +++ /dev/null @@ -1,779 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\event.cpv 2.17 16 Oct 1995 16:50:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : EVENT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/09/94 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * EventClass::EventClass -- Construct an id and cell based event. * - * EventClass::EventClass -- Construct simple target type event. * - * EventClass::EventClass -- Constructor for mission change events. * - * EventClass::EventClass -- Constructor for navigation computer events. * - * EventClass::EventClass -- Constructor for object types affecting cells event. * - * EventClass::EventClass -- Constructor for sidebar build events. * - * EventClass::EventClass -- Constructs event to transfer special flags. * - * EventClass::EventClass -- Default constructor for event objects. * - * EventClass::EventClass -- Event for sequencing animations. * - * EventClass::EventClass -- Megamission assigned to unit. * - * EventClass::Execute -- Execute a queued command. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "ccdde.h" - -/*************************************************************************** -** Table of what data is really used in the EventClass struct for different -** events. This table must be kept current with the EventType enum. -*/ -unsigned char EventClass::EventLength[EventClass::LAST_EVENT] = { - 0, // EMPTY - size_of(EventClass, Data.General ), // ALLY - size_of(EventClass, Data.MegaMission ), // MEGAMISSION - size_of(EventClass, Data.Target ), // IDLE - size_of(EventClass, Data.Target ), // SCATTER - 0, // DESTRUCT - 0, // DEPLOY - size_of(EventClass, Data.Place ), // PLACE - 0, // OPTIONS - size_of(EventClass, Data.General ), // GAMESPEED - size_of(EventClass, Data.Specific ), // PRODUCE - size_of(EventClass, Data.Specific.Type ), // SUSPEND - size_of(EventClass, Data.Specific.Type ), // ABANDON - size_of(EventClass, Data.Target ), // PRIMARY - size_of(EventClass, Data.Special ), // SPECIAL_PLACE - 0, // EXIT - size_of(EventClass, Data.Anim ), // ANIMATION - size_of(EventClass, Data.Target ), // REPAIR - size_of(EventClass, Data.Target ), // SELL - size_of(EventClass, Data.Options ), // SPECIAL - 0, // FRAMESYNC - 0, // MESSAGE - size_of(EventClass, Data.FrameInfo.Delay ), // RESPONSE_TIME - size_of(EventClass, Data.FrameInfo ), // FRAMEINFO - size_of(EventClass, Data.NavCom ), // ARCHIVE - size_of(EventClass, Data.Timing ), // TIMING - size_of(EventClass, Data.ProcessTime ), // PROCESS_TIME -}; - -char * EventClass::EventNames[EventClass::LAST_EVENT] = { - "EMPTY", - "ALLY", - "MEGAMISSION", - "IDLE", - "SCATTER", - "DESTRUCT", - "DEPLOY", - "PLACE", - "OPTIONS", - "GAMESPEED", - "PRODUCE", - "SUSPEND", - "ABANDON", - "PRIMARY", - "SPECIAL_PLACE", - "EXIT", - "ANIMATION", - "REPAIR", - "SELL", - "SPECIAL", - "FRAMESYNC", - "MESSAGE", - "RESPONSE_TIME", - "FRAMEINFO", - "ARCHIVE", - "TIMING", - "PROCESS_TIME", -}; - - -/*********************************************************************************************** - * EventClass::EventClass -- Constructs event to transfer special flags. * - * * - * This constructs an event that will transfer the special flags. * - * * - * INPUT: data -- The special flags to be transported to all linked computers. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(SpecialClass data) -{ - ID = Houses.ID(PlayerPtr); - Type = SPECIAL; - Frame = ::Frame; - Data.Options.Data = data; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Construct simple target type event. * - * * - * This will construct a generic event that needs only a target parameter. The actual * - * event and target values are specified as parameters. * - * * - * INPUT: type -- The event type to construct. * - * * - * target-- The target value that this event is to apply to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type, TARGET target) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Frame = ::Frame; - Data.Target.Whom = target; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Default constructor for event objects. * - * * - * This constructs a simple event object that requires no parameters other than the * - * type of event it is. * - * * - * INPUT: type -- The type of event to construct. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Frame = ::Frame; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Constructor for general-purpose-data events. * - * * - * INPUT: type -- The type of event to construct. * - * val -- data value * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type, int val) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Data.General.Value = val; - Frame = ::Frame; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Constructor for navigation computer events. * - * * - * Constructor for events that are used to assign the navigation computer. * - * * - * INPUT: type -- The type of event (this constructor can be used by other navigation * - * type events). * - * * - * src -- The object that the event should apply to. * - * * - * dest -- The destination (or target) that the event needs to complete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type, TARGET src, TARGET dest) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Frame = ::Frame; - Data.NavCom.Whom = src; - Data.NavCom.Where = dest; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Event for sequencing animations. * - * * - * This constructor is used for animations that must be created through the event system. * - * * - * INPUT: anim -- The animation that will be created. * - * * - * coord -- The location where the animation is to be created. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/19/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(AnimType anim, HousesType owner, COORDINATE coord) -{ - ID = Houses.ID(PlayerPtr); - Type = ANIMATION; - Frame = ::Frame; - Data.Anim.What = anim; - Data.Anim.Owner = owner; - Data.Anim.Where = coord; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Megamission assigned to unit. * - * * - * This is the event that is used to assign most missions to units. It combines both the * - * mission and the target (navcom and tarcom). * - * * - * INPUT: src -- The object that this mission is to apply to. * - * * - * mission -- The mission to assign to this object. * - * * - * target -- The target to assign to this object's TarCom. * - * * - * destination -- The destination to assign to this object's NavCom. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(TARGET src, MissionType mission, TARGET target, TARGET destination) -{ - ID = Houses.ID(PlayerPtr); - Type = MEGAMISSION; - Frame = ::Frame; - Data.MegaMission.Whom = src; - Data.MegaMission.Mission = mission; - Data.MegaMission.Target = target; - Data.MegaMission.Destination = destination; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Constructor for sidebar build events. * - * * - * This constructor is used for events that deal with an object type and an object ID. * - * Typically, this is used exclusively by the sidebar. * - * * - * INPUT: type -- The event type of this object. * - * * - * object -- The object type number. * - * * - * id -- The object sub-type number. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type, RTTIType object, int id) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Frame = ::Frame; - Data.Specific.Type = object; - Data.Specific.ID = id; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Constructor for object types affecting cells event. * - * * - * This constructor is used for those events that have an object type and associated cell. * - * Typically, this is for building placement after construction has completed. * - * * - * INPUT: type -- The event type for this object. * - * * - * object -- The object type number (actual object is probably inferred from the * - * sidebar data). * - * * - * cell -- The cell location where this event is to occur. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type, RTTIType object, CELL cell) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Frame = ::Frame; - Data.Place.Type = object; - Data.Place.Cell = cell; -} - - -/*********************************************************************************************** - * EventClass::EventClass -- Construct an id and cell based event. * - * * - * This constructor is used for those events that require an ID number and a cell location. * - * * - * INPUT: type -- The event type this will be. * - * * - * id -- The arbitrary id number to assign. * - * * - * cell -- The location for this event. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -EventClass::EventClass(EventType type, int id, CELL cell) -{ - ID = Houses.ID(PlayerPtr); - Type = type; - Frame = ::Frame; - Data.Special.ID = id; - Data.Special.Cell = cell; -} - - -/*********************************************************************************************** - * EventClass::Execute -- Execute a queued command. * - * * - * This routine executes an event. The even must already have been confirmed by any * - * remote machine before calling this routine. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -void EventClass::Execute(void) -{ - TechnoClass * techno; - AnimClass * anim = 0; - HouseClass * house = 0; - char txt[80]; - int i; -//#if (0) -if (Type < 0 || Type > PROCESS_TIME){ -char tempbuf[128]; -sprintf (tempbuf, "Packet type %d received\n", Type); -CCDebugString (tempbuf); - -sprintf (tempbuf, " ID = %d\n", ID); -CCDebugString (tempbuf); - -sprintf (tempbuf, " Frame = %d\n", Frame); -CCDebugString (tempbuf); - -sprintf (tempbuf, " MPlayer ID = %d\n", MPlayerID); -CCDebugString (tempbuf); - -} -//#endif //(0) - - - switch (Type) { - /* - ** Update the archive target for this building. - */ - case ARCHIVE: - techno = As_Techno(Data.NavCom.Whom); - if (techno && techno->IsActive) { - techno->ArchiveTarget = Data.NavCom.Where; - } - break; - - /* - ** Make or break alliance. - */ - case ALLY: - house = Houses.Raw_Ptr(Data.General.Value); - if (Houses.Raw_Ptr(ID)->Is_Ally(house)) { - Houses.Raw_Ptr(ID)->Make_Enemy((HousesType)Data.General.Value); - } else { - Houses.Raw_Ptr(ID)->Make_Ally((HousesType)Data.General.Value); - } - break; - - /* - ** Special self destruct action requested. This is active in the multiplayer mode. - */ - case DESTRUCT: -CCDebugString ("C&C95 - Resignation packet received\n"); - Houses.Raw_Ptr(ID)->Flag_To_Die(); - Houses.Raw_Ptr(ID)->Resigned = true; - break; - - /* - ** Update the special control flags. This is necessary so that in a multiplay - ** game, all machines will agree on the rules. If these options change during - ** game play, then all players are informed that options have changed. - */ - case SPECIAL: - { - Special = Data.Options.Data; - HouseClass * house = Houses.Raw_Ptr(ID); - - sprintf(txt, Text_String(TXT_SPECIAL_WARNING), house->Name); - Messages.Add_Message(txt, MPlayerTColors[house->RemapColor], - TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW, 1200, 0, 0); - Map.Flag_To_Redraw(false); - } - break; - - /* - ** Starts or stops repair on the specified object. This event is triggered by the - ** player clicking the repair wrench on a building. - */ - case REPAIR: -CCDebugString ("C&C95 - Repair packet received\n"); - techno = As_Techno(Data.Target.Whom); - if (techno && techno->IsActive) { - techno->Repair(-1); - } - break; - - /* - ** Tells a building/unit to sell. This event is triggered by the player clicking the - ** sell animating cursor over the building or unit. - */ - case SELL: -CCDebugString ("C&C95 - Sell packet received\n"); - techno = As_Techno(Data.Target.Whom); - if (techno && techno->IsActive && techno->House == Houses.Raw_Ptr(ID)) { - techno->Sell_Back(-1); - } else { - if (Is_Target_Cell(Data.Target.Whom)) { - Houses.Raw_Ptr(ID)->Sell_Wall(As_Cell(Data.Target.Whom)); - } - } - break; - - /* - ** This even is used to trigger an animation that is generated as a direct - ** result of player intervention. - */ - case ANIMATION: - anim = new AnimClass(Data.Anim.What, Data.Anim.Where); - if (anim) { - //2019/09/19 JAS - Visibility needs to be determined per player - if (Data.Anim.What != ANIM_MOVE_FLASH || Data.Anim.Owner == HOUSE_NONE || Special.IsVisibleTarget) - { - anim->Set_Visible_Flags(0xffff); - } - else - { - anim->Set_Visible_Flags(1 << Data.Anim.Owner); - } - } - break; - - /* - ** This event will place the specified object at the specified location. - ** The event is used to place newly constructed buildings down on the map. The - ** object type is specified. From this object type, the house can determine the - ** exact factory and real object pointer to use. - */ - case PLACE: -CCDebugString ("C&C95 - Place packet received\n"); - Houses.Raw_Ptr(ID)->Place_Object(Data.Place.Type, Data.Place.Cell); - break; - - /* - ** This event starts production of the speicified object type. The house can - ** determine from the type and ID value, what object to begin production on and - ** what factory to use. - */ - case PRODUCE: -CCDebugString ("C&C95 - Produce packet received\n"); - Houses.Raw_Ptr(ID)->Begin_Production(Data.Specific.Type, Data.Specific.ID); - break; - - /* - ** This event is generated when the player puts production on hold. From the - ** object type, the factory can be inferred. - */ - case SUSPEND: -CCDebugString ("C&C95 - Suspend packet received\n"); - Houses.Raw_Ptr(ID)->Suspend_Production(Data.Specific.Type); - break; - - /* - ** This event is generated when the player cancels production of the specified - ** object type. From the object type, the exact factory can be inferred. - */ - case ABANDON: -CCDebugString ("C&C95 - Abandon packet received\n"); - Houses.Raw_Ptr(ID)->Abandon_Production(Data.Specific.Type); - break; - - /* - ** Toggles the primary factory state of the specified building. - */ - case PRIMARY:{ -CCDebugString ("C&C95 - Primary building packet received\n"); - BuildingClass * building = As_Building(Data.Target.Whom); - if (building && building->IsActive) { - building->Toggle_Primary(); - } - } - break; - - /* - ** This is the general purpose mission control event. Most player - ** action routes through this event. It sets a unit's mission, TarCom, - ** and NavCom to the values specified. - */ - case MEGAMISSION: - techno = As_Techno(Data.MegaMission.Whom); - if (techno && techno->IsActive) { - - /* - ** Fetch a pointer to the object of the mission. - */ - ObjectClass * object; - if (Target_Legal(Data.MegaMission.Target)) { - object = As_Object(Data.MegaMission.Target); - } else { - object = As_Object(Data.MegaMission.Destination); - } - - /* - ** Break any existing team contact, since it is now invalid. - */ - if (!techno->IsTethered) { - techno->Transmit_Message(RADIO_OVER_OUT); - } - switch (techno->What_Am_I()) { - case RTTI_INFANTRY: - case RTTI_UNIT: - if (((FootClass *)techno)->Team) { - ((FootClass *)techno)->Team->Remove((FootClass *)techno); - } - break; - } - - if (object) { - - // 2019/09/20 JAS - Added record of who clicked on the object - HouseClass* house = Houses.Raw_Ptr(ID); - bool is_allied = house != nullptr && house->Is_Ally(techno); - if (is_allied || Special.IsVisibleTarget) { - object->Clicked_As_Target((HousesType)ID); - } - } - techno->Assign_Mission(Data.MegaMission.Mission); - - /* - ** Guard area mode is handled with care. The specified target is actually - ** assigned as the location that should be guarded. In addition, the - ** movement destination is immediately set to this new location. - */ - if (Data.MegaMission.Mission == MISSION_GUARD_AREA && -// Target_Legal(Data.MegaMission.Target) && - (techno->What_Am_I() == RTTI_INFANTRY || techno->What_Am_I() == RTTI_UNIT || techno->What_Am_I() == RTTI_AIRCRAFT)) { - - techno->ArchiveTarget = Data.MegaMission.Target; - techno->Assign_Target(TARGET_NONE); - techno->Assign_Destination(Data.MegaMission.Target); - } else { - techno->Assign_Target(Data.MegaMission.Target); - techno->Assign_Destination(Data.MegaMission.Destination); - } - -#ifdef NEVER - if ((techno->What_Am_I() == RTTI_UNIT || techno->What_Am_I() == RTTI_INFANTRY) && - Data.MegaMission.Mission == MISSION_GUARD_AREA) { - - techno->ArchiveTarget = Data.MegaMission.Destination; - } -#endif - } - break; - - /* - ** Request that the unit/infantry/aircraft go into idle mode. - */ - case IDLE: - techno = As_Techno(Data.Target.Whom); - if (techno && techno->IsActive && !techno->IsInLimbo && !techno->IsTethered) { - techno->Assign_Destination(TARGET_NONE); - techno->Assign_Target(TARGET_NONE); - techno->Enter_Idle_Mode(); - } - break; - - /* - ** Request that the unit/infantry/aircraft scatter from its current location. - */ - case SCATTER: - techno = As_Techno(Data.Target.Whom); - if (techno && techno->IsActive && !techno->IsInLimbo && !techno->IsTethered) { - techno->Scatter(0, true); - } - break; - - /* - ** If we are placing down the ion cannon blast then lets take - ** care of it. - */ - case SPECIAL_PLACE: -CCDebugString ("C&C95 - Special blast packet received\n"); - Houses.Raw_Ptr(ID)->Place_Special_Blast((SpecialWeaponType)Data.Special.ID, Data.Special.Cell); - break; - - /* - ** Exit the game. - ** Give parting message while palette is fading to black. - */ - case EXIT: -CCDebugString ("C&C95 - Exit game packet received\n"); - Theme.Queue_Song(THEME_NONE); - Stop_Speaking(); - Speak(VOX_CONTROL_EXIT); - while (Is_Speaking()) { - Call_Back(); - } - GameActive = false; - break; - - /* - ** Process the options menu. - */ - case OPTIONS: - SpecialDialog = SDLG_OPTIONS; - break; - - /* - ** Process the options Game Speed - */ - case GAMESPEED: -CCDebugString ("C&C95 - Game speed packet received\n"); - Options.GameSpeed = Data.General.Value; - break; - - /* - ** Adjust connection timing for multiplayer games - */ - case RESPONSE_TIME: -char flip[128]; -sprintf (flip, "C&C95 - Changing MaxAhead to %d frames\n", Data.FrameInfo.Delay); -CCDebugString (flip); - MPlayerMaxAhead = Data.FrameInfo.Delay; - break; - - // - // This event tells all systems to use new timing values. It's like - // RESPONSE_TIME, only it works. It's only used with the - // COMM_MULTI_E_COMP protocol. - // - case TIMING: -CCDebugString ("C&C95 - Timing packet received\n"); -//#if(TIMING_FIX) - // - // If MaxAhead is about to increase, we're vulnerable to a Packet- - // Received-Too-Late error, if any system generates an event after - // this TIMING event, but before it executes. So, record the - // period of vulnerability's frame start & end values, so we - // can reschedule these events to execute after it's over. - // - if (Data.Timing.MaxAhead > MPlayerMaxAhead) { - NewMaxAheadFrame1 = Frame; - NewMaxAheadFrame2 = Frame + Data.Timing.MaxAhead; - } -//#endif - - DesiredFrameRate = Data.Timing.DesiredFrameRate; - MPlayerMaxAhead = Data.Timing.MaxAhead; - -sprintf (flip, "C&C95 - Timing packet: DesiredFrameRate = %d\n", Data.Timing.DesiredFrameRate); -CCDebugString (flip); -sprintf (flip, "C&C95 - Timing packet: MaxAhead = %d\n", Data.Timing.MaxAhead); -CCDebugString (flip); - - /* - ** If spawned from WChat then we should be getting poked every minute. If not then - ** deliberately break the max ahead value - */ - if (Special.IsFromWChat){ - MPlayerMaxAhead += DDEServer.Time_Since_Heartbeat()/(70*60); -//if (DDEServer.Time_Since_Heartbeat() >= 70*60) CCDebugString ("C&C95 - Missed a heartbeat\n"); - } - break; - - // - // This event tells all systems what the other systems' process - // timing requirements are; it's used to compute a desired frame rate - // for the game. - // - case PROCESS_TIME: - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID == ::MPlayerID[i]) { - TheirProcessTime[i] = Data.ProcessTime.AverageTicks; - -char flip[128]; -sprintf (flip, "C&C95 - Received PROCESS_TIME packet of %04x ticks\n", Data.ProcessTime.AverageTicks); -CCDebugString (flip); - - break; - } - } - break; - - /* - ** Default: do nothing. - */ - default: - break; - } -} diff --git a/code/TIBERIANDAWN/EVENT.H b/code/TIBERIANDAWN/EVENT.H deleted file mode 100644 index b880d87..0000000 --- a/code/TIBERIANDAWN/EVENT.H +++ /dev/null @@ -1,224 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\event.h_v 2.19 16 Oct 1995 16:46:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : EVENT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/09/94 * - * * - * Last Update : December 9, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef EVENT_H -#define EVENT_H - -/* -** This event class is used to contain all external game events (things that the player can -** do at any time) so that these events can be transported between linked computers. This -** encapsulation is required in order to ensure that each event affects all computers at the -** same time (same game frame). -*/ -class EventClass -{ - public: - - /* - ** All external events are identified by these labels. - */ - typedef enum EventType : unsigned char { - EMPTY, - - ALLY, // Make allie of specified house. - MEGAMISSION, // Full change of mission with target and destination. - IDLE, // Request to enter idle mode. - SCATTER, // Request to scatter from current location. - DESTRUCT, // Self destruct request (surrender action). - DEPLOY, // MCV is to deploy at current location. - PLACE, // Place building at location specified. - OPTIONS, // Bring up options screen. - GAMESPEED, // Set game speed - PRODUCE, // Start or Resume production. - SUSPEND, // Suspend production. - ABANDON, // Abandon production. - PRIMARY, // Primary factory selected. - SPECIAL_PLACE, // Special target location selected - EXIT, // Exit game. - ANIMATION, // Flash ground as movement feedback. - REPAIR, // Repair specified object. - SELL, // Sell specified object. - SPECIAL, // Special options control. - - // Private events. - FRAMESYNC, // Game-connection packet; includes Scenario CRC & sender's frame # - // Used to initiate game connection phase & to reconnect; - // When one of these is received, the receiver knows there are - // no associated commands in this packet. - MESSAGE, // Message to another player (The message is the 40 bytes - // after the event class). - RESPONSE_TIME, // use a new propogation delay value - FRAMEINFO, // Game-heartbeat packet; includes Game CRC & command count - // All packets sent for a frame are prefixed with one of these - ARCHIVE, // Updates archive target on specified object. - TIMING, // new timing values for all systems to use - PROCESS_TIME, // a system's average processing time, in ticks per frame - LAST_EVENT, // one past the last event - } EventType; - - EventType Type; // Type of queue command object. - - /* - ** 'Frame' is the frame that the command should execute on. - ** 27 bits gives over 25 days of playing time without wrapping, - ** at 30 frames per second, so it should be plenty! - */ - unsigned Frame : 27; - - /* - ** House index of the player originating this event - */ - unsigned ID : 4; - - /* - ** This bit tells us if we've already executed this event. - */ - unsigned IsExecuted: 1; - - /* - ** Multiplayer ID of the player originating this event. - ** High nybble: the color index of this player. - ** Low nybble: the HousesType this player is "acting like" (GDI/NOD) - */ - unsigned char MPlayerID; - - /* - ** This union contains the specific data that the event requires. - */ - union { - struct { - SpecialClass Data; // The special option flags. - } Options; - struct { - TARGET Whom; // The object to apply the event to. - } Target; - struct { - AnimType What; // The animation to create. - HousesType Owner; // The owner of the animation (when it matters). - COORDINATE Where; // The location to place the animation. - } Anim; - struct { - int Value; // general-purpose data - } General; - struct { - TARGET Whom; // Whom to apply mission to. - MissionType Mission; // What mission to apply. - TARGET Target; // Target to assign. - TARGET Destination;// Destination to assign. - } MegaMission; - struct { - TARGET Whom; // Whom to apply mission to. - MissionType Mission; // What mission to apply. - } Mission; - struct { - TARGET Whom; // Whom to apply movement change to. - TARGET Where; // Where to set NavCom to. - } NavCom; - struct { - TARGET Whom; // Whom to apply attack change to. - TARGET Target; // What to set TarCom to. - } TarCom; - struct { - RTTIType Type; - int ID; - } Specific; - struct { - RTTIType Type; - CELL Cell; - } Place; - struct { - int ID; - CELL Cell; - } Special; - /* - ** This structure is used for FRAMEINFO, FRAMESYNC, and RESPONSE_TIME - ** events; exactly one of these will be sent each frame, whether there's - ** data that frame or not. - ** CRC: the game CRC when this packet was generated; used to detect sync errors - ** CommandCount: # of commands the sender has sent; used to detect missed packets - ** Delay: sender's propogation delay value for this frame - */ - struct { - unsigned long CRC; - unsigned short CommandCount; // # commands sent so far - unsigned char Delay; // propogation delay used this frame - // (Frame - Delay = sender's current frame #) - } FrameInfo; - - // - // This structure sets new timing values for all systems in a multiplayer - // game. This structure replaces the RESPONSE_TIME event for - // the COMM_MULTI_E_COMP protocol. - // - struct { - unsigned short DesiredFrameRate; - unsigned short MaxAhead; - } Timing; - - // - // This structure is transmitted by all systems, and is used to compute - // the "desired" frame rate for the game. - // - struct { - unsigned short AverageTicks; - } ProcessTime; - - } Data; - - //-------------- Functions --------------------- - EventClass(void) {Type = EMPTY;}; - EventClass(SpecialClass data); - EventClass(EventType type, TARGET target); - EventClass(EventType type); - EventClass(EventType type, int val); - EventClass(EventType type, TARGET src, TARGET dest); -// EventClass(TARGET src, MissionType mission); - EventClass(TARGET src, MissionType mission, TARGET target=TARGET_NONE, TARGET destination=TARGET_NONE); - EventClass(EventType type, RTTIType object, int id); - EventClass(EventType type, RTTIType object, CELL cell); - EventClass(EventType type, int id, CELL cell); - EventClass(AnimType anim, HousesType owner, COORDINATE coord); - - // Process the event. - void Execute(void); - - int operator == (EventClass & q) { - return memcmp(this, &q, sizeof(q)) == 0; - }; - - static unsigned char EventLength[LAST_EVENT]; - static char * EventNames[LAST_EVENT]; -}; - -#endif diff --git a/code/TIBERIANDAWN/EXPAND.CPP b/code/TIBERIANDAWN/EXPAND.CPP deleted file mode 100644 index ec92ab0..0000000 --- a/code/TIBERIANDAWN/EXPAND.CPP +++ /dev/null @@ -1,420 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header$ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : EXPAND.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 11/03/95 * - * * - * Last Update : November 3, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef NEWMENU - -bool Expansion_Present(void) -{ - CCFileClass file("EXPAND.DAT"); - - return(file.Is_Available()); -} - - - - -class EListClass : public ListClass -{ - public: - EListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down) : - ListClass(id, x, y, w, h, flags, up, down) {}; - - protected: - virtual void Draw_Entry(int index, int x, int y, int width, int selected); -}; - - -void EListClass::Draw_Entry(int index, int x, int y, int width, int selected) -{ - if (TextFlags & TPF_6PT_GRAD) { - TextPrintType flags = TextFlags; - - if (selected) { - flags = flags | TPF_BRIGHT_COLOR; - LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, CC_GREEN_SHADOW); - } else { - if (!(flags & TPF_USE_GRAD_PAL)) { - flags = flags | TPF_MEDIUM_COLOR; - } - } - - Conquer_Clip_Text_Print(List[index]+sizeof(int), x, y, CC_GREEN, TBLACK, flags, width, Tabs); - - } else { - Conquer_Clip_Text_Print(List[index]+sizeof(int), x, y, (selected ? BLUE : WHITE), TBLACK, TextFlags, width, Tabs); - } -} - -bool Expansion_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - int option_width = 236 * factor; - int option_height = 162 * factor; - int option_x = (320*factor - option_width) /2; - int option_y = (200*factor - option_height) /2; - - GadgetClass * buttons = NULL; - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - TextButtonClass ok(200, TXT_OK, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+25*factor, option_y+option_height-15*factor); - TextButtonClass cancel(201, TXT_CANCEL, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+option_width-50*factor, option_y+option_height-15*factor); - EListClass list(202, option_x+10*factor, option_y+20*factor, option_width-20*factor, option_height-40*factor, TPF_6PT_GRAD|TPF_NOSHADOW, up_button, down_button); - - buttons = &ok; - cancel.Add(*buttons); - list.Add(*buttons); - - - /* - ** Add in all the expansion scenarios. - */ - char * sbuffer = (char*)_ShapeBuffer; - int index; - for (index = 20; index < 60; index++) { - char buffer[128]; - CCFileClass file; - - Set_Scenario_Name(buffer, index, SCEN_PLAYER_GDI, SCEN_DIR_EAST, SCEN_VAR_A); - strcat(buffer, ".INI"); - file.Set_Name(buffer); - if (file.Is_Available()) { - file.Read(sbuffer, 1000); - sbuffer[1000] = '\r'; - sbuffer[1000+1] = '\n'; - sbuffer[1000+2] = '\0'; - - WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer); - char * data = new char [strlen(buffer)+1+sizeof(int)+25]; - *((int*)&data[0]) = index; - strcpy(&data[sizeof(int)], "GDI: "); - strcat(&data[sizeof(int)], buffer); - list.Add_Item(data); - } - } - - for (index = 20; index < 60; index++) { - char buffer[128]; - CCFileClass file; - - Set_Scenario_Name(buffer, index, SCEN_PLAYER_NOD, SCEN_DIR_EAST, SCEN_VAR_A); - strcat(buffer, ".INI"); - file.Set_Name(buffer); - if (file.Is_Available()) { - file.Read(sbuffer, 1000); - sbuffer[1000] = '\r'; - sbuffer[1000+1] = '\n'; - sbuffer[1000+2] = '\0'; - - WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer); - char * data = new char [strlen(buffer)+1+sizeof(int)+25]; - *((int*)&data[0]) = index; - strcpy(&data[sizeof(int)], "NOD: "); - strcat(&data[sizeof(int)], buffer); - list.Add_Item(data); - } - } - - Set_Logic_Page(SeenBuff); - bool recalc = true; - bool display = true; - bool process = true; - bool okval = true; - while (process) { - - Call_Back(); - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - if (display) { - display = false; - - Hide_Mouse(); - - /* - ** Load the background picture. - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - - Dialog_Box(option_x, option_y, option_width, option_height); - Draw_Caption(TXT_MISSION_DESCRIPTION, option_x, option_y, option_width); - buttons->Draw_All(); - Show_Mouse(); - } - - KeyNumType input = buttons->Input(); - switch (input) { - case KN_RETURN: - case 200|KN_BUTTON: - if (list.Current_Item()[sizeof(int)] == 'G') { - ScenPlayer = SCEN_PLAYER_GDI; - } else { - ScenPlayer = SCEN_PLAYER_NOD; - } - ScenDir = SCEN_DIR_EAST; - Whom = HOUSE_GOOD; - Scenario = *(int *)list.Current_Item(); - process = false; - okval = true; - break; - - case KN_ESC: - case 201|KN_BUTTON: - ScenPlayer = SCEN_PLAYER_GDI; - ScenDir = SCEN_DIR_EAST; - Whom = HOUSE_GOOD; - Scenario = *(int *)list.Current_Item(); - process = false; - okval = false; - break; - - default: - break; - } - } - - /* - ** Free up the allocations for the text lines in the list box. - */ - for (index = 0; index < list.Count(); index++) { - delete [] (char *)list.Get_Item(index); - } - - return(okval); -} - - - - - - - - - - - - -/*********************************************************************************************** - * Bonus_Dialog -- Asks the user which bonus mission he wants to play * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/26/97 11:07AM ST : Created * - *=============================================================================================*/ -bool Bonus_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - int option_width = 236 * factor; - int option_height = 162 * factor; - int option_x = (320*factor - option_width) /2; - int option_y = (200*factor - option_height) /2; - - GadgetClass * buttons = NULL; - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - TextButtonClass ok(200, TXT_OK, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+25*factor, option_y+option_height-15*factor); - TextButtonClass cancel(201, TXT_CANCEL, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+option_width-50*factor, option_y+option_height-15*factor); - EListClass list(202, option_x+10*factor, option_y+20*factor, option_width-20*factor, option_height-40*factor, TPF_6PT_GRAD|TPF_NOSHADOW, up_button, down_button); - - buttons = &ok; - cancel.Add(*buttons); - list.Add(*buttons); - - - /* - ** Add in all the expansion scenarios. - */ - char * sbuffer = (char*)_ShapeBuffer; - int gdi_scen_names[3]={ - TXT_BONUS_MISSION_1, - TXT_BONUS_MISSION_2, - TXT_BONUS_MISSION_3 - }; - - int nod_scen_names[2]={ - TXT_BONUS_MISSION_4, - TXT_BONUS_MISSION_5 - }; - - int index; - for (index = 60; index < 63; index++) { - char buffer[128]; - CCFileClass file; - - Set_Scenario_Name(buffer, index, SCEN_PLAYER_GDI, SCEN_DIR_EAST, SCEN_VAR_A); - strcat(buffer, ".INI"); - file.Set_Name(buffer); - if (file.Is_Available()) { - memcpy (buffer, Text_String (gdi_scen_names[index-60]), 1+strlen(Text_String (gdi_scen_names[index-60]))); - char * data = new char [strlen(buffer)+1+sizeof(int)+25]; - *((int*)&data[0]) = index; - strcpy(&data[sizeof(int)], "GDI: "); - strcat(&data[sizeof(int)], buffer); - list.Add_Item(data); - } - } - - for (index = 60; index < 62; index++) { - char buffer[128]; - CCFileClass file; - - Set_Scenario_Name(buffer, index, SCEN_PLAYER_NOD, SCEN_DIR_EAST, SCEN_VAR_A); - strcat(buffer, ".INI"); - file.Set_Name(buffer); - if (file.Is_Available()) { - memcpy (buffer, Text_String (nod_scen_names[index-60]), 1+strlen(Text_String (nod_scen_names[index-60]))); - char * data = new char [strlen(buffer)+1+sizeof(int)+25]; - *((int*)&data[0]) = index; - strcpy(&data[sizeof(int)], "NOD: "); - strcat(&data[sizeof(int)], buffer); - list.Add_Item(data); - } - } - - Set_Logic_Page(SeenBuff); - bool recalc = true; - bool display = true; - bool process = true; - bool okval = true; - while (process) { - - Call_Back(); - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - if (display) { - display = false; - - Hide_Mouse(); - - /* - ** Load the background picture. - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - - Dialog_Box(option_x, option_y, option_width, option_height); - Draw_Caption(TXT_BONUS_MISSIONS, option_x, option_y, option_width); - buttons->Draw_All(); - Show_Mouse(); - } - - KeyNumType input = buttons->Input(); - switch (input) { - case KN_RETURN: - case 200|KN_BUTTON: - if (list.Current_Item()[sizeof(int)] == 'G') { - ScenPlayer = SCEN_PLAYER_GDI; - } else { - ScenPlayer = SCEN_PLAYER_NOD; - } - ScenDir = SCEN_DIR_EAST; - Whom = HOUSE_GOOD; - Scenario = *(int *)list.Current_Item(); - process = false; - okval = true; - break; - - case KN_ESC: - case 201|KN_BUTTON: - ScenPlayer = SCEN_PLAYER_GDI; - ScenDir = SCEN_DIR_EAST; - Whom = HOUSE_GOOD; - Scenario = *(int *)list.Current_Item(); - process = false; - okval = false; - break; - - default: - break; - } - } - - /* - ** Free up the allocations for the text lines in the list box. - */ - for (index = 0; index < list.Count(); index++) { - delete [] (char *)list.Get_Item(index); - } - - return(okval); -} - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/EXTERNS.H b/code/TIBERIANDAWN/EXTERNS.H deleted file mode 100644 index 0e84ea6..0000000 --- a/code/TIBERIANDAWN/EXTERNS.H +++ /dev/null @@ -1,407 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\externs.h_v 2.15 16 Oct 1995 16:45:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : EXTERNS.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 27, 1994 * - * * - * Last Update : May 27, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef EXTERNS_H -#define EXTERNS_H - -#include "cell.h" - -#ifdef SCENARIO_EDITOR -#include "mapedit.h" -#endif -#include "techno.h" -#include "type.h" -#include "building.h" -#include "unit.h" -#include "credits.h" -#include "goptions.h" -#include "options.h" -#include "infantry.H" - -#ifdef JAPANESE -extern bool ForceEnglish; -#endif - -extern bool Debug_Quiet; -extern bool Debug_Cheat; -extern bool Debug_Remap; -extern bool Debug_Flag; -extern bool Debug_Lose; -extern bool Debug_Map; -extern bool Debug_Win; -extern bool Debug_Icon; -extern bool Debug_Passable; -extern bool Debug_Unshroud; -extern bool Debug_Threat; -extern bool Debug_Find_Path; -extern bool Debug_Check_Map; -extern bool Debug_Playtest; - -extern bool Debug_Heap_Dump; -extern bool Debug_Smart_Print; -extern bool Debug_Trap_Check_Heap; -extern bool Debug_Instant_Build; -extern bool Debug_Force_Crash; - -extern void const *WarFactoryOverlay; - - -/* -** Dynamic global variables (these change or are initialized at run time). -*/ -#ifdef PATCH -extern bool IsV107; -extern char OverridePath[128]; -#endif -extern bool SlowPalette; -extern char VersionText[16]; -extern bool ScoresPresent; -extern int CrateCount; -extern TCountDownTimerClass CrateTimer; -extern bool CrateMaker; -extern ThemeType TransitTheme; -extern bool AllowVoice; -extern NewConfigType NewConfig; -extern char BriefingText[512]; -extern char IntroMovie[_MAX_FNAME+_MAX_EXT]; -extern char ActionMovie[_MAX_FNAME+_MAX_EXT]; -extern char BriefMovie[_MAX_FNAME+_MAX_EXT]; -extern char WinMovie[_MAX_FNAME+_MAX_EXT]; -extern char WinMovie2[_MAX_FNAME + _MAX_EXT]; -extern char WinMovie3[_MAX_FNAME + _MAX_EXT]; -extern char WinMovie4[_MAX_FNAME + _MAX_EXT]; -extern char LoseMovie[_MAX_FNAME+_MAX_EXT]; -extern char MovieThemeName[_MAX_FNAME + _MAX_EXT]; -extern VoxType SpeakQueue; -extern bool PlayerWins; -extern bool PlayerLoses; -extern bool PlayerRestarts; -extern StructType SabotagedType; -extern bool TempleIoned; -extern long Frame; -extern void * SpeechBuffer; -extern int PreserveVQAScreen; -extern bool BreakoutAllowed; -extern bool Brokeout; -extern CELL Views[4]; - -extern GameOptionsClass Options; - -extern LogicClass Logic; -#ifdef SCENARIO_EDITOR -extern MapEditClass Map; -#else -extern MouseClass Map; -#endif -extern ScoreClass Score; -extern MonoClass MonoArray[MonoClass::MAX_MONO_PAGES]; -extern MixFileClass * ScoreMix; -extern MixFileClass * TheaterData; -extern MixFileClass * LowTheaterData; -extern MixFileClass * MoviesMix; -extern MixFileClass * GeneralMix; -extern ThemeClass Theme; -extern SpecialClass Special; -extern RulesClass Rule; - -/* -** Game object allocation and tracking classes. -*/ -extern TFixedIHeapClass Units; -extern TFixedIHeapClass Factories; -extern TFixedIHeapClass Terrains; -extern TFixedIHeapClass Templates; -extern TFixedIHeapClass Smudges; -extern TFixedIHeapClass Overlays; -extern TFixedIHeapClass Infantry; -extern TFixedIHeapClass Bullets; -extern TFixedIHeapClass Buildings; -extern TFixedIHeapClass Anims; -extern TFixedIHeapClass Aircraft; -extern TFixedIHeapClass Triggers; -extern TFixedIHeapClass TeamTypes; -extern TFixedIHeapClass Teams; -extern TFixedIHeapClass Houses; - -extern QueueClass OutList; -extern QueueClass DoList; - -typedef DynamicVectorArrayClass SelectedObjectsType; -extern SelectedObjectsType CurrentObject; -extern DynamicVectorClass CellTriggers; -extern DynamicVectorClass HouseTriggers[HOUSE_COUNT]; - -extern CELL Waypoint[WAYPT_COUNT]; - -extern BaseClass Base; - -/* -** Loaded data file pointers. -*/ -extern void const * Green12FontPtr; -extern void const * Green12GradFontPtr; -extern void const * MapFontPtr; -extern void const * VCRFontPtr; -extern void const * Font3Ptr; -extern void const * Font6Ptr; -extern void const * Font8Ptr; -extern void const * FontLEDPtr; -extern void const * ScoreFontPtr; -extern void const * GradFont6Ptr; -extern char const * SystemStrings; - -/* -** Miscellaneous globals. -*/ -extern HousesType Whom; -//extern _VQAConfig AnimControl; -extern long SpareTicks; -extern int MonoPage; -extern unsigned char * OriginalPalette; -extern int EndCountDown; -extern bool GameActive; -extern bool SpecialFlag; -extern int ScenarioInit; -extern long TutorFlags[2]; -extern HouseClass * PlayerPtr; -extern unsigned char * BlackPalette; -extern unsigned char * WhitePalette; -extern unsigned char * GamePalette; -extern unsigned Scenario; -extern ScenarioPlayerType ScenPlayer; -extern ScenarioDirType ScenDir; -extern ScenarioVarType ScenVar; -extern int CarryOverMoney; -extern int CarryOverCap; -extern int CarryOverPercent; -extern char ScenarioName[_MAX_FNAME+_MAX_EXT]; -extern unsigned BuildLevel; -extern unsigned long ScenarioCRC; - -#ifdef SCENARIO_EDITOR -extern CELL CurrentCell; -#endif - -extern GameType GameToPlay; - -extern CommProtocolType CommProtocol; - -extern CCFileClass RecordFile; -extern int RecordGame; -extern int SuperRecord; -extern int PlaybackGame; -extern int AllowAttract; - -extern GetCDClass CDList; - -/* -** Modem globals -*/ -extern bool ModemService; -//extern NullModemClass NullModem; -//extern DynamicVectorClass PhoneBook; -extern int CurPhoneIdx; -extern DynamicVectorClass InitStrings; -extern SerialSettingsType SerialDefaults; -extern ModemGameType ModemGameToPlay; -extern char * DialMethodCheck[ DIAL_METHODS ]; -extern char * CallWaitStrings[ CALL_WAIT_STRINGS_NUM ]; - -/* -** Network/Modem globals -*/ -extern int ScenarioIdx; -extern int ColorUsed[]; -extern char MPlayerName[MPLAYER_NAME_MAX]; -extern int MPlayerGColors[]; -extern int MPlayerTColors[]; -extern char MPlayerDescriptions[100][40]; -extern DynamicVectorClass MPlayerScenarios; -extern DynamicVectorClass MPlayerFilenum; -extern int MPlayerMax; -extern int MPlayerPrefColor; -extern int MPlayerColorIdx; -extern HousesType MPlayerHouse; -extern unsigned char MPlayerLocalID; -extern int MPlayerCount; -extern int MPlayerBases; -extern int MPlayerCredits; -extern int MPlayerTiberium; -extern int MPlayerGoodies; -extern int MPlayerGhosts; -extern int MPlayerSolo; -extern int MPlayerUnitCount; -extern int MPlayerCountMin[2]; -extern int MPlayerCountMax[2]; -extern unsigned long MPlayerMaxAhead; -extern unsigned long FrameSendRate; -extern unsigned char MPlayerID[MAX_PLAYERS]; -extern HousesType MPlayerHouses[MAX_PLAYERS]; -extern char MPlayerNames [MAX_PLAYERS][MPLAYER_NAME_MAX]; -extern MessageListClass Messages; -extern IPXAddressClass MessageAddress; -extern char LastMessage[MAX_MESSAGE_LENGTH]; -extern int MPlayerBlitz; -extern int MPlayerObiWan; -extern MPlayerScoreType MPlayerScore[MAX_MULTI_NAMES]; -extern int MPlayerGamesPlayed; -extern int MPlayerNumScores; -extern int MPlayerWinner; -extern int MPlayerCurGame; - -extern int TheirProcessTime[MAX_PLAYERS - 1]; -extern int DesiredFrameRate; - -extern char * GlobalPacketNames[]; -extern char * SerialPacketNames[]; - -typedef struct { - union { - AircraftClass *Aircraft; - AnimClass *Anim; - BuildingClass *Building; - BulletClass *Bullet; - InfantryClass *Infantry; - UnitClass *Unit; - void *All; - } Ptr; -} TrapObjectType; - -extern long TrapFrame; -extern RTTIType TrapObjType; -extern TrapObjectType TrapObject; -extern COORDINATE TrapCoord; -extern void * TrapThis; -extern CellClass * TrapCell; -extern int TrapCheckHeap; - -/* -** Network (IPX) globals -*/ -extern IPXManagerClass Ipx; -extern int IsBridge; -extern IPXAddressClass BridgeNet; -extern bool NetMaster; -extern bool NetStealth; -extern bool NetProtect; -extern bool NetOpen; -extern char MPlayerGameName[MPLAYER_NAME_MAX]; -extern GlobalPacketType GPacket; -extern int GPacketlen; -extern IPXAddressClass GAddress; -extern unsigned short GProductID; -extern char * MetaPacket; -extern int MetaSize; -extern DynamicVectorClass Games; -extern DynamicVectorClass Players; - -extern int Seed; -extern long * RandSeedPtr; -extern int CustomSeed; -extern int NewMaxAheadFrame1; -extern int NewMaxAheadFrame2; - -/* -** Constant externs (data is not modified during game play). -*/ -extern unsigned char const RemapGreen[256]; -extern unsigned char const RemapBlue[256]; -extern unsigned char const RemapOrange[256]; -extern unsigned char const RemapNone[256]; -extern unsigned char const RemapGold[256]; -extern unsigned char const RemapRed[256]; -extern unsigned char const RemapLtBlue[256]; -extern WeaponTypeClass const Weapons[WEAPON_COUNT]; -extern WarheadTypeClass const Warheads[WARHEAD_COUNT]; -extern char const * SourceName[SOURCE_COUNT]; -extern GroundType const Ground[LAND_COUNT]; -extern TheaterDataType const Theaters[THEATER_COUNT]; -extern unsigned char const Facing32[256]; -extern unsigned char const Facing8[256]; -extern unsigned char const Pixel2Lepton[24]; -extern COORDINATE const StoppingCoordAbs[5]; -extern CELL const AdjacentCell[FACING_COUNT]; -extern COORDINATE const AdjacentCoord[FACING_COUNT]; - -extern int SoundOn; -//extern GraphicBufferClass SeenPage; -extern GraphicBufferClass VisiblePage; -extern GraphicBufferClass HiddenPage; -extern GraphicViewPortClass SeenBuff; -extern GraphicBufferClass ModeXBuff; -extern GraphicViewPortClass HidPage; -extern GraphicBufferClass LoResHidPage; -extern GraphicBufferClass SysMemPage; -extern int MenuList[][8]; -extern CountDownTimerClass FrameTimer; -extern CountDownTimerClass CountDownTimer; - -extern TimerClass ProcessTimer; -extern int ProcessTicks; -extern int ProcessFrames; - -extern SpecialDialogType SpecialDialog; -//extern bool IsFindPath; - -extern char *DebugFname; // for stoopid debugging purposes -extern int DebugLine; // for stoopid debugging purposes -extern int RequiredCD; -extern int MouseInstalled; -extern int AreThingiesEnabled; - -extern WWKeyboardClass Kbd; -extern int In_Debugger; -extern WWMouseClass *WWMouse; -extern HANDLE hInstance; -extern int AllDone; -extern "C" bool MMXAvailable; -extern int Get_CD_Index (int cd_drive, int timeout); -void Memory_Error_Handler(void); -extern bool GameStatisticsPacketSent; -extern bool ConnectionLost; -extern bool InMainLoop; // True if in game state rather than menu state -void CCDebugString (char *string); -extern void *PacketLater; -void Load_Title_Screen(char *name, GraphicViewPortClass *video_page, unsigned char *palette); - -extern "C"{ - extern bool IsTheaterShape; -} - -extern void Reset_Theater_Shapes(void); -extern TheaterType LastTheater; - -extern bool ShareAllyVisibility; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/FACING.CPP b/code/TIBERIANDAWN/FACING.CPP deleted file mode 100644 index eef3edc..0000000 --- a/code/TIBERIANDAWN/FACING.CPP +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\facing.cpv 1.9 16 Oct 1995 16:49:40 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FACING.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/21/95 * - * * - * Last Update : March 21, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FacingClass::Rotation_Adjust -- Perform a rotation adjustment to current facing. * - * FacingClass::Set_Current -- Sets the current rotation value. * - * FacingClass::Set_Desired -- Sets the desired facing value. * - * FacingClass::FacingClass -- Default constructor for the facing class. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "facing.h" - - -/*********************************************************************************************** - * FacingClass::FacingClass -- Default constructor for the facing class. * - * * - * This default constructor merely sets the desired and current facing values to be the * - * same (North). * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/21/1995 JLB : Created. * - *=============================================================================================*/ -FacingClass::FacingClass(void) -{ - CurrentFacing = DIR_N; - DesiredFacing = DIR_N; -} - - -/*********************************************************************************************** - * FacingClass::Set_Desired -- Sets the desired facing value. * - * * - * This routine is used to set the desired facing value without altering the current * - * facing setting. Typicall use of this routine is when a vehicle needs to face a * - * direction, but currently isn't facing the correct direction. After this routine is * - * called, it is presumed that subsequent calls to Rotation_Adjust() will result in the * - * eventual alignment of the current facing. * - * * - * INPUT: facing -- The new facing to assign to the desired value. * - * * - * OUTPUT: bool; Did the desired facing value actually change by this routine call? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/21/1995 JLB : Created. * - *=============================================================================================*/ -int FacingClass::Set_Desired(DirType facing) -{ - if (DesiredFacing != facing) { - DesiredFacing = facing; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FacingClass::Set_Current -- Sets the current rotation value. * - * * - * This routine will set the current rotation value. It is used to override the facing * - * value without adjusting the desired setting. * - * * - * INPUT: facing -- The new facing to assign to the current facing value. * - * * - * OUTPUT: bool; Was the current setting changed by this routine. Failure means that the * - * current setting was already at the value specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/21/1995 JLB : Created. * - *=============================================================================================*/ -int FacingClass::Set_Current(DirType facing) -{ - if (CurrentFacing != facing) { - CurrentFacing = facing; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FacingClass::Rotation_Adjust -- Perform a rotation adjustment to current facing. * - * * - * This routine is used when the current and desired facings differ but the current * - * facing should be adjusted toward the desired facing. The amount of rotation to adjust * - * is provided as a rotation rate parameter. Typical use of this routine is for turrets * - * and other vehicle related rotating. * - * * - * INPUT: rate -- The rotation rate to use when adjusting the current facing toward the * - * desired facing. A value of 127 means instantaneous rotation. * - * * - * OUTPUT: bool; Did the rotation result in the current facing transitioning from one * - * 1/32 zone to another? If true, then the owning object most likely will * - * need to be redrawn to reflect the change. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/21/1995 JLB : Created. * - *=============================================================================================*/ -int FacingClass::Rotation_Adjust(int rate) -{ - /* - ** Only perform the rotation adjustment if the desired facing is not the - ** same as the current facing. - */ - if (Is_Rotating()) { - rate = MIN(rate, 127); - - DirType oldfacing = CurrentFacing; - int diff = Difference(); - - /* - ** If the allowed facing change is greater than the difference between - ** the current facing and the desired facing, then just snap the - ** facing to the new value. - */ - if (ABS(diff) < rate) { - CurrentFacing = DesiredFacing; - } else { - - /* - ** Adjust the current facing clockwise or counterclockwise depending - ** on the shortest distance to the desired facing from the current - ** facing. - */ - if (diff < 0) { - CurrentFacing = (DirType)(CurrentFacing - (DirType)rate); - } else { - CurrentFacing = (DirType)(CurrentFacing + (DirType)rate); - } - } - - /* - ** If this facing adjustment caused the current facing to rotate into a - ** new 1/32 rotation zone (likely to cause a redraw), then return - ** this fact with a true value. - */ - return(Facing_To_32(CurrentFacing) != Facing_To_32(oldfacing)); - } - return(false); -} diff --git a/code/TIBERIANDAWN/FACING.H b/code/TIBERIANDAWN/FACING.H deleted file mode 100644 index afbbacf..0000000 --- a/code/TIBERIANDAWN/FACING.H +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\facing.h_v 1.14 16 Oct 1995 16:46:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FACING.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/21/95 * - * * - * Last Update : March 21, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FACING_H -#define FACING_H - -/* -** This is a general facing handler class. It is used in those cases where facing needs to be -** kept track of, but there could also be an associated desired facing. The current facing -** is supposed to transition to the desired state over time. Using this class facilitates this -** processing as well as isolating the rest of the code from the internals. -*/ -class FacingClass -{ - public: - FacingClass(void); - FacingClass(DirType dir) {CurrentFacing = DesiredFacing = dir;}; - operator DirType(void) const {return CurrentFacing;}; - - DirType Current(void) const {return CurrentFacing;}; - DirType Desired(void) const {return DesiredFacing;}; - - int Set_Desired(DirType facing); - int Set_Current(DirType facing); - - void Set(DirType facing) { - Set_Current(facing); - Set_Desired(facing); - }; - - DirType Get(void) const { return CurrentFacing; } - - int Is_Rotating(void) const {return (DesiredFacing != CurrentFacing);}; - - int Difference(void) const {return (signed char)(*((unsigned char*)&DesiredFacing) - *((unsigned char*)&CurrentFacing));}; - int Difference(DirType facing) const {return (signed char)(*((signed char*)&facing) - *((signed char*)&CurrentFacing));}; - int Rotation_Adjust(int rate); - - private: - DirType CurrentFacing; - DirType DesiredFacing; -}; - - -#endif diff --git a/code/TIBERIANDAWN/FACTORY.CPP b/code/TIBERIANDAWN/FACTORY.CPP deleted file mode 100644 index 79b35e9..0000000 --- a/code/TIBERIANDAWN/FACTORY.CPP +++ /dev/null @@ -1,772 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\factory.cpv 2.18 16 Oct 1995 16:51:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FACTORY.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/26/94 * - * * - * Last Update : May 22, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FactoryClass::AI -- Process factory production logic. * - * FactoryClass::Abandon -- Abandons current construction with money refunded. * - * FactoryClass::Completed -- Clears factory object after a completed production process. * - * FactoryClass::Completion -- Fetchs the completion step for this factory. * - * FactoryClass::Cost_Per_Tick -- Breaks entire production cost into managable chunks. * - * FactoryClass::FactoryClass -- Default constructor for factory objects. * - * FactoryClass::Get_Object -- Fetches pointer to object being constructed. * - * FactoryClass::Get_Special_Item -- gets factorys spc prod item * - * FactoryClass::Has_Changed -- Checks to see if a production step has occurred? * - * FactoryClass::Has_Completed -- Checks to see if object has completed production. * - * FactoryClass::Set -- Assigns a factory to produce an object. * - * FactoryClass::Set -- Fills a factory with an already completed object. * - * FactoryClass::Set -- Force factory to "produce" special object. * - * FactoryClass::Start -- Resumes production after suspension or creation. * - * FactoryClass::Suspend -- Temporarily stop production. * - * FactoryClass::operator delete -- Returns a factory to the free factory pool. * - * FactoryClass::operator new -- Allocates a factory object from the free factory pool. * - * FactoryClass::~FactoryClass -- Default destructor for factory objects. * - * FactoryClass::Validate -- validates factory pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * FactoryClass::Validate -- validates factory pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int FactoryClass::Validate(void) const -{ - int num; - - num = Factories.ID(this); - if (num < 0 || num >= FACTORY_MAX) { - Validate_Error("FACTORY"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * FactoryClass::FactoryClass -- Default constructor for factory objects. * - * * - * This brings the factory into a null state. It is called when a factory object is * - * created. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -FactoryClass::FactoryClass(void) -{ - IsSuspended = false; - IsDifferent = false; - IsBlocked = false; - Balance = 0; - SpecialItem = SPC_NONE; - Object = NULL; - House = NULL; - Set_Rate(0); - Set_Stage(0); -} - - -/*********************************************************************************************** - * FactoryClass::~FactoryClass -- Default destructor for factory objects. * - * * - * This cleans up a factory object in preparation for deletion. If there is currently * - * an object in production, it is abandoned and money is refunded. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -FactoryClass::~FactoryClass(void) -{ - if (GameActive) { - Abandon(); - } -} - - -/*********************************************************************************************** - * FactoryClass::Init -- Clears all units for scenario preparation. * - * * - * This routine will zero out the factory list and objects. This routine is typically * - * used in preparation for a new scenario load. All factorys are guaranteed to be eliminated* - * by this routine. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/15/1994 JLB : Created. * - *=============================================================================================*/ -void FactoryClass::Init(void) -{ - Factories.Free_All(); -} - - -/*********************************************************************************************** - * FactoryClass::operator new -- Allocates a factory object from the free factory pool. * - * * - * This routine allocates a factory from the free factory pool. If there is no more room * - * to allocate a factory, then NULL is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with pointer to the newly allocated factory object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -void * FactoryClass::operator new(size_t) -{ - void * ptr = Factories.Allocate(); - if (ptr) { - ((FactoryClass *)ptr)->IsActive = true; - } - return(ptr); -} - - -/*********************************************************************************************** - * FactoryClass::operator delete -- Returns a factory to the free factory pool. * - * * - * This returns the factory object back to the factory allocation pool. The factory is then * - * available to be allocated. * - * * - * INPUT: ptr -- Pointer to the factory object to delete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -void FactoryClass::operator delete(void *ptr) -{ - if (ptr) { - ((FactoryClass *)ptr)->IsActive = false; - } - Factories.Free((FactoryClass *)ptr); -} - - -/*********************************************************************************************** - * FactoryClass::AI -- Process factory production logic. * - * * - * This routine should be called once per game tick. It handles the production process. * - * As production proceeds, money is deducted from the owner object's house. When production * - * completes, the factory stop processing. A call to Abandon, Delete, or Completed is * - * required after that point. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - * 01/04/1995 JLB : Uses exact installment payment method. * - *=============================================================================================*/ -void FactoryClass::AI(void) -{ - Validate(); - if (!IsSuspended && (Object != NULL || SpecialItem)) { - int stages = 1; - - /* - ** Determine the acceleration factor for factory production. - ** This applies only to human players. The computer builds - ** units on a building by building basis -- quantity of building - ** factory types doesn't affect individual factories. - */ - if (Object && House->IsHuman) { - switch (Object->What_Am_I()) { - case RTTI_AIRCRAFT: - stages = House->AircraftFactories; - break; - - case RTTI_INFANTRY: - stages = House->InfantryFactories; - break; - - case RTTI_UNIT: - stages = House->UnitFactories; - break; - - case RTTI_BUILDING: - stages = House->BuildingFactories; - break; - } - stages = MAX(stages, 1); - } - - - for (int index = 0; index < stages; index++) { - if (!Has_Completed() && Graphic_Logic()) { - IsDifferent = true; - - int cost = Cost_Per_Tick(); - - cost = MIN(cost, Balance); - - /* - ** Enough time has expired so that another production step can occur. - ** If there is insufficient funds, then go back one production step and - ** continue the countdown. The idea being that by the time the next - ** production step occurs, there may be sufficient funds available. - */ - if (cost > House->Available_Money()) { - Set_Stage(Fetch_Stage()-1); - } else { - House->Spend_Money(cost); - Balance -= cost; - } - if ( Debug_Instant_Build ) { - Set_Stage(STEP_COUNT); - } - /* - ** If the production has completed, then suspend further production. - */ - if (Fetch_Stage() == STEP_COUNT) { - IsSuspended = true; - Set_Rate(0); - House->Spend_Money(Balance); - Balance = 0; - } - } - } - } -} - - - -/*********************************************************************************************** - * FactoryClass::Force_Complete -- Force the factory to finish what it's building * - * * - * For debugging/testing support * - * * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 8/23/2019 3:54PM ST : Created. * - *=============================================================================================*/ -void FactoryClass::Force_Complete(void) -{ - Validate(); - if (!IsSuspended && (Object != NULL || SpecialItem)) { - Set_Stage(STEP_COUNT); - IsSuspended = true; - Set_Rate(0); - Balance = 0; - IsDifferent = true; - } -} - - -/*********************************************************************************************** - * FactoryClass::Has_Changed -- Checks to see if a production step has occurred? * - * * - * Use this routine to determine if production has advanced at least one step. By using * - * this function, intelligent rendering may be performed. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Has the production process advanced one step since the last time this * - * function was called? * - * * - * WARNINGS: This function clears the changed status flag as a side effect. * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Has_Changed(void) -{ - Validate(); - bool changed = IsDifferent; - IsDifferent = false; - return(changed); -} - - -/*********************************************************************************************** - * FactoryClass::Set -- Assigns a factory to produce an object. * - * * - * This routine initializes a factory to produce the object specified. The desired object * - * type is created and placed in suspended animation (limbo) until such time as production * - * completes. Production is not actually started by this routine. An explicit call to * - * Start() is required to begin production. * - * * - * INPUT: object -- Reference to the object type class that is to be produced. * - * * - * house -- Reference to the owner of the object to be produced. * - * * - * OUTPUT: bool; Was production successfully prepared for this factory object. Failure means * - * that the object could not be created. This is catastrophic and in such * - * cases, the factory object should be deleted. * - * * - * WARNINGS: Be sure to examine the return value from this function. Failure to initialize * - * the factory means that the factory is useless and should be deleted. * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Set(TechnoTypeClass const & object, HouseClass & house) -{ - Validate(); - /* - ** If there is any production currently in progress, abandon it. - */ - Abandon(); - - /* - ** Set up the factory for the new production process. - */ - IsDifferent = true; - IsSuspended = true; - Set_Rate(0); - Set_Stage(0); - - /* - ** Create an object of the type requested. - */ - Object = (TechnoClass *)object.Create_One_Of(&house); - - if (Object) { - House = Object->House; - Balance = object.Cost_Of() * house.CostBias; - Object->PurchasePrice = Balance; - } - - /* - ** If all was set up successfully, then return true. - */ - return(Object != NULL); -} - - -/*********************************************************************************************** - * FactoryClass::Set -- Force factory to "produce" special object. * - * * - * Use this routine to force the factory into special production mode. Such production is * - * used for the ion cannon and other timed special weapon events. * - * * - * INPUT: type -- The special weapon type to begin "production" of. * - * * - * house -- The owner of this production object. * - * * - * OUTPUT: Was the assignment successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Set(int const & type, HouseClass & house) -{ - Validate(); - /* - ** If there is any production currently in progress, abandon it. - */ - Abandon(); - - /* - ** Set up the factory for the new production process. - */ - IsDifferent = true; - IsSuspended = true; - Set_Rate(0); - Set_Stage(0); - - /* - ** Create an object of the type requested. - */ - SpecialItem = type; - House = &house; - Balance = 0; - - /* - ** If all was set up successfully, then return true. - */ - return(SpecialItem != SPC_NONE); -} - - -/*********************************************************************************************** - * FactoryClass::Set -- Fills a factory with an already completed object. * - * * - * This routine is called when a produced object is in placement mode but then placement * - * is suspended. The object must then return to the factory as if it were newly completed * - * and awaiting removal. * - * * - * INPUT: object -- The object to return to the factory. * - * * - * OUTPUT: none * - * * - * WARNINGS: This will abandon any current object being produced at the factory in order * - * to set the new object into it. * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -void FactoryClass::Set(TechnoClass & object) -{ - Validate(); - Abandon(); - Object = &object; - House = Object->House; - Balance = 0; - Set_Rate(0); - Set_Stage(STEP_COUNT); - IsDifferent = true; - IsSuspended = true; -} - - -/*********************************************************************************************** - * FactoryClass::Suspend -- Temporarily stop production. * - * * - * This routine will suspend production until a subsiquent call to Start() or Abandon(). * - * Typical use of this function is when the player puts production on hold or when there * - * is insufficient funds. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was production actually stopped? A false return value indicates that the * - * factory was empty or production was already stopped (or never started). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Suspend(void) -{ - Validate(); - if (!IsSuspended) { - IsSuspended = true; - Set_Rate(0); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FactoryClass::Start -- Resumes production after suspension or creation. * - * * - * This function will start the production process. It works for newly created factory * - * objects, as well as if production had been suspended previously. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was production started? A false return value means that the factory is * - * empty or there is unsufficient credits to begin production. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Start(void) -{ - Validate(); - if ((Object || SpecialItem) && IsSuspended && !Has_Completed()) { - if (House->IsHuman || House->Available_Money() >= Cost_Per_Tick()) { - int time; - - if (Object) { - time = Object->Class_Of().Time_To_Build(House->Class->House); - } else { - time = TICKS_PER_MINUTE * 5; - } - - time /= STEP_COUNT; - time = Bound(time, 1, 255); - - Set_Rate(time); - IsSuspended = false; - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * FactoryClass::Abandon -- Abandons current construction with money refunded. * - * * - * This routine is used when construction is to be abandoned and current money spend is * - * to be refunded. This function effectively clears out this factory of all record of the * - * producing object so that it may either be deleted or started anew with the Set() * - * function. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was an object actually abandoned? A false return value indicates that the * - * factory was not producing any object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Abandon(void) -{ - Validate(); - if (Object) { - - if (Object) { - /* - ** Refund all money expended so far, back to the owner of the object under construction. - */ - int money = Object->Class_Of().Cost_Of() * Object->House->CostBias; - House->Refund_Money(money - Balance); - Balance = 0; - - /* - ** Delete the object under construction. - */ - ScenarioInit++; - delete Object; - Object = NULL; - ScenarioInit--; - } - if (SpecialItem) { - SpecialItem = SPC_NONE; - } - - /* - ** Set the factory back to the idle and empty state. - */ - Set_Rate(0); - Set_Stage(0); - IsSuspended = true; - IsDifferent = true; - - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FactoryClass::Completion -- Fetchs the completion step for this factory. * - * * - * Use this routine to determine what animation (or completion step) the factory is * - * currently on. * - * * - * INPUT: none * - * * - * OUTPUT: Returns a completion step number beteen 0 (uncompleted), to STEP_COUNT (completed) * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -int FactoryClass::Completion(void) -{ - Validate(); - return(Fetch_Stage()); -} - - -/*********************************************************************************************** - * FactoryClass::Has_Completed -- Checks to see if object has completed production. * - * * - * Use this routine to examine the factory object in order to determine if the associated * - * object has completed production and is awaiting placement. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the associated object to the factory completed and ready for placement? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Has_Completed(void) -{ - Validate(); - if (Object && Fetch_Stage() == STEP_COUNT) { - return(true); - } - if (SpecialItem && Fetch_Stage() == STEP_COUNT) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FactoryClass::Get_Object -- Fetches pointer to object being constructed. * - * * - * This routine gets the pointer to the currently constructing object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the object undergoing construction. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -TechnoClass * FactoryClass::Get_Object(void) const -{ - Validate(); - return(Object); -} - - -/*************************************************************************** - * FactoryClass::Get_Special_Item -- gets factorys spc prod item * - * * - * INPUT: none * - * * - * OUTPUT: int the item the factory is currently working on * - * * - * HISTORY: * - * 05/05/1995 PWG : Created. * - *=========================================================================*/ -int FactoryClass::Get_Special_Item(void) const -{ - Validate(); - return(SpecialItem); -} - - -/*********************************************************************************************** - * FactoryClass::Cost_Per_Tick -- Breaks entire production cost into managable chunks. * - * * - * Use this routine to determine the cost per game "tick" to produce the object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of credits necessary to advance production one game tick. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -int FactoryClass::Cost_Per_Tick(void) -{ - Validate(); - if (Object) { - int steps = STEP_COUNT - Fetch_Stage(); - if (steps) { - return(Balance / steps); - } - return(Balance); - } - return(0); -} - - -/*********************************************************************************************** - * FactoryClass::Completed -- Clears factory object after a completed production process. * - * * - * This routine is called after production completes, and the object produced has been * - * placed into the game. It resets the factory for deletion or starting of new production. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Did any resetting occur? Failure is the result of the factory not having * - * any completed object. An immediate second call to this routine will also * - * yield false. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Completed(void) -{ - Validate(); - if (Object && Fetch_Stage() == STEP_COUNT) { - Object = NULL; - IsSuspended = true; - IsDifferent = true; - Set_Stage(0); - Set_Rate(0); - return(true); - } - - if (SpecialItem && Fetch_Stage() == STEP_COUNT) { - SpecialItem = SPC_NONE; - IsSuspended = true; - IsDifferent = true; - Set_Stage(0); - Set_Rate(0); - return(true); - } - return(false); -} diff --git a/code/TIBERIANDAWN/FACTORY.H b/code/TIBERIANDAWN/FACTORY.H deleted file mode 100644 index f351a82..0000000 --- a/code/TIBERIANDAWN/FACTORY.H +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\factory.h_v 2.17 16 Oct 1995 16:45:44 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FACTORY.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/26/94 * - * * - * Last Update : December 26, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FACTORY_H -#define FACTORY_H - -#include "stage.h" - -class FactoryClass : private StageClass -{ - friend class DLLExportClass; // ST - 1/29/2019 11:04AM - - public: - FactoryClass(void); - ~FactoryClass(void); - static void * operator new(size_t size); - static void operator delete(void *ptr); - - static void Init(void); - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - bool Abandon(void); - bool Completed(void); - bool Has_Changed(void); - bool Has_Completed(void); - bool Is_Building(void) const {return(Fetch_Rate() != 0);}; - bool Set(TechnoTypeClass const & object, HouseClass & house); - bool Set(int const & type, HouseClass & house); - bool Start(void); - bool Suspend(void); - int Completion(void); - TechnoClass * Get_Object(void) const; - int Get_Special_Item(void) const; - void AI(void); - void Set(TechnoClass & object); - HouseClass * Get_House(void) {return(House);}; - bool Is_Blocked(void) {return IsBlocked;} - void Set_Is_Blocked(bool set) {IsBlocked = set;} - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** Added for debugging / testing. ST - 8/23/2019 3:52PM - */ - void Force_Complete(void); - - /* - ** This flag is used to maintain the pool of factory class objects. If the object has - ** been allocated, then this flag is true. Otherwise, the object is free to be - ** allocated. - */ - unsigned IsActive:1; - - protected: - enum StepCountEnum { - STEP_COUNT=108 // Number of steps to break production down into. - }; - - int Cost_Per_Tick(void); - - private: - - /* - ** If production is temporarily suspended, then this flag will be true. A factory - ** is suspended when it is first created, when production has completed, and when - ** explicitly instructed to Suspend() production. Suspended production is not - ** abandoned. It may be resumed with a call to Start(). - */ - unsigned IsSuspended:1; - - /* - ** If the AI process detected that the production process has advanced far enough - ** that a change in the building animation would occur, this flag will be true. - ** Examination of this flag (through the Has_Chaged function) allows intelligent - ** updating of any production graphic. - */ - unsigned IsDifferent:1; - - /* - ** The exit from the factory is blocked by something, which means a unit is prevented from exiting after construction - ** has completed. ST - 2/25/2020 11:29AM - */ - unsigned IsBlocked:1; - - /* - ** This records the balance due on the current production item. This value will - ** be reduced as production proceeds. It will reach zero the moment production has - ** finished. Using this method ensures that the total production cost will be EXACT - ** regardless of the number of installment payments that are made. - */ - int Balance; - int OriginalBalance; - - /* - ** This is the object that is being produced. It is held in a state of limbo while - ** undergoing production. Since the object is created at the time production is - ** started, it is always available when production completes. - */ - TechnoClass * Object; - - /* - ** If the factory is not producing an object and is instead producing - ** a special item, then special item will be set. - */ - int SpecialItem; - - /* - ** The factory has to be doing production for one house or another. - ** The house pointer will point to whichever house it is being done - ** for. - */ - HouseClass * House; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/FIELD.CPP b/code/TIBERIANDAWN/FIELD.CPP deleted file mode 100644 index c9cf696..0000000 --- a/code/TIBERIANDAWN/FIELD.CPP +++ /dev/null @@ -1,213 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - * * - * Project Name : Westwood Auto Registration App * - * * - * File Name : FIELD.CPP * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 04/22/96 * - * * - * Last Update : April 22, 1996 [PWG] * - * * - * Actual member function for the field class. * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include -#include "field.h" - -// ST - 12/18/2018 10:14AM -#pragma warning(disable:4996) - -FieldClass::FieldClass(char *id, char data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_CHAR; - Size = sizeof(data); - Data = new char[Size]; - memcpy(Data, &data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, unsigned char data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_UNSIGNED_CHAR; - Size = sizeof(data); - Data = new char[Size]; - memcpy(Data, &data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, short data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_SHORT; - Size = sizeof(data); - Data = new char[Size]; - memcpy(Data, &data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, unsigned short data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_UNSIGNED_SHORT; - Size = sizeof(data); - Data = new char[Size]; - memcpy(Data, &data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, long data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_LONG; - Size = sizeof(data); - Data = new char[Size]; - memcpy(Data, &data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, unsigned long data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_UNSIGNED_LONG; - Size = sizeof(data); - Data = new char[Size]; - memcpy(Data, &data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, char *data) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_STRING; - Size = (unsigned short)(strlen(data)+1); - Data = new char[Size]; - memcpy(Data, data, Size); - Next = NULL; -} - -FieldClass::FieldClass(char *id, void *data, int length) -{ - strncpy(ID, id, sizeof(ID)); - DataType = TYPE_CHUNK; - Size = (unsigned short)length; - Data = new char[Size]; - memcpy(Data, data, Size); - Next = NULL; -} - - -/************************************************************************** - * PACKETCLASS::HOST_TO_NET_FIELD -- Converts host field to net format * - * * - * INPUT: FIELD * to the data field we need to convert * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 04/22/1996 PWG : Created. * - *========================================================================*/ -void FieldClass::Host_To_Net(void) -{ - // - // Before we convert the data type, we should convert the actual data - // sent. - // - switch (DataType) { - case TYPE_CHAR: - case TYPE_UNSIGNED_CHAR: - case TYPE_STRING: - case TYPE_CHUNK: - break; - - case TYPE_SHORT: - case TYPE_UNSIGNED_SHORT: - *((unsigned short *)Data) = htons(*((unsigned short *)Data)); - break; - - case TYPE_LONG: - case TYPE_UNSIGNED_LONG: - *((unsigned long *)Data) = htonl(*((unsigned long *)Data)); - break; - - // - // Might be good to insert some type of error message here for unknown - // datatypes -- but will leave that for later. - // - default: - break; - } - // - // Finally convert over the data type and the size of the packet. - // - DataType = htons(DataType); - Size = htons(Size); -} -/************************************************************************** - * PACKETCLASS::NET_TO_HOST_FIELD -- Converts net field to host format * - * * - * INPUT: FIELD * to the data field we need to convert * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 04/22/1996 PWG : Created. * - *========================================================================*/ -void FieldClass::Net_To_Host(void) -{ - // - // Convert the variables to host order. This needs to be converted so - // the switch statement does compares on the data that follows. - // - Size = ntohs(Size); - - DataType = ntohs(DataType); - - // - // Before we convert the data type, we should convert the actual data - // sent. - // - switch (DataType) { - case TYPE_CHAR: - case TYPE_UNSIGNED_CHAR: - case TYPE_STRING: - case TYPE_CHUNK: - break; - - case TYPE_SHORT: - case TYPE_UNSIGNED_SHORT: - *((unsigned short *)Data) = ntohs(*((unsigned short *)Data)); - break; - - case TYPE_LONG: - case TYPE_UNSIGNED_LONG: - *((unsigned long *)Data) = ntohl(*((unsigned long *)Data)); - break; - - // - // Might be good to insert some type of error message here for unknown - // datatypes -- but will leave that for later. - // - default: - break; - } -} diff --git a/code/TIBERIANDAWN/FIELD.H b/code/TIBERIANDAWN/FIELD.H deleted file mode 100644 index d35b0c5..0000000 --- a/code/TIBERIANDAWN/FIELD.H +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - * * - * Project Name : Westwood Auto Registration App * - * * - * File Name : FIELD.H * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 04/22/96 * - * * - * Last Update : April 22, 1996 [PWG] * - * * - * This module takes care of maintaining the field list used to process * - * packets. * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef __FIELD_H -#define __FIELD_H - -#include -#include - -#define FIELD_HEADER_SIZE (sizeof(FieldClass) - (sizeof(void *) * 2)) - -#define TYPE_CHAR 1 -#define TYPE_UNSIGNED_CHAR 2 -#define TYPE_SHORT 3 -#define TYPE_UNSIGNED_SHORT 4 -#define TYPE_LONG 5 -#define TYPE_UNSIGNED_LONG 6 -#define TYPE_STRING 7 -#define TYPE_CHUNK 20 - -class PacketClass; - -class FieldClass { - - public: - friend class PacketClass; - // - // Define constructors to be able to create all the different kinds - // of fields. - // - FieldClass(void) {}; - FieldClass(char *id, char data); - FieldClass(char *id, unsigned char data); - FieldClass(char *id, short data); - FieldClass(char *id, unsigned short data); - FieldClass(char *id, long data); - FieldClass(char *id, unsigned long data); - FieldClass(char *id, char *data); - FieldClass(char *id, void *data, int length); - - void Host_To_Net(void); - void Net_To_Host(void); - - private: - char ID[4]; // id value of this field - unsigned short DataType; // id of the data type we are using - unsigned short Size; // size of the data portion of this field - void *Data; // pointer to the data portion of this field - FieldClass *Next; // pointer to the next field in the field list -}; - -#endif diff --git a/code/TIBERIANDAWN/FINDPATH.CPP b/code/TIBERIANDAWN/FINDPATH.CPP deleted file mode 100644 index 92f245c..0000000 --- a/code/TIBERIANDAWN/FINDPATH.CPP +++ /dev/null @@ -1,1557 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\findpath.cpv 2.17 16 Oct 1995 16:51:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FINDPATH.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : May 25, 1995 [PWG] * - * * - * The path algorithm works by following a LOS path to the target. If it * - * collides with an impassable spot, it uses an Edge following routine to * - * get around it. The edge follower moves along the edge in a clockwise or * - * counter clockwise fashion until finding the destination spot. The * - * destination is determined by Find_Path. It is the first passable that * - * can be reached (so it will handle the doughnut case, where there is * - * a passable in the center of an unreachable area). * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Clear_Path_Overlap -- clears the path overlap list * - * Find_Path -- Find a path from point a to point b. * - * Find_Path_Cell -- Finds a given cell on a specified path * - * Follow_Edge -- Follow an edge to get around an impassable spot. * - * FootClass::Unravel_Loop -- Unravels a loop in the movement path * - * Get_New_XY -- Get the new x,y based on current position and direction. * - * Optimize_Moves -- Optimize the move list. * - * Set_Path_Overlap -- Sets the overlap bit for given cell * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -//#include - -/* -** When an edge search is started, it can be performed CLOCKwise or -** COUNTERCLOCKwise direction. -*/ -#define CLOCK (FacingType)1 // Clockwise. -#define COUNTERCLOCK (FacingType)-1 // Counterclockwise. - -/* -** If defined, diagonal moves are allowed, else no diagonals. -*/ -#define DIAGONAL - -/* -** This is the marker to signify the end of the path list. -*/ -#define END FACING_NONE - -/* -** If memory is more important than speed, set this define to -** true. It will then perform intermediate optimizations to get the most -** milage out of a limited movement list staging area. If this value -** is true then it figures paths a bit more intelligently. -*/ -#define SAVEMEM true - -/* -** Modify this macro so that given two cell values, it will return -** a value between 0 and 7, with 0 being North and moving -** clockwise (just like map degrees). -*/ -#define CELL_FACING(a,b) Dir_Facing(::Direction((a),(b))) - - -/*-------------------------------------------------------------------------*/ -/* -** Cells values are really indexes into the 'map'. The following value is -** the X width of the map. -*/ -#define MODULO MAP_CELL_W - -/* -** Maximum lookahead cells. Twice this value in bytes will be -** reserved on the stack. The smaller this number, the faster the processing. -*/ -#define MAX_MLIST_SIZE 300 -#define THREAT_THRESHOLD 5 - -#define MAX_PATH_EDGE_FOLLOW 400 - -#ifdef NEVER -typedef enum { - FACING_N, // North - FACING_NE, // North-East - FACING_E, // East - FACING_SE, // South-East - FACING_S, // South - FACING_SW, // South-West - FACING_W, // West - FACING_NW, // North-West - - FACING_COUNT // Total of 8 directions (0..7). -} FacingType; -#endif - - -/*-------------------------------------------------------------------------*/ -static bool DrawPath; - -inline FacingType Opposite(FacingType face) -{ - return( (FacingType) (face ^ 4)); -} - -static inline void Draw_Cell_Point(CELL cell, bool passable, int threat_stage, int overide = 0) -{ - if (DrawPath) { - if (!Debug_Find_Path) { - int x, y; - - if (Map.Coord_To_Pixel(Cell_Coord(cell), x, y)) { - if (threat_stage>2) { - SeenBuff.Put_Pixel(x, y, (passable) ? LTGREEN : RED); - } else { - SeenBuff.Put_Pixel(x, y, (passable) ? 9+threat_stage : RED); - } - } - } else { - int x = cell & 63; - int y = cell / 64; - if (!overide) { - SeenBuff.Put_Pixel(64 + (x * 3) + 1, 8 + (y * 3) + 1, (passable) ? WHITE : BLACK); - } else { - SeenBuff.Put_Pixel(64 + (x * 3) + 1, 8 + (y * 3) + 1, overide); - } - } - } -} - -inline static FacingType Next_Direction(FacingType facing, FacingType dir) -{ - facing = facing + dir; - #ifndef DIAGONAL - facing = (FacingType)(facing & 0x06); - #endif - return(facing); -} - -/*=========================================================================*/ -/* Define a couple of variables which are private to the module they are */ -/* declared in. */ -/*=========================================================================*/ -static unsigned long MainOverlap[MAP_CELL_TOTAL/32]; // overlap list for the main path -static unsigned long LeftOverlap[MAP_CELL_TOTAL/32]; // overlap list for the left path -static unsigned long RightOverlap[MAP_CELL_TOTAL/32]; // overlap list for the right path - - -//static CELL MoveMask = 0; -static CELL DestLocation; -static CELL StartLocation; - -/*************************************************************************** - * Point_Relative_To_Line -- Relation between a point and a line * - * * - * If a point is on a line then the following function holds true: * - * (x - x2)(z1 - z2) = (z - z2)(x1 - x2) given x,z a point on the * - * line (x1,z1),(x2,z2). * - * If the right side is > then the left side then the point is on one * - * side of the line and if the right side is < the the left side, then* - * the point is on the other side of the line. By subtracting one side* - * from the other we can determine on what side (if any) the point is on* - * by testing the side of the resulting subtraction. * - * * - * INPUT: * - * int x - x pos of point. * - * int z - z pos of point. * - * int x1 - x pos of first end of line segment. * - * int z1 - z pos of first end of line segment. * - * int x1 - x pos of second end of line segment. * - * int z1 - z pos of second end of line segment. * - * * - * OUTPUT: * - * Assuming (x1,z1) is north, (x2,z2) is south: * - * 0 : point is on line. * - * > 0 : point is east of line. * - * < 0 : point is west of line. * - * * - * WARNINGS: * - * Remember that int means that is assumes 16 bits of persision. * - * * - * HISTORY: * - * 10/28/1994 SKB : Created. * - *=========================================================================*/ -int Point_Relative_To_Line(int x, int z, int x1, int z1, int x2, int z2) -{ - return((((long)x - (long)x2) * ((long)z1 - (long)z2)) - (((long)z - (long)z2) * ((long)x1 - (long)x2))); -} - - -/*************************************************************************** - * FootClass::Unravel_Loop -- Unravels a loop in the movement path * - * * - * While in the midst of the Follow Edge logic, it is possible (due to the * - * fact that we support diagonal movement) to begin looping around a * - * column of some type. The Unravel loop function will scan backward * - * through the list and fixup the path to try to prevent the loop. * - * * - * INPUT: path - pointer to the generated path so we can pull the * - * commands out of it. * - * cell - the cell we tried to enter that generated the * - * double overlap condition. * - * dir - the direction we tried to enter from when we * - * generated the double overlap condition * - * startx - the start x position of this path segment * - * starty - the start y position of this path segment * - * destx - the dest x position for this path segment * - * desty - the dest y position for this path segment * - * * - * OUTPUT: TRUE - loop has been sucessfully unravelled * - * FALSE - loop can not be unravelled so abort follow edge * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/25/1995 PWG : Created. * - *=========================================================================*/ -bool FootClass::Unravel_Loop(PathType *path, CELL &cell, FacingType &dir, int sx, int sy, int dx, int dy, MoveType threshhold) -{ - /* - ** Walk back to the actual cell before we advanced our position - */ - FacingType curr_dir = dir; - CELL curr_pos = Adjacent_Cell(cell, Opposite(curr_dir)); - int idx = path->Length; // start at the last position - FacingType *list = &path->Command[idx-1]; // point to the last command - int checkx; - int checky; - int last_was_line = false; - - /* - ** loop backward through the list searching for a point that is - ** on the line. If the point was a diagonal move then adjust - ** it. - */ - while (idx) { - checkx = Cell_X(curr_pos); - checky = Cell_Y(curr_pos); - - if (!Point_Relative_To_Line(checkx, checky, sx, sy, dx, dy) || last_was_line) { - - /* - ** We have now found a point on the line. Now we must check to see - ** if we left the line on a diagonal. If we did then we need to fix - ** it up. - */ - if (curr_dir & 1 && curr_pos != path->LastFixup) { - cell = curr_pos; - dir = *(list-1); - path->Length = idx; - path->LastFixup = curr_pos; - Draw_Cell_Point(curr_pos, true, -1, CYAN); - return(true); - } - - last_was_line = !last_was_line; - } - - /* - ** Since this cell will not be in the list, then pull out its cost - */ - path->Cost -= Passable_Cell(curr_pos, *list, -1, threshhold); - - /* - ** Remove this cells flag from the overlap list for the path - */ - path->Overlap[curr_pos >> 5] &= ~(1 << ((curr_pos & 31) - 1)); - - /* - ** Mark cell on the map - */ - Draw_Cell_Point(curr_pos, true, -1, LTCYAN); - - /* - ** Adjust to the next list position and direction. - */ - curr_dir = *list--; - curr_pos = Adjacent_Cell(curr_pos, Opposite(curr_dir)); - idx--; - } - - /* - ** If we can't modify the list to eliminate the problem, then we have - ** a larger problem in that we have deleted all of the cells in the - ** list. - */ - return(false); -} - - -/*************************************************************************** - * Register_Cell -- registers a cell on our path and check for backtrack * - * * - * This function adds a new cell to our path. If the cell has already * - * been recorded as part of our path, then this function moves back down * - * the list truncating it at the point we registered that cell. This * - * function will elliminate all backtracking from the list. * - * * - * INPUT: long * list - the list to set the overlap bit for * - * CELL cell - the cell to mark on the overlap list * - * * - * OUTPUT: BOOL - TRUE if bit has been set, FALSE if bit already set * - * * - * HISTORY: * - * 05/23/1995 PWG : Created. * - *=========================================================================*/ -bool FootClass::Register_Cell(PathType *path, CELL cell, FacingType dir, int cost, MoveType threshhold) -{ - FacingType *list; - int pos = cell >> 5; - int bit = (cell & 31) - 1; - - /* - ** See if this point has already been registered as on the list. If so - ** we need to truncate the list back to this point and register the - ** new direction. - */ - if (path->Overlap[pos] & (1 << bit)) { - /* - ** If this is not a case of immediate back tracking then handle - ** by searching the list to see what we find. However is this is - ** an immediate back track, then pop of the last direction - ** and unflag the cell we are in (not the cell we are moving to). - ** Note: That we do not check for a zero length cell because we - ** could not have a duplicate unless there are cells in the list. - */ - - if (path->Command[path->Length - 1] == Opposite(dir)) { - CELL pos = Adjacent_Cell(cell, Opposite(dir)); - path->Overlap[pos >> 5] &= ~(1 << ((pos & 31) - 1)); - path->Length--; - Draw_Cell_Point(pos, true, -1, BLUE); - } else { - /* - ** If this overlap is in the same place as we had our last overlap - ** then we are in a loop condition. We need to signify that we - ** cannot register this cell. - */ - if (path->LastOverlap == cell) { - return(false); - } else { - path->LastOverlap = cell; - } - - CELL pos = path->Start; - int newlen = 0; - int idx = 0; - list = path->Command; - - /* - ** Note that the cell has to be in this list, so theres no sense - ** in checking whether we found it (famous last words). - ** - ** PWG 8/16/95 - However there is no sense searching the list if - ** the cell we have overlapped on is the cell we - ** started in. - */ - - if (pos != cell) { - while (idx < path->Length) { - pos = Adjacent_Cell(pos, *list); - if (pos == cell) { - idx++; - list++; - break; - } - idx++; - list++; - } - newlen = idx; - } - - /* - ** Now we are pointing at the next command in the list. From here on - ** out we need to unmark the fact that we have entered these cells and - ** adjust the cost of our path to reflect that we have not entered - ** then. - */ - while (idx < path->Length) { - pos = Adjacent_Cell(pos, *list); - path->Cost -= Passable_Cell(pos, *list, -1, threshhold); - path->Overlap[pos >> 5] &= ~(1 << ((pos & 31) - 1)); - Draw_Cell_Point(pos, true, -1, LTBLUE); - idx++; - list++; - } - path->Length = newlen; - } - } else { - /* - ** Now we need to register the new direction, updating the cell structure - ** and the cost. - */ - int cpos = path->Length++; - path->Command[cpos] = dir; // save of the direction we moved - path->Cost += cost; // figure new cost for cell - path->Overlap[pos] |= (1 << bit); // mark the we have entered point - } - return(true); -} -#ifdef OBSOLETE -bool FootClass::Register_Cell(PathType *path, CELL cell, FacingType dir, int cost, MoveType threshhold) -{ - FacingType *list; - int pos = cell >> 5; - int bit = (cell & 31) - 1; - int idx; - - /* - ** See if this point has already been registered as on the list. If so - ** we need to truncate the list back to this point and register the - ** new direction. - */ - if (path->Overlap[pos] & (1 << bit)) { - /* - ** If this is not a case of immediate back tracking then handle - ** by searching the list to see what we find. However is this is - ** an immediate back track, then pop of the last direction - ** and unflag the cell we are in (not the cell we are moving to). - ** Note: That we do not check for a zero length cell because we - ** could not have a duplicate unless there are cells in the list. - */ - - if (path->Command[path->Length - 1] == Opposite(dir)) { - CELL pos = Adjacent_Cell(cell, Opposite(dir)); - path->Overlap[pos >> 5] &= ~(1 << ((pos & 31) - 1)); - path->Length--; - Draw_Cell_Point(pos, true, -1, BLUE); - } else { - /* - ** If this overlap is in the same place as we had our last overlap - ** then we are in a loop condition. We need to signify that we - ** cannot register this cell. - */ - if (path->LastOverlap == cell) { - return(false); - } else { - path->LastOverlap = cell; - } - - CELL pos = path->Start; - int newlen = 0; - - /* - ** Note that the cell has to be in this list, so theres no sense - ** in checking whether we found it (famous last words) - */ - for (idx = 0, list = path->Command; idx < path->Length; idx++, list++) { - pos = Adjacent_Cell(pos, *list); - if (pos == cell) { - idx++; - list++; - break; - } - } - newlen = idx; - - /* - ** Now we are pointing at the next command in the list. From here on - ** out we need to unmark the fact that we have entered these cells and - ** adjust the cost of our path to reflect that we have not entered - ** then. - */ - while (idx < path->Length) { - pos = Adjacent_Cell(pos, *list); - path->Cost -= Passable_Cell(pos, *list, -1, threshhold); - path->Overlap[pos >> 5] &= ~(1 << ((pos & 31) - 1)); - Draw_Cell_Point(pos, true, -1, LTBLUE); - idx++; - list++; - } - path->Length = newlen; - } - } else { - /* - ** Now we need to register the new direction, updating the cell structure - ** and the cost. - */ - int cpos = path->Length++; - path->Command[cpos] = dir; // save of the direction we moved - path->Cost += cost; // figure new cost for cell - path->Overlap[pos] |= (1 << bit); // mark the we have entered point - } - return(true); -} -#endif - - -/*********************************************************************************************** - * Find_Path -- Find a path from point a to point b. * - * * - * INPUT: int source x,y, int destination x,y, char *final moves * - * array to store moves, int maximum moves we may attempt * - * * - * OUTPUT: int number of moves it took (IMPOSSIBLE_MOVES if we could * - * not reach the destination * - * * - * WARNINGS: This algorithm assumes that the target is NOT situated * - * inside an impassable. If this case may arise, the do-while * - * statement inside the inner while (true) must be changed * - * to include a check to se if the next_x,y is equal to the * - * dest_x,y. If it is, then return(IMPOSSIBLE_MOVES). * - * * - * HISTORY: * - * 07/08/1991 CY : Created. * - *=============================================================================================*/ -PathType * FootClass::Find_Path(CELL dest, FacingType *final_moves, int maxlen, MoveType threshhold) -{ - CELL source = Coord_Cell(Coord); // Source expressed as cell - static PathType path; // Main path control. - CELL next; // Next cell to enter - CELL startcell; // Cell we started in - FacingType direction; // Working direction of look ahead. - FacingType newdir; // Tentative facing value. - - bool left=false, // Was leftward path legal? - right=false; // Was rightward path legal? - - int len; // Length of detour command list. - int unit_threat; // Calculated unit threat rating - int cost; // Cost to enter the square - FacingType moves_left[MAX_MLIST_SIZE+2], // Counterclockwise move list. - moves_right[MAX_MLIST_SIZE+2]; // Clockwise move list. - PathType pleft,pright; // Path control structures. - PathType *which; // Which path to actually use. - int threat = 0; // - int threat_stage = 0; //These weren't initialized. ST - 1/8/2019 12:03PM - - /* - ** If we have been provided an illegal place to store our final moves - ** then forget it. - */ - if (!final_moves) return(NULL); -// IsFindPath = true; - - /* - ** Set the draw path variable to draw the path of the selected unit - ** if necessary. - */ - if (!Debug_Find_Path) { - DrawPath = Is_Selected_By_Player() && Special.IsShowPath; - } else { - DrawPath = Is_Selected_By_Player(); - } - Debug_Draw_Map("Initial Draw", source, dest, false); - -// MoveMask = flags; - if (Team && Team->Class->IsRoundAbout) { - unit_threat = (Team) ? Team->Risk : Risk(); - threat_stage = 0; - threat = 0; - } else { - unit_threat = threat = -1; - } - - StartLocation = source; - DestLocation = dest; - - /* - ** Initialize the path structure so that we can keep track of the - ** path. - */ - path.Start = source; - path.Cost = 0; - path.Length = 0; - path.Command = final_moves; - path.Command[0] = END; - path.Overlap = MainOverlap; - path.LastOverlap = -1; - path.LastFixup = -1; - - memset(path.Overlap, 0, sizeof(MainOverlap)); - - /* - ** Clear the over lap list and then make sure that our starting position is marked - ** on the overlap list. (Otherwise the harvesters will drive in circles... ) - */ -// memset(path.Overlap, 0, 512); - path.Overlap[source >> 5] |= (1 << ((source & 31) - 1)); - - startcell = source; - - /* - ** Account for trailing end of list command, so reduce the maximum - ** allowed legal commands to reflect this. - */ - maxlen--; - - /* - ** As long as there is room to put commands in the movement command list, - ** then put commands in it. We build the path using the following - ** methodology. - ** - ** 1. Scan through the desired strait line path until we eiter hit an - ** impassable or have created a valid path. - ** - ** 2. If we have hit an impassable, walk through the impassable to make - ** sure that there is a passable on the other side. If there is not - ** and we can not change the impassable, then this list is dead. - ** - ** 3. Walk around the impassable on both the left and right edges and - ** take the shorter of the two paths. - ** - ** 4. Taking the new location as our start location start again with - ** step #1. - */ - while (path.Length < maxlen) { - -top_of_list: - /* - ** Have we reached the destination already? If so abort any further - ** command building. - */ - if (startcell == dest) { - break; - } - - /* - ** Find the absolute correct direction to reach the next straight - ** line cell and what cell it is. - */ - direction = CELL_FACING(startcell, dest); - next = Adjacent_Cell(startcell, direction); - - /* - ** If we can move here, then make this our next move. - */ - cost = Passable_Cell(next, direction, threat, threshhold); - if (cost) { - Draw_Cell_Point(next, true, threat_stage); - Register_Cell(&path, next, direction, cost, threshhold); - } else { - if (Debug_Find_Path && DrawPath) { - Debug_Draw_Map("Walk Through Obstacle", startcell, dest, true); - } - Draw_Cell_Point(next, false, threat_stage); - - /* - ** If the impassable location is actually the destination, - ** then stop here and consider this "good enough". - */ - if (next == dest) break; - - /* - ** We could not move to the next cell, so follow through the - ** impassable until we find a passable spot that can be reached. - ** Once we find a passable, figure out the shortest path to it. - ** Since we have variable passable conditions this is not as - ** simple as it used to be. The limiter loop below allows us to - ** step through ten donuts before we give up. - */ - for (int limiter = 0; limiter < 5; limiter++) { - - /* - ** Get the next passable position by zipping through the - ** impassable positions until a passable position is found - ** or the destination is reached. - */ - for (;;) { - - /* - ** Move one step closer toward destination. - */ - newdir = CELL_FACING(next, dest); - next = Adjacent_Cell(next, newdir); - - /* - ** If the cell is passable then we have been completely - ** sucessful. If the cell is not passable then continue. - */ - if ((Passable_Cell(next, FACING_NONE, threat, threshhold)) || (next == dest)) { - Draw_Cell_Point(next, true, threat_stage); - break; - } else { - Draw_Cell_Point(next, false, threat_stage); - } - - /* - ** If we reached destination while in this loop, we - ** know that either the destination is impassible (if - ** we are ignoring) or that we need to up our threat - ** tolerance and try again. - */ - if (next == dest) { - if (threat != -1) { - switch (threat_stage++) { - case 0: - threat = unit_threat >> 1; - break; - - case 1: - threat += unit_threat; - break; - - case 2: - threat = -1; - break; - } - goto top_of_list; - } - goto end_of_list; - } - } - - /* - ** Try to find a path to the passable position by following - ** the edge of the blocking object in both CLOCKwise and - ** COUNTERCLOCKwise fashions. - */ - int follow_len = maxlen + (maxlen >> 1); - - Debug_Draw_Map("Follow left edge", startcell,next,true); - Mem_Copy(&path, &pleft, sizeof(PathType)); - pleft.Command = &moves_left[0]; - pleft.Overlap = LeftOverlap; - Mem_Copy(path.Command, pleft.Command, path.Length); - Mem_Copy(path.Overlap, pleft.Overlap, sizeof(LeftOverlap)); - // MBL 09.30.2019: We hit a runtime bounds crash where END (-1 / 0xFF) was being poked into +1 just past the end of the moves_right[] array; - // The FacingType moves_left[] and moves_right[] arrays already have MAX_MLIST_SIZE+2 as their size, which may have been a previous attempted fix; - // We are now passing MAX_MLIST_SIZE, since the sizeof calculations included the +2 buffering; - #if 0 - left = Follow_Edge(startcell, next, &pleft, COUNTERCLOCK, direction, threat, threat_stage, sizeof(moves_left), threshhold); -// left = Follow_Edge(startcell, next, &pleft, COUNTERCLOCK, direction, threat, threat_stage, follow_len, threshhold); - #endif - left = Follow_Edge(startcell, next, &pleft, COUNTERCLOCK, direction, threat, threat_stage, MAX_MLIST_SIZE, threshhold); - - if (left) { - follow_len = MIN(maxlen, pleft.Length + (pleft.Length >> 1)); - } - - /* - ** If we are in debug mode then let us know how well our left path - ** did. - */ - if (Debug_Find_Path && DrawPath) { - Fancy_Text_Print(" Left", 0, 92, WHITE, BLACK, TPF_6POINT); - Fancy_Text_Print("Total Steps", 0, 100, WHITE, BLACK, TPF_6POINT); - if (left) { - Fancy_Text_Print(" %d", 0, 108, WHITE, BLACK, TPF_6POINT, pleft.Length); - } else { - Fancy_Text_Print(" FAIL", 0, 108, WHITE, BLACK, TPF_6POINT); - } - } - - Debug_Draw_Map("Follow right edge", startcell, next, true); - Mem_Copy(&path, &pright, sizeof(PathType)); - pright.Command = &moves_right[0]; - pright.Overlap = RightOverlap; - Mem_Copy(path.Command, pright.Command, path.Length); - Mem_Copy(path.Overlap, pright.Overlap, sizeof(RightOverlap)); - // MBL 09.30.2019: We hit a runtime bounds crash where END (-1 / 0xFF) was being poked into +1 just past the end of the moves_right[] array; - // The FacingType moves_left[] and moves_right[] arrays already have MAX_MLIST_SIZE+2 as their size, which may have been a previous attempted fix; - // We are now passing MAX_MLIST_SIZE, since the sizeof calculations included the +2 buffering; - #if 0 - right = Follow_Edge(startcell, next, &pright, CLOCK, direction, threat, threat_stage, sizeof(moves_right), threshhold); -// right = Follow_Edge(startcell, next, &pright, CLOCK, direction, threat, threat_stage, follow_len, threshhold); - #endif - right = Follow_Edge(startcell, next, &pright, CLOCK, direction, threat, threat_stage, MAX_MLIST_SIZE, threshhold); - - /* - ** If we are in debug mode then let us know how well our right path - ** did. - */ - if (Debug_Find_Path && DrawPath) { - Fancy_Text_Print(" Right", 0, 92, WHITE, BLACK, TPF_6POINT); - Fancy_Text_Print("Total Steps", 0, 100, WHITE, BLACK, TPF_6POINT); - if (right) { - Fancy_Text_Print(" %d", 0, 108, WHITE, BLACK, TPF_6POINT, pright.Length); - } else { - Fancy_Text_Print(" FAIL", 0, 108, WHITE, BLACK, TPF_6POINT); - } - } - - /* - ** If we could find a path, break from this loop. Otherwise this - ** means that we have found a "hole" of passable terrain that - ** cannot be reached by normal means. Scan forward looking for - ** the other side of the "doughnut". - */ - if (left || right) break; - - /* - ** If no path can be found to the intermediate cell, then - ** presume we have found a doughnut of some sort. Scan - ** forward until the next impassable is found and then - ** process this loop again. - */ - do { - - /* - ** If we reached destination while in this loop, we - ** know that either the destination is impassible (if - ** we are ignoring) or that we need to up our threat - ** tolerance and try again. - */ - if (next == dest) { - if (threat != -1) { - switch (threat_stage++) { - case 0: - threat = unit_threat >> 1; - break; - - case 1: - threat += unit_threat; - break; - - case 2: - threat = -1; - break; - } - goto top_of_list; - } - goto end_of_list; - } - - newdir = CELL_FACING(next, dest); - next = Adjacent_Cell(next, newdir); - } while (Passable_Cell(next, newdir, threat, threshhold)); - } - - if (!left && !right) break; - - /* - ** We found a path around the impassable locations, so figure out - ** which one was the smallest and copy those moves into the - ** path.Command array. - */ - which = &pleft; - if (right) { - which = &pright; - if (left) { - if (pleft.Length < pright.Length) { - which = &pleft; - } else { - which = &pright; - } - } - } - - /* - ** Record as much as possible of the shorter of the two - ** paths. The trailing EOL command is not copied because - ** this may not be the end of the find path logic. - */ - len = which->Length; - len = MIN(len, maxlen); - if (len > 0) { - memcpy(&path.Overlap[0], &which->Overlap[0], sizeof(LeftOverlap)); - memcpy(&path.Command[0], &which->Command[0], len); - path.Length = len; - path.Cost = which->Cost; - path.LastOverlap = -1; - path.LastFixup = -1; - } else { - break; - } - Debug_Draw_Map("Walking to next obstacle", next, dest, true); - } - startcell = next; - } - -end_of_list: - /* - ** Poke in the stop command. - */ - if (path.Length < maxlen) { - path.Command[path.Length++] = END; - } - if (Debug_Find_Path && DrawPath) { - Map.Flag_To_Redraw(true); - } - /* - ** Optimize the move list but only necessary if - ** diagonal moves are allowed. - */ - #ifdef DIAGONAL - Optimize_Moves(&path, threshhold); - #endif - if (Debug_Find_Path && DrawPath) { - Debug_Draw_Map("Final Generated Path", startcell,dest,false); - Debug_Draw_Path(&path); - Get_Key_Num(); - } -// IsFindPath = false; - return(&path); -} - - -/*********************************************************************************************** - * Follow_Edge -- Follow an edge to get around an impassable spot. * - * * - * INPUT: start -- cell to head from * - * * - * target -- Target cell to head to. * - * * - * path -- Pointer to path list structure. * - * * - * search -- Direction of search (1=clock, -1=counterclock). * - * * - * olddir -- Facing impassible direction from start. * - * * - * callback -- Function pointer for determining if a cell is * - * passable or not. * - * * - * OUTPUT: bool: Could a path be found to the desired cell? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1991 CY : Created. * - * 06/01/1992 JLB : Optimized & commented. * - *=============================================================================================*/ -bool FootClass::Follow_Edge(CELL start, CELL target, PathType *path, FacingType search, FacingType olddir, int threat, int threat_stage, int max_cells, MoveType threshhold) -{ - FacingType newdir; // Direction of facing before surrounding cell check. - CELL oldcell, // Current cell. - newcell; // Tentative new cell. - int cost; // Working cost value. - int startx; - int starty; - int online=true; - int targetx; - int targety; - int oldval = 0; - int cellcount=0; - int forceout = false; - FacingType firstdir = (FacingType)-1; - CELL firstcell = -1; - bool stepped_off_line = false; - startx = Cell_X(start); - starty = Cell_Y(start); - targetx = Cell_X(target); - targety = Cell_Y(target); - - if (!path) return(false); - path->LastOverlap = -1; - path->LastFixup = -1; - - #ifndef DIAGONAL - /* - ** The edge following algorithm doesn't "do" diagonals. Force initial facing - ** to be an even 90 degree value. Adjust it in the direction it should be - ** rotating. - */ - if (olddir & 0x01) { - olddir = Next_Direction(olddir, search); - } - #endif - - newdir = Next_Direction(olddir, search); - oldcell = start; - newcell = Adjacent_Cell(oldcell, newdir); - - /* - ** Continue until we find our target, find our original starting spot, - ** or run out of moves. - */ - while (path->Length < max_cells) { - - /* - ** Look in all the adjacent cells to determine a passable one that - ** most closely matches the desired direction (working in the specified - ** direction). - */ - newdir = olddir; - for (;;) { - bool forcefail; // Is failure forced? - - forcefail = false; - - #ifdef DIAGONAL - /* - ** Rotate 45/90 degrees in desired direction. - */ - newdir = Next_Direction(newdir, search); - - /* - ** If facing a diagonal we must check the next 90 degree location - ** to make sure that we don't walk right by the destination. This - ** will happen if the destination it is at the corner edge of an - ** impassable that we are moving around. - */ - if (newdir & FACING_NE) { - CELL checkcell; // Non-diagonal check cell. - //int x,y; - - checkcell = Adjacent_Cell(oldcell, Next_Direction(newdir, search)); - - if (checkcell == target) { - - /* - ** This only works if in fact, it is possible to move to the - ** cell from the current location. - */ - cost = Passable_Cell(checkcell, Next_Direction(newdir, search), threat, threshhold); - if (cost) { - Draw_Cell_Point(checkcell, true, threat_stage); - - /* - ** YES! The destination is at the corner of an impassable, so - ** set the direction to point directly at it and then the - ** scanning will terminate later. - */ - newdir = Next_Direction(newdir, search); - newcell = Adjacent_Cell(oldcell, newdir); - break; - } else { - Draw_Cell_Point(checkcell, false, threat_stage); - } - } - - /* - ** Perform special diagonal check. If the edge follower would cross the - ** diagonal or fall on the diagonal line from the source, then consider - ** that cell impassible. Otherwise, the find path algorithm will fail - ** when there are two impassible locations located on a diagonal - ** that is lined up between the source and destination location. - ** - ** P.S. It might help if you check the right cell rather than using - ** the value that just happened to be in checkcell. - */ - - checkcell = Adjacent_Cell(oldcell, newdir); - - int checkx = Cell_X(checkcell); - int checky = Cell_Y(checkcell); - int checkval = Point_Relative_To_Line(checkx, checky, startx, starty, targetx, targety); - if (checkval && !online) { - forcefail = ((checkval ^ oldval) < 0); - } else { - forcefail = false; - } - /* - ** The only exception to the above is when we are directly backtracking - ** because we could be trying to escape from a culdesack! - */ - if (forcefail && path->Length > 0 && (FacingType)(newdir ^ 4) == path->Command[path->Length - 1]) { -// ST - 12/18/96 5:15PM if (forcefail && (FacingType)(newdir ^ 4) == path->Command[path->Length - 1]) { - forcefail = false; - } - } - - #else - newdir = Next_Direction(newdir, search*2); - #endif - - /* - ** If we have just checked the same heading we started with, - ** we are surrounded by impassable characters and we exit. - */ - if (newdir == olddir) { - return(false); - } - - /* - ** Get the new cell. - */ - newcell = Adjacent_Cell(oldcell, newdir); - - /* - ** If we found a passable position, this is where we should move. - */ - if (!forcefail && ((cost = Passable_Cell(newcell, newdir, threat, threshhold)) != 0)) { - Draw_Cell_Point(newcell, true, threat_stage); - break; - } else { - Draw_Cell_Point(newcell, false, threat_stage, (forcefail) ? BROWN : 0); - if (newcell == target) { - forceout = true; - break; - } - } - - } - - /* - ** Record the direction. - */ - if (!forceout) { - /* - ** Mark the cell because this is where we need to be. If register - ** cell fails then the list has been shortened and we need to adjust - ** the new direction. - */ - if (!Register_Cell(path, newcell, newdir, cost, threshhold)) { - /* - ** The only reason we could not register a cell is that we are in - ** a looping situation. So we need to try and unravel the loop if - ** we can. - */ - if (!Unravel_Loop(path, newcell, newdir, startx, starty, targetx, targety, threshhold)) { - return(false); - } - /* - ** Since we need to eliminate a diagonal we must pretend the upon - ** attaining this square, we were moving turned farther in the - ** search direction then we really were. - */ - newdir = Next_Direction(newdir, (FacingType)(search*2)); - } - /* - ** Find out which side of the line this cell is on. If it is on - ** a side, then store off that side. - */ - int newx = Cell_X(newcell); - int newy = Cell_Y(newcell); - int val = Point_Relative_To_Line(newx, newy, startx, starty, targetx, targety); - if (val) { - oldval = val; - online = false; - } else { - online = true; - } - cellcount++; - if (cellcount==MAX_PATH_EDGE_FOLLOW) { -// DrawPath = true; -// Debug_Find_Path = true; -// Debug_Draw_Map("Loop failure", start, target, false); -// Debug_Draw_Path(path); - return(false); - } - } - - /* - ** If we have found the target spot, we are done. - */ - if (newcell == target) { - path->Command[path->Length] = END; - return(true); - } - - /* - ** If we make a full circle back to our original spot, get out. - */ - if (newcell == firstcell && newdir == firstdir) { - return(false); - } - - if (firstcell == -1) { - firstcell = newcell; - firstdir = newdir; - } - - /* - ** Because we moved, our facing is now incorrect. We want to face toward - ** the impassable edge we are following (well, not actually toward, but - ** a little past so that we can turn corners). We have to turn 45/90 degrees - ** more than expected in anticipation of the pending 45/90 degree turn at - ** the start of this loop. - */ - #ifdef DIAGONAL - olddir = Next_Direction(newdir, (FacingType)(-(int)search*3)); - #else - olddir = Next_Direction(newdir, (FacingType)(-(int)search*4)); - #endif - oldcell = newcell; - } - - /* - ** The maximum search path is exhausted... abort with a failure. - */ - return(false); -} - - -/*********************************************************************************************** - * Optimize_Moves -- Optimize the move list. * - * * - * INPUT: char *moves to optimize * - * * - * OUTPUT: none (list is optimized) * - * * - * WARNINGS: EMPTY moves are used to hold the place of eliminated * - * commands. Also, NEVER call this routine with a list that * - * contains illegal commands. The list MUST be terminated * - * with a EOL command * - * * - * HISTORY: * - * 07/08/1991 CY : Created. * - * 06/01/1992 JLB : Optimized and commented. * - *=============================================================================================*/ -#define EMPTY (FacingType)-2 -int FootClass::Optimize_Moves(PathType *path, MoveType threshhold) -//int Optimize_Moves(PathType *path, int (*callback)(CELL, FacingType), int threshold) -{ - /* - ** Facing command pair adjustment table. Compare the facing difference between - ** the two commands. 0 means no optimization is possible. 3 means backtracking - ** so eliminate both commands. Any other value adjusts the first command facing. - */ -#ifdef DIAGONAL - static FacingType _trans[FACING_COUNT] = {(FacingType)0, (FacingType)0, (FacingType)1, (FacingType)2, (FacingType)3, (FacingType)-2, (FacingType)-1, (FacingType)0}; // Smoothing. -#else - static FacingType _trans[FACING_COUNT] = {(FacingType)0, (FacingType)0, (FacingType)0, (FacingType)2, (FacingType)3, (FacingType)-2, (FacingType)0, (FacingType)0}; -#endif - FacingType *cmd1, // Floating first command pointer. - *cmd2, // Floating second command pointer. - newcmd; // Calculated new optimized command. - FacingType newdir; // Tentative new direction for smoothing. - CELL cell; // Working cell (as it moves along path). - - /* - ** Abort if there is any illegal parameter. - */ - if (!path || !path->Command) return(0); - - /* - ** Optimization loop -- start scanning with the - ** first pair of commands (if there are at least two - ** in the command list). - */ - path->Command[path->Length] = END; // Force end of list. - cell = path->Start; - if (path->Length > 1) { - cmd2 = path->Command + 1; - while (*cmd2 != END) { - - /* - ** Set the cmd1 pointer to point to the valid command closest, but - ** previous to cmd2. Be sure not to go previous to the head of the - ** command list. - */ - cmd1 = cmd2-1; - while (*cmd1 == EMPTY && cmd1 != path->Command) { - cmd1--; - } - - /* - ** If there isn't any valid previous command, then bump the - ** cmd pointers to the next command pair and continue... - */ - if (*cmd1 == EMPTY) { - cmd2++; - continue; - } - - /* - ** Fetch precalculated command change value. 0 means leave - ** command set alone, 3 means backtrack and eliminate two - ** commands. Any other value is new direction and eliminate - ** one command. - */ - newcmd = (FacingType)(*cmd2 - *cmd1); - if (newcmd < FACING_N) newcmd = (FacingType)(newcmd + FACING_COUNT); - newcmd = _trans[newcmd]; - - /* - ** Check for backtracking. If this occurs, then eliminate the - ** two commands. This is the easiest optimization. - */ - if (newcmd == FACING_SE) { - *cmd1 = EMPTY; - *cmd2++ = EMPTY; - continue; - } - - /* - ** If an optimization code was found the process it. The command is a facing - ** offset to more directly travel toward the immediate destination cell. - */ - if (newcmd) { - - /* - ** Optimizations differ when dealing with diagonals. Especially when dealing - ** with diagonals of 90 degrees. In such a case, 90 degree optimizations can - ** only be optimized if the intervening cell is passable. The distance travelled - ** is the same, but the path is less circuitous. - */ - if (*cmd1 & FACING_NE) { - - /* - ** Diagonal optimizations are always only 45 - ** degree adjustments. - */ - newdir = Next_Direction(*cmd1, (newcmd < FACING_N) ? (FacingType)-1 : (FacingType)1); - - /* - ** Diagonal 90 degree changes can be smoothed, although - ** the path isn't any shorter. - */ - if (ABS((int)newcmd) == 1) { - if (Passable_Cell(Adjacent_Cell(cell, newdir), newdir, -1, threshhold)) { - *cmd2 = newdir; - *cmd1 = newdir; - } - // BOB 16.12.92 - cell = Adjacent_Cell(cell, *cmd1); - cmd2++; - continue; - } - } else { - newdir = Next_Direction(*cmd1, newcmd); - } - - /* - ** Allow shortening turn only on right angle moves that are based on - ** 90 degrees. Always allow 135 degree optimizations. - */ - *cmd2 = newdir; - *cmd1 = EMPTY; - - /* - ** Backup what it thinks is the current cell. - */ - while (*cmd1 == EMPTY && cmd1 != path->Command) { - cmd1--; - } - if (*cmd1 != EMPTY) { - cell = Adjacent_Cell(cell, Next_Direction(*cmd1, FACING_S)); - } else { - cell = path->Start; - } - continue; - } - - /* - ** Since we could not make an optimization, we move our - ** head pointer forward. - */ - cell = Adjacent_Cell(cell, *cmd1); - cmd2++; - } - } - - /* - ** Pack the command list to remove any EMPTY command entries. - */ - cmd1 = path->Command; - cmd2 = path->Command; - cell = path->Start; - path->Cost = 0; - path->Length = 0; - while (*cmd2 != END) { - if (*cmd2 != EMPTY) { - -#ifdef NEVER - if (Debug_ShowPath) { - int x,y,x1,y1; - - if (Map.Coord_To_Pixel(Cell_Coord(cell), x, y)) { - Map.Coord_To_Pixel(Cell_Coord(Adjacent_Cell(cell, *cmd2)), x1, y1); - Set_Logic_Page(SeenBuff); - LogicPage->Draw_Line(x, y+8, x1, y1+8, DKGREY); - } - } -#endif - - cell = Adjacent_Cell(cell, *cmd2); - path->Cost+= Passable_Cell(cell, *cmd2, -1, threshhold); - path->Length++; - *cmd1++ = *cmd2; - } - cmd2++; - } - path->Length++; - *cmd1 = END; - return(path->Length); -} - - -CELL FootClass::Safety_Point(CELL src, CELL dst, int start, int max) -{ - FacingType dir; - CELL next; - int lp; - - dir = (FacingType)(CELL_FACING(src, dst) ^ 4) - 1; - - /* - ** Loop through the different acceptable distances. - */ - for (int dist = start; dist < max; dist ++) { - - /* - ** Move to the starting location. - */ - next = dst; - - for (lp = 0; lp < dist; lp ++) { - next = Adjacent_Cell(next, dir); - } - - if (dir & 1) { - /* - ** If our direction is diagonal than we need to check - ** only one side which is as long as both of the old sides - ** together. - */ - for (lp = 0; lp < dist << 1; lp ++) { - next = Adjacent_Cell(next, dir + 3); - if (!Can_Enter_Cell(next)) { - return(next); - } - } - } else { - /* - ** If our direction is not diagonal than we need to check two - ** sides so that we are checking a corner like location. - */ - for (lp = 0; lp < dist; lp ++) { - next = Adjacent_Cell(next, dir + 2); - if (!Can_Enter_Cell(next)) { - return(next); - } - } - - for (lp = 0; lp < dist; lp ++) { - next = Adjacent_Cell(next, dir + 4); - if (!Can_Enter_Cell(next)) { - return(next); - } - } - } - } - return(-1); -} - - - - -int FootClass::Passable_Cell(CELL cell, FacingType face, int threat, MoveType threshhold) -{ - MoveType move = Can_Enter_Cell(cell, face); - - if (move < MOVE_MOVING_BLOCK && Distance(cell) > 1) threshhold = MOVE_MOVING_BLOCK; - - if (move > threshhold) return(0); - - if (GameToPlay == GAME_NORMAL) { - if (threat != -1) { - if (Map.Cell_Distance(cell, DestLocation) > THREAT_THRESHOLD) { - if (Map.Cell_Threat(cell, Owner()) > threat) - return(0); - } - } - } - - static int _value[MOVE_COUNT] = { - 1, // MOVE_OK - 1, // MOVE_CLOAK - 3, // MOVE_MOVING_BLOCK - 8, // MOVE_DESTROYABLE - 10, // MOVE_TEMP - 0 // MOVE_NO - }; - return(_value[move]); - -#ifdef NEVER - int can; - int retval; - - int temp_move_mask = MoveMask; - - if (!House->IsHuman) { - temp_move_mask &= ~MOVEF_TEMP; - } - -#ifdef NEVER - if ((!(MoveMask & MOVEF_MOVING_BLOCK)) && Map.Cell_Distance(StartLocation, cell) > 2) { - temp_move_mask |= MOVEF_MOVING_BLOCK; - } -#endif - - can = (temp_move_mask & Can_Enter_Cell(cell, face)); - if (can & MOVEF_NO) return(0); - - retval = 1; - if (can & MOVEF_MOVING_BLOCK) retval += 3; - if (can & MOVEF_DESTROYABLE) retval += 10; - if (can & MOVEF_TEMP) retval += 10; - - if (threat != -1) { - if (Map.Cell_Distance(cell, DestLocation) > THREAT_THRESHOLD) { - if (Map.Cell_Threat(cell, Owner()) > threat) - return(0); - } - } - - return(retval); -#endif -} - - -void FootClass::Debug_Draw_Map(char *txt, CELL start, CELL dest, bool pause) -{ - if ((!Debug_Find_Path) || (!DrawPath)) return; - - if (pause) Get_Key_Num(); - GraphicViewPortClass * page = Set_Logic_Page(SeenBuff); - - VisiblePage.Clear(); - Fancy_Text_Print(txt, 160, 0, WHITE, BLACK, TPF_8POINT|TPF_CENTER); - for (int x = 0; x < 64; x++) { - for (int y = 0; y < 64; y++) { - int color = 0; - - switch (Can_Enter_Cell( (CELL)((y << 6) + x))) { - case MOVE_OK: - color = GREEN; - break; - case MOVE_MOVING_BLOCK: - color = LTGREEN; - break; - - case MOVE_DESTROYABLE: - color = YELLOW; - break; - case MOVE_TEMP: - color = BROWN; - break; - default: - color = RED; - break; - } - if ((CELL)((y << 6) + x) == start) - color = LTBLUE; - if ((CELL)((y << 6) + x) == dest) - color = BLUE; - Fat_Put_Pixel(64 + (x*3), 8 + (y*3), color, 3, SeenBuff); - } - } - Set_Logic_Page(page); -} - -void FootClass::Debug_Draw_Path(PathType *path) -{ - if (!path) return; - - FacingType *list = path->Command; - CELL pos = path->Start; - - for (int idx = 0; idx < path->Length; idx++) { - pos = Adjacent_Cell(pos, *list++); - Draw_Cell_Point(pos, true, -1, 0); - } -} diff --git a/code/TIBERIANDAWN/FLASHER.CPP b/code/TIBERIANDAWN/FLASHER.CPP deleted file mode 100644 index b81aa80..0000000 --- a/code/TIBERIANDAWN/FLASHER.CPP +++ /dev/null @@ -1,129 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\flasher.cpv 2.18 16 Oct 1995 16:49:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FLASHER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 28, 1994 * - * * - * Last Update : October 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FlasherClass::Process -- Performs the logic processing for the flashing ability. * - * FlasherClass::Debug_Dump -- Displays current status to the monochrome screen. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * FlasherClass::Debug_Dump -- Displays current status to the monochrome screen. * - * * - * This utility function will output the current status of the FlasherClass to the mono * - * screen. It is through this display that bugs may be fixed or detected. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void FlasherClass::Debug_Dump(MonoClass *mono) const -{ - mono->Set_Cursor(50, 7); - mono->Printf("%2d", FlashCount); -} -#endif - - -/*********************************************************************************************** - * FlasherClass::Process -- Performs the logic processing for the flashing ability. * - * * - * The ability for an object to flash is controlled by this logic processing routine. It * - * should be called once per game tick per unit. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Should the associated object be redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - * 06/20/1994 JLB : Is now independent of object it represents. * - *=============================================================================================*/ -bool FlasherClass::Process(void) -{ - // 2019/09/20 JAS - Flashing info needs to exist per player - for (int i = 0; i < HOUSE_COUNT; i++) - { - if (FlashCountPerPlayer[i]) - { - FlashCountPerPlayer[i]--; - } - } - - if (FlashCount) { - FlashCount--; - IsBlushing = false; - - if (FlashCount & 0x01) { - IsBlushing = true; - } - return(true); - } - return(false); -} - -/*********************************************************************************************** - * FlasherClass::Get_Flashing_Flags -- * - * * - * Gets the flags tell which players this object should flash for. * - * * - * INPUT: none * - * * - * OUTPUT: unsigned int; Flag representing the players to flash for * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 2019/09/20 JAS : Created. * - *=============================================================================================*/ -unsigned int FlasherClass::Get_Flashing_Flags() const -{ - unsigned flags = 0; - for (int i = 0; i < HOUSE_COUNT; ++i) - { - if (FlashCountPerPlayer[i] > 0) - { - flags |= (1 << i); - } - } - - return flags; -} diff --git a/code/TIBERIANDAWN/FLASHER.H b/code/TIBERIANDAWN/FLASHER.H deleted file mode 100644 index c150ce8..0000000 --- a/code/TIBERIANDAWN/FLASHER.H +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\flasher.h_v 2.17 16 Oct 1995 16:45:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FLASHER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 28, 1994 * - * * - * Last Update : May 28, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FLASHER_H -#define FLASHER_H - -class FlasherClass { - public: - /* - ** When this object is targeted, it will flash a number of times. This is the - ** flash control number. It counts down to zero and then stops. Odd values - ** cause the object to be rendered in a lighter color. - */ - unsigned FlashCount:7; - - /* - ** When an object is targeted, it flashes several times to give visual feedback - ** to the player. Every other game "frame", this flag is true until the flashing - ** is determined to be completed. - */ - unsigned IsBlushing:1; - - // 2019/09/20 JAS - Flashing info needs to exist per player - FlasherClass(void) { - FlashCount = 0; - IsBlushing = false; - - for (int i = 0; i < HOUSE_COUNT; ++i) - { - FlashCountPerPlayer[i] = 0; - } - } - #ifdef CHEAT_KEYS - void Debug_Dump(MonoClass *mono) const; - #endif - bool Process(void); - - /* - ** File I/O. - */ - void Code_Pointers(void); - void Decode_Pointers(void); - - - // 2019/09/20 JAS - Flashing info needs to exist per player - unsigned int Get_Flashing_Flags() const; - unsigned int FlashCountPerPlayer[HOUSE_COUNT]; -}; - -#endif diff --git a/code/TIBERIANDAWN/FLY.CPP b/code/TIBERIANDAWN/FLY.CPP deleted file mode 100644 index d68ab5d..0000000 --- a/code/TIBERIANDAWN/FLY.CPP +++ /dev/null @@ -1,130 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\fly.cpv 2.18 16 Oct 1995 16:50:40 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FLY.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 24, 1994 * - * * - * Last Update : June 5, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FlyClass::Physics -- Performs vector physics (movement). * - * FlyClass::Fly_Speed -- Sets the flying object to the speed specified. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * FlyClass::Physics -- Performs vector physics (movement). * - * * - * This routine performs movement (vector) physics. It takes the * - * specified location and moves it according to the facing and speed * - * of the vector. It returns the status of the move. * - * * - * INPUT: coord -- Reference to the coordinate that the vector will * - * be applied to. * - * * - * OUTPUT: Returns with the status of the vector physics. This could * - * range from no effect, to exiting the edge of the world. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/24/1994 JLB : Created. * - * 06/05/1995 JLB : Simplified to just do movement. * - *=============================================================================================*/ -ImpactType FlyClass::Physics(COORDINATE & coord, DirType facing) -{ - if (SpeedAdd != MPH_IMMOBILE) { - int actual = (int)SpeedAdd + SpeedAccum; - div_t result = div(actual, PIXEL_LEPTON_W); - SpeedAccum = result.rem; - actual -= result.rem; - COORDINATE old = coord; - - /* - ** If movement occurred that is at least one - ** pixel, then check update the coordinate and - ** check for edge of world collision. - */ - if (result.quot) { - COORDINATE newcoord; // New working coordinate. - - newcoord = Coord_Move(coord, facing, actual); - - /* - ** If no movement occurred, then presume it hasn't moved at all - ** and return immediately with this indication. - */ - if (newcoord == coord) { - return(IMPACT_NONE); - } - - /* - ** Remember the new position. - */ - coord = newcoord; - - /* - ** If the new coordinate is off the edge of the world, then report - ** this. - */ - if (newcoord & 0xC000C000L /*|| !Map.In_Radar(Coord_Cell(newcoord))*/) { - coord = old; - return(IMPACT_EDGE); - } - - return(IMPACT_NORMAL); - } - } - return(IMPACT_NONE); -} - - -/*********************************************************************************************** - * FlyClass::Fly_Speed -- Sets the flying object to the speed specified. * - * * - * This sets the speed of the projectile. It basically functions like a throttle value * - * where 0 equals stop and 255 equals maximum speed (whatever that is for the particular * - * object). * - * * - * INPUT: speed -- Speed setting from 0 to 255. * - * * - * maximum -- The maximum speed of the object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/26/1994 JLB : Created. * - * 07/26/1994 JLB : Added maximum speed as guiding value. * - *=============================================================================================*/ -void FlyClass::Fly_Speed(int speed, MPHType maximum) -{ - SpeedAdd = (MPHType)Fixed_To_Cardinal((int)maximum, speed); -} - diff --git a/code/TIBERIANDAWN/FLY.H b/code/TIBERIANDAWN/FLY.H deleted file mode 100644 index e0818ed..0000000 --- a/code/TIBERIANDAWN/FLY.H +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\fly.h_v 2.19 16 Oct 1995 16:45:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FLY.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 24, 1994 * - * * - * Last Update : April 24, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FLY_H -#define FLY_H - -typedef enum ImpactType : unsigned char { - IMPACT_NONE, // No movement (of significance) occurred. - IMPACT_NORMAL, // Some (non eventful) movement occurred. - IMPACT_EDGE // The edge of the world was reached. -} ImpactType; - - -/**************************************************************************** -** Flying objects are handled by this class definition. -*/ -class FlyClass { - public: - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - FlyClass(void) { - SpeedAdd = MPH_IMMOBILE; - SpeedAccum = 0; - }; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - void Fly_Speed(int speed, MPHType maximum); - ImpactType Physics(COORDINATE &coord, DirType facing); - MPHType Get_Speed(void) const {return(SpeedAdd);}; - - /* - ** File I/O. - */ - void Code_Pointers(void); - void Decode_Pointers(void); - - private: - /* - ** Object movement consists of incrementing the accumulator until enough "distance" - ** has accumulated so that moving the object becomes reasonable. - */ - unsigned SpeedAccum; // Lepton accumulator. - MPHType SpeedAdd; // Lepton add (per frame). -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/FOOT.CPP b/code/TIBERIANDAWN/FOOT.CPP deleted file mode 100644 index c71453f..0000000 --- a/code/TIBERIANDAWN/FOOT.CPP +++ /dev/null @@ -1,2062 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\foot.cpv 2.17 16 Oct 1995 16:51:42 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FOOT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 22, 1994 * - * * - * Last Update : August 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FootClass::Active_Click_With -- Intiates attack or move according to target clicked on. * - * FootClass::Active_Click_With -- Performs action as a result of left mouse click. * - * FootClass::Approach_Target -- Sets the navigation computer to approach target object. * - * FootClass::Assign_Destination -- Assigns specified destination to NavCom. * - * FootClass::Assign_Mission -- Assign mission to foot class object. * - * FootClass::Basic_Path -- Finds the basic path for a ground object. * - * FootClass::Body_Facing -- Set the body rotation/facing. * - * FootClass::Can_Demolish -- Checks to see if this object can be sold back. * - * FootClass::Can_Enter_Cell -- Checks to see if the object can enter cell specified. * - * FootClass::Death_Announcement -- Announces the death of a unit. * - * FootClass::Debug_Dump -- Displays the status of the FootClass to the mono monitor. * - * FootClass::Detach -- Detaches a target from tracking systems. * - * FootClass::Detach_All -- Removes this object from the game system. * - * FootClass::Enters_Building -- When unit enters a building for some reason. * - * FootClass::FootClass -- Default constructor for foot class objects. * - * FootClass::FootClass -- Normal constructor for the foot class object. * - * FootClass::Greatest_Threat -- Fetches the greatest threat to this object. * - * FootClass::Likely_Coord -- Fetches the coordinate the object will be at shortly. * - * FootClass::Limbo -- Intercepts limbo event and handles FootClass processing. * - * FootClass::Mark -- Unit interface to map rendering system. * - * FootClass::Mission_Attack -- AI for heading towards and firing upon target. * - * FootClass::Mission_Capture -- Handles the capture mission. * - * FootClass::Mission_Enter -- Enter (cooperatively) mission handler. * - * FootClass::Mission_Guard_Area -- Causes unit to guard an area about twice weapon range. * - * FootClass::Mission_Hunt -- Handles the default hunt order. * - * FootClass::Mission_Move -- AI process for moving a vehicle to its destination. * - * FootClass::Offload_Tiberium_Bail -- Fetches the Tiberium to offload per step. * - * FootClass::Override_Mission -- temporarily overides a units mission * - * FootClass::Per_Cell_Process -- Perform action based on once-per-cell condition. * - * FootClass::Receive_Message -- Movement related radio messages are handled here. * - * FootClass::Rescue_Mission -- Calls this unit to the rescue. * - * FootClass::Restore_Mission -- Restores an overidden mission * - * FootClass::Sell_Back -- Causes this object to be sold back. * - * FootClass::Set_Speed -- Initiate unit movement physics. * - * FootClass::Sort_Y -- Determine the sort coordinate for foot class objects. * - * FootClass::Start_Driver -- This starts the driver heading to the destination desired. * - * FootClass::Stop_Driver -- This routine clears the driving state of the object. * - * FootClass::Stun -- Prepares a ground travelling object for removal. * - * FootClass::Take_Damage -- Handles taking damage to this object. * - * FootClass::Unlimbo -- Unlimbos object and performs special fixups. * - * FootClass::~FootClass -- Default destructor for foot class objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * FootClass::FootClass -- Default constructor for foot class objects. * - * * - * This is the default constructor for FootClass objects. It sets the foot class values to * - * their default starting settings. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/23/1994 JLB : Created. * - *=============================================================================================*/ -FootClass::FootClass(void) : Speed(0) -{ - IsDriving = false; - IsInitiated = false; - IsPlanningToLook = false; - IsDeploying = false; - IsNewNavCom = false; - IsFiring = false; - IsRotating = false; - IsUnloading = false; - NavCom = TARGET_NONE; - SuspendedNavCom = TARGET_NONE; - Path[0] = FACING_NONE; - HeadToCoord = NULL; - Member = 0; - Team = 0; - PathDelay = 0; - TryTryAgain = PATH_RETRY; - if (House) { - House->CurUnits++; - } - Group = -1; -} - - -/*********************************************************************************************** - * FootClass::~FootClass -- Default destructor for foot class objects. * - * * - * At this level of the destruction process, the house record of the number of units * - * currently in inventory is decremented to reflect this units destruction. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/10/1995 JLB : Created. * - *=============================================================================================*/ -FootClass::~FootClass(void) -{ - if (GameActive && House) { - House->CurUnits--; - } -} - - -/*********************************************************************************************** - * FootClass::FootClass -- Normal constructor for the foot class object. * - * * - * This is the normal constructor used when creating a foot class object. * - * * - * INPUT: house -- The house that owns this object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -FootClass::FootClass(HousesType house) : - TechnoClass(house), - Speed(0) -{ - Member = 0; - Team = 0; - Path[0] = FACING_NONE; - NavCom = TARGET_NONE; - SuspendedNavCom = TARGET_NONE; - IsUnloading = false; - IsDriving = false; - IsInitiated = false; - IsRotating = false; - IsFiring = false; - IsDeploying = false; - IsNewNavCom = false; - IsPlanningToLook = false; - HeadToCoord = 0L; - PathDelay = 0; - Group = -1; - TryTryAgain = PATH_RETRY; - House->CurUnits++; -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * FootClass::Debug_Dump -- Displays the status of the FootClass to the mono monitor. * - * * - * This routine is used to output the current status of the foot class to the mono * - * monitor. Through this display bugs may be tracked down or eliminated. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - * 07/04/1995 JLB : Handles aircraft special case. * - *=============================================================================================*/ -void FootClass::Debug_Dump(MonoClass *mono) const -{ - static char const * _p2c[9] = {"-","0","1","2","3","4","5","6","7"}; -#define Path_To_String(a) _p2c[((ABS((int)a+1))%9)] - - /* - ** Display the common data for all objects that inherity from FootClass. - */ - mono->Set_Cursor(63, 7); - if (Team) { - mono->Printf("%s(%d)", Team->Class->IniName, Teams.ID(Team)); - } else { - mono->Printf("(none)"); - } - mono->Set_Cursor(73, 7);mono->Printf("%04X", ArchiveTarget); - mono->Set_Cursor(42, 1);mono->Printf("%04X", NavCom); - mono->Set_Cursor(44, 3);mono->Printf("%d", Speed); - - /* - ** Although aircraft inherit from FootClass, some of the variables are not - ** used and thus should not be displayed. - */ - if (What_Am_I() != RTTI_AIRCRAFT) { - mono->Set_Cursor(50, 3); - mono->Printf("%s%s%s%s%s%s%s%s%s%s%s%s", - Path_To_String(Path[0]), - Path_To_String(Path[1]), - Path_To_String(Path[2]), - Path_To_String(Path[3]), - Path_To_String(Path[4]), - Path_To_String(Path[5]), - Path_To_String(Path[6]), - Path_To_String(Path[7]), - Path_To_String(Path[8]), - Path_To_String(Path[9]), - Path_To_String(Path[10]), - Path_To_String(Path[11]), - Path_To_String(Path[12])); - - mono->Set_Cursor(65, 1);mono->Printf("%08lX", Head_To_Coord()); - mono->Text_Print("X", 16 + (IsDeploying?2:0), 12); - mono->Text_Print("X", 16 + (IsRotating?2:0), 13); - mono->Text_Print("X", 16 + (IsDriving?2:0), 15); - mono->Text_Print("X", 16 + (IsFiring?2:0), 14); - mono->Text_Print("X", 16 + (IsPlanningToLook?2:0), 16); - } - TechnoClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * FootClass::Set_Speed -- Initiate unit movement physics. * - * * - * This routine is used to set a unit's velocity control structure. * - * The game will then process the unit's movement during the momentum * - * physics calculation. * - * * - * INPUT: unit -- Pointer to the unit to alter. * - * * - * speed -- Throttle setting (0=stop, 255=full throttle). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/07/1992 JLB : Created. * - * 09/24/1993 JLB : Revised for faster speed. * - * 04/02/1994 JLB : Revised for new system. * - * 04/15/1994 JLB : Converted to member function. * - * 07/21/1994 JLB : Simplified. * - *=============================================================================================*/ -void FootClass::Set_Speed(int speed) -{ - speed &= 0xFF; - ((unsigned char &)Speed) = speed; -} - - -/*********************************************************************************************** - * FootClass::Mark -- Unit interface to map rendering system. * - * * - * This routine is the interface function for units as they relate to * - * the map rendering system. Whenever a unit's imagery changes, this * - * function is called. * - * * - * INPUT: mark -- Type of image change (MARK_UP, _DOWN, _CHANGE) * - * MARK_UP -- Unit is removed. * - * MARK_CHANGE -- Unit alters image but doesn't move. * - * MARK_DOWN -- Unit is overlaid onto existing icons. * - * * - * OUTPUT: bool; Did the marking operation succeed? Failure could be the result of marking * - * down when it is already down, or visa versa. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/14/1991 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - * 12/23/1994 JLB : Performs low level check before processing. * - *=============================================================================================*/ -bool FootClass::Mark(MarkType mark) -{ - if (TechnoClass::Mark(mark)) { - CELL cell = Coord_Cell(Coord); - - /* - ** Inform the map of the refresh, occupation, and overlap - ** request. - */ - switch (mark) { - case MARK_UP: - Map.Pick_Up(cell, this); - break; - - case MARK_DOWN: - Map.Place_Down(cell, this); - break; - - default: - Map.Refresh_Cells(cell, Overlap_List()); - Map.Refresh_Cells(cell, Occupy_List()); - break; - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FootClass::Basic_Path -- Finds the basic path for a ground object. * - * * - * This is a common routine used by both infantry and other ground travelling units. It * - * will fill in the unit's basic path to the NavCom destination. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was a path found? A failure to find a path means either the target cannot * - * be found or the terrain prohibits the unit's movement. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -bool FootClass::Basic_Path(void) -{ - PathType *path; // Pointer to path control structure. - CELL cell; - int skip_path = false; - - Path[0] = FACING_NONE; - - if (Target_Legal(NavCom)) { - cell = As_Cell(NavCom); - - /* - ** When the navigation computer is set to a location that is impassible, then - ** find a nearby cell that can be entered and try to head toward that instead. - ** EXCEPT when that cell is very close -- then just bail. - */ -// IsFindPath = true; - if (Can_Enter_Cell(cell) == MOVE_NO && Distance(NavCom) > 0x0300) { - static int _faceadjust[8] = {0, 1, -1, 2, -2, 3, -3, 4}; - FacingType f2 = (FacingType)(((unsigned)::Direction(cell, Coord_Cell(Coord)))>>5); - - for (unsigned index = 0; index < (sizeof(_faceadjust) / sizeof(_faceadjust[0])); index++) { - CELL cell2; - - cell2 = Adjacent_Cell(cell, (FacingType)((f2+_faceadjust[index])&0x7)); - if (Can_Enter_Cell(cell2, FACING_NONE) <= MOVE_CLOAK) { - cell = cell2; - break; - } - } - } -// IsFindPath = false; - -#ifdef SPECIAL - if (What_Am_I() == RTTI_INFANTRY) { - CELL mycell = Coord_Cell(Center_Coord()); -// Mark(MARK_UP); - ObjectClass *obj = Map[mycell].Cell_Occupier(); - while (obj) { - if (obj != this && obj->What_Am_I() == RTTI_INFANTRY) { - InfantryClass *inf = (InfantryClass *)obj; - if (inf->NavCom == NavCom && inf->Path[0] != FACING_NONE) { - if (Coord_Cell(inf->Head_To_Coord()) == Coord_Cell(inf->Coord)) { - Mem_Copy(&inf->Path[1], Path, sizeof(Path)-sizeof(Path[0])); - } else { - Mem_Copy(inf->Path, Path, sizeof(Path)); - } - if (Path[0] != FACING_NONE) { - skip_path = true; - } - break; - } - } - obj = obj->Next; - } -// Mark(MARK_DOWN); - } -#endif - - if (!skip_path) { - Mark(MARK_UP); - Path[0] = FACING_NONE; // Probably not necessary, but... - - /* - ** Try to find a path to the destination. If a failure occurs, then keep trying - ** with greater determination until either a complete failure occurs, or a decent - ** path was found. - */ - bool found1=false; // Found a best path yet? - PathType path1; - FacingType workpath1[200]; // Staging area for path list. - FacingType workpath2[200]; // Staging area for path list. - MoveType maxtype = MOVE_TEMP; - if (!House->IsHuman) { - maxtype = MOVE_DESTROYABLE; - } else { - - /* - ** For simple movement missions by the human player, then don't - ** consider friendly units as passable if close to the destination. - ** This will prevent a human controlled unit from just sitting next - ** to a destination just because there is another friendly unit - ** occupying the destination location. - */ - if (Mission == MISSION_MOVE && Distance(NavCom) < 0x0280) { - maxtype = MOVE_DESTROYABLE; - } - } - - /* - ** Determine if ANY path could be calculated by first examining the most - ** aggressive case. If this fails, then no path will succeed. Further - ** scanning is unnecessary. - */ - path = Find_Path(cell, &workpath1[0], sizeof(workpath1), maxtype); - if (path && path->Cost) { - memcpy(&path1, path, sizeof(path1)); - found1 = true; - - /* - ** Scan for the best path possible. If this succeeds, then do a simple - ** comparison with the most agressive path. If they are very close, then - ** go with the best (easiest) path method. - */ - path = Find_Path(cell, &workpath2[0], sizeof(workpath2), MOVE_CLOAK); - if (path && path->Cost && path->Cost < MAX((path1.Cost + (path1.Cost/2)), 3)) { - memcpy(&path1, path, sizeof(path1)); - memcpy(workpath1, workpath2, sizeof(workpath1)); - } else { - - /* - ** The easiest path method didn't result in a satisfactory path. Scan through - ** the rest of the path options, looking for the best one. - */ - for (MoveType move = MOVE_MOVING_BLOCK; move < maxtype; move++) { - path = Find_Path(cell, &workpath2[0], sizeof(workpath2), move); - if (path && path->Cost && path->Cost < MAX((path1.Cost + (path1.Cost/2)), 3)) { - memcpy(&path1, path, sizeof(path1)); - memcpy(workpath1, workpath2, sizeof(workpath1)); - } - } - } - } - -#ifdef OBSOLETE - for (MoveType move = MOVE_CLOAK; move <= maxtype; move++) { - if (!found1) { - path = Find_Path(cell, &workpath1[0], sizeof(workpath1), move); - if (path && path->Cost) { - memcpy(&path1, path, sizeof(path1)); - found1 = true; - if (path1.Cost < 5) break; - } - } else { - path = Find_Path(cell, &workpath2[0], sizeof(workpath2), move); - - if (path) { - if (path->Cost && path->Cost <= path1.Cost/2) { - memcpy(&path1, path, sizeof(path1)); - memcpy(workpath1, workpath2, sizeof(workpath1)); - } - } - } - } -#endif - - /* - ** If a good path was found, then record it in the object's path - ** list. - */ - if (found1) { - Fixup_Path(&path1); - memcpy(&Path[0], &workpath1[0], MIN(path->Length, (int)sizeof(Path))); - } - - Mark(MARK_DOWN); - } - - -#ifdef NEVER - /* - ** Patch at this point to see if we are moving directly into a - ** MOVE_TEMP. This allows units to bunch up at a bridge even if there - ** is an enormously long way around. This also allows units to give - ** up trying to move into the MOVE_TEMP using the normal movement - ** retry logic. - */ - CELL cell = Adjacent_Cell(Coord_Cell(Coord), Path[0]); - if (Can_Enter_Cell(cell, FACING_NONE) == MOVEF_TEMP) { - Path[0] = FACING_NONE; - } -#endif - - PathDelay = PATH_DELAY; - if (Path[0] != FACING_NONE) return(true); - - /* - ** If a basic path couldn't be determined, then abort the navigation process. - */ -// NavCom = TARGET_NONE; - Stop_Driver(); - } - return(false); -} - - -/*********************************************************************************************** - * FootClass::Mission_Move -- AI process for moving a vehicle to its destination. * - * * - * This simple AI script handles moving the vehicle to its desired destination. Since * - * simple movement is handled directly by the engine, this routine merely waits until * - * the unit has reached its destination, and then causes the unit to enter idle mode. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Move(void) -{ - if (!Target_Legal(NavCom) && !IsDriving && MissionQueue == MISSION_NONE) { - Enter_Idle_Mode(); - } - if (!Target_Legal(TarCom) && !House->IsHuman) { - Target_Something_Nearby(THREAT_RANGE); - } - return(TICKS_PER_SECOND+3); -} - - -/*********************************************************************************************** - * FootClass::Mission_Capture -- Handles the capture mission. * - * * - * Capture missions are nearly the same as normal movement missions. The only difference * - * is that the final destination is handled in a special way so that it is not marked as * - * impassable. This allows the object (usually infantry) the ability to walk onto the * - * object and thus capture it. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game ticks to delay before calling this routine. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Capture(void) -{ - if (!Target_Legal(NavCom) && !In_Radio_Contact()) { - Enter_Idle_Mode(); - if (Map[Coord_Cell(Center_Coord())].Cell_Building()) { - Scatter(0, true); - } - } - return(TICKS_PER_SECOND-2); -} - - -/*********************************************************************************************** - * FootClass::Mission_Attack -- AI for heading towards and firing upon target. * - * * - * This AI routine handles heading to within range of the target and then firing upon * - * it until it is destroyed. If the target is destroyed, then the unit will change * - * missions to match its "idle mode" of operation (usually guarding). * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Attack(void) -{ - if (Target_Legal(TarCom)) { - Approach_Target(); - } else { - Enter_Idle_Mode(); - } - return(TICKS_PER_SECOND+2); -} - - -/*********************************************************************************************** - * FootClass::Mission_Guard -- Handles the AI for guarding in place. * - * * - * Units that are performing stationary guard duty use this AI process. They will sit * - * still and target any enemies that get within range. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Guard(void) -{ - if (!Target_Something_Nearby(THREAT_RANGE)) { - Random_Animate(); - } - return(TICKS_PER_SECOND+Random_Picky((int)0, (int)4, (char*)NULL, (int)0)); -} - - -/*********************************************************************************************** - * FootClass::Mission_Hunt -- Handles the default hunt order. * - * * - * This routine is the default hunt order for game objects. It handles searching for a * - * nearby object and heading toward it. The act of targetting will cause it to attack * - * the target it selects. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the game tick delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Hunt(void) -{ - if (!Target_Something_Nearby(THREAT_NORMAL)) { - Random_Animate(); - } else { - if (What_Am_I() == RTTI_INFANTRY && ((InfantryTypeClass const &)Class_Of()).Type == INFANTRY_E7) { - Assign_Destination(TarCom); - Assign_Mission(MISSION_CAPTURE); - } else { - Approach_Target(); - } - } - return(TICKS_PER_SECOND+5); -} - - -/*********************************************************************************************** - * FootClass::Mission_Timed_Hunt -- This is the AI process for multiplayer computer units. * - * * - * For multiplayer games, the computer AI can't just blitz the human players; the humans * - * need a little time to set up their base, or whatever. This state just waits for * - * a certain period of time, then goes into hunt mode. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Timed_Hunt(void) -{ - int rndmax; - int changed = 0; // has the unit changed into Hunt mode? - - if (!House->IsHuman) { - - /* - ** Jump into HUNT mode if we're supposed to Blitz, and the EndCountDown - ** has expired, or if our owning house has lost more than 1/4 of its units - ** (it gets mad at you) - */ - if ( (MPlayerBlitz && House->BlitzTime==0) || - House->CurUnits < ((House->MaxUnit * 4) / 5)) { - Assign_Mission(MISSION_HUNT); - changed = 1; - } - - /* - ** Jump into HUNT mode on a random die roll; the computer units will periodically - ** "snap out" of their daze, and begin hunting. Try to time it so that all - ** units will be hunting within 10 minutes (600 calls to this routine). - */ - if (MPlayerBases) { - rndmax = 5000; - } else { - rndmax = 1000; - } - - if (IRandom(0,rndmax) == 1) { - Assign_Mission(MISSION_HUNT); - changed = 1; - } - - /* - ** If this unit is still just sitting in Timed Hunt mode, call Guard Area - ** so it doesn't just sit there stupidly. - */ - if (!changed) { - Mission_Guard_Area(); - } - } - - return(TICKS_PER_SECOND+Random_Pick(0, 4)); // call me back in 1 second. - -} - - -/*********************************************************************************************** - * FootClass::Stop_Driver -- This routine clears the driving state of the object. * - * * - * This is the counterpart routine to the Start_Driver function. It clears the driving * - * status flags and destination coordinate record. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was driving stopped? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 12/12/1994 JLB : Greatly simplified. * - *=============================================================================================*/ -bool FootClass::Stop_Driver(void) -{ - if (HeadToCoord) { - HeadToCoord = NULL; - Set_Speed(0); - IsDriving = false; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FootClass::Start_Driver -- This starts the driver heading to the destination desired. * - * * - * Before a unit can move it must be started by this routine. This routine handles * - * reserving the cell and setting the driving flag. * - * * - * INPUT: headto -- The coordinate of the immediate drive destination. This is one cell * - * away from the unit's current location. * - * * - * OUTPUT: bool; Was driving initiated? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 12/12/1994 JLB : Uses simple spot index finder. * - *=============================================================================================*/ -bool FootClass::Start_Driver(COORDINATE &headto) -{ - Stop_Driver(); - if (headto) { - HeadToCoord = headto; - IsDriving = true; - - /* - ** Check for crate goodie finder here. - */ - if (Map[Coord_Cell(headto)].Goodie_Check(this)) { - return(true); - } - - HeadToCoord = NULL; - IsDriving = false; - } - return(false); -} - - -/*********************************************************************************************** - * FootClass::Sort_Y -- Determine the sort coordinate for foot class objects. * - * * - * This routine will determine the sort coordinate for foot class object. This coordinate * - * is usually the coordinate of the object. The exception is if the object is teathered. * - * In this case (presumes offloading to the north), the sorting coordinate is adjusted * - * so that the object will be drawn on top of the transport unit. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate to use for sorting. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 11/04/1994 JLB : Sort value is different when unloading from aircraft. * - *=============================================================================================*/ -COORDINATE FootClass::Sort_Y(void) const -{ - if (IsUnloading) { - return(Coord_Add(Coord, 0x01000000L)); - } - if (In_Radio_Contact() && IsTethered && Contact_With_Whom()->What_Am_I() == RTTI_UNIT) { - return(Coord_Add(Coord, 0x01000000L)); - } - return(Coord_Add(Coord, 0x00300000L)); -} - - -/*********************************************************************************************** - * FootClass::Stun -- Prepares a ground travelling object for removal. * - * * - * This routine clears the units' navigation computer in preparation for removal from the * - * game. This is probably called as a result of unit destruction in combat. Clearing the * - * navigation computer ensures that the normal AI process won't start it moving again while * - * the object is undergoing any death animations. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -void FootClass::Stun(void) -{ - Assign_Destination(TARGET_NONE); - Path[0] = FACING_NONE; - Stop_Driver(); - TechnoClass::Stun(); -} - - -/*********************************************************************************************** - * FootClass::Approach_Target -- Sets the navigation computer to approach target object. * - * * - * This routine will set the navigation computer to approach the target indicated by the * - * targeting computer. It is through this function that the unit nears the target so * - * that weapon firing may occur. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 12/13/1994 JLB : Made part of TechnoClass. * - * 12/22/1994 JLB : Enhanced search algorithm. * - * 05/20/1995 JLB : Always approaches if the object is off the map. * - *=============================================================================================*/ -void FootClass::Approach_Target(void) -{ - /* - ** Determine that if there is an existing target it is still legal - ** and within range. - */ - if (Target_Legal(TarCom)) { - - /* - ** If the target is too far away then head toward it. - */ - int maxrange = MAX(Weapon_Range(0), Weapon_Range(1)); - - if (!Target_Legal(NavCom) && (!In_Range(TarCom) || !IsLocked)) { -// if (!Target_Legal(NavCom) && (Distance(TarCom) > maxrange || !IsLocked)) { - - /* - ** If the object that we are attacking is a building adjust the units - ** max range so that people can stand far away from the buildings and - ** hit them. - */ - BuildingClass * obj = As_Building(TarCom); - if (obj) { - maxrange += ((obj->Class->Width() + obj->Class->Height()) * (0x100 / 4)); - } - - /* - ** Adjust the max range of an infantry unit for where he is standing - ** in the room. - */ - maxrange -= 0x00B7; -#ifdef OBSOLETE - if (What_Am_I() == RTTI_INFANTRY) { - maxrange -= 0x0111; - } else { - maxrange -= 0x00B7; - } -#endif - maxrange = MAX(maxrange, 0); - - COORDINATE tcoord = ::As_Coord(TarCom); - COORDINATE trycoord = 0; - CELL tcell = Coord_Cell(tcoord); - CELL trycell = tcell; - DirType dir = Direction256(tcoord, Center_Coord()); - bool found = false; - - /* - ** Sweep through the cells between the target and the unit, looking for - ** a cell that the unit can enter but which is also within weapon range - ** of the target. If after a reasonable search, no appropriate cell could - ** be found, then the target will be assigned as the movement destination - ** and let "the chips fall where they may." - */ - for (int range = maxrange; range > 0x0080; range -= 0x0100) { - static int _angles[] = {0, 8, -8, 16, -16, 24, -24, 32, -32, 48, -48, 64, -64}; - - for (int index = 0; index < (sizeof(_angles)/sizeof(_angles[0])); index++) { - trycoord = Coord_Move(tcoord, (DirType)(dir + _angles[index]), range); - - if (::Distance(trycoord, tcoord) < range) { - trycell = Coord_Cell(trycoord); - if (Can_Enter_Cell(trycell) <= MOVE_CLOAK && Map.In_Radar(trycell)) { - found = true; - break; - } - } - } - if (found) break; - } - - /* - ** If a suitable intermediate location was found, then head toward it. - ** Otherwise, head toward the enemy unit directly. - */ - if (found) { - Assign_Destination(::As_Target(trycell)); - } else { - Assign_Destination(TarCom); - } - } - } -} - - -/*********************************************************************************************** - * FootClass::Mission_Guard_Area -- Causes unit to guard an area about twice weapon range. * - * * - * This mission routine causes the unit to scan for targets out to twice its weapon range * - * from the home point. If a target was found, then it will be attacked. The unit will * - * chase the target until it gets up to to its weapon range from the home position. * - * In that case, it will return to home position and start scanning for another target. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with time delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - * 07/27/1995 JLB : Greatly simplified. * - *=============================================================================================*/ -int FootClass::Mission_Guard_Area(void) -{ - if (What_Am_I() == RTTI_UNIT && ((UnitClass *)this)->Class->IsToHarvest) { - Assign_Mission(MISSION_HARVEST); - return(1+Random_Pick(1, 10)); - } - - /* - ** Ensure that the archive target is valid. - */ - if (!Target_Legal(ArchiveTarget)) { - ArchiveTarget = ::As_Target(Coord_Cell(Coord)); - } - - /* - ** Make sure that the unit has not strayed too far from the home position. - ** If it has, then race back to it. - */ - int maxrange = MAX(Weapon_Range(0), Weapon_Range(1))+0x0100; - if (!Target_Legal(NavCom) && (Distance(ArchiveTarget) > maxrange || (!Target_Legal(TarCom) && Distance(ArchiveTarget) > 0x0200))) { - Assign_Target(TARGET_NONE); - Assign_Destination(ArchiveTarget); - } - - if (!Target_Legal(TarCom)) { - COORDINATE old = Coord; - Coord = As_Coord(ArchiveTarget); - Target_Something_Nearby(THREAT_AREA); - Coord = old; - if (Target_Legal(TarCom)) return(1); - Random_Animate(); - } else { - Approach_Target(); - } - return(TICKS_PER_SECOND+Random_Picky((int)0, (int)4, (char*)NULL, (int)0)); -} - - -/*********************************************************************************************** - * FootClass::Unlimbo -- Unlimbos object and performs special fixups. * - * * - * This routine will make sure that the home position for the foot class object gets * - * reset. This is necessary since the home position may change depending on the unit's * - * transition between limbo and non-limbo condition. * - * * - * INPUT: coord -- The coordinate to unlimbo the unit at. * - * * - * dir -- The initial direction to give the unit. * - * * - * OUTPUT: bool; Was the unit unlimboed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -bool FootClass::Unlimbo(COORDINATE coord, DirType dir) -{ - /* - ** Try to unlimbo the unit. - */ - if (TechnoClass::Unlimbo(coord, dir)) { - - /* - ** Mobile units are always revealed to the house that owns them. - */ - Revealed(House); - - /* - ** Start in a still (non-moving) state. - */ - Path[0] = FACING_NONE; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FootClass::Assign_Mission -- Assign mission to foot class object. * - * * - * When a new mission is assigned, any precalculated path should be truncated. This is * - * in anticipation that the new mission will result in a change of path. * - * * - * INPUT: order -- The new mission to assign to the unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -void FootClass::Assign_Mission(MissionType order) -{ - if (What_Am_I() != RTTI_UNIT || *(UnitClass*)this != UNIT_GUNBOAT) { - Path[0] = FACING_NONE; - } - TechnoClass::Assign_Mission(order); -} - - -/*********************************************************************************************** - * FootClass::Limbo -- Intercepts limbo event and handles FootClass processing. * - * * - * When an object of FootClass type is limboed, then it must be removed from any team * - * it may be a member of. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the object successfully limboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -bool FootClass::Limbo(void) -{ - if (!IsInLimbo) { - if (Team) { - Team->Remove(this); - } - } - return(TechnoClass::Limbo()); -} - - -/*********************************************************************************************** - * FootClass::Take_Damage -- Handles taking damage to this object. * - * * - * This routine intercepts the damage assigned to this object and if this object is * - * a member of a team, it informs the team that the damage has occurred. The team may * - * change it's priority or action based on this event. * - * * - * INPUT: damage -- The damage points inflicted on the unit. * - * * - * distance -- The distance from the point of damage to the unit itself. * - * * - * warhead -- The type of damage that is inflicted. * - * * - * source -- The purpitrator of the damage. By knowing who caused the damage, * - * the team know's who to "get even with". * - * * - * OUTPUT: Returns with the result type of the damage. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/30/1994 JLB : Created. * - *=============================================================================================*/ -ResultType FootClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - ResultType result = TechnoClass::Take_Damage(damage, distance, warhead, source); - - if (result != RESULT_NONE && Team) { - - if (GameToPlay != GAME_NORMAL || (source && !House->Is_Ally(source))) { - Team->Took_Damage(this, result, source); - } - - } else { - - if (result != RESULT_DESTROYED) { - /* - ** Determine if the target that is current being attacked has a weapon that can - ** do harm to a ground based unit. This information is needed so that an appropriate - ** response will occur when damage is taken. - */ - WeaponType weap = WEAPON_NONE; - if (As_Techno(TarCom)) { - weap = As_Techno(TarCom)->Techno_Type_Class()->Primary; - } - bool tweap = (weap != WEAPON_NONE && weap != WEAPON_NIKE); - - /* - ** This ensures that if a unit is in sticky mode, then it will snap out of - ** it when it takes damage. - */ - if (source && Mission == MISSION_STICKY) { - Enter_Idle_Mode(); - } - - /* - ** If this object is not part of a team and it can retaliate for the damage, then have - ** it try to do so. This prevents it from just sitting there and taking damage. - */ - if ( - source && - !House->Is_Ally(source) && - Techno_Type_Class()->Primary != WEAPON_NONE && - (source->What_Am_I() != RTTI_AIRCRAFT || BulletTypeClass::As_Reference(Weapons[Techno_Type_Class()->Primary].Fires).IsAntiAircraft) && - (!Target_Legal(TarCom) || ((!House->IsHuman || Special.IsSmartDefense) && (!tweap || !In_Range(TarCom)))) && -// !Target_Legal(NavCom) && - (Mission == MISSION_AMBUSH || - Mission == MISSION_GUARD || - Mission == MISSION_RESCUE || - Mission == MISSION_GUARD_AREA || - Mission == MISSION_ATTACK || - Mission == MISSION_TIMED_HUNT)) { - - /* - ** Assign the source of the damage as the new target. This occurs for the computer - ** controled units. For the player, this only occurs if the source of the damage - ** is within range. - */ - if (!House->IsHuman) { - - /* - ** If this unit is in TIMED_HUNT (multiplayer computer-controlled) - ** mode, "snap out of it" into HUNT mode; otherwise, assign - ** HUNT as the next mission through the normal mission queue. - */ - if (Mission == MISSION_TIMED_HUNT) { - Set_Mission(MISSION_HUNT); - } else { - Assign_Mission(MISSION_HUNT); - } - Assign_Target(source->As_Target()); - } else { - if (In_Range(source)) { - Assign_Target(source->As_Target()); - } else { - - /* - ** Simple retaliation cannot occur because the source of the damage - ** is too far away. If scatter logic is enabled, then scatter now. - */ - if (Special.IsScatter) { - Scatter(0, true); - } - } - } - } else { - - /* - ** If this object isn't doing anything important, then scatter. - */ - if (!IsDriving && !Target_Legal(TarCom) && !Target_Legal(NavCom) && Special.IsScatter && What_Am_I() != RTTI_AIRCRAFT) { - Scatter(0, true); - } - } - } - } - return(result); -} - - -/*********************************************************************************************** - * FootClass::Active_Click_With -- Intiates attack or move according to target clicked on. * - * * - * At this level, the object is known to have the ability to attack or move to the * - * target specified (in theory). Perform the attack or move as indicated. * - * * - * INPUT: target -- The target clicked upon that will precipitate action. * - * * - * OUTPUT: Returns with the type of action performed. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/06/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Active_Click_With(ActionType action, ObjectClass * object) -{ - switch (action) { - case ACTION_GUARD_AREA: - if (Can_Player_Fire() && Can_Player_Move()) { - Player_Assign_Mission(MISSION_GUARD_AREA, object->As_Target()); - } - break; - - case ACTION_SELF: - Player_Assign_Mission(MISSION_UNLOAD); - break; - - case ACTION_ATTACK: - if (Can_Player_Fire()) { - Player_Assign_Mission(MISSION_ATTACK, object->As_Target()); - } - break; - - case ACTION_ENTER: - if (Can_Player_Move() && object && object->Is_Techno() /*&& !((RadioClass *)object)->In_Radio_Contact()*/) { - Player_Assign_Mission(MISSION_ENTER, TARGET_NONE, object->As_Target()); - } - break; - - case ACTION_CAPTURE: - if (Can_Player_Move()) { - Player_Assign_Mission(MISSION_CAPTURE, TARGET_NONE, object->As_Target()); - } - break; - - case ACTION_SABOTAGE: - if (Can_Player_Move()) { - Player_Assign_Mission(MISSION_SABOTAGE, TARGET_NONE, object->As_Target()); - } - break; - - case ACTION_NOMOVE: - case ACTION_MOVE: - if (Can_Player_Move()) { - Player_Assign_Mission(MISSION_MOVE, TARGET_NONE, object->As_Target()); - } - break; - - case ACTION_NO_DEPLOY: - Speak(VOX_DEPLOY); - break; - - default: - break; - } -} - - -/*********************************************************************************************** - * FootClass::Active_Click_With -- Performs action as a result of left mouse click. * - * * - * This routine performs the action requested when the left mouse button was clicked over * - * a cell. Typically, this is just a move command. * - * * - * INPUT: action -- The predetermined action that should occur. * - * * - * cell -- The cell number that the action should occur at. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Active_Click_With(ActionType action, CELL cell) -{ - switch (action) { - case ACTION_HARVEST: - Player_Assign_Mission(MISSION_HARVEST, TARGET_NONE, ::As_Target(cell)); - break; - - case ACTION_MOVE: - if (AllowVoice) { - COORDINATE coord = Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()); - OutList.Add(EventClass(ANIM_MOVE_FLASH, PlayerPtr->Class->House, coord)); - } - // Fall into next case. - - case ACTION_NOMOVE: - //using function for IsVisible so we have different results for different players - JAS 2019/09/30 - if (What_Am_I() != RTTI_AIRCRAFT || Map[cell].Is_Visible(PlayerPtr)) { - Player_Assign_Mission(MISSION_MOVE, TARGET_NONE, ::As_Target(cell)); - } - break; - - case ACTION_ATTACK: - Player_Assign_Mission(MISSION_ATTACK, ::As_Target(cell)); - break; - - // MBL 05.15.2020 - Adding support for CTRL+ALT clicking the ground to have units move to an area and guard it - case ACTION_GUARD_AREA: - if (Can_Player_Fire() && Can_Player_Move()) { - Player_Assign_Mission(MISSION_GUARD_AREA, ::As_Target(cell)); - } - break; - // END MBL 05.15.2020 - } -} - - -/*********************************************************************************************** - * FootClass::Per_Cell_Process -- Perform action based on once-per-cell condition. * - * * - * This routine is called as this object moves from cell to cell. When the center of the * - * cell is reached, check to see if any trigger should be sprung. For moving units, reduce * - * the path to the distance to the target. This forces path recalculation in an effort to * - * avoid units passing each other. * - * * - * INPUT: center -- Is this the center of the cell? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - * 07/08/1995 JLB : Handles generic enter trigger event. * - * 07/16/1995 JLB : If next to a scanner and cloaked, then shimmer. * - *=============================================================================================*/ -void FootClass::Per_Cell_Process(bool center) -{ -// if (center) { - - /* - ** Clear any unloading flag if necessary. - */ - IsUnloading = false; - - /* - ** If adjacent to an enemy building that has the ability to reveal a stealth tank, - ** then shimmer the cloaked object. - */ - if (Cloak == CLOAKED) { - for (FacingType face = FACING_N; face < FACING_COUNT; face++) { - CELL cell = Adjacent_Cell(Coord_Cell(Coord), face); - - if (Map.In_Radar(cell)) { - TechnoClass const * techno = Map[cell].Cell_Techno(); - - if (techno && !House->Is_Ally(techno) && techno->Techno_Type_Class()->IsScanner) { - Do_Shimmer(); - break; - } - } - } - } - - /* - ** Shorten the path if the target is now within weapon range of this - ** unit and this unit is on an attack type mission. But only if the target - ** is slow enough for leading to make sense. - */ - if (What_Am_I() != RTTI_UNIT || *((UnitClass *)this) != UNIT_GUNBOAT) { - bool inrange = In_Range(TarCom); - TechnoClass const * techno = As_Techno(TarCom); - if (techno && techno->What_Am_I() != RTTI_BUILDING) { - FootClass const * foot = (FootClass const *)techno; - MPHType speed = ((TechnoTypeClass const &)techno->Class_Of()).MaxSpeed; - COORDINATE rangecoord = (speed > MPH_SLOW) ? foot->Likely_Coord() : foot->Target_Coord(); - inrange = In_Range(rangecoord); - } - - if (Target_Legal(TarCom) && (Mission == MISSION_RESCUE || Mission == MISSION_GUARD_AREA || Mission == MISSION_ATTACK || Mission == MISSION_HUNT) && inrange) { - Assign_Destination(TARGET_NONE); - Path[0] = FACING_NONE; - } - } - - /* - ** Trigger event associated with the player entering the cell. - */ - TriggerClass * trigger = Map[Coord_Cell(Coord)].Get_Trigger(); - if (Cloak != CLOAKED && trigger && trigger->House == Owner()) { - trigger->Spring(EVENT_PLAYER_ENTERED, Coord_Cell(Coord)); - } -// } - - TechnoClass::Per_Cell_Process(center); -} - - -/*************************************************************************** - * FootClass::Override_Mission -- temporarily overides a units mission * - * * - * * - * * - * INPUT: MissionType mission - the mission we want to overide * - * TARGET tarcom - the new target we want to overide * - * TARGET navcom - the new navigation point to overide * - * * - * OUTPUT: none * - * * - * WARNINGS: If a mission is already overidden, the current mission is * - * just re-assigned. * - * * - * HISTORY: * - * 04/28/1995 PWG : Created. * - *=========================================================================*/ -void FootClass::Override_Mission(MissionType mission, TARGET tarcom, TARGET navcom) -{ - SuspendedNavCom = NavCom; - TechnoClass::Override_Mission(mission, tarcom, navcom); - - Assign_Destination(navcom); -} - - -/*************************************************************************** - * FootClass::Restore_Mission -- Restores an overidden mission * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/28/1995 PWG : Created. * - *=========================================================================*/ -bool FootClass::Restore_Mission(void) -{ - if (TechnoClass::Restore_Mission()) { - Assign_Destination(SuspendedNavCom); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FootClass::Receive_Message -- Movement related radio messages are handled here. * - * * - * This routine handles radio message that are related to movement. These are used for * - * complex coordinated maneuvers. * - * * - * INPUT: from -- Pointer to the originator of this radio message. * - * * - * message -- The radio message that is being received. * - * * - * param -- The optional parameter (could be a movement destination). * - * * - * OUTPUT: Returns with the radio response appropriate to the message received. Usually the * - * response is RADIO_ROGER. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1995 JLB : Created. * - *=============================================================================================*/ -RadioMessageType FootClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - switch (message) { - - /* - ** Answers if this object is located on top of a service depot. - */ - case RADIO_ON_DEPOT: - if (Map[Coord_Cell(Center_Coord())].Cell_Building() != NULL) { - BuildingClass const * building = Map[Coord_Cell(Center_Coord())].Cell_Building(); - if (*building == STRUCT_REPAIR) { - return(RADIO_ROGER); - } - } - return(RADIO_NEGATIVE); - - /* - ** Intercept the repair request and if this object is moving, then no repair - ** is possible. - */ - case RADIO_REPAIR: - if (Target_Legal(NavCom)) return(RADIO_NEGATIVE); - break; - - /* - ** Something bad has happened to the object in contact with. Abort any coordinated - ** activity with this object. Basically, ... run away! Run away! - */ - case RADIO_RUN_AWAY: - if (In_Radio_Contact()) { - if (NavCom == Contact_With_Whom()->As_Target()) { - Assign_Destination(TARGET_NONE); - } - } - if (Mission == MISSION_SLEEP) { - Assign_Mission(MISSION_GUARD); - Commence(); - } - if (Mission == MISSION_ENTER) { - Assign_Mission(MISSION_GUARD); - } - if (!IsRotating && !Target_Legal(NavCom)) { - Scatter(0, true, true); - } - break; - - /* - ** Checks to see if this unit needs to move somewhere. If it is already in motion, - ** then it doesn't need furthur movement instructions. - */ - case RADIO_NEED_TO_MOVE: - param = (long)NavCom; - if (!Target_Legal(NavCom)) { - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - - /* - ** Radio request to move to location specified. Typically this is used - ** for complex loading and unloading missions. - */ - case RADIO_MOVE_HERE: - if (NavCom != (TARGET)param) { - if (::As_Target(Coord_Cell(Coord)) == (TARGET)param) { - return(RADIO_YEA_NOW_WHAT); - } else { - if (Mission == MISSION_GUARD && MissionQueue == MISSION_NONE) { - Assign_Mission(MISSION_MOVE); - } - Assign_Destination((TARGET)param); - } - } - return(RADIO_ROGER); - - /* - ** Requests if this unit is trying to cooperatively load up. Typically, this occurs - ** for passengers and when vehicles need to be repaired. - */ - case RADIO_TRYING_TO_LOAD: - if (Mission == MISSION_ENTER || MissionQueue == MISSION_ENTER) { - TechnoClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - } - break; - } - return(TechnoClass::Receive_Message(from, message, param)); -} - - -/*********************************************************************************************** - * FootClass::Mission_Enter -- Enter (cooperatively) mission handler. * - * * - * This mission handler will cooperatively coordinate the object to maneuver into the * - * object it is in radio contact with. This is used by infantry when they wish to load * - * into an APC as well as by vehicles when they wish to enter a repair facility. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of game ticks before this routine should be called again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/15/1995 JLB : Created. * - *=============================================================================================*/ -int FootClass::Mission_Enter(void) -{ - /* - ** Find out who to coordinate with. If in radio contact, then this the transporter is - ** defined. If not in radio contact, then try the archive target value to see if that - ** is suitable. - */ - TechnoClass * contact = Contact_With_Whom(); - if (contact == NULL) { - contact = As_Techno(ArchiveTarget); - } - if (contact == NULL) { - contact = As_Techno(NavCom); - } - - /* - ** If in contact, then let the transporter handle the movement coordination. - */ - if (contact != NULL) { - - /* - ** If the transport says to "bug off", then abort the enter mission. The transport may - ** likely say all is 'ok' with the "RADIO ROGER", then try again later. - */ - if (Transmit_Message(RADIO_DOCKING, contact) != RADIO_ROGER && !IsTethered) { - Transmit_Message(RADIO_OVER_OUT); - Enter_Idle_Mode(); - } - - } else { - - /* - ** Since there is no potential object to enter, then abort this - ** mission with some default standby mission. - */ - ArchiveTarget = TARGET_NONE; - Enter_Idle_Mode(); - } - return(TICKS_PER_SECOND/2); -} - - -/*********************************************************************************************** -z * FootClass::Assign_Destination -- Assigns specified destination to NavCom. * - * * - * This routine will assign the specified target to the navigation computer. No legality * - * checks are performed. * - * * - * INPUT: target -- The target value to assign to the navigation computer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Assign_Destination(TARGET target) -{ - NavCom = target; -} - - -/*********************************************************************************************** - * FootClass::Detach_All -- Removes this object from the game system. * - * * - * This routine will remove this object from the game system. This routine is called when * - * this object is about to be deleted. All other objects should no longer reference this * - * object in that case. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Detach_All(bool all) -{ - if (Team) Team->Remove(this); - Team = NULL; - - TechnoClass::Detach_All(all); -} - - -/*********************************************************************************************** - * FootClass::Rescue_Mission -- Calls this unit to the rescue. * - * * - * This routine is called when the house determines that it should attack the specified * - * target. This routine will determine if it can attack the target specified and if so, * - * the amount of power it can throw at it. This returned power value is used to allow * - * intelligent distribution of retaliation. * - * * - * INPUT: target -- The target that this object just might be assigned to attack and thus * - * how much power it can bring to bear should be returned. * - * * - * OUTPUT: Returns with the amount of power that this object can bring to bear against the * - * potential target specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -int FootClass::Rescue_Mission(TARGET tarcom) -{ - /* - ** If the target specified is not legal, then it cannot be attacked. Always return - ** zero in this case. - */ - if (!Target_Legal(tarcom)) return(0); - - /* - ** If the unit is already assigned to destroy the tarcom then we need - ** to return a negative value which tells the computer to lower the - ** desired threat rating. - */ - if (TarCom == tarcom) { - return(-Risk()); - } - - /* - ** If the unit is currently attacking a target that has a weapon then we - ** cannot abandon it as it will destroy us if we return to base. - */ - if (Target_Legal(TarCom)) { - TechnoClass * techno = As_Techno(TarCom); - if (techno && techno->Techno_Type_Class()->Primary != WEAPON_NONE) { - return(0); - } - } - - /* - ** If the unit is in a harvest mission or is currently attacking - ** something, or is not very effective, then it will be of no help - ** at all. - */ - if (Team || Mission == MISSION_HARVEST || !Risk()) { - return(0); - } - - /* - ** Find the distance to the target modified by the range. If the - ** the distance is 0, then things are ok. - */ - int dist = Distance(tarcom) - Weapon_Range(0); - int threat = Risk() * 256; - int speed = -1; - if (dist > 0) { - - /* - ** Next we need to figure out how fast the unit moves because this - ** decreases the distance penalty. - */ - speed = Max((unsigned)Techno_Type_Class()->MaxSpeed, (unsigned)1); - - int ratio = (speed > 0) ? Max(dist / speed, 1) : 1; - - /* - ** Finally modify the threat by the distance the unit is away. - */ - threat = Max(threat/ratio, 1); - } - return(threat); -} - - -/*********************************************************************************************** - * FootClass::Death_Announcement -- Announces the death of a unit. * - * * - * This routine is called when a unit (infantry, vehicle, or aircraft) is destroyed. * - * * - * INPUT: source -- The purpetrator of this death. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/01/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Death_Announcement(TechnoClass const * source) const -{ - // Changed for multiplayer. ST - 3/13/2019 5:36PM - if ((GameToPlay == GAME_GLYPHX_MULTIPLAYER && House->IsHuman) || (GameToPlay != GAME_GLYPHX_MULTIPLAYER && Is_Discovered_By_Player() || Is_Owned_By_Player())) { // ST - //if (Is_Discovered_By_Player() || Is_Owned_By_Player()) { - //if (IsDiscoveredByPlayer || IsOwnedByPlayer) { - if (!source || source->What_Am_I() != RTTI_INFANTRY || *((InfantryClass const *)source) != INFANTRY_RAMBO) { - if (What_Am_I() == RTTI_INFANTRY && ((InfantryTypeClass const &)Class_Of()).IsCivilian && !((InfantryClass *)this)->IsTechnician) { - // if (Options.IsDeathAnnounce) Speak(VOX_DEAD_CIV); // MBL 02.06.2020 - if (Options.IsDeathAnnounce) Speak(VOX_DEAD_CIV, House, Center_Coord()); - } - else { - if (House != PlayerPtr && GameToPlay != GAME_NORMAL) { - // if (Options.IsDeathAnnounce) Speak(VOX_ENEMY_UNIT); // MBL 02.06.2020 - if (Options.IsDeathAnnounce) Speak(VOX_ENEMY_UNIT, House); - } - else { - if (((GameToPlay == GAME_GLYPHX_MULTIPLAYER && House->IsHuman) || House == PlayerPtr) || Options.IsDeathAnnounce) { // ST - if (!Options.IsDeathAnnounce) { // MBL 02.06.2020 - // Speak(VOX_UNIT_LOST); - Speak(VOX_UNIT_LOST, House, Center_Coord()); - } - else { - switch (House->ActLike) { - case HOUSE_GOOD: - // Speak(VOX_DEAD_GDI); // MBL 02.06.2020 - Speak(VOX_DEAD_GDI, House, Center_Coord()); - break; - - case HOUSE_BAD: - // Speak(VOX_DEAD_NOD); // MBL 02.06.2020 - Speak(VOX_DEAD_NOD, House, Center_Coord()); - break; - - default: - break; - } - } - } - } - } - } - } -} - - -/*********************************************************************************************** - * FootClass::Greatest_Threat -- Fetches the greatest threat to this object. * - * * - * This routine will return with the greatest threat (best target) for this object. For * - * movable ground object, they won't automatically return ANY target if this object is * - * cloaked. Otherwise, cloaking is relatively useless. * - * * - * INPUT: method -- The request method (bit flags) to use when scanning for a target. * - * * - * OUTPUT: Returns with the best target to attack. If there is no target that qualifies, then * - * TARGET_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -TARGET FootClass::Greatest_Threat(ThreatType method) const -{ - /* - ** If this object can cloak, then it won't select a target automatically. - */ - if (House->IsHuman && IsCloakable && Mission == MISSION_GUARD) { - return(TARGET_NONE); - } - - if (Techno_Type_Class()->Primary != WEAPON_NONE && BulletTypeClass::As_Reference(Weapons[Techno_Type_Class()->Primary].Fires).IsAntiAircraft) { - method = method | THREAT_AIR; - } - if (Techno_Type_Class()->Secondary != WEAPON_NONE && BulletTypeClass::As_Reference(Weapons[Techno_Type_Class()->Secondary].Fires).IsAntiAircraft) { - method = method | THREAT_AIR; - } - - return(TechnoClass::Greatest_Threat(method|THREAT_GROUND)); -} - - -/*********************************************************************************************** - * FootClass::Detach -- Detaches a target from tracking systems. * - * * - * This routine will detach the specified target from the tracking systems of this object. * - * It will be removed from the navigation computer and any queued mission record. * - * * - * INPUT: target -- The target to be removed from this object. * - * * - * all -- Is the unit really about to be eliminated? If this is true then even * - * friendly contact (i.e., radio) must be eliminated. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Detach(TARGET target, bool all) -{ - TechnoClass::Detach(target, all); - - if (!SpecialFlag) { - if (ArchiveTarget == target) { - ArchiveTarget = TARGET_NONE; - } - } - - if (SuspendedNavCom == target) { - SuspendedNavCom = TARGET_NONE; - SuspendedMission = MISSION_NONE; - } - - /* - ** If the navigation computer is assigned to the target, then the navigation - ** computer must be cleared. - */ - if (NavCom == target) { - NavCom = TARGET_NONE; - Path[0] = FACING_NONE; - Restore_Mission(); - } - - /* - ** If targeting the specified object and this unit is obviously heading - ** toward the target to get within range, then abort the path. - */ - if (TarCom == target && House->IsHuman) { - Path[0] = FACING_NONE; - } -} - - -/*********************************************************************************************** - * FootClass::Offload_Tiberium_Bail -- Fetches the Tiberium to offload per step. * - * * - * This routine is called when a packet/package/bail of Tiberium needs to be offloaded * - * from the object. This function is overridden for those objects that can contain * - * Tiberium. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of credits offloaded from the object. * - * * - * WARNINGS: This routine must be called multiple times in order to completely offload the * - * Tiberium. When this routine return 0, all Tiberium has been offloaded. * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -int FootClass::Offload_Tiberium_Bail(void) -{ - return(0); -} - - -/*********************************************************************************************** - * FootClass::Can_Enter_Cell -- Checks to see if the object can enter cell specified. * - * * - * This routine examines the specified cell to see if the object can enter it. This * - * function is to be overridden for objects that could have the possibility of not being * - * allowed to enter the cell. Typical objects at the FootClass level always return * - * MOVE_OK. * - * * - * INPUT: cell -- The cell to examine. * - * * - * facing -- The direction that this cell might be entered from. * - * * - * OUTPUT: Returns with the move check result type. This will be MOVE_OK if there is not * - * blockage. There are various other values that represent other blockage types. * - * The value returned will indicatd the most severe reason why entry into the cell * - * is blocked. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -MoveType FootClass::Can_Enter_Cell(CELL , FacingType) const -{ - return MOVE_OK; -} - - -/*********************************************************************************************** - * FootClass::Can_Demolish -- Checks to see if this object can be sold back. * - * * - * This routine determines if it is legal to sell the object back. A foot class object can * - * only be sold back if it is sitting on a repair bay. * - * * - * INPUT: none * - * * - * OUTPUT: Was the object successfully sold back? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -bool FootClass::Can_Demolish(void) const -{ - switch (What_Am_I()) { - case RTTI_UNIT: - case RTTI_AIRCRAFT: - if (In_Radio_Contact() && - Contact_With_Whom()->What_Am_I() == RTTI_BUILDING && - *((BuildingClass *)Contact_With_Whom()) == STRUCT_REPAIR && - Distance(Contact_With_Whom()) < 0x0080) { - - return(true); - } - break; - - default: - break; - } - return(TechnoClass::Can_Demolish()); -} - - -/*********************************************************************************************** - * FootClass::Sell_Back -- Causes this object to be sold back. * - * * - * When an object is sold back, a certain amount of money is refunded to the owner and then * - * the object is removed from the game system. * - * * - * INPUT: control -- The action to perform. The only supported action is "1", which means * - * to sell back. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -void FootClass::Sell_Back(int control) -{ - if (control != 0) { - if (House == PlayerPtr) { - Sound_Effect(VOC_CASHTURN); - } - House->Refund_Money(Refund_Amount()); - Stun(); - Limbo(); - Delete_This(); - } -} - - -/*********************************************************************************************** - * FootClass::Likely_Coord -- Fetches the coordinate the object will be at shortly. * - * * - * This routine comes in handy when determining where a travelling object will be at * - * when considering the amount of time it would take for a normal unit to travel one cell. * - * Using this information, an intelligent "approach target" logic can be employed. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate the object is at or soon will be. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE FootClass::Likely_Coord(void) const -{ - if (Head_To_Coord()) { - return(Head_To_Coord()); - } - return(Target_Coord()); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/FOOT.H b/code/TIBERIANDAWN/FOOT.H deleted file mode 100644 index 3a76c2e..0000000 --- a/code/TIBERIANDAWN/FOOT.H +++ /dev/null @@ -1,304 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\foot.h_v 2.20 16 Oct 1995 16:47:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FOOT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 14, 1994 * - * * - * Last Update : April 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FOOT_H -#define FOOT_H - -#include "target.h" -#include "type.h" -#include "techno.h" -#include "ftimer.h" - -class UnitClass; -class BuildingClass; - - -/**************************************************************************** -** Movable objects are handled by this class definition. Moveable objects -** cover everything except buildings. -*/ -class FootClass : public TechnoClass -{ - public: - /* - ** If this unit has officially joined the team's group, then this flag is - ** true. A newly assigned unit to a team is not considered part of the - ** team until it actually reaches the location where the team is. By - ** using this flag, it allows a team to continue to intelligently attack - ** a target without falling back to regroup the moment a distant member - ** joins. - */ - unsigned IsInitiated:1; - - /* - ** When the player gives this object a navigation target AND that target - ** does not result in any movement of the unit, then a beep should be - ** sounded. This typically occurs when selecting an invalid location for - ** movement. This flag is cleared if any movement was able to be performed. - ** It never gets set for computer controlled units. - */ - unsigned IsNewNavCom:1; - - /* - ** There are certain cases where a unit should perform a full scan rather than - ** the more efficient "ring scan". This situation occurs when a unit first - ** appears on the map or when it finishes a multiple cell movement track. - */ - unsigned IsPlanningToLook:1; - - /* - ** Certain units have the ability to metamorphize into a building. When this - ** operation begins, certain processes must occur. During these operations, this - ** flag will be true. This ensures that any necessary special case code gets - ** properly executed for this unit. - */ - unsigned IsDeploying:1; - - /* - ** This flag tells the system that the unit is doing a firing animation. This is - ** critical to the firing logic. - */ - unsigned IsFiring:1; - - /* - ** This unit could be either rotating its body or rotating its turret. During the - ** process of rotation, this flag is set. By examining this flag, unnecessary logic - ** can be avoided. - */ - unsigned IsRotating:1; - - /* - ** If this object is current driving to a short range destination, this flag is - ** true. A short range destination is either the next cell or the end of the - ** current "curvy" track. An object that is driving is not allowed to do anything - ** else until it reaches its destination. The exception is when infantry wish to - ** head to a different destination, they are allowed to start immediately. - */ - unsigned IsDriving:1; - - /* - ** If this object is unloading from a hover transport, then this flag will be - ** set to true. This handles the unusual case of an object disembarking from the - ** hover lander yet not necessarily tethered but still located in an overlapping - ** position. This flag will be cleared automatically when the object moves to the - ** center of a cell. - */ - unsigned IsUnloading:1; - - /* - ** This is the "throttle setting" of the unit. It is a fractional value with 0 = stop - ** and 255 = full speed. - */ - unsigned char const Speed; - - /* - ** - ** This is the desired destination of the unit. The unit will attempt to head - ** toward this target (avoiding intervening obstacles). - */ - TARGET NavCom; - TARGET SuspendedNavCom; - - /* - ** This points to the team that "owns" this object. This pointer is used to - ** quickly process the team when this object is the source of the change. An - ** example would be if this object were to be destroyed, it would inform the - ** team of this fact by using this pointer. - */ - TeamClass * Team; - - /* - ** If this object is part of a pseudo-team that the player is managing, then - ** this will be set to the team number (0 - 9). If it is not part of any - ** pseudo-team, then the number will be -1. - */ - unsigned char Group; - - /* - ** This points to the next member in the team that this object is part of. This - ** is used to quickly process each team member when the team class is the source - ** of the change. An example would be if the team decided that everyone is going - ** to move to a new location, it would inform each of the objects by chaining - ** through this pointer. - */ - FootClass * Member; - - /* - ** Since all objects derived from this class move according to a path list. - ** This is the path list. It specifies, as a simple list of facings, the - ** path that the object should follow in order to reach its destination. - ** This path list is limited in size, so it might require several generations - ** of path lists before the ultimate destination is reached. The game logic - ** handles regenerating the path list as necessary. - */ - FacingType Path[CONQUER_PATH_MAX]; - - /* - ** When there is a complete findpath failure, this timer is initialized so - ** that a findpath won't be calculated until this timer expires. - */ - TCountDownTimerClass PathDelay; - enum {PATH_DELAY=15,PATH_RETRY=10}; - int TryTryAgain; // Number of retry attempts remaining. - - /* - ** If the object has recently attacked a base, then this timer will not - ** have expired yet. It is used so a building does not keep calling - ** for help from the same attacker. - */ - TCountDownTimerClass BaseAttackTimer; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - FootClass(void); - virtual ~FootClass(void); - FootClass(HousesType house); - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - bool Basic_Path(void); - - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual bool Can_Demolish(void) const; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Sort_Y(void) const; - virtual COORDINATE Likely_Coord(void) const; - - /* - ** Driver control support functions. These are used to control cell - ** occupation flags and driver instructions. - */ - COORDINATE Head_To_Coord(void) const {return (HeadToCoord);}; - virtual bool Start_Driver(COORDINATE &headto); - virtual bool Stop_Driver(void); - virtual void Assign_Destination(TARGET target); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual bool Unlimbo(COORDINATE , DirType dir = DIR_N); - virtual bool Limbo(void); - virtual bool Mark(MarkType mark); - - /* - ** User I/O. - */ - virtual void Active_Click_With(ActionType action, ObjectClass * object); - virtual void Active_Click_With(ActionType action, CELL cell); - - /* - ** Combat related. - */ - virtual void Stun(void); - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source=0); - virtual void Death_Announcement(TechnoClass const * source=0) const; - - /* - ** AI. - */ - virtual void Sell_Back(int control); - virtual int Offload_Tiberium_Bail(void); - virtual TARGET Greatest_Threat(ThreatType method) const; - virtual void Detach(TARGET target, bool all); - virtual void Detach_All(bool all=true); - virtual void Assign_Mission(MissionType order); - virtual int Mission_Enter(void); - virtual int Mission_Move(void); - virtual int Mission_Capture(void); - virtual int Mission_Attack(void); - virtual int Mission_Guard(void); - virtual int Mission_Hunt(void); - virtual int Mission_Timed_Hunt(void); - virtual int Mission_Guard_Area(void); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** Movement and animation. - */ - virtual void Per_Cell_Process(bool center); - virtual void Approach_Target(void); - virtual void Fixup_Path(PathType *) {}; - virtual void Set_Speed(int speed); - virtual MoveType Can_Enter_Cell(CELL , FacingType =FACING_NONE) const; - int Optimize_Moves(PathType *path, MoveType threshhold); - virtual void Override_Mission(MissionType mission, TARGET tarcom, TARGET navcom); - virtual bool Restore_Mission(void); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - CELL Safety_Point(CELL src, CELL dst, int start, int max); - int Rescue_Mission(TARGET tarcom); - - private: - int Passable_Cell(CELL cell, FacingType face, int threat, MoveType threshhold); - PathType * Find_Path(CELL dest, FacingType *final_moves, int maxlen, MoveType threshhold); - void Debug_Draw_Map(char *txt, CELL start, CELL dest, bool pause); - void Debug_Draw_Path(PathType *path); - bool Follow_Edge(CELL start, CELL target, PathType *path, FacingType search, FacingType olddir, int threat, int threat_stage, int max_cells, MoveType threshhold); - bool Register_Cell(PathType *path, CELL cell, FacingType dir, int cost, MoveType threshhold); - bool Unravel_Loop(PathType *path, CELL &cell, FacingType &dir, int sx, int sy, int dx, int dy, MoveType threshhold); - - /* - ** This is the coordinate that the unit is heading to - ** as an immediate destination. This coordinate is never further - ** than once cell (or track) from the unit's location. When this coordinate - ** is reached, then the next location in the path list becomes the - ** next HeadTo coordinate. - */ - COORDINATE HeadToCoord; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[16]; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/FTIMER.H b/code/TIBERIANDAWN/FTIMER.H deleted file mode 100644 index d3a3bc7..0000000 --- a/code/TIBERIANDAWN/FTIMER.H +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ftimer.h_v 2.14 16 Oct 1995 16:47:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FTIMER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/16/95 * - * * - * Last Update : March 16, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FTIMER_H -#define FTIMER_H - -/* -** This timer class is based around an external tick system. As such, it is inherently -** in sync with any connected system (through network or modem) that also keeps the external -** tick system in sync. The game frame number is a good sync value. -*/ -class TCountDownTimerClass { - public: - // Constructor. Timers set before low level init has been done will not - // be able to be 'Started' or 'on' until timer system is in place. - TCountDownTimerClass(long set=0) { - Set(set); - }; - - // No destructor. - ~TCountDownTimerClass(void) {} - - operator long(void) const {return Time();}; - - // Public functions - void Set(long set) { - Started = Frame; - DelayTime = set; - }; // Set count down value. - - void Clear(void) { - Started = -1; - DelayTime = 0; - }; - long Get_Start(void) const { - return(Started); - }; - long Get_Delay(void) const { - return(DelayTime); - }; - bool Active(void) const { - return(Started != -1); - }; - int Expired(void) const {return (Time() == 0);}; - long Time(void) const { - long remain = DelayTime - (Frame-Started); - if (remain < 0) remain = 0; - return(remain); - }; // Fetch current count down value. - - protected: - long Started; // Initial frame time start. - long DelayTime; // Ticks remaining before countdown timer expires. -}; - - -#endif diff --git a/code/TIBERIANDAWN/FUNCTION.H b/code/TIBERIANDAWN/FUNCTION.H deleted file mode 100644 index 3d07eb8..0000000 --- a/code/TIBERIANDAWN/FUNCTION.H +++ /dev/null @@ -1,983 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\function.h_v 2.21 16 Oct 1995 16:46:44 JOE_BOSTIC $*/ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FUNCTION.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 27, 1994 * - * * - * Last Update : May 27, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FUNCTION_H -#define FUNCTION_H - -#ifdef NEVER -Map (screen) class heirarchy. - - MapeditClass (most derived class) -- scenario editor - ³ - MouseClass -- handles mouse animation and display control - ³ - ScrollClass -- map scroll handler - ³ - HelpClass -- pop-up help text handler - ³ - TabClass -- file folder tab screen mode control dispatcher - ³ - SidebarClass -- displays and controls construction list sidebar - ³ - PowerClass -- display power production/consumption bargraph - ³ - RadarClass -- displays and controls radar map - ³ - DisplayClass -- general tactical map display handler - ³ - MapClass -- general tactical map data handler - ³ - GScreenClass (pure virtual base class) -- generic screen control - - AbstractClass - ³ - ³ - ³ - ³ - ObjectClass - ³ - ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄ¿ - AnimClass ³ TemplateClass ³ ÃÄ FuseClass ³ TerrainClass - ³ ³ ÃÄ FlyClass ³ - ³ ³ BulletClass ³ - OverlayClass MissionClass SmudgeClass - ³ - RadioClass - ³ - ÃÄ CrewClass - ÃÄ FlasherClass - ÃÄ StageClass - ÃÄ CargoClass - TechnoClass - ³ - ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - FootClass BuildingClass - ³ - ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - DriveClass InfantryClass ÃÄ FlyClass - ³ AircraftClass - TurretClass - ³ - TarComClass - ³ - UnitClass - - - AbstractTypeClass - ³ - ObjectTypeClass - ³ - ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - ³ ³ ³ ³ - TechnoTypeClass ³ ³ ³ - ³ BulletTypeClass ³ ³ - ³ TemplateTypeClass ³ - ÚÄÄÄÄÄÄÄÄÁÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ TerrainTypeClass - ³ ³ ³ ³ -UnitTypeClass ³ BuildingTypeClass ³ - ³ InfantryTypeClass - AircraftTypeClass -#endif - -/* -** The "bool" integral type was defined by the C++ comittee in -** November of '94. Until the compiler supports this, use the following -** definition. -*/ -#if (0) -#ifndef TRUE_FALSE_DEFINED -enum {false=0,true=1}; -typedef int bool; -#define TRUE_FALSE_DEFINED -#endif //TRUE_FALSE_DEFINED -#endif - -//#define _WIN32 -//#define WIN32 =1 //_LEAN_AND_MEAN -#include - - -/********************************************************************** -** If the following define is enabled, then the memory checking code -** will be disabled. -*/ -#define NOMEMCHECK - -#include "watcom.h" -#define FILE_H -#define WWMEM_H -#include "compat.h" -#include "rawfile.h" -#include "wwlib32.h" -#include "jshell.h" - - - -// Should be part of WWLIB.H. This is used in JSHELL.CPP. -typedef struct { - unsigned char SourceColor; - unsigned char DestColor; - unsigned char Fading; - unsigned char reserved; -} TLucentType; - - -// Don't complain if these headers aren't referenced. -#include -#include -#include -#include -//#include -//#include -#include -#include -#include -#include -#include -//#include - -/* -** VQ player specific includes. -*/ -//#include -//#include - -extern bool GameActive; -extern long LParam; - -#include "vector.h" -#include "heap.h" -#include "ccfile.h" -#include "monoc.h" -#include "conquer.h" -//#include "debug.h" -#include "special.h" -#include "defines.h" - - -/* -** Greenleaf specific includes. -*/ -//#include -//#include - - -extern long Frame; -inline CELL Coord_XCell(COORDINATE coord) {return (CELL)(*(((unsigned char*)&coord)+1));} -inline CELL Coord_YCell(COORDINATE coord) {return (CELL)(*(((unsigned char*)&coord)+3));} -//inline CELL Coord_Cell(COORD coord){return (CELL)(((*(((unsigned short *)&coord)+1) & 0xFF00) >> 2) | *(((unsigned char *)&coord)+1));} -#if (0) -__cdecl CELL Coord_Cell(COORDINATE coord); -#pragma aux Coord_Cell parm [eax] \ - modify [ebx] \ - value [ax] = \ - "mov ebx,eax" \ - "shr eax,010h" \ - "xor al,al" \ - "shr eax,2" \ - "or al,bh" -#endif -CELL __cdecl Coord_Cell(COORDINATE coord); - -#include "rules.h" -#include "utracker.h" -#include "facing.h" -#include "ftimer.h" -#include "theme.h" -#include "link.h" -#include "gadget.h" -#include "control.h" -#include "toggle.h" -#include "checkbox.h" -#include "shapebtn.h" -#include "textbtn.h" -#include "slider.h" -#include "list.h" -#include "cheklist.h" -#include "colrlist.h" -#include "edit.h" -#include "gauge.h" -#include "msgbox.h" -#include "dial8.h" -#include "txtlabel.h" -#include "super.h" -#include "house.h" -#include "gscreen.h" -#include "map.h" -#include "display.h" -#include "radar.h" -#include "power.h" -#include "sidebar.h" -#include "tab.h" -#include "help.h" -#include "mouse.h" -//#include "mapedit.h" -#include "help.h" -#include "target.h" -#include "theme.h" -#include "team.h" // Team objects. -#include "teamtype.h" // Team type objects. -#include "trigger.h" // Trigger event objects. -#include "mapedit.h" // ??? -#include "abstract.h" -#include "object.h" -#include "mission.h" -#include "door.h" -#include "bullet.h" // Bullet objects. -#include "terrain.h" // Terrain objects. -#include "anim.h" // Animation objects. -#include "template.h" // Icon template objects. -#include "overlay.h" // Overlay objects. -#include "smudge.h" // Stains on the terrain objects. -#include "aircraft.h" // Aircraft objects. -#include "unit.h" // Ground unit objects. -#include "infantry.h" // Infantry objects. -#include "credits.h" // Credit counter class. -#include "score.h" // Scoring system class. -#include "factory.h" // Production manager class. -#include "intro.h" -#include "ending.h" -#include "logic.h" -#include "queue.h" -#include "event.h" -#include "base.h" // defines the AI's pre-built base -#include "ipxmgr.h" -#include "combuf.h" -#include "connect.h" -#include "connmgr.h" -#include "noseqcon.h" -#include "msglist.h" -//#include "nullconn.h" -//#include "nullmgr.h" -//#include "phone.h" -#include "loaddlg.h" -#include "ipxaddr.h" -#include "FACINGFF.h" -/**************************************************************************** -** This is a "node", used for the lists of available games & players. The -** 'Game' structure is used for games; the 'Player' structure for players. -*/ -typedef struct NodeNameTag { - char Name[MPLAYER_NAME_MAX]; - IPXAddressClass Address; - union { - struct { - int Version; - unsigned char IsOpen; - unsigned long LastTime; - } Game; - struct { - HousesType House; - unsigned char Color; - } Player; - }; -} NodeNameType; - - -#include "externs.h" - - -extern int Get_CD_Drive(void); -extern void Fatal(char const *message, ...); - - -/* -** ANIM.CPP -*/ -void Shorten_Attached_Anims(ObjectClass * obj); - -/* -** AUDIO.CPP -*/ -int Sound_Effect(VocType voc, VolType volume, int variation=1, signed short panvalue=0); -// void Speak(VoxType voice); // MBL 02.06.2020 -void Speak(VoxType voice, HouseClass *house=NULL, COORDINATE coord=0); -void Speak_AI(void); -void Stop_Speaking(void); -void Sound_Effect(VocType voc, COORDINATE coord=NULL, int variation=1); -bool Is_Speaking(void); - -/* -** COMBAT.CPP -*/ -int Modify_Damage(int damage, WarheadType warhead, ArmorType armor, int distance); -void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass * source, WarheadType warhead); - -/* -** CONQUER.CPP -*/ -void Center_About_Objects(void); -bool Force_CD_Available(int cd); -void Handle_View(int view, int action=0); -void Handle_Team(int team, int action=0); -TechnoTypeClass const * Fetch_Techno_Type(RTTIType type, int id); -char const * Fading_Table_Name(char const * base, TheaterType theater); -void Unselect_All(void); -void Unselect_All_Except(ObjectClass* object); -void Play_Movie(char const * name, ThemeType theme=THEME_NONE, bool clrscrn=true); -bool Main_Loop(); -TheaterType Theater_From_Name(char const *name); -//DirType Rotation_Calc(DirType current, DirType desired, int rate); -void Main_Game(int argc, char *argv[]); -long VQ_Call_Back(unsigned char * buffer=NULL, long frame=0); -void Call_Back(void); -char const *Language_Name(char const *basename); -SourceType Source_From_Name(char const *name); -char const *Name_From_Source(SourceType source); -FacingType KN_To_Facing(int input); -void const *Get_Radar_Icon(void const *shapefile, int shapenum, int frames, int zoomfactor); -void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata=0, void const * ghostdata=0); - -// Added for draw intercept. ST - 1/17/2019 12:31PM -void CC_Draw_Shape(ObjectClass *object, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata=0, void const * ghostdata=0, int scale=0x100); -void CC_Draw_Shape(ObjectClass *object, const char *shape_file_name, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata = 0, void const * ghostdata = 0, char override_owner = HOUSE_NONE); - -// Added for pip draw intercept - SKY -void CC_Draw_Pip(ObjectClass *object, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata=0, void const * ghostdata=0); - -// Added for line draw intercept (ex. Obelisk laser) - SKY -void CC_Draw_Line(int x, int y, int x1, int y1, unsigned char color, int frame, WindowNumberType window); - -void Go_Editor(bool flag); -//long MixFileHandler(VQAHandle *vqa, long action, void *buffer, long nbytes); - -char *CC_Get_Shape_Filename(void const *shapeptr ); -void CC_Add_Shape_To_Global(void const *shapeptr, char *filename, char code ); - -void Bubba_Print(char *format,...); - -void Heap_Dump_Check( char *string ); -void Dump_Heap_Pointers( void ); -unsigned long Disk_Space_Available(void); - -void Validate_Error(char *name); -void const * Hires_Retrieve(char *name); -int Get_Resolution_Factor(void); - -void Shake_The_Screen(int shakes, HousesType house = HOUSE_NONE); - - -/* -** INTERPAL.CPP -*/ -#define SIZE_OF_PALETTE 256 -extern "C" unsigned char *InterpolationPalette; -extern BOOL InterpolationPaletteChanged; -extern void Interpolate_2X_Scale( GraphicBufferClass *source, GraphicViewPortClass *dest ,char const *palette_file_name); -void Read_Interpolation_Palette (char const *palette_file_name); -void Write_Interpolation_Palette (char const *palette_file_name); -void Increase_Palette_Luminance(unsigned char *InterpolationPalette , int RedPercentage ,int GreenPercentage ,int BluePercentage ,int cap); -extern "C"{ - extern unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE]; - extern unsigned char *InterpolationPalette; - void __cdecl Asm_Create_Palette_Interpolation_Table(void); -} - - -/* -** COORD.CPP -*/ -void Move_Point(short &x, short &y, register DirType dir, unsigned short distance); -COORDINATE Adjacent_Cell(COORDINATE coord, FacingType dir); -COORDINATE Coord_Move(COORDINATE start, DirType facing, unsigned short distance); -COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock=false); -DirType Direction(CELL cell1, CELL cell2); -DirType Direction(COORDINATE coord1, COORDINATE coord2); -DirType Direction256(COORDINATE coord1, COORDINATE coord2); -DirType Direction8(COORDINATE coord1, COORDINATE coord2); -int Distance(CELL coord1, CELL coord2); -int Distance(COORDINATE coord1, COORDINATE coord2); -short const * Coord_Spillage_List(COORDINATE coord, int maxsize); -//void Move_Point(unsigned short &x, unsigned short &y, DirType dir, unsigned short distance); - -/* -** COORDA.CPP -*/ -//extern "C" { -//unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal); -//unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed); -//} - -/* -** DEBUG.CPP -*/ -void Log_Event(char const *text, ...); -void Debug_Key(unsigned input); -void Self_Regulate(void); - -/* -** DIALOG.CPP -*/ -int Format_Window_String(char * string, int maxlinelen, int & width, int & height); -extern void Dialog_Box(int x, int y, int w, int h); -void Conquer_Clip_Text_Print(char const *, unsigned x, unsigned y, unsigned fore, unsigned back=(unsigned)TBLACK, TextPrintType flag=TPF_8POINT|TPF_DROPSHADOW, unsigned width=-1, int const * tabs=0); -void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled); -int __cdecl Dialog_Message(char *errormsg, ...); -void Window_Box(WindowNumberType window, BoxStyleEnum style); -void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...); -void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...); -void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag); - -/* -** DISPLAY.CPP -*/ -ObjectClass* Best_Object_With_Action(DynamicVectorClass& objects, ObjectClass* object); -ObjectClass* Best_Object_With_Action(DynamicVectorClass& objects, CELL cell); - -ActionType Best_Object_Action(DynamicVectorClass& objects, ObjectClass* object); -ActionType Best_Object_Action(DynamicVectorClass& objects, CELL cell); - -ObjectClass* Best_Object_With_Action(ObjectClass* object); -ObjectClass* Best_Object_With_Action(CELL cell); - -ActionType Best_Object_Action(ObjectClass* object); -ActionType Best_Object_Action(CELL cell); - -/* -** ENDING.CPP -*/ -void GDI_Ending(void); -void Nod_Ending(void); - -/* -** EXPAND.CPP -*/ -bool Expansion_Present(void); -bool Expansion_Dialog(void); -bool Bonus_Dialog(void); - -/* -** FINDPATH.CPP -*/ -//PathType * Find_Path(CELL source, CELL dest, FacingType *final_moves, int maxlen, int (*callback)(CELL, FacingType), int threshhold); -int Optimize_Moves(PathType *path, int (*callback)(CELL, FacingType), int threshhold); - -/* -** GOPTIONS.CPP -*/ -void Draw_Caption(int text, int x, int y, int w); - -/* -** INI.CPP -*/ -void Set_Scenario_Name(char *buf, int scenario, ScenarioPlayerType player, ScenarioDirType dir = SCEN_DIR_NONE, ScenarioVarType var = SCEN_VAR_NONE); -void Write_Scenario_Ini(char *root); -bool Read_Scenario_Ini(char *root, bool fresh=true); -bool Read_Scenario_Ini_File(char *scenario_file_name, char* bin_file_name, const char* root, bool fresh); -int Scan_Place_Object(ObjectClass *obj, CELL cell); - -/* -** INIT.CPP -*/ -void Uninit_Game(void); -long Obfuscate(char const * string); -void Anim_Init(void); -bool Init_Game(int argc, char *argv[]); -bool Select_Game(bool fade = false); -bool Parse_Command_Line(int argc, char *argv[]); -void Parse_INI_File(void); -int Version_Number(void); -void Save_Recording_Values(void); -void Load_Recording_Values(void); - -/* -** JSHELL.CPP -*/ -void * Small_Icon(void const * iconptr, int iconnum); -void Set_Window(int window, int x, int y, int w, int h); -void * Load_Alloc_Data(FileClass &file); -long Load_Uncompress(FileClass &file, BuffType &uncomp_buff, BuffType &dest_buff, void *reserved_data); -long Translucent_Table_Size(int count); -void *Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer); -void *Conquer_Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer); - -/* -** KEYFBUFF.ASM -*/ -#ifdef __cplusplus -extern "C" { -#endif -long __cdecl Buffer_Frame_To_Page(int x, int y, int w, int h, void *Buffer, GraphicViewPortClass &view, int flags, ...); -#ifdef __cplusplus -} -#endif - -/* -** KEYFRAME.CPP -*/ -int Get_Last_Frame_Length(void); -unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr); -unsigned short Get_Build_Frame_Count(void const *dataptr); -unsigned short Get_Build_Frame_X(void const *dataptr); -unsigned short Get_Build_Frame_Y(void const *dataptr); -unsigned short Get_Build_Frame_Width(void const *dataptr); -unsigned short Get_Build_Frame_Height(void const *dataptr); -bool Get_Build_Frame_Palette(void const *dataptr, void *palette); - -/* -** MAP.CPP -*/ -int Terrain_Cost(CELL cell, FacingType facing); -int Coord_Spillage_Number(COORDINATE coord, int maxsize); - -/* -** MENUS.CPP -*/ -void Setup_Menu(int menu, char const *text[], unsigned long field, int index, int skip); -int Check_Menu(int menu, char const *text[], char *selection, long field, int index); -int Do_Menu(char const **strings, bool blue); -extern int UnknownKey; -int Main_Menu(unsigned long timeout); - -/* -** MPLAYER.CPP -*/ -GameType Select_MPlayer_Game (void); -void Read_MultiPlayer_Settings (void); -void Write_MultiPlayer_Settings (void); -void Read_Scenario_Descriptions (void); -void Free_Scenario_Descriptions(void); -void Computer_Message(void); -int Surrender_Dialog(void); - -/* -** NETDLG.CPP -*/ -bool Init_Network (void); -void Shutdown_Network (void); -bool Remote_Connect (void); -void Destroy_Connection(int id, int error); -bool Process_Global_Packet(GlobalPacketType *packet, IPXAddressClass *address); -unsigned long Compute_Name_CRC(char *name); -void Net_Reconnect_Dialog(int reconn, int fresh, int oldest_index, unsigned long timeval); - -/* -** NULLDLG.CPP -*/ -int Init_Null_Modem( SerialSettingsType *settings ); -void Shutdown_Modem( void ); -void Modem_Signoff( void ); -int Test_Null_Modem( void ); -int Reconnect_Modem( void ); -void Destroy_Null_Connection(int id, int error); -GameType Select_Serial_Dialog( void ); -int Com_Scenario_Dialog(void); -int Com_Show_Scenario_Dialog(void); - -void Smart_Printf( char *format, ... ); -void Hex_Dump_Data( char *buffer, int length ); -void itoh( int i, char *s); - -/* -** PROFILE.CPP -*/ -int WWGetPrivateProfileInt(char const *section, char const *entry, int def, char *profile); -bool WWWritePrivateProfileInt(char const *section, char const *entry, int value, char *profile); -bool WWWritePrivateProfileString(char const *section, char const *entry, char const *string, char *profile); -char * WWGetPrivateProfileString(char const *section, char const *entry, char const *def, char *retbuffer, int retlen, char *profile); -unsigned WWGetPrivateProfileHex (char const *section, char const *entry, char *profile); - -/* -** QUEUE.CPP -*/ -bool Queue_Target(TARGET whom, TARGET target); -bool Queue_Destination(TARGET whom, TARGET target); -bool Queue_Mission(TARGET whom, MissionType mission); -bool Queue_Mission(TARGET whom, MissionType mission, TARGET target, TARGET destination); -bool Queue_Options(void); -bool Queue_Exit(void); -void Queue_AI(void); -void Add_CRC(unsigned long *crc, unsigned long val); - -/* -** RAND.CPP -*/ -int Sim_IRandom(int minval, int maxval); -int Sim_Random(void); - -/* -** REINF.CPP -*/ -bool Do_Reinforcements(TeamTypeClass *team); -bool Create_Special_Reinforcement(HouseClass * house, TechnoTypeClass const * type, TechnoTypeClass const * another, TeamMissionType mission = TMISSION_NONE, int argument =0); -int Create_Air_Reinforcement(HouseClass *house, AircraftType air, int number, MissionType mission, TARGET tarcom, TARGET navcom); - -/* -** SAVELOAD.CPP -*/ -bool Load_Misc_Values(FileClass &file); -bool Save_Misc_Values(FileClass &file); -bool Get_Savefile_Info(int id, char *buf, unsigned *scenp, HousesType *housep); -bool Load_Game(int id); -bool Load_Game(const char *file_name); -//bool Read_Object (void *ptr, int base_size, int class_size, FileClass & file, void * vtable); // Original Read_Object prototype. ST - 9/17/2019 12:50PM -bool Read_Object(void *ptr, int class_size, FileClass & file, bool has_vtable); -bool Save_Game(int id,char *descr); -bool Save_Game(const char *file_name, const char *descr); -bool Write_Object (void *ptr, int class_size, FileClass & file); -TARGET TechnoType_To_Target(TechnoTypeClass const * ptr); -TechnoTypeClass const * Target_To_TechnoType(TARGET target); -void * Get_VTable(void *ptr, int base_size); -void Code_All_Pointers(void); -void Decode_All_Pointers(void); -void Dump(void); -void Set_VTable(void *ptr, int base_size, void *vtable); - -/* -** SCENARIO.CPP -*/ -bool End_Game(void); -bool Read_Scenario(char *root); -bool Start_Scenario(char *root, bool briefing=true); -void Set_Scenario_Difficulty(int difficulty); -HousesType Select_House(void); -void Clear_Scenario(void); -void Do_Briefing(char const * text); -void Do_Lose(void); -void Do_Win(void); -void Do_Restart(void); -void Fill_In_Data(void); -bool Restate_Mission(char const * name, int button1, int button2); -void Fixup_Scenario(void); - -/* -** SCORE.CPP -*/ -void Map_Selection(void); -void Bit_It_In_Scale(int x, int y, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest, GraphicViewPortClass *seen , int delay=0, int dagger=0); -void Bit_It_In(int x, int y, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest, int delay=0, int dagger=0); -void Call_Back_Delay(int time); -int Alloc_Object(ScoreAnimClass *obj); -extern GraphicBufferClass *PseudoSeenBuff; - -void Window_Dialog_Box(HANDLE hinst, LPCTSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc); - -/* -** SPECIAL.CPP -*/ -void Special_Dialog(void); - -/* -** SUPPORT.ASM -*/ -#ifdef __cplusplus -extern "C" { -#endif -void __cdecl Remove_From_List(void **list, int *index, void * ptr); -void * __cdecl Conquer_Build_Fading_Table(void const *palette, void *dest, int color, int frac); -void __cdecl Fat_Put_Pixel(int x, int y, int color, int size, GraphicViewPortClass &); -void __cdecl strtrim(char *buffer); -long __cdecl Get_EAX( void ); -#ifdef __cplusplus -} -#endif - -/* -** TARCOM.CPP -*/ - -/* -** TARGET.CPP -*/ -COORDINATE As_Movement_Coord(TARGET target); -AircraftClass * As_Aircraft(TARGET target, bool check_active = true); -AnimClass * As_Animation(TARGET target, bool check_active = true); -BuildingClass * As_Building(TARGET target, bool check_active = true); -BulletClass * As_Bullet(TARGET target, bool check_active = true); -CELL As_Cell(TARGET target); -COORDINATE As_Coord(TARGET target); -InfantryClass * As_Infantry(TARGET target, bool check_active = true); -TeamClass * As_Team(TARGET target, bool check_active = true); -TeamTypeClass * As_TeamType(TARGET target); -TechnoClass * As_Techno(TARGET target, bool check_active = true); -//TerrainClass * As_Terrain(TARGET target); -TriggerClass * As_Trigger(TARGET target, bool check_active = true); -UnitClass * As_Unit(TARGET target, bool check_active = true); -bool Target_Legal(TARGET target); -ObjectClass * As_Object(TARGET target, bool check_active = true); - -/* -** ULOGIC.CPP -*/ -int Terrain_Cost(CELL cell, FacingType facing); - -/* -** Inline miscellaneous functions. -*/ -#define XYP_COORD(x,y) (unsigned long)(((x)*ICON_LEPTON_W)/CELL_PIXEL_W + ((((y)*ICON_LEPTON_H)/CELL_PIXEL_H)<<16)) -inline FacingType Dir_Facing(DirType facing) {return (FacingType)(((unsigned char)(facing+0x10)&0xFF)>>5);} -inline DirType Facing_Dir(FacingType facing) {return (DirType)((int)facing << 5);} -inline int Cell_To_Lepton(int cell) {return cell<<8;} -inline int Lepton_To_Cell(int lepton) {return ((unsigned)(lepton + 0x0080))>>8;} -inline CELL XY_Cell(int x, int y) {return ((CELL)(((y)<<6)|(x)));} -inline COORDINATE XY_Coord(int x, int y) {return ((COORDINATE)MAKE_LONG(y, x));} -inline int Coord_X(COORDINATE coord) {return (short)(LOW_WORD(coord));} -inline int Coord_Y(COORDINATE coord) {return (short)(HIGH_WORD(coord));} -inline int Cell_X(CELL cell) {return (int)(((unsigned)cell) & 0x3F);} -inline int Cell_Y(CELL cell) {return (int)(((unsigned)cell) >> 6);} -inline int Dir_Diff(DirType dir1, DirType dir2) {return (int)(*((signed char*)&dir2) - *((signed char*)&dir1));} -inline CELL Coord_XLepton(COORDINATE coord) {return (CELL)(*((unsigned char*)&coord));} -inline CELL Coord_YLepton(COORDINATE coord) {return (CELL)(*(((unsigned char*)&coord)+2));} -//inline COORD CellXY_Coord(unsigned x, unsigned y) {return (COORD)(MAKE_LONG(y<<8, x<<8));} -inline COORDINATE Coord_Add(COORDINATE coord1, COORDINATE coord2) {return (COORDINATE)MAKE_LONG((*((short*)(&coord1)+1) + *((short*)(&coord2)+1)), (*((short*)(&coord1)) + *((short*)(&coord2))));} -inline COORDINATE Coord_Sub(COORDINATE coord1, COORDINATE coord2) {return (COORDINATE)MAKE_LONG((*((short*)(&coord1)+1) - *((short*)(&coord2)+1)), (*((short*)(&coord1)) - *((short*)(&coord2))));} -inline COORDINATE Coord_Snap(COORDINATE coord) {return (COORDINATE)MAKE_LONG((((*(((unsigned short *)&coord)+1))&0xFF00)|0x80), (((*((unsigned short *)&coord))&0xFF00)|0x80));} -inline COORDINATE Coord_Mid(COORDINATE coord1, COORDINATE coord2) {return (COORDINATE)MAKE_LONG((*((unsigned short *)(&coord1)+1) + *((unsigned short *)(&coord2)+1))>>1, (*((unsigned short *)(&coord1)) + *((unsigned short *)(&coord2)))>>1);} -inline COORDINATE Cell_Coord(CELL cell) {return (COORDINATE) MAKE_LONG( (((cell & 0x0FC0)<<2)|0x80), ((((cell & 0x003F)<<1)+1)<<7) );} -inline COORDINATE XYPixel_Coord(int x, int y) {return ((COORDINATE)MAKE_LONG((int)(((long)y*(long)ICON_LEPTON_H)/(long)ICON_PIXEL_H)/*+LEPTON_OFFSET_Y*/, (int)(((long)x*(long)ICON_LEPTON_W)/(long)ICON_PIXEL_W)/*+LEPTON_OFFSET_X*/));} -//inline int Facing_To_16(int facing) {return Facing16[facing];} -inline int Facing_To_32(DirType facing) {return Facing32[facing];} -inline DirType Direction256(COORDINATE coord1, COORDINATE coord2) {return ((DirType)Desired_Facing256(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -inline DirType Direction(COORDINATE coord1, COORDINATE coord2) {return ((DirType)Desired_Facing256(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -inline DirType Direction8(COORDINATE coord1, COORDINATE coord2) {return ((DirType)Desired_Facing8(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -//inline int Direction16(COORDINATE coord1, COORD coord2) {return (Desired_Facing16(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -inline DirType Direction(CELL cell1, CELL cell2) {return (DirType)(Desired_Facing8(Cell_X(cell1), Cell_Y(cell1), Cell_X(cell2), Cell_Y(cell2)));} -inline COORDINATE Adjacent_Cell(COORDINATE coord, FacingType dir) {return (Coord_Snap(Coord_Add(AdjacentCoord[dir & 0x07], coord)));} -inline COORDINATE Adjacent_Cell(COORDINATE coord, DirType dir) {return Adjacent_Cell(coord, Dir_Facing(dir));} -inline CELL Adjacent_Cell(CELL cell, FacingType dir) {return (CELL)(cell + AdjacentCell[dir]);} -inline CELL Adjacent_Cell(CELL cell, DirType dir) {return (CELL)(cell + AdjacentCell[Dir_Facing(dir)]);} -inline int Lepton_To_Pixel(int lepton) {return ((lepton * ICON_PIXEL_W) + (ICON_LEPTON_W / 2) - ((lepton < 0) ? (ICON_LEPTON_W - 1) : 0)) / ICON_LEPTON_W;} -inline int Pixel_To_Lepton(int pixel) {return ((pixel * ICON_LEPTON_W) + (ICON_PIXEL_W / 2) - ((pixel < 0) ? (ICON_PIXEL_W - 1) : 0)) / ICON_PIXEL_W;} -//inline FacingType Facing_To_8(DirType facing) {return (FacingType)(((unsigned char)(facing|0x10))>>5);} -inline COORDINATE XYP_Coord(int x,int y) {return XY_Coord(Pixel_To_Lepton(x), Pixel_To_Lepton(y));}; -inline char const * Text_String(int string) {return(Extract_String(SystemStrings, string));}; - -// -// We need to know when the visible page changes -// ST - 1/4/2019 10:31AM -// -void Blit_Hid_Page_To_Seen_Buff(void); -extern bool RunningAsDLL; - - -template inline T Random_Picky(T a, T b, char *sfile, int line) -{ - sfile = sfile; - line = line; - return (T)IRandom((int)a, (int)b); //, sfile, line); -}; - -#define Random_Pick(low, high) Random_Picky ( (low), (high), __FILE__, __LINE__) - - -template inline T Sim_Random_Pick(T a, T b) -{ - return (T)Sim_IRandom((int)a, (int)b); -}; - - -#ifdef CHEAT_KEYS -#define Check_Ptr(ptr,file,line) \ -{ \ - if (!ptr) { \ - Mono_Clear_Screen(); \ - Mono_Printf("NULL Pointer, Module:%s, line:%d!\n",file,line); \ - Prog_End(); \ - exit(EXIT_SUCCESS); \ - } \ -} -#else -#define Check_Ptr(ptr,file,line) -#endif - -/* -** These routines are for coding & decoding multiplayer ID's -*/ -inline PlayerColorType MPlayerID_To_ColorIndex(unsigned short id) {return (PlayerColorType)(id >> 4);} -inline HousesType MPlayerID_To_HousesType(unsigned short id) {return ((HousesType)(id & 0x000f)); } -inline unsigned short Build_MPlayerID(int c_idx, HousesType htype) { return ((c_idx << 4) | htype); } - - - - -// -// True if we are the currently in focus windows app -// -extern bool GameInFocus; - -extern int ScreenWidth; -extern int ScreenHeight; -extern "C" void ModeX_Blit (GraphicBufferClass *source); -extern void Colour_Debug (int call_number); - - -extern unsigned char *InterpolatedPalettes[100]; -extern BOOL PalettesRead; -extern unsigned PaletteCounter; - -extern "C"{ - extern unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE]; - extern unsigned char *InterpolationPalette; -} - -extern void Free_Interpolated_Palettes(void); -extern int Load_Interpolated_Palettes(char const *filename, BOOL add=FALSE); - - -#define CELL_BLIT_ONLY 1 -#define CELL_DRAW_ONLY 2 - -/*********************************************************************************************** - * Distance -- Determines the lepton distance between two coordinates. * - * * - * This routine is used to determine the distance between two coordinates. It uses the * - * Dragon Strike method of distance determination and thus it is very fast. * - * * - * INPUT: coord1 -- First coordinate. * - * * - * coord2 -- Second coordinate. * - * * - * OUTPUT: Returns the lepton distance between the two coordinates. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -int Distance_Coord(COORDINATE coord1, COORDINATE coord2); - -#if (0) -#pragma aux Distance_Coord parm [eax] [ebx] \ - modify [edx ebx] \ - value [eax] = \ - "mov dx,ax" \ - "sub dx,bx" \ - "jg okx" \ - "neg dx" \ - "okx:" \ - "shr eax,16" \ - "shr ebx,16" \ - "sub ax,bx" \ - "jg oky" \ - "neg ax" \ - "oky:" \ - "cmp ax,dx" \ - "jg ok" \ - "xchg ax,dx" \ - "ok:" \ - "shr dx,1" \ - "add ax,dx" -#endif - -inline int Distance(COORDINATE coord1, COORDINATE coord2) -{ -#ifdef NEVER - int diff1, diff2; - - diff1 = Coord_Y(coord1) - Coord_Y(coord2); - if (diff1 < 0) diff1 = -diff1; - diff2 = Coord_X(coord1) - Coord_X(coord2); - if (diff2 < 0) diff2 = -diff2; - if (diff1 > diff2) { - return(diff1 + (diff2>>1)); - } - return(diff2 + (diff1>>1)); -#else - return(Distance_Coord(coord1, coord2)); -#endif -} - - - -/*********************************************************************************************** - * Distance -- Determines the cell distance between two cells. * - * * - * Use this routine to determine the distance between the two cells specified. The distance * - * is returned in cells. * - * * - * INPUT: cell1, cell2 -- The two cells to determine the distance between. * - * * - * OUTPUT: Returns with the distance between the two cells in units of cell size. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -inline int Distance(CELL coord1, CELL coord2) -{ - int diff1, diff2; - - diff1 = Cell_Y(coord1) - Cell_Y(coord2); - if (diff1 < 0) diff1 = -diff1; - diff2 = Cell_X(coord1) - Cell_X(coord2); - if (diff2 < 0) diff2 = -diff2; - if (diff1 > diff2) { - return(diff1 + (diff2>>1)); - } - return(diff2 + (diff1>>1)); -} - - -/*********************************************************************************************** - * CellClass::Cell_Number -- Returns the cell ID number for this cell object. * - * * - * Call this routine if you wish to determine what the cell number ID is for the currrent * - * cell object. This ID number is the index number into the cell array. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the cell number for this cell object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -inline CELL CellClass::Cell_Number(void) const -{ - return(Map.ID(this)); -} -#if(0) -#ifndef NOMEMCHECK -#define NO_INTERCEPT -#include "memcheck.h" -#endif -#endif - -void WWDOS_Shutdown(void); - -#endif - - - -/* -** Debug output. ST - 6/27/2019 10:00PM -*/ -void GlyphX_Debug_Print(const char *debug_text); - -/* -** Achievement event. ST - 11/11/2019 11:39AM -*/ -void On_Achievement_Event(const HouseClass* player_ptr, const char *achievement_type, const char *achievement_reason); \ No newline at end of file diff --git a/code/TIBERIANDAWN/FUSE.CPP b/code/TIBERIANDAWN/FUSE.CPP deleted file mode 100644 index 5390aa8..0000000 --- a/code/TIBERIANDAWN/FUSE.CPP +++ /dev/null @@ -1,193 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\fuse.cpv 2.18 16 Oct 1995 16:50:46 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FUSE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 24, 1994 * - * * - * Last Update : October 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FuseClass::Arm_Fuse -- Sets up fuse for detonation check. * - * FuseClass::Fuse_Checkup -- Determines if the fuse triggers. * - * FuseClass::Fuse_Write -- Writes the fuse data to the save game file. * - * FuseClass::Fuse_Read -- Reads the fuse class data from the save game file. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * FuseClass::FuseClass -- Constructor. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/27/1995 BRR : Created. Gosh, what a lotta work. * - *=============================================================================================*/ -FuseClass::FuseClass(void) -{ - Timer = 0; - Arming = 0; - HeadTo = 0; - Proximity = 0; -} - - -/*********************************************************************************************** - * FuseClass::Arm_Fuse -- Sets up fuse for detonation check. * - * * - * This starts a fuse. Fuses are proximity detonation variety but * - * can be modified to have a minimum time to elapse before detonation * - * and a maximum time to exist before detonation. Typically, the * - * timing values are used for missiles that have a minimum arming * - * distance and a limited amount of fuel. * - * * - * INPUT: location -- The coordinate where the projectile start. This * - * is needed for proper proximity tracking. * - * * - * target -- The actual impact point. Fuses are based on real * - * word coordinates. * - * * - * time -- The maximum time that the fuse may work before * - * explosion is forced. * - * * - * arming -- The minimum time that must elapse before the * - * fuse may explode. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/24/1994 JLB : Created. * - *=============================================================================================*/ -void FuseClass::Arm_Fuse(COORDINATE location, COORDINATE target, int timeto, int arming) -{ - timeto = MAX(timeto, arming); - Timer = MIN(timeto, 0xFF); - Arming = MIN(arming, 0xFF); - HeadTo = target; - Proximity = Distance(location, target); -} - - -/*********************************************************************************************** - * FuseClass::Fuse_Checkup -- Determines if the fuse triggers. * - * * - * This will process the fuse and update the internal clocks as well * - * as check to see if the fuse should trigger (explode) or not. * - * * - * INPUT: newlocation -- The new location of the fuse. This is needed * - * to determine proximity explosions. * - * * - * OUTPUT: bool; Was the fuse triggered to explode now? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/24/1994 JLB : Created. * - *=============================================================================================*/ -bool FuseClass::Fuse_Checkup(COORDINATE newlocation) -{ - int proximity; - - /* - ** Always decrement the fuse timer. - */ - if (Timer) Timer--; - - /* - ** If the arming countdown has not expired, then do nothing. - */ - if (Arming) { - Arming--; - } else { - - /* - ** If the timer has run out, then the warhead explodes. - */ - if (!Timer) return(true); - - proximity = Distance(newlocation, HeadTo); - if (proximity < 0x0010) return(true); - if (proximity < ICON_LEPTON_W && proximity > Proximity) { - return(true); - } - Proximity = proximity; - } - return(false); -} - - -/*********************************************************************************************** - * FuseClass::Fuse_Write -- Writes the fuse data to the save game file. * - * * - * Use this routine to output the fuse class data to the save game file specified. * - * * - * INPUT: file -- The file to output the data to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void FuseClass::Fuse_Write(FileClass & file) -{ - file.Write(&Timer, sizeof(Timer)); - file.Write(&Arming, sizeof(Arming)); - file.Write(&HeadTo, sizeof(HeadTo)); - file.Write(&Proximity, sizeof(Proximity)); -} - - -/*********************************************************************************************** - * FuseClass::Fuse_Read -- Reads the fuse class data from the save game file. * - * * - * Use this routine to input the fuse class data from the save game file specified. * - * * - * INPUT: file -- The file to input the data from. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void FuseClass::Fuse_Read(FileClass & file) -{ - file.Read(&Timer, sizeof(Timer)); - file.Read(&Arming, sizeof(Arming)); - file.Read(&HeadTo, sizeof(HeadTo)); - file.Read(&Proximity, sizeof(Proximity)); -} - diff --git a/code/TIBERIANDAWN/FUSE.H b/code/TIBERIANDAWN/FUSE.H deleted file mode 100644 index 9714aba..0000000 --- a/code/TIBERIANDAWN/FUSE.H +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\fuse.h_v 2.17 16 Oct 1995 16:46:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FUSE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 24, 1994 * - * * - * Last Update : April 24, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FUSE_H -#define FUSE_H - -/**************************************************************************** -** The fuse is used by projectiles to determine whether detonation should -** occur. This is usually determined by tracking the distance to the -** designated target reaches zero or when the timer expires. -*/ -class FuseClass { - public: - FuseClass(void); - void Arm_Fuse(COORDINATE location, COORDINATE target, int time=0xFF, int arming=0); - bool Fuse_Checkup(COORDINATE newlocation); - void Fuse_Write(FileClass & file); - void Fuse_Read(FileClass & file); - COORDINATE Fuse_Target(void); - - /* - ** File I/O. - */ - void Code_Pointers(void); - void Decode_Pointers(void); - - /* - ** Fuses can detonate if enough time has elapsed. This value counts - ** down. When it reaches zero, detonation occurs. - */ - unsigned char Timer; - - private: - - /* - ** Some fuses need a certain amount of time before detonation can - ** occur. This counts down and when it reaches zero, normal fuse - ** detonation checking can occur. - */ - unsigned char Arming; - - /* - ** This is the designated impact point of the projectile. The fuse - ** will trip when the closest point to this location has been reached. - */ - COORDINATE HeadTo; - - /* - ** This is the running proximity value to the impact point. This value - ** will progressively get smaller. Detonation occurs when it reaches - ** zero or when it starts to grow larger. - */ - short Proximity; -}; - -inline COORDINATE FuseClass::Fuse_Target(void) -{ - return(HeadTo); -} - -#endif diff --git a/code/TIBERIANDAWN/GADGET.CPP b/code/TIBERIANDAWN/GADGET.CPP deleted file mode 100644 index bfdbaf5..0000000 --- a/code/TIBERIANDAWN/GADGET.CPP +++ /dev/null @@ -1,801 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gadget.cpv 2.18 16 Oct 1995 16:49:40 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GADGET.CPP * - * * - * Programmer : Maria del Mar McCready Legg * - * Joe L. Bostic * - * * - * Start Date : 01/03/95 * - * * - * Last Update : July 8, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * GadgetClass::Action -- Base action for gadget. * - * GadgetClass::Clear_Focus -- Clears the focus if this gadget has it. * - * GadgetClass::Delete_List -- Deletes all gadget objects in list. * - * GadgetClass::Disable -- Disables the gaget from input processing. * - * GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn. * - * GadgetClass::Draw_Me -- Gadget redraw action (flag control). * - * GadgetClass::Enable -- Enables the gadget. * - * GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified. * - * GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn. * - * GadgetClass::GadgetClass -- Constructor for gadget object. * - * GadgetClass::GadgetClass -- Default constructor for a gadget class object. * - * GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain. * - * GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget. * - * GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus. * - * GadgetClass::Remove -- Removes the specified gagdet from the list. * - * GadgetClass::Set_Focus -- Sets focus to this gadget. * - * GadgetClass::Sticky_Process -- Handles the sticky flag processing. * - * GadgetClass::~GadgetClass -- Destructor for gadget object. * - * GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include -#include - -/* -** This records the current gadget the the gadget system is "stuck on". Such a -** gadget will be processed to the exclusion of all others until the mouse button -** is no longer pressed. -*/ -GadgetClass * GadgetClass::StuckOn = 0; - -/* -** This is a copy of a pointer to the last list used by the gadget input system. -** If a change of list is detected, then all gadgets are forced to be redrawn. -*/ -GadgetClass * GadgetClass::LastList = 0; - - -/* -** This points to the gadget that is intercepting all keyboard events. -*/ -GadgetClass * GadgetClass::Focused = 0; - - -/*********************************************************************************************** - * GadgetClass::GadgetClass -- Constructor for gadget object. * - * * - * This is the normal constructor for gadget objects. A gadget object is only concerned * - * with the region on the screen to considered "its own" as well as the flags that tell * - * what mouse action should be recognized when the mouse is over this screen area. * - * * - * INPUT: x,y -- Coordinates (in pixels) of the upper left hand corner of the region that * - * will be "owned" by this gadget. * - * * - * w,h -- Width and height (in pixels) of this gadget's region. * - * * - * flags -- The flags (mouse conditions) that will cause this gadget's action * - * function to be called. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/03/1995 MML : Created. * - *=============================================================================================*/ -GadgetClass::GadgetClass(int x, int y, int w, int h, unsigned flags, int sticky) -{ - X = x; - Y = y; - Width = w; - Height = h; - Flags = flags; - IsToRepaint = false; - IsSticky = sticky; - IsDisabled = false; - - if (IsSticky) { - Flags |= LEFTPRESS|LEFTRELEASE; - } -} - - -/*********************************************************************************************** - * GadgetClass::~GadgetClass -- Destructor for gadget object. * - * * - * This is the destructor for the gadget object. It will clear the focus from this gadget * - * if this gadget currently has the focus. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -GadgetClass::~GadgetClass(void) -{ - if (Has_Focus()) { - Clear_Focus(); - } -} - - -/*************************************************************************** - * GADGETCLASS::CLICKEDON -- If a mouse click is detected within gadget's * - * area and the appropriate flag is set, then call Action(). * - * * - * INPUT: int key, int mousex, int mousey * - * * - * OUTPUT: true or false * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/03/1995 MML : Created. * - *=========================================================================*/ -int GadgetClass::Clicked_On(KeyNumType & key, unsigned flags, int mousex, int mousey) -{ - /* - ** Set flags to match only those events that occur AND are being looked for. If - ** the result is NULL, then we know that this button should be ignored. - */ - flags &= Flags; - - /* - ** If keyboard input should be processed by this "gadget" and keyboard input is - ** detected, then always call the action function. It is up to the action function - ** in this case to either ignore the keyboard input or not. - ** - ** For mouse actions, check to see if the mouse is in the region of the button - ** before calling the associated action function. This is the typical action for - ** buttons. - */ - if (this == StuckOn || - (flags & KEYBOARD) || - (flags && (mousex - X) < Width && (mousey - Y) < Height)) { - - return(Action(flags, key)); - } - return(false); -} - - -/*********************************************************************************************** - * GadgetClass::Enable -- Enables the gadget. * - * * - * This function enables the gadget. An enabled gadget will be processed for input * - * purposes. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Enable(void) -{ - IsDisabled = false; - IsToRepaint = true; - Clear_Focus(); -} - - -/*********************************************************************************************** - * GadgetClass::Disable -- Disables the gaget from input processing. * - * * - * This routine will disable the gadget. A disabled gadget might be rendered, but is * - * ignored for input processing. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Disable(void) -{ - IsDisabled = true; - IsToRepaint = true; - Clear_Focus(); -} - - -/*********************************************************************************************** - * GadgetClass::Remove -- Removes the specified gagdet from the list. * - * * - * Use this routine if an individual gadget needs to be removed from the list of gadgets. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the specified gadget found and removed? A false indicates that the * - * gadget wasn't in the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -GadgetClass * GadgetClass::Remove(void) -{ - Clear_Focus(); - return(GadgetClass *)LinkClass::Remove(); -} - - -/*********************************************************************************************** - * GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain. * - * * - * This returns with the next gadget's pointer. It is identical to the base Get_Next() * - * function, but returns a pointer to a GadgetClass object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the next gadget in the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -GadgetClass * GadgetClass::Get_Next(void) const -{ - return(GadgetClass*)LinkClass::Get_Next(); -} - - -/*********************************************************************************************** - * GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget. * - * * - * This routine will return the previous gadget in the list. It is identical to the base * - * function Get_Prev, but returns a pointer to a GadgetClass object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the previous gadget in the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -GadgetClass * GadgetClass::Get_Prev(void) const -{ - return(GadgetClass*)LinkClass::Get_Prev(); -} - - -/*********************************************************************************************** - * GadgetClass::Delete_List -- Deletes all gadget objects in list. * - * * - * This function will delete all gadgets in the list. It is the counterpart to the * - * Create_One_Of functions. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Any references to these gadget become invalidated by this routine. * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Delete_List(void) -{ - GadgetClass * g = this; - - /* - ** Move to head of the list. - */ - while (g->Get_Prev()) { - g = g->Get_Prev(); - } - - /* - ** First delete all the gadgets following the first one. The reason the first one - ** is kept around is that sometimes deleting one gadget will result in related gadgets - ** in the same list also being deleted. The first gadget will always contain the - ** correct gadget pointer. - */ - while (g) { - g->Clear_Focus(); - - GadgetClass * temp = g; - g = g->Get_Next(); - delete temp; - } -} - - -/*********************************************************************************************** - * GadgetClass::Action -- Base action for gadget. * - * * - * This handles the base level action that a gadget performs when a qualifying input event * - * is detected. This sets the redraw flag and returns true (to stop further processing). * - * If no qualifying input event was detected, but this routine was called anyway, then * - * don't perform any action. The call to this routine, in that case, must have been forced * - * for some other reason. * - * * - * INPUT: flag -- The input event bits that qualify for this gadget. A NULL indicates that * - * no qualifying event occured. * - * * - * OUTPUT: bool; Should further gadget list processing be aborted? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int GadgetClass::Action(unsigned flags, KeyNumType &) -{ - /* - ** If any of the event flags are active, then this indicates that something probably - ** has changed the gadget. Flag the gadget to be redrawn. Also, make sure that - ** any sticky flags are cleared up. - */ - if (flags) { - IsToRepaint = true; - Sticky_Process(flags); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * GadgetClass::Draw_Me -- Gadget redraw action (flag control). * - * * - * At this level, there is no actual rendering taking place with the call to Draw_Me, but * - * the IsToRepaint flag must be cleared. Derived objects will call this routine and if it * - * returns true, they will perform their custom rendering. * - * * - * INPUT: forced -- Is this redraw forced by outside circumstances? * - * * - * OUTPUT: bool; Should the gadget imagery be redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/14/1995 JLB : Created. * - *=============================================================================================*/ -int GadgetClass::Draw_Me(int forced) -{ - if (forced || IsToRepaint) { - IsToRepaint = false; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn. * - * * - * Use this function to cause all gadget in the list to be redrawn regardless of the state * - * of the IsToRepaint flag. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/03/1995 MML : Created. * - *=============================================================================================*/ -void GadgetClass::Draw_All(bool forced) -{ - GadgetClass *gadget = this; - - while (gadget != NULL) { - gadget->Draw_Me(forced); - gadget = gadget->Get_Next(); - } -} - - -/*************************************************************************** - * GADGETCLASS::PROCESSLIST -- Check list for a mouse click within a gadget* - * * - * INPUT: none. * - * * - * OUTPUT: key pressed. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/03/1995 MML : Created. * - *=========================================================================*/ -KeyNumType GadgetClass::Input(void) -{ - int mousex, mousey; - KeyNumType key; - unsigned flags; - int forced = false; - - /* - ** Record this list so that a forced redraw only occurs the FIRST time the - ** gadget list is passed to this routine. - */ - if (LastList != this) { - LastList = this; - forced = true; - StuckOn = NULL; - Focused = NULL; - } - - /* - ** Fetch any pending keyboard input. - */ - key = Keyboard::Check(); - if (key) { - key = Keyboard::Get(); - } - -#ifdef SCENARIO_EDITOR - - if ( key == KN_K ){ - /* - ** time to create a screen shot using the PCX code (if it works) - */ - GraphicBufferClass temp_page( SeenBuff.Get_Width(), - SeenBuff.Get_Height(), - NULL, - SeenBuff.Get_Width() * SeenBuff.Get_Height()); - char filename[30]; - - SeenBuff.Blit(temp_page); - for (int lp = 0; lp < 99; lp ++) { - if (lp < 10) { - sprintf(filename, "scrsht0%d.pcx", lp); - } else { - sprintf(filename, "scrsht%d.pcx", lp); - } - if (access(filename, F_OK) == -1) - break; - } - - Write_PCX_File(filename, temp_page, (unsigned char *)CurrentPalette); - //Map.Place_Random_Crate(); - } - -#endif //SCENARIO_EDITOR - - /* - ** For mouse button clicks, the mouse position is actually held in the MouseQ... - ** globals rather than their normal Mouse... globals. This is because we need to - ** know the position of the mouse at the exact instant when the click occured - ** rather the the mouse position at the time we get around to this function. - */ - if (((key&0x10FF) == KN_LMOUSE) || ((key&0x10FF) == KN_RMOUSE)) { - mousex = _Kbd->MouseQX; - mousey = _Kbd->MouseQY; - } else { - mousex = Get_Mouse_X(); - mousey = Get_Mouse_Y(); - } - - /* - ** Set the mouse button state flags. These will be passed to the individual - ** buttons so that they can determine what action to perform (if any). - */ - flags = 0; - if (key) { - if (key == KN_LMOUSE) { - flags |= LEFTPRESS; - } - if (key == KN_RMOUSE) { - flags |= RIGHTPRESS; - } - if (key == (KN_LMOUSE | KN_RLSE_BIT)) { - flags |= LEFTRELEASE; - } - if (key == (KN_RMOUSE | KN_RLSE_BIT)) { - flags |= RIGHTRELEASE; - } - } - - /* - ** If the mouse wasn't responsible for this key code, then it must be from - ** the keyboard. Flag this fact. - */ - if (key && !flags) { - flags |= KEYBOARD; - } - - /* - ** Mouse button up or down action is ignored if there is a keyboard event. This - ** allows keyboard events to fall through normally even if the mouse is over a - ** gadget that is flagged for LEFTUP or RIGHTUP. - */ - if (!key) { - - /* - ** Check for the mouse being held down. We can't use the normal input system - ** for this, so we must examine the actual current state of the mouse - ** buttons. As a side note, if we determine that the mouse button isn't being - ** held down, then we automatically know that it must be up -- set the flag - ** accordingly. - */ - if (Keyboard::Down(KN_LMOUSE)) { - flags |= LEFTHELD; - } else { - flags |= LEFTUP; - } - if (Keyboard::Down(KN_RMOUSE)) { - flags |= RIGHTHELD; - } else { - flags |= RIGHTUP; - } - } - - /* - ** If "sticky" processing is active, then only process the stuck gadget. - */ - if (StuckOn) { - StuckOn->Draw_Me(false); - StuckOn->Clicked_On(key, flags, mousex, mousey); - if (StuckOn) { - StuckOn->Draw_Me(false); - } - } else { - - /* - ** If there is a gadget that has the keyboard focus, then route all keyboard - ** events to it. - */ - if (Focused && (flags & KEYBOARD)) { - Focused->Draw_Me(false); - Focused->Clicked_On(key, flags, mousex, mousey); - if (Focused) { - Focused->Draw_Me(false); - } - } else { - - /* - ** Sweep through all the buttons in the chain and pass the current button state - ** and keyboard input data to them. These routines will detect whether they should - ** perform some action and return a flag to this effect. They also have the option - ** of changing the key value so that an appropriate return value is use for this - ** processing routine. - */ - GadgetClass *next_button = this; - while (next_button != NULL) { - - /* - ** Maybe redraw the button if it needs to or is being forced to redraw. - */ - next_button->Draw_Me(forced); - - if (!next_button->IsDisabled) { - - /* - ** Process this button. If the button was recognized and action was - ** performed, then bail from further processing (speed reasons?). - */ - if (next_button->Clicked_On(key, flags, mousex, mousey)) { - - /* - ** Some buttons will require repainting when they perform some action. - ** Do so at this time. - */ - next_button->Draw_Me(false); - break; - } - } - - next_button = next_button->Get_Next(); - } - } - } - return(key); -} - - -/*********************************************************************************************** - * GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified. * - * * - * This examines the gadget list looking for on that has the same ID as specified. If that * - * gadget was found, then a pointer to it is returned. Since only ControlClass gadgets * - * or ones derived from it can have an ID value, we know that the returned pointer is at * - * least of the ControlClass type. * - * * - * INPUT: id -- The ID number to scan for. Zero is not a legal ID number and if passed in, * - * a NULL will always be returned. * - * * - * OUTPUT: Returns with a pointer to the ControlClass gadget that has the matching ID number. * - * If no matching gadget was found, then NULL is returned. * - * * - * WARNINGS: If there happens to be more than one gadget with a matching ID, this routine * - * will return a pointer to the first one only. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -ControlClass * GadgetClass::Extract_Gadget(unsigned id) -{ - GadgetClass * g = this; - - if (id) { - while (g) { - if (g->Get_ID() == id) { - return((ControlClass *)g); - } - g = g->Get_Next(); - } - } - return(0); -} - - -/*********************************************************************************************** - * GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn. * - * * - * Use this routine to flag the gadget to be redrawn. A gadget so flagged will have its * - * Draw_Me function called at the next available opportunity. Usually, this is the next * - * time the Input() function is called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Flag_To_Redraw(void) -{ - IsToRepaint = true; -} - - -/*********************************************************************************************** - * GadgetClass::Sticky_Process -- Handles the sticky flag processing. * - * * - * This function examines the event flags and handles any "sticky" processing required. * - * Sticky processing is when the button is flagged with the "IsSticky" bit and it will * - * be processed to the exclusion of all other gadgets while the mouse button is held * - * down. * - * * - * INPUT: flags -- The event flags that triggered the call to this routine. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Sticky_Process(unsigned flags) -{ - if (IsSticky && (flags & LEFTPRESS)) { - StuckOn = this; - } - if (StuckOn == this && (flags & LEFTRELEASE)) { - StuckOn = 0; - } -} - - -/*********************************************************************************************** - * GadgetClass::Set_Focus -- Sets focus to this gadget. * - * * - * This will set the focus to this gadget regardless of any current focus setting. If there * - * is another gadget that has focus, it will have its focus cleared before this gadget will * - * get the focus. A focused gadget is one that has all keyboard input routed to it. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Set_Focus(void) -{ - if (Focused) { - Focused->Flag_To_Redraw(); - Focused->Clear_Focus(); - } - Flags |= KEYBOARD; - Focused = this; -} - - -/*********************************************************************************************** - * GadgetClass::Clear_Focus -- Clears the focus if this gadget has it. * - * * - * Use this function to clear the focus for the gadget. If the gadget doesn't currently * - * have focus, then this routine will do nothing. For added functionality, overload this * - * virtual function so that gadget specific actions may be take when focus is lost. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - *=============================================================================================*/ -void GadgetClass::Clear_Focus(void) -{ - if (Focused == this) { - Flags &= ~KEYBOARD; - Focused = 0; - } -} - - -/*********************************************************************************************** - * GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus. * - * * - * If this object has the keyboard focus, then this routine will return true. When the * - * gadget has keyboard focus, all keyboard events get routed to the gadget. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Does this gadget have the keyboard focus? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/21/1995 JLB : Created. * - *=============================================================================================*/ -bool GadgetClass::Has_Focus(void) -{ - return(this == Focused); -} - -/*********************************************************************************************** - * GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing * - * * - * This function is mostly for supporting HidPage drawing. If it returns true, it means * - * the application needs to re-blit the HidPage forward, after calling the list's Input(). * - * * - * INPUT: none * - * * - * OUTPUT: true = an item needs redrawing, false = no items need redrawing * - * * - * WARNINGS: It is assumed 'this' is the head of the list. * - * * - * HISTORY: * - * 01/03/1995 MML : Created. * - *=============================================================================================*/ -int GadgetClass::Is_List_To_Redraw(void) -{ - GadgetClass *gadget = this; - - while (gadget != NULL) { - if (gadget->IsToRepaint) - return (true); - gadget = gadget->Get_Next(); - } - return (false); -} - - diff --git a/code/TIBERIANDAWN/GADGET.H b/code/TIBERIANDAWN/GADGET.H deleted file mode 100644 index 3fe8fad..0000000 --- a/code/TIBERIANDAWN/GADGET.H +++ /dev/null @@ -1,245 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gadget.h_v 2.17 16 Oct 1995 16:46:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GADGET.H * - * * - * Programmer : Maria del Mar McCready Legg * - * * - * Start Date : January 3, 1995 * - * * - * Last Update : January 3, 1995 [MML] * - * * - * * - * LinkClass [This is the linked list manager class. It keeps a record * - * ³ of the next and previous gadget in the list. It is possible * - * ³ delete a gadget out of the middle of the list with this * - * ³ class.] * - * ³ * - * GadgetClass [The is the basic gadget class. It handles processing of * - * ³ input events and dispatching the appropriate functions. * - * ³ All gadgets must be derived from this class.] * - * ÃÄÄÄÄ¿ * - * ³ ³ * - * ³ ListClass [Ths list class functions like a list box does in Windows. It * - * ³ keeps track of a list of text strings. This list can be * - * ³ scrolled and an item selected. If the list becomes larger than * - * ³ can be completely displayed, it will automatically create a * - * ³ slider (at the right edge) to manage the scrolling.] * - * ³ * - * ControlClass [This class adds the concept of giving an ID number to the * - * ³ gadget. This ID can then be returned from the Input() * - * ³ function as if it were a pseudo-keystroke. Additionally, * - * ³ the ability to inform another button that this button has * - * ³ been actioned is allowed. This ability allows one button * - * ³ to watch what happens to another button. Example: a list * - * ³ box gadget can tell when an attached slider has been * - * ³ touched.] * - * ÚÄÄÄÄÄÄÄÅÄÄÄÄ¿ * - * ³ ³ ³ * - * ³ ³ GaugeClass [This class looks similar to Windows slider, but has * - * ³ ³ ³ a different controlling logic. There is no thumb and * - * ³ ³ ³ it serves as a simple variable control setting. This * - * ³ ³ ³ is analagous to a volume slider.] * - * ³ ³ ³ * - * ³ ³ SliderClass [The slider class is similar to the typical Windows slider. It * - * ³ ³ has a current setting, a thumb, and a controlable scale. This * - * ³ ³ is the object created to handle a scrolling list box.] * - * ³ ³ * - * ³ EditClass * - * ³ * - * ³ * - * ToggleClass [The toggle class is used for buttons that have an image and behave just * - * ³ like the buttons in Windows do. That is, they have a separate visual for * - * ³ when they are pressed and raised. They are officially triggered (return * - * ³ their ID number) when the mouse button is released while over the button. * - * ³ This class doesn't perform any rendering itself. It merely provides the * - * ³ logic so that the derived classes will function correctly.] * - * ÚÄÁÄÄÄÄ¿ * - * ³ ³ * - * ³ TextButtonClass [The text button functions like a normal Windows style button, but * - * ³ the imagery is based on text that is displayed on the button. A * - * ³ typical example would be the "OK" or "Cancel" buttons.] * - * ³ * - * ShapeButtonClass [The shape buttons is similar to the TextButton but instead of text * - * being used to give the button its imagery, an actual shape is used * - * instead. This allows graphic buttons. These are similar to the up/down * - * arrows seen in a Windows slider.] * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GADGET_H -#define GADGET_H - -#include "link.h" - -class ControlClass; - -class GadgetClass : public LinkClass -{ - public: - typedef enum FlagEnum { - LEFTPRESS = 0x0001, // Left mouse button press. - LEFTHELD = 0x0002, // Left mouse button is being held down. - LEFTRELEASE = 0x0004, // Left mouse button released. - LEFTUP = 0x0008, // Left mouse button is being held up. - RIGHTPRESS = 0x0010, // Right mouse button press. - RIGHTHELD = 0x0020, // Right mouse button is being held down. - RIGHTRELEASE = 0x0040, // Right mouse button released. - RIGHTUP = 0x0080, // Right mouse button is being held up. - KEYBOARD = 0x0100, // Keyboard input processing (maybe). - } FlagEnum; - - GadgetClass(int x, int y, int w, int h, unsigned flags, int sticky=false); - GadgetClass(void) {}; - virtual ~GadgetClass(void); -// static GadgetClass * Create_One_Of(int x, int y, int w, int h, unsigned flags, int sticky=false); - - /* - ** Gadget list management functions. - */ - virtual KeyNumType Input(void); - virtual void Draw_All(bool forced=true); - virtual void Delete_List(void); - virtual ControlClass * Extract_Gadget(unsigned id); - virtual void Flag_List_To_Redraw(void) {LastList = 0;}; - virtual GadgetClass * Remove(void); - virtual GadgetClass * Get_Next(void) const; - virtual GadgetClass * Get_Prev(void) const; - - /* - ** Manages individual gadget states and actions. - */ - virtual void Disable(void); - virtual void Enable(void); - virtual unsigned Get_ID(void) const {return 0;}; - virtual void Flag_To_Redraw(void); - virtual void Peer_To_Peer(unsigned , KeyNumType & , ControlClass & ) {}; - virtual void Set_Focus(void); - virtual void Clear_Focus(void); - virtual bool Has_Focus(void); - virtual int Is_List_To_Redraw(void); - - /* - ** General render function. - */ - virtual int Draw_Me(int forced=false); - - /* - ** This is the coordinates and dimensions of the gadget region. These are in - ** absolute screen pixel coordinates. - */ - int X; - int Y; - int Width; - int Height; - - protected: - - /* - ** Processes the event flags so that if this gadget needs to "stick" or - ** "unstick", it will be properly flagged. Call this function if you are - ** going to clear the button press flags before calling the base class - ** Action() function. Otherwise, calling this function manually, is - ** unnecessary since the base class Action() function already does so. - */ - virtual void Sticky_Process(unsigned flags); - - /* - ** This is the action functio that will be called whenever the flags and mouse - ** input indicates. This is the main method by which this button performs a useful - ** function. - */ - virtual int Action(unsigned flags, KeyNumType & key); - - /* - ** If there is a sticky button being processed, then this will point to it. A sticky - ** button is one that will ONLY be processed while the mouse button is being - ** held down. - */ - static GadgetClass * StuckOn; - - /* - ** This is a record of the last list passed to the Input() function. If a list - ** different than the last recorded one is detected, then the draw function is - ** called for every gadget in the list. This causes all buttons to be redrawn the - ** fire time Input() is called without forced a manual call to Draw_All(). - */ - static GadgetClass * LastList; - - /* - ** This points to the gadget that has the keyboard focus. All keyboard only - ** events are fed to this gadget to the exclusion of all others. - */ - static GadgetClass * Focused; - - /* - ** This button should call the Draw_Me function because some graphic element needs - ** to be redrawn. This flag is set by default if the Action function is called. - */ - unsigned IsToRepaint:1; - - public: // HACK HACK HACK.. this is here becuase the sidebar buttons are static. - /* - ** A sticky button is one that is processed to the exclusion of all other buttons - ** IF the mouse was pressed down while over this button and the mouse continues - ** to remain pressed. This is the standard behavior for all normal Windows style - ** buttons. - */ - unsigned IsSticky:1; - - protected: - - /* - ** If the button is disabled, then it won't be processed by the input function. It will - ** have its Draw_Me function called as necessary. In order to not display the button - ** at all, the appropriate draw function should perform no action -- just return. Or, - ** just remove the button from the list. - */ - unsigned IsDisabled:1; - - /* - ** These are the action flags that are used to determine when the action function - ** should be called. Example: If this gadget only wants the action button called when - ** the left mouse button is pressed over the its region, then the flag will be set - ** to LEFTPRESS. - */ - unsigned Flags; - - private: -public: //ST - 1/21/2019 12:06PM - virtual int Clicked_On(KeyNumType & key, unsigned flags, int x, int y); -}; - -//inline GadgetClass::FlagEnum operator |(GadgetClass::FlagEnum, GadgetClass::FlagEnum); -//inline GadgetClass::FlagEnum operator &(GadgetClass::FlagEnum, GadgetClass::FlagEnum); -//inline GadgetClass::FlagEnum operator ~(GadgetClass::FlagEnum); - -inline GadgetClass::FlagEnum operator|(GadgetClass::FlagEnum a, GadgetClass::FlagEnum b) -{return static_cast(static_cast(a) | static_cast(b));} - -inline GadgetClass::FlagEnum operator&(GadgetClass::FlagEnum a, GadgetClass::FlagEnum b) -{return static_cast(static_cast(a) & static_cast(b));} - -inline GadgetClass::FlagEnum operator~(GadgetClass::FlagEnum a) -{return static_cast(~static_cast(a));} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/GAMEDLG.CPP b/code/TIBERIANDAWN/GAMEDLG.CPP deleted file mode 100644 index 5fc581d..0000000 --- a/code/TIBERIANDAWN/GAMEDLG.CPP +++ /dev/null @@ -1,419 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gamedlg.cpv 2.17 16 Oct 1995 16:52:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GAMEDLG.CPP * - * * - * Programmer : Maria del Mar McCready Legg, Joe L. Bostic * - * * - * Start Date : Jan 8, 1995 * - * * - * Last Update : Jan 18, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * OptionsClass::Process -- Handles all the options graphic interface. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "gamedlg.h" -#include "sounddlg.h" -#include "visudlg.h" - - -/*********************************************************************************************** - * OptionsClass::Process -- Handles all the options graphic interface. * - * * - * This routine is the main control for the visual representation of the options * - * screen. It handles the visual overlay and the player input. * - * * - * INPUT: none * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: * - * 12/31/1994 MML : Created. * - *=============================================================================================*/ -void GameControlsClass::Process(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - /* - ** Dialog & button dimensions - */ - int d_dialog_w = 232 * factor; // dialog width - int d_dialog_h = 141 * factor; // dialog height - int d_dialog_x = ((SeenBuff.Get_Width()- d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((SeenBuff.Get_Height() - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - int d_top_margin= 30 * factor; - - int d_txt6_h = 7 * factor; // ht of 6-pt text - int d_margin1 = 5 * factor; // large margin - int d_margin2 = 2 * factor; // small margin - - int d_speed_w = d_dialog_w - (20 * factor); - int d_speed_h = 6 * factor; - int d_speed_x = d_dialog_x + (10 * factor); - int d_speed_y = d_dialog_y + d_top_margin + d_margin1 + d_txt6_h; - - int d_scroll_w = d_dialog_w - (20 * factor); - int d_scroll_h = 6 * factor; - int d_scroll_x = d_dialog_x + (10 * factor); - int d_scroll_y = d_speed_y + d_speed_h + d_txt6_h + (d_margin1 * 2) + d_txt6_h; - - int d_visual_w = d_dialog_w - (40 * factor); - int d_visual_h = 9 * factor; - int d_visual_x = d_dialog_x + (20 * factor); - int d_visual_y = d_scroll_y + d_scroll_h + d_txt6_h + (d_margin1 * 2); - - int d_sound_w = d_dialog_w - (40 * factor); - int d_sound_h = 9 * factor; - int d_sound_x = d_dialog_x + (20 * factor); - int d_sound_y = d_visual_y + d_visual_h + d_margin1; - - int d_ok_w = 20 * factor; - int d_ok_h = 9 * factor; - int d_ok_x = d_dialog_cx - (d_ok_w / 2); - int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin1; - - /* - ** Button Enumerations - */ - enum { - BUTTON_SPEED = 100, - BUTTON_SCROLLRATE, - BUTTON_VISUAL, - BUTTON_SOUND, - BUTTON_OK, - BUTTON_COUNT, - BUTTON_FIRST = BUTTON_SPEED, - }; - - /* - ** Dialog variables - */ - KeyNumType input; - - int gamespeed = Options.GameSpeed; - int scrollrate = Options.ScrollRate; - int selection; - bool pressed = false; - int curbutton = 0; - TextButtonClass *buttons[BUTTON_COUNT - BUTTON_FIRST]; - TextPrintType style; - - /* - ** Buttons - */ - GadgetClass *commands; // button list - - SliderClass gspeed_btn(BUTTON_SPEED, d_speed_x, d_speed_y, d_speed_w, d_speed_h); - - SliderClass scrate_btn(BUTTON_SCROLLRATE, d_scroll_x, d_scroll_y, d_scroll_w, d_scroll_h); - - TextButtonClass visual_btn(BUTTON_VISUAL, TXT_VISUAL_CONTROLS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_visual_x, d_visual_y, d_visual_w, d_visual_h); - - TextButtonClass sound_btn(BUTTON_SOUND, TXT_SOUND_CONTROLS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_sound_x, d_sound_y, d_sound_w, d_sound_h); - - TextButtonClass okbtn(BUTTON_OK, TXT_OPTIONS_MENU, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ok_x, d_ok_y); - okbtn.X = (SeenBuff.Get_Width()-okbtn.Width)/2; - - /* - ** Various Inits. - */ - Set_Logic_Page(SeenBuff); - - /* - ** Build button list - */ - commands = &okbtn; - gspeed_btn.Add_Tail(*commands); - scrate_btn.Add_Tail(*commands); - visual_btn.Add_Tail(*commands); - sound_btn.Add_Tail(*commands); - - /* - ** Init button states - ** For sliders, the thumb ranges from 0 - (maxval-1), so to convert the - ** thumb value to a real-world value: - ** val = (MAX - slider.Get_Value()) - 1; - ** and, - ** slider.Set_Value(-(val + 1 - MAX)); - */ - gspeed_btn.Set_Maximum(OptionsClass::MAX_SPEED_SETTING); // varies from 0 - 7 - gspeed_btn.Set_Thumb_Size(1); - gspeed_btn.Set_Value((OptionsClass::MAX_SPEED_SETTING-1) - gamespeed); - - scrate_btn.Set_Maximum(OptionsClass::MAX_SCROLL_SETTING); // varies from 0 - 7 - scrate_btn.Set_Thumb_Size(1); - scrate_btn.Set_Value((OptionsClass::MAX_SCROLL_SETTING-1) - scrollrate); - - /* - ** Fill array of button ptrs. - */ - buttons[0] = NULL; - buttons[1] = NULL; - buttons[2] = &visual_btn; - buttons[3] = &sound_btn; - buttons[4] = &okbtn; - - /* - ** Processing loop. - */ - bool process = true; - bool display = true; - bool refresh = true; - while (process) { - - /* - ** Invoke game callback. - */ - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - } - } - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Refresh display if needed. - */ - if (display) { - Hide_Mouse(); - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - Draw_Caption(TXT_GAME_CONTROLS, d_dialog_x, d_dialog_y, d_dialog_w); - Show_Mouse(); - display = false; - refresh = true; - } - - if (refresh) { - Hide_Mouse(); - - /* - ** Label the game speed slider - */ - style = TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL; - if (curbutton == (BUTTON_SPEED - BUTTON_FIRST)) { - style = (TextPrintType)(style | TPF_BRIGHT_COLOR); - } - Fancy_Text_Print(TXT_SPEED, d_speed_x, d_speed_y - d_txt6_h, CC_GREEN, TBLACK, style); - - Fancy_Text_Print(TXT_SLOWER, d_speed_x, d_speed_y + d_speed_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - Fancy_Text_Print(TXT_FASTER, d_speed_x + d_speed_w, d_speed_y + d_speed_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT); - - /* - ** Label the scroll rate slider - */ - style = TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL; - if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST)) { - style = (TextPrintType)(style | TPF_BRIGHT_COLOR); - } - Fancy_Text_Print(TXT_SCROLLRATE, d_scroll_x, d_scroll_y - d_txt6_h, CC_GREEN, TBLACK, style); - - Fancy_Text_Print (TXT_SLOWER, d_scroll_x, d_scroll_y + d_scroll_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - Fancy_Text_Print (TXT_FASTER, d_scroll_x + d_scroll_w, d_scroll_y + d_scroll_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT); - - commands->Draw_All(); - - Show_Mouse(); - refresh = false; - } - - /* - ** Get user input. - */ - input = commands->Input(); - - /* - ** Process input. - */ - switch (input) { - case (BUTTON_SPEED | KN_BUTTON): - curbutton = (BUTTON_SPEED - BUTTON_FIRST); - refresh = true; - break; - - case (BUTTON_SCROLLRATE | KN_BUTTON): - curbutton = (BUTTON_SCROLLRATE - BUTTON_FIRST); - refresh = true; - break; - - case (BUTTON_VISUAL | KN_BUTTON): - selection = BUTTON_VISUAL; - pressed = true; - break; - - case (BUTTON_SOUND | KN_BUTTON): - selection = BUTTON_SOUND; - pressed = true; - break; - - case (BUTTON_OK | KN_BUTTON): - selection = BUTTON_OK; - pressed = true; - break; - - case (KN_ESC): - process = false; - break; - - case (KN_LEFT): - if (curbutton == (BUTTON_SPEED - BUTTON_FIRST) ) { - gspeed_btn.Bump(1); - } else - if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST) ) { - scrate_btn.Bump(1); - } - break; - - case (KN_RIGHT): - if (curbutton == (BUTTON_SPEED - BUTTON_FIRST) ) { - gspeed_btn.Bump(0); - } else - if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST) ) { - scrate_btn.Bump(0); - } - break; - - case (KN_UP): - if (buttons[curbutton]) { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - } - - curbutton--; - if (curbutton < 0) { - curbutton = (BUTTON_COUNT - BUTTON_FIRST - 1); - } - - if (buttons[curbutton]) { - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - refresh = true; - break; - - case (KN_DOWN): - if (buttons[curbutton]) { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - } - - curbutton++; - if (curbutton > (BUTTON_COUNT - BUTTON_FIRST - 1) ) { - curbutton = 0; - } - - if (buttons[curbutton]) { - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - refresh = true; - break; - - case (KN_RETURN): - selection = curbutton + BUTTON_FIRST; - pressed = true; - break; - - default: - break; - } - - /* - ** Perform some action. Either to exit the dialog or bring up another. - */ - if (pressed) { - - /* - ** Record the new options slider settings. - ** The GameSpeed data member MUST NOT BE SET HERE!!! It will cause multiplayer - ** games to go out of sync. It's set by virtue of the event being executed. - */ - if (gamespeed != ((OptionsClass::MAX_SPEED_SETTING-1) - gspeed_btn.Get_Value()) ) { - gamespeed = (OptionsClass::MAX_SPEED_SETTING-1) - gspeed_btn.Get_Value(); - OutList.Add(EventClass(EventClass::GAMESPEED, gamespeed)); - } - - if (scrollrate != ((OptionsClass::MAX_SCROLL_SETTING-1) - scrate_btn.Get_Value()) ) { - scrollrate = (OptionsClass::MAX_SCROLL_SETTING-1) - scrate_btn.Get_Value(); - Options.ScrollRate = scrollrate; - } - process = false; - - /* - ** Save the settings in such a way that the GameSpeed is only set during - ** the save process; restore it when we're done, so multiplayer games don't - ** go out of sync. - */ - int old = Options.GameSpeed; // save orig value - Options.GameSpeed = gamespeed; - Options.Save_Settings(); // save new value - Options.GameSpeed = old; // restore old value - - /* - ** Possibly launch into another dialog if so directed. - */ - switch (selection) { - case (BUTTON_VISUAL): - VisualControlsClass().Process(); - process = true; - display = true; - refresh = true; - break; - - case (BUTTON_SOUND): - if (!SoundType) { - CCMessageBox().Process(Text_String(TXT_NO_SOUND_CARD)); - process = true; - display = true; - refresh = true; - } else { - SoundControlsClass().Process(); - } - break; - - case (BUTTON_OK): - break; - } - - pressed = false; - } - } -} - diff --git a/code/TIBERIANDAWN/GAMEDLG.H b/code/TIBERIANDAWN/GAMEDLG.H deleted file mode 100644 index 50f7e58..0000000 --- a/code/TIBERIANDAWN/GAMEDLG.H +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gamedlg.h_v 2.17 16 Oct 1995 16:45:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GAMEDLG.H * - * * - * Programmer : Maria del Mar McCready Legg, Joe L. Bostic * - * * - * Start Date : Jan 8, 1995 * - * * - * Last Update : Jan 18, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GAMEDLG_H -#define GAMEDLG_H - -#include "gadget.h" - -class GameControlsClass -{ - public: - GameControlsClass(void) {}; - void Process(void); -}; - - -#endif - diff --git a/code/TIBERIANDAWN/GAUGE.CPP b/code/TIBERIANDAWN/GAUGE.CPP deleted file mode 100644 index c6f4c52..0000000 --- a/code/TIBERIANDAWN/GAUGE.CPP +++ /dev/null @@ -1,536 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gauge.cpv 2.19 16 Oct 1995 16:50:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GAUGE.CPP * - * * - * Programmer : Joe L. Bostic, Maria del Mar McCready Legg * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 16, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * GaugeClass::Action -- Handles input events for the gauge. * - * GaugeClass::Draw_Me -- Draws the body of the gauge. * - * GaugeClass::Value_To_Pixel -- Convert gauge value to pixel offset. * - * GaugeClass::Pixel_To_Value -- Convert a pixel offset into a gauge value. * - * GaugeClass::Set_Value -- Set the value of the gauge. * - * GaugeClass::Set_Maximum -- Sets the maximum value for the gauge. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * GAUGECLASS::GAUGECLASS -- class constructor * - * * - * INPUT: id -- button ID * - * * - * x,y -- upper-left corner, in pixels * - * * - * w,h -- width, height, in pixels * - * * - * OUTPUT: none. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/05/1995 MML : Created. * - *=========================================================================*/ -GaugeClass::GaugeClass(unsigned id, int x, int y, int w, int h) - : ControlClass(id, x, y, w, h, LEFTHELD|LEFTPRESS|LEFTRELEASE, true) -{ - Set_Maximum(255); - Set_Value(0); - - HasThumb = true; - IsHorizontal = (w > h); - IsColorized = true; - - ClickDiff = 0; -} - - -/*********************************************************************************************** - * GaugeClass::Set_Maximum -- Sets the maximum value for the gauge. * - * * - * This routine will set the maximum value for the gauge. This is the largest value that * - * the current setting may reach. The ability to change this allows the guage to use and * - * return values that are convenient for the programmer's current needs. * - * * - * INPUT: value -- The value to use as the gauge maximum. * - * * - * OUTPUT: bool; Was the gauge maximum changed? A false indicates that the specified value * - * already matches the current maximum. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int GaugeClass::Set_Maximum(int value) -{ - if (value != MaxValue) { - MaxValue = value; - Flag_To_Redraw(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * GaugeClass::Set_Value -- Set the value of the gauge. * - * * - * This routine will set the current value for the gauge. This value is clipped to the * - * limits of the gauge maximum. * - * * - * INPUT: value -- The value to set at the new current value. * - * * - * OUTPUT: bool; Was the current setting changed? A false indicates that the setting * - * specified is the same as what was already there. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int GaugeClass::Set_Value(int value) -{ - value = Bound(value, 0, MaxValue); -// value = MIN(value, MaxValue); -// value = MAX(value, 0); - if (value != CurValue) { - CurValue = value; - Flag_To_Redraw(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * GaugeClass::Pixel_To_Value -- Convert a pixel offset into a gauge value. * - * * - * Use this routine to conver the specified pixel offset into a gauge value. This is used * - * in translating mouse clicks into a cooresponding setting for the guage. * - * * - * INPUT: pixel -- The pixel offset form the start of the gauge. * - * * - * OUTPUT: Returns with the setting value in guage coordinates. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int GaugeClass::Pixel_To_Value(int pixel) -{ - int maximum; - - if (IsHorizontal) { - pixel -= X+1; - maximum = Width; - } else { - pixel -= Y+1; - maximum = Height; - } - maximum -= 2; - pixel = Bound(pixel, 0, maximum); -// pixel = MIN(pixel, maximum); -// pixel = MAX(pixel, 0); - return(Fixed_To_Cardinal(MaxValue, Cardinal_To_Fixed(maximum, pixel))); -} - - -/*********************************************************************************************** - * GaugeClass::Value_To_Pixel -- Convert gauge value to pixel offset. * - * * - * Use this routine to convert the specified gauge value into a pixel offset from the * - * star of the gauge. This is used for thumb positioning. * - * * - * INPUT: value -- The value to convert to a pixel offset. * - * * - * OUTPUT: Returns with the pixel offset of the specified value from the start of the * - * guage. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int GaugeClass::Value_To_Pixel(int value) -{ - int maximum; - int start; - if (IsHorizontal) { - maximum = Width; - start = X; - } else { - maximum = Height; - start = Y; - } - maximum -= 2; - return(start + Fixed_To_Cardinal(maximum, Cardinal_To_Fixed(MaxValue, value))); -} - - -/*********************************************************************************************** - * GaugeClass::Draw_Me -- Draws the body of the gauge. * - * * - * This routine will draw the body of the gauge if necessary. * - * * - * INPUT: forced -- Should the gauge be redrawn regardless of the current redraw flag? * - * * - * OUTPUT: bool; Was the gauge redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int GaugeClass::Draw_Me(int forced) -{ - if (ControlClass::Draw_Me(forced)) { - - /* - ===================== Hide the mouse ===================== - */ - if (LogicPage == &SeenBuff) { - Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); - } - - /* - =========== Draw the body & set text color =============== - */ - Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_DOWN, true); - - /* - ** Colorize the inside of the gauge if indicated. - */ - if (IsColorized) { - int middle = Value_To_Pixel(CurValue); - int color = CC_BRIGHT_GREEN; - if (IsHorizontal) { - if (middle >= (X + 1)) - LogicPage->Fill_Rect(X+1, Y+1, middle, Y+Height-2, color); - } else { - if (middle >= (Y + 1)) - LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, middle, color); - } - } - - if (HasThumb) - Draw_Thumb(); - - /* - =================== Display the mouse =================== - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * GaugeClass::Action -- Handles input events for the gauge. * - * * - * This routine will handle input event processing for the gauge. It will adjust the * - * current setting of the gauge according to the mouse position. * - * * - * INPUT: flags -- The input event that is the reason for this function call. * - * key -- The key code that caused the event. * - * * - * OUTPUT: bool; Was the even recognized, processed, and no further gadget scanning is * - * desird (for this pass). * - * * - * WARNINGS: none * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int GaugeClass::Action(unsigned flags, KeyNumType &key) -{ - /* - ** If there's no thumb on this gauge, it's a display-only device; ignore - ** any input. - */ - if (!HasThumb) { - key = KN_NONE; - return(true); - } - - /* - ** We might end up clearing the event bits. Make sure that the sticky - ** process is properly updated anyway. - */ - Sticky_Process(flags); - - /* - ** If the thumb is currently being "dragged around", then update the slider - ** position according to the mouse position. In all other cases, ignore the - ** button being held down. - */ - if ((flags & LEFTPRESS) || ((flags & LEFTHELD) && StuckOn == this)) { - - /* - ** Compute the difference between where we clicked, and the edge of - ** the thumb (only if we clicked on the thumb.) - */ - if (flags & LEFTPRESS) { - int curpix = Value_To_Pixel(CurValue); - int clickpix = (IsHorizontal ? Get_Mouse_X() : Get_Mouse_Y()); - - if ( (clickpix > curpix) && (clickpix - curpix) < Thumb_Pixels()) { - ClickDiff = (clickpix - curpix); - } else { - ClickDiff = 0; - } - - int testval = Pixel_To_Value(IsHorizontal ? - Get_Mouse_X() - ClickDiff : Get_Mouse_Y() - ClickDiff); - - /* - ** Correct for round-down errors in Pixel_To_Value() and - ** Value_To_Pixe(); make ClickDiff exactly right so that - ** at this point, Get_Mouse_n() - ClickDiff converts to - ** CurValue. - */ - while (testval < CurValue && ClickDiff > 0) { - ClickDiff--; - testval = Pixel_To_Value(IsHorizontal ? - Get_Mouse_X() - ClickDiff : Get_Mouse_Y() - ClickDiff); - } - } - - /* - ** If no change occurred in the gauge, just call Control's Action routine, - ** but turn off the flags so it won't fill in 'key' with the button ID. - ** Thus, no button ID will be returned by Input. - */ - if (!Set_Value(Pixel_To_Value(IsHorizontal ? - Get_Mouse_X() - ClickDiff : Get_Mouse_Y() - ClickDiff))) { - - flags &= ~(LEFTHELD|LEFTRELEASE|LEFTPRESS); - ControlClass::Action(0,key); - key = KN_NONE; - return(true); - } - - } else { - - /* - ** Ingore the left mouse button being held down if this gauge is not - ** currently in "sticky" mode. This allows processing of the LEFTPRESS - ** by any derived classes such that this guage can be more closely - ** controlled. - */ - flags &= ~LEFTHELD; - } - return(ControlClass::Action(flags, key)); -} - - -/*********************************************************************************************** - * GaugeClass::Draw_Thumb -- Draws the body of the gauge. * - * * - * This routine will draw the body of the gauge if necessary. * - * * - * INPUT: none. * - * * - * OUTPUT: none. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/16/1995 MML : Created. * - *=============================================================================================*/ -void GaugeClass::Draw_Thumb(void) -{ - int x = Value_To_Pixel(CurValue); - -// if ((x + 8) > Value_To_Pixel(MaxValue)) { - if ((x + 4) > Value_To_Pixel(MaxValue)) { - x = Value_To_Pixel(MaxValue) - 2; - } - - if (IsHorizontal) { - Draw_Box(x, Y, 4, Height, BOXSTYLE_GREEN_RAISED, true); - //Draw_Box(x, Y, 8, Height, BOXSTYLE_GREEN_RAISED, true); - } else { - Draw_Box(X, x, Width, 4, BOXSTYLE_GREEN_RAISED, true); - //Draw_Box(X, x, Width, 8, BOXSTYLE_GREEN_RAISED, true); - } -} - - -/*********************************************************************************************** - * TriColorGaugeClass::TriColorGaugeClass -- Constructor for 3 color (red\yellow\green) gauge. * - * * - * This routine will draw the body of the gauge if necessary. * - * * - * INPUT: See below. * - * * - * OUTPUT: none. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/16/1995 MML : Created. * - *=============================================================================================*/ -TriColorGaugeClass::TriColorGaugeClass(unsigned id, int x, int y, int w, int h) - : GaugeClass(id, x, y, w, h) -{ - RedLimit = 0; // maximum value for red - YellowLimit = 0; // maximum value for yellow -} - - -/*********************************************************************************************** - * TriColorGaugeClass::Set_Red_Limit -- Set the value for the red area of gauge. * - * * - * INPUT: int value. * - * * - * OUTPUT: bool true of false. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/16/1995 MML : Created. * - *=============================================================================================*/ -int TriColorGaugeClass::Set_Red_Limit(int value) -{ - if (value >= 0 && value < MaxValue) { - -// if (value > YellowLimit) { -// RedLimit = YellowLimit; -// YellowLimit = value; -// } else { - RedLimit = value; -// } - Flag_To_Redraw(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TriColorGaugeClass::Set_Yellow_Limit -- Set the value for the yellow area of gauge. * - * * - * INPUT: int value. * - * * - * OUTPUT: bool true of false. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/16/1995 MML : Created. * - *=============================================================================================*/ -int TriColorGaugeClass::Set_Yellow_Limit(int value) -{ - if (value >= 0 && value < MaxValue) { - -// if (value < RedLimit) { -// YellowLimit = RedLimit; -// RedLimit = value; -// } else { - YellowLimit = value; -// } - Flag_To_Redraw(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TriColorGaugeClass::Draw_Me -- Draw the tri color gauge. * - * * - * INPUT: int forced -- draw or not? * - * * - * OUTPUT: bool true of false. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/16/1995 MML : Created. * - *=============================================================================================*/ -int TriColorGaugeClass::Draw_Me(int forced) -{ - if (ControlClass::Draw_Me(forced)) { - - /* - ===================== Hide the mouse ===================== - */ - if (LogicPage == &SeenBuff) { - Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); - } - /* - =========== Draw the body & set text color =============== - */ - Draw_Box (X, Y, Width, Height, (IsDisabled ? BOXSTYLE_GREEN_RAISED : BOXSTYLE_GREEN_DOWN), true); - - /* - ** Colorize the inside of the gauge if indicated. - */ - int red = Value_To_Pixel(RedLimit); - int yellow = Value_To_Pixel(YellowLimit); - int middle = Value_To_Pixel(CurValue); - - if (CurValue <= RedLimit) { - if (IsHorizontal) { - LogicPage->Fill_Rect(X+1, Y+1, middle, Y+Height-2, PINK); - } else { - LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, middle, PINK); - } - } else if (CurValue > RedLimit && CurValue <= YellowLimit) { - if (IsHorizontal) { - LogicPage->Fill_Rect(X+1, Y+1, red, Y+Height-2, PINK); - LogicPage->Fill_Rect(red, Y+1, middle, Y+Height-2, YELLOW); - } else { - LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, red, PINK); - LogicPage->Fill_Rect(X+1, red, X+Width-2, middle, YELLOW); - } - } else if (CurValue > YellowLimit && CurValue <= MaxValue) { - - if (IsHorizontal) { - LogicPage->Fill_Rect(X+1, Y+1, red, Y+Height-2, PINK); - LogicPage->Fill_Rect(red, Y+1, yellow, Y+Height-2, YELLOW); - LogicPage->Fill_Rect(yellow, Y+1, middle, Y+Height-2, GREEN); - } else { - LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, red, PINK); - LogicPage->Fill_Rect(X+1, red, X+Width-2, yellow, YELLOW); - LogicPage->Fill_Rect(X+1, yellow, X+Width-2, middle, GREEN); - } - } - - if (HasThumb) - Draw_Thumb(); - - /* - =================== Display the mouse =================== - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - return(true); - } - return(false); -} - diff --git a/code/TIBERIANDAWN/GAUGE.H b/code/TIBERIANDAWN/GAUGE.H deleted file mode 100644 index cc63ccc..0000000 --- a/code/TIBERIANDAWN/GAUGE.H +++ /dev/null @@ -1,108 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gauge.h_v 2.17 16 Oct 1995 16:45:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GAUGE.H * - * * - * Programmer : Joe L. Bostic, Maria del Mar McCready Legg * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GAUGE_H -#define GAUGE_H - -class GaugeClass : public ControlClass -{ - public: - - GaugeClass(unsigned id, int x, int y, int w, int h); -// static GaugeClass * Create_One_Of(unsigned id, int x, int y, int w, int h); - - virtual int Draw_Me(int forced=false); - virtual int Set_Maximum(int value); - virtual int Set_Value(int value); - virtual int Get_Value(void) const {return (CurValue);}; - virtual void Use_Thumb(int value) { HasThumb = value ? true : false; }; - - virtual int Thumb_Pixels(void) { return (8);} - - /* - ** If this gauge has a color to the left of the current setting, then this - ** flag will be true. - */ - unsigned IsColorized:1; - - protected: - - /* - ** If a thumb is desired, set to true. - */ - unsigned HasThumb:1; - - /* - ** Is this a horizontal slider? - */ - unsigned IsHorizontal:1; - - int MaxValue; // maximum value (in application units) - int CurValue; // index of 1st displayed string in box - // (in application units) - - /* - ** This value records the difference between where the user clicked - ** and the edge of the thumb, so that the thumb follows the mouse - ** with the proper offset. - */ - int ClickDiff; - - protected: - virtual void Draw_Thumb(void); - virtual int Action(unsigned flags, KeyNumType &key); - virtual int Pixel_To_Value(int pixel); - virtual int Value_To_Pixel(int value); -}; - - - -class TriColorGaugeClass : public GaugeClass -{ - public: - TriColorGaugeClass(unsigned id, int x, int y, int w, int h); -// static TriColorGaugeClass * Create_One_Of(unsigned id, int x, int y, int w, int h); - virtual int Draw_Me(int forced); - virtual int Set_Red_Limit(int value); - virtual int Set_Yellow_Limit(int value); - - protected: - int RedLimit; // maximum value for red - int YellowLimit; // maximum value for yellow -}; - - - - -#endif diff --git a/code/TIBERIANDAWN/GLOBALS.CPP b/code/TIBERIANDAWN/GLOBALS.CPP deleted file mode 100644 index 8370947..0000000 --- a/code/TIBERIANDAWN/GLOBALS.CPP +++ /dev/null @@ -1,1053 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\globals.cpv 2.17 16 Oct 1995 16:52:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GLOBALS.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : September 10, 1993 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef JAPANESE -bool ForceEnglish = false; -#endif - -bool Debug_Quiet = false; -bool Debug_Cheat = false; -bool Debug_Remap = false; -bool Debug_Icon = false; -bool Debug_Flag = false; -bool Debug_Lose = false; -bool Debug_Win = false; -bool Debug_Map = false; // true = map editor mode -bool Debug_Passable = false; // true = show passable/impassable terrain -bool Debug_Unshroud = false; // true = hide the shroud -bool Debug_Threat = false; -bool Debug_Find_Path = false; -bool Debug_Check_Map = false; // true = validate the map each frame -bool Debug_Playtest = false; -int In_Debugger = 0; -bool Debug_Heap_Dump = false; // true = print the Heap Dump -bool Debug_Smart_Print = false; // true = print everything that calls Smart_Printf -bool Debug_Trap_Check_Heap = false; // true = check the Heap -bool Debug_Instant_Build = false; -bool Debug_Force_Crash = false; - - -TFixedIHeapClass Units; -TFixedIHeapClass Factories; -TFixedIHeapClass Terrains; -TFixedIHeapClass Templates; -TFixedIHeapClass Smudges; -TFixedIHeapClass Overlays; -TFixedIHeapClass Infantry; -TFixedIHeapClass Bullets; -TFixedIHeapClass Buildings; -TFixedIHeapClass Anims; -TFixedIHeapClass Aircraft; -TFixedIHeapClass Triggers; -TFixedIHeapClass TeamTypes; -TFixedIHeapClass Teams; -TFixedIHeapClass Houses; - - -#ifdef PATCH -/*************************************************************************** -** Compatibility with version 1.07 flag. -*/ -bool IsV107 = false; -char OverridePath[128]="."; -#endif - - -/*************************************************************************** -** This tracks all selected objects per house (for this map). -*/ -SelectedObjectsType CurrentObject; - - -/*************************************************************************** -** This holds the custom version text that is fetched from the version -** text file. This version is displayed on the options dialog. -*/ -char VersionText[16]; - - -/*************************************************************************** -** This is the VQ animation controller structure. It is filled in by reading -** the PLAYER.INI and overridden through program control. -*/ -//PG_TO_FIX -//VQAConfig AnimControl; - -int PreserveVQAScreen; // Used for screen mode transition control. -bool BreakoutAllowed = true; // "true" if aborting of movies is allowed. -bool Brokeout; // Was the movie broken out of? -bool SlowPalette = true; // Slow palette flag set? - - -/*************************************************************************** -** These are the movie names to use for mission briefing, winning, and losing -** sequences. They are read from the INI file. -*/ -char IntroMovie[_MAX_FNAME+_MAX_EXT]; -char BriefMovie[_MAX_FNAME+_MAX_EXT]; -char WinMovie[_MAX_FNAME+_MAX_EXT]; -char WinMovie2[_MAX_FNAME + _MAX_EXT]; -char WinMovie3[_MAX_FNAME + _MAX_EXT]; -char WinMovie4[_MAX_FNAME + _MAX_EXT]; -char LoseMovie[_MAX_FNAME+_MAX_EXT]; -char ActionMovie[_MAX_FNAME+_MAX_EXT]; -char MovieThemeName[_MAX_FNAME + _MAX_EXT]; -char BriefingText[512]; -ThemeType TransitTheme = THEME_NONE; - - -/*************************************************************************** -** This records the view hotspots for the player. These are the cell numbers -** of the upper left corner for the view position. -*/ -CELL Views[4]; - - -/*************************************************************************** -** This is the pending speech sample to play. This sample will be played -** at the first opportunity. -*/ -VoxType SpeakQueue = VOX_NONE; - - -/*************************************************************************** -** This records if the score (music) file is present. If not, then much of -** the streaming score system can be disabled. -*/ -bool ScoresPresent; - - -/*************************************************************************** -** This flag will control whether there is a response from game units. -** By carefully controlling this global, multiple responses are supressed -** when a large group of infantry is given the movement order. -*/ -bool AllowVoice = true; - - -/*************************************************************************** -** This counts the number of crates on the map. When this value reaches zero, -** then a timer is started that will control crate creation. -*/ -int CrateCount; -TCountDownTimerClass CrateTimer; -bool CrateMaker = false; - - -/*************************************************************************** -** This is the current frame number. This number is guaranteed to count -** upward at the rate of one per game logic process. The target rate is 15 -** per second. This value is saved and restored with the saved game. -*/ -long Frame = 0; - - -/*************************************************************************** -** These globals are constantly monitored to determine if the player -** has won or lost. They get set according to the trigger events associated -** with the scenario. -*/ -bool PlayerWins; -bool PlayerLoses; -bool PlayerRestarts; - -/* -** This flag is set if the player neither wins nor loses; it's mostly for -** multiplayer mode. -*/ -bool PlayerAborts; - - -/*************************************************************************** -** This is the pointer for the speech staging buffer. This buffer is used -** to hold the currently speaking voice data. Since only one speech sample -** is played at a time, this buffer is only as big as the largest speech -** sample that can be played. -*/ -void * SpeechBuffer; - - -/*************************************************************************** -** This is a running accumulation of the number of ticks that were unused. -** This accumulates into a useful value that contributes to a -** histogram of game performance. -*/ -long SpareTicks; - - -/*************************************************************************** -** This is a special scenario count down value. End of game condition will -** not be checked until this value reaches zero. -*/ -int EndCountDown; - - -/*************************************************************************** -** When the player sabotages a building (scenario #6 GDI only) then when -** the next scenario starts, that building will already be destroyed. -*/ -StructType SabotagedType; - - -/*************************************************************************** -** If the Nod temple was destroyed by the ion cannon, then this flag will -** be set to true. -*/ -bool TempleIoned = false; - - -/*************************************************************************** -** This is the monochrome debug page array. The various monochrome data -** screens are located here. -*/ -MonoClass MonoArray[MonoClass::MAX_MONO_PAGES]; -int MonoPage; // The current page. - - -/*************************************************************************** -** This is true if the game is the currently in focus windows app -** -*/ -bool GameInFocus = true; - -/*************************************************************************** -** This holds the theater specific mixfiles. -*/ -MixFileClass *TheaterData = NULL; -MixFileClass *TheaterIcons = NULL; -MixFileClass *LowTheaterData; -MixFileClass *MoviesMix = 0; -MixFileClass *GeneralMix = 0; -MixFileClass *ScoreMix = 0; - - -/*************************************************************************** -** This is the options control class. The options control such things as -** game speed, visual controls, and other user settings. -*/ -GameOptionsClass Options; - - -/*************************************************************************** -** Logic processing is controlled by this element. It handles both graphic -** and AI logic. -*/ -LogicClass Logic; - - -/*************************************************************************** -** This handles the background music. -*/ -ThemeClass Theme; - - -/*************************************************************************** -** This is the main control class for the map. -*/ -#ifdef SCENARIO_EDITOR -MapEditClass Map; -#else -MouseClass Map; -#endif - -/************************************************************************** -** The running game score is handled by this class (and member functions). -*/ -ScoreClass Score; - - -/*************************************************************************** -** The running credit display is controlled by this class (and member -** functions. -*/ -CreditClass CreditDisplay; - - -/*************************************************************************** -** These are the bits that are set when the appropriate tutor message -** has been displayed. Once the message has been displayed, it will not be -** displayed again. -*/ -long TutorFlags[2]; - - -/************************************************************************** -** This class records the special command override options that C&C -** supports. -*/ -SpecialClass Special; - - -/*************************************************************************** -** General rules that control the game. -*/ -RulesClass Rule; - - -/*************************************************************************** -** This is the scenario data for the currently loaded scenario. -** These variables should all be set together. -*/ -HousesType Whom; // Initial command line house choice. -unsigned Scenario; // Scenario # -ScenarioPlayerType ScenPlayer; // GDI, NOD, 2-Player, Multi-Player -ScenarioDirType ScenDir; // East/West -ScenarioVarType ScenVar; // variation A/B/C -char ScenarioName[_MAX_FNAME+_MAX_EXT]; // name of scenario -int CarryOverMoney; // Carry over money from last scenario. -int CarryOverPercent; // Carry over money percentage control. -int CarryOverCap; // Maxmimum carry over money allowed. -int ScenarioInit; -bool SpecialFlag = false; - - -/*************************************************************************** -** This value tells the sidebar what items it's allowed to add. The -** lower the value, the simpler the sidebar will be. -*/ -unsigned BuildLevel = 3; // Buildable level (1 = simplest) - - -/*************************************************************************** -** This value is computed every time a new scenario is loaded; it's a -** CRC of the INI and binary map files. -*/ -unsigned long ScenarioCRC; - - -/*************************************************************************** -** The various tutor and dialog messages are located in the data block -** referenced by this pointer. -*/ -char const * SystemStrings; - - -/*************************************************************************** -** The game plays as long as this var is true. -*/ -bool GameActive; - - -/*************************************************************************** -** This is a scratch variable that is used to when a reference is needed to -** a long, but the value wasn't supplied to a function. This is used -** specifically for the default reference value. As such, it is not stable. -*/ -long LParam; - - -#ifdef SCENARIO_EDITOR -/*************************************************************************** -** The currently-selected cell for the Scenario Editor -*/ -CELL CurrentCell = 0; -#endif - - -/*************************************************************************** -** Most of the text in the game will use the six point font. These are the -** pointers to the fonts. If it is NULL, then the font hasn't been loaded -** yet. -*/ -void const *Green12FontPtr; // Green font for pressed in tabs -void const *Green12GradFontPtr; // Graduated green font for tabs -void const *MapFontPtr; // Standard very small font. -void const *Font3Ptr; // Standard very small font. -void const *Font6Ptr; // Standard small font. -void const *Font8Ptr; // 8 point proportional. -void const *FontLEDPtr; // LED fixed point font. -void const *VCRFontPtr; // VCR font pointer. -void const *ScoreFontPtr; // font for score & map selection screens -void const *GradFont6Ptr; // gradient 6 point font pointer. - - -/*************************************************************************** -** This is the house that the human player is currently playing. -*/ -HouseClass * PlayerPtr; - - -/*************************************************************************** -** Special palettes for MCGA mode goes here. These palette buffers are used -** for pictures that do not use the game palette or are used for fading to -** black. -*/ -unsigned char *GamePalette; -unsigned char *BlackPalette; -unsigned char *WhitePalette; -unsigned char *OriginalPalette; -unsigned char *Palette; - - -/*************************************************************************** -** These are the event queues. One is for holding events until they are ready to be -** sent to the remote computer for processing. The other list is for incoming events -** that need to be executed when the correct frame has been reached. -*/ -QueueClass OutList; -QueueClass DoList; - - -/*************************************************************************** -** These are arrays/lists of trigger pointers for each cell & the houses. -*/ -DynamicVectorClass CellTriggers; -DynamicVectorClass HouseTriggers[HOUSE_COUNT]; - - -/*************************************************************************** -** This is an array of waypoints; each waypoint corresponds to a letter of -** the alphabet, and points to a cell number. -1 means unassigned. -** The CellClass has a bit that tells if that cell has a waypoint attached to -** it; the only way to find which waypoint it is, is to scan this array. This -** shouldn't be needed often; usually, you know the waypoint & you want the CELL. -*/ -CELL Waypoint[WAYPT_COUNT]; - - -/*************************************************************************** -** This is the list of BuildingTypes that define the AI's base. -*/ -BaseClass Base; - - -/*************************************************************************** -** This value tells what type of multiplayer game we're playing. -*/ -GameType GameToPlay = GAME_NORMAL; - - -/*************************************************************************** -** This is the current communications protocol -*/ -CommProtocolType CommProtocol; - - -/*************************************************************************** -** These values are used for recording & playing back a game. -*/ -CCFileClass RecordFile ("RECORD.BIN"); -int RecordGame = 0; // 1 = record a game -int SuperRecord = 0; // 1 = reopen record file with every write -int PlaybackGame= 0; // 1 = play back a game -int AllowAttract = 0; // 1 = allow attract mode - - -/*************************************************************************** -** This is the null modem manager class. Declaring this class doesn't -** perform any allocations; -** the class itself is ?? bytes. -*/ -#if (0) //PG_TO_FIX -bool ModemService = true; // When false disable servicing modem. -NullModemClass NullModem ( - 16, // number of send entries - 64, // number of receive entries -// sizeof (EventClass) * MAX_EVENTS, // maxlen of entry buffer - (200 / sizeof(EventClass) ) * sizeof(EventClass) + sizeof( CommHeaderType ), - 0x1234); // Magic number must have each digit unique - // and different from the queue magic number - - -DynamicVectorClass PhoneBook; -int CurPhoneIdx; // current phonebook index, for dialing - -DynamicVectorClass InitStrings; - -SerialSettingsType SerialDefaults; // serial port default settings - -//ModemGameType ModemGameToPlay; // type of modem play Dialer, answerer, null - -char *DialMethodCheck[ DIAL_METHODS ] = { - "T", - "P" -}; - -char *CallWaitStrings[ CALL_WAIT_STRINGS_NUM ] = { - "*70,", - "70#,", - "1170,", - "CUSTOM - " -}; -#endif - -ModemGameType ModemGameToPlay; // type of modem play Dialer, answerer, null - -/*************************************************************************** -** Index into scenario description list box -*/ -int ScenarioIdx; - - -/*************************************************************************** -** This array of flags tells if the given colors have been used, or are -*/ -int ColorUsed[MAX_MPLAYER_COLORS]; - - -/*************************************************************************** -** This string stores the player's name. -*/ -char MPlayerName[MPLAYER_NAME_MAX]; - - -/*************************************************************************** -** This is the array of remap colors. Each player in a network game is -** assigned one of these colors. The 'G' is for graphics drawing; the 'T' -** is for text printing (indicates a remap table for the font to use). -*/ -int MPlayerGColors[MAX_MPLAYER_COLORS] = { - 5, // Yellow - 127, // Red - 135, // BlueGreen - 26, // Orange - 4, // Green - 202 // Blue-Grey -}; - -int MPlayerTColors[MAX_MPLAYER_COLORS] = { - CC_GDI_COLOR, // Yellow - CC_NOD_COLOR, // Red - CC_BLUE_GREEN, // BlueGreen - CC_ORANGE, // Orange //26 - CC_GREEN, // Green - CC_BLUE_GREY, // Blue -}; - - -/*************************************************************************** -** This is a list of all the names of the multiplayer scenarios that use -** bases (production), and those that don't. There is a list for -** descriptions, and another for actual filenames. -*/ -char MPlayerDescriptions[100][40]; -DynamicVectorClass MPlayerScenarios; -DynamicVectorClass MPlayerFilenum; - - -/*************************************************************************** -** This value determines the max allowable # of players. -*/ -int MPlayerMax = 4; - - -/*************************************************************************** -** Multiplayer game options -*/ -int MPlayerPrefColor; // preferred color index for this player -int MPlayerColorIdx; // actual color index of this player -HousesType MPlayerHouse; // House of this player (GDI/NOD) -unsigned char MPlayerLocalID; // ID of this player -int MPlayerCount; // # of human players in this game -int MPlayerBases; // 1 = bases are on for this scenario -int MPlayerCredits; // # credits everyone gets -int MPlayerTiberium; // 1 = tiberium enabled for this scenario -int MPlayerGoodies; // 1 = goodies enabled for this scenario -int MPlayerGhosts; // 1 = houses with no players will still play -int MPlayerSolo = 0; // 1 = allows a single-player net game -int MPlayerUnitCount = 10; // # units for non-base multiplayer scenarios - - -/*--------------------------------------------------------------------------- -Min & Max unit count values; index0 = bases OFF, index1 = bases ON ----------------------------------------------------------------------------*/ -int MPlayerCountMin[2] = {1,0}; -int MPlayerCountMax[2] = {50,12}; - - -/*--------------------------------------------------------------------------- -MPlayerMaxAhead is the number of frames ahead of this one to execute a given -packet. It's set by the RESPONSE_TIME event. ----------------------------------------------------------------------------*/ -unsigned long MPlayerMaxAhead = 3; - - -/*--------------------------------------------------------------------------- -'FrameSendRate' is the # frames between data packets -'FrameRateDelay' is the time ticks to wait between frames, for smoothing. ----------------------------------------------------------------------------*/ -unsigned long FrameSendRate; - - -/*************************************************************************** -** Multiplayer ID's, stored in order of event execution. -** Format: -** bits 0-3: the "preferred" house of the player (GDI/NOD) -** bits 4-7: the player's Color Index -** These values are used as the IPX connection ID's. -*/ -unsigned char MPlayerID [MAX_PLAYERS]; - - -/*************************************************************************** -** This array stores the actual HousesType for all players (MULT1, etc). -*/ -HousesType MPlayerHouses [MAX_PLAYERS]; - - -/*************************************************************************** -** This array stores the names of all players in a multiplayer game. -*/ -char MPlayerNames [MAX_PLAYERS][MPLAYER_NAME_MAX]; - - -/*************************************************************************** -** This is a list of the messages received from / sent to other players, -** the address to send to (IPX only), and the last message received or -** sent (for the computer's messages). -*/ -MessageListClass Messages; -IPXAddressClass MessageAddress; -char LastMessage[MAX_MESSAGE_LENGTH]; - - -/*************************************************************************** -** If this flag is set, computer AI will blitz the humans all at once; -** otherwise, the computer units trickle gradually out. -*/ -int MPlayerBlitz = 0; - - -/*************************************************************************** -** If this flag is set, we can move around the map, but we can't do anything. -** It means we've been defeated, but we're still allowed to watch the action. -*/ -int MPlayerObiWan = 0; - - -/*************************************************************************** -** These variables keep track of the multiplayer game scores. -*/ -MPlayerScoreType MPlayerScore[MAX_MULTI_NAMES]; -int MPlayerGamesPlayed; // # games played this run -int MPlayerNumScores; // # active entries in MPlayerScore -int MPlayerWinner; // index of winner of last game -int MPlayerCurGame; // index of current game being played - - -// -// This array stores the processing time required by all multiplayer systems. -// The values are stored in the same order as the 'MPlayerID' array. -// -int TheirProcessTime[MAX_PLAYERS - 1]; -int DesiredFrameRate; - - -/*************************************************************************** -** These values are used purely for the Mono debug display. They show the -** names of the Global Channel packet types, and the event types. -*/ -char *GlobalPacketNames[] = { - "Game?", - "Game!", - "Player?", - "Player!", - "Join?", - "Join!", - "Reject", - "GameOptions", - "Sign Off", - "GO!", - "Message", - "Ping" -}; - - -// yeah, there's 100 empty names here, because the SerialCommandType starts at 100. -char *SerialPacketNames[] = { - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "CONNECT", - "GAME_OPTIONS", - "SIGN_OFF", - "GO", - "MESSAGE", - "TIMING", - "SCORE_SCREEN", - "LAST_COMMAND", -}; - - -/*************************************************************************** -** These variables are just to help find sync bugs. -*/ -long TrapFrame = 0x7fffffff; // frame to start trapping object values at -RTTIType TrapObjType = RTTI_NONE; // type of object to trap -TrapObjectType TrapObject = {NULL}; // ptr to object being trapped -COORDINATE TrapCoord = 0; // COORD of object to trap -void *TrapThis = NULL; // 'this' ptr of object to trap -CellClass *TrapCell = NULL; // for trapping a cell -int TrapCheckHeap = 0; // start checking the Heap - - -/*************************************************************************** -** This is the network IPX manager class. It handles multiple remote -** connections. Declaring this class doesn't perform any allocations; -** the class itself is 140 bytes. -*/ -IPXManagerClass Ipx ( - sizeof (GlobalPacketType), // size of Global Channel packets - ((546 - sizeof(CommHeaderType)) / sizeof(EventClass) ) * sizeof(EventClass), - 10, // # entries in Global Queue - 8, // # entries in Private Queues - VIRGIN_SOCKET, // Socket ID # - IPXGlobalConnClass::COMMAND_AND_CONQUER); // Product ID # - - -//#if(TIMING_FIX) -// -// These values store the min & max frame #'s for when MaxAhead >>increases<<. -// If MaxAhead increases, and the other systems free-run to the new MaxAhead -// value, they may miss an event generated after the MaxAhead event was sent, -// but before it executed, since it will have been scheduled with the older, -// shorter MaxAhead value. This will cause a Packet_Received_Too_Late error. -// The frames from the point where the new MaxAhead takes effect, up to that -// frame Plus the new MaxAhead, represent a "period of vulnerability"; any -// events received that are scheduled to execute during this period should -// be re-scheduled for after that period. -// -int NewMaxAheadFrame1; -int NewMaxAheadFrame2; -//#endif - -/*************************************************************************** -** This is the user-specified IPX address of a desired game owner machine. -** Use this to cross a bridge. Only the 1st 4 numbers in the address are -** used; the rest are set to ff's, for broadcasting. 'IsBridge' is set -** if this address should be used. -*/ -int IsBridge = 0; -IPXAddressClass BridgeNet; - - -/*************************************************************************** -** This flag is true if the user has requested that this game be "secret" -** (The game will not appear to other systems just starting up.) -*/ -bool NetStealth = false; - - -/*************************************************************************** -** If this flag is true, the user won't receive messages from any player -** other than those in his own game. It defaults to protected mode. -*/ -bool NetProtect = true; - - -/*************************************************************************** -** This flag indicates whether the game is "open" or not to other network players. -*/ -bool NetOpen = false; - - -/*************************************************************************** -** This string stores the game's network name. -** GameName does not include the "'s Game"; comparing GameName to -** PlayerName can determine if this player is the originator of the game. -*/ -char MPlayerGameName[MPLAYER_NAME_MAX]; - - -/*************************************************************************** -** These variables are for servicing the Global Channel. -*/ -GlobalPacketType GPacket; // Global Channel packet -int GPacketlen; // length of incoming packet -IPXAddressClass GAddress; // address of sender -unsigned short GProductID; // sender's Product ID - - -/*************************************************************************** -** This is the "meta-packet"; it's a bunch of events lumped together. -** The packet's size is IPX's max size (546), rounded down to accommodate -** the max number of events possible. -*/ -char *MetaPacket = 0; -int MetaSize = ((546 - sizeof(CommHeaderType)) / sizeof(EventClass) ) * sizeof(EventClass); - - -/*************************************************************************** -** This is the random-number seed; it's synchronized between systems for -** multiplayer games. -*/ -int Seed = 0; -long *RandSeedPtr; - - -/*************************************************************************** -** If this value is non-zero, use it as the random # seed instead; this should -** help reproduce some bugs. -*/ -int CustomSeed = 0; - -int WindowList[][8] = { -/* xbyte, ypixel, bytewid, pixelht, cursor color, bkgd color, cursor x, cursor y */ - - /* do not change the first 2 entries!! they are necc. to the system */ - {0,0,40,200,WHITE,BLACK,0,0}, /* screen window */ - {1,75,38,100,WHITE,BLACK,0,0}, /* DOS Error window */ - - // Tactical map. - {0, 0, 40, 200, WHITE,LTGREY,0,0}, - - // Initial menu window. - {12, 199-42, 16, 42, LTGREY, DKGREY, 0, 0}, - - // Sidebar clipping window. - {0,0,0,0,0,0,0,0}, - - // Scenario editor window. - {5, 30, 30, 140, 0, 0, 0, 0}, - - // Custom window. - {0, 0, 0, 0, 0, 0, 0, 0}, - - // Virtual window for external rendering. ST - 1/15/2019 3:02PM - {0, 0, 0, 0, 0, 0, 0, 0}, -}; - - -/* X,Y,Item Width,Items High,Selected,Norm Color,Sel Color,zero */ -int MenuList[][8]={ - {1, 3, 12, 3, 0, WHITE, PINK, 0}, -}; - -GraphicBufferClass VisiblePage; -GraphicBufferClass HiddenPage; - -GraphicViewPortClass SeenBuff(&VisiblePage, 0,0,1536,1536); -GraphicBufferClass ModeXBuff; -GraphicViewPortClass HidPage(&HiddenPage, 0,0, 1536,1536); -byte SysMemPageBuffer[DEFAULT_SCREEN_WIDTH * 200]; -GraphicBufferClass SysMemPage(DEFAULT_SCREEN_WIDTH, 200, (void*)&SysMemPageBuffer[0]); -int SoundOn; -CountDownTimerClass FrameTimer(BT_SYSTEM, 0L); -CountDownTimerClass DebugTimer(BT_SYSTEM, 0L); -CountDownTimerClass CountDownTimer(BT_SYSTEM, 0L); - -NewConfigType NewConfig; - -/*************************************************************************** -** This timer measures how long (in ticks) it takes to process the game's -** logic, with no packet processing or artificial delays. -*/ -TimerClass ProcessTimer; -int ProcessTicks; // accumulated ticks -int ProcessFrames; // # frames used to measure 'ProcessTicks' - - -/*************************************************************************** -** This flag is for popping up dialogs that call the main loop. -*/ -SpecialDialogType SpecialDialog = SDLG_NONE; - - -/* -** This flags if used to tell can enter cell that we are in a find path -** check and thus should not uncloak units via Can_Enter_Cell. -*/ -//bool IsFindPath = false; - - -/*************************************************************************** -** Globals for the network Dialogs. -*/ - -/* -** List of all games out there, & the address of the game's owner -*/ -DynamicVectorClass Games; - -/* -** List of names & addresses of all the players in the game I'm joining. -** This is the really critical list, since it's used to form connections with -** all other players in my game. It's updated when I get a response to my -** outgoing query, or when I get a query from another system in my game asking -** who I am. This double-insurance means that if any system knows about me, -** I know about them too. The only catch is that if the game is started very, -** very soon after a player joins, not everyone may know about him; to prevent -** this, a timer restriction is put on the New Game dialog's GO button. -*/ -DynamicVectorClass Players; - -char *DebugFname; // for stoopid debugging purposes -int DebugLine; // for stoopid debugging purposes -#ifdef DEMO -int RequiredCD = -2; -#else -int RequiredCD = -1; -#endif -int MouseInstalled; - -/* -** Certain options must be enabled by both a command-line option, and an -** an entry in an INI file. If this flag is 'true', those options have been -** enabled by the INI file. -*/ -int AreThingiesEnabled = false; - - -/* -** Pointer to windows timer object -** -** -*/ - -WinTimerClass *WindowsTimer=NULL; - - -/* -** Command line arguments -** -** -*/ -char * Argv[20]; //Pointers to command line arguments -int Argc; //Command line argument count - - -WWKeyboardClass Kbd; -int ScreenWidth=1536; -int ScreenHeight=1536; -WWMouseClass *WWMouse = NULL; -HANDLE hInstance; -int AllDone; -BOOL InMovie = FALSE; //Are we currently playing a VQ movie? -bool MMXAvailable = false; //Does this CPU support MMX extensions? -//GetCDClass CDList; -bool GameStatisticsPacketSent; -bool ConnectionLost; - -TheaterType LastTheater = THEATER_NONE; - - -bool RunningAsDLL = false; \ No newline at end of file diff --git a/code/TIBERIANDAWN/GOPTIONS.CPP b/code/TIBERIANDAWN/GOPTIONS.CPP deleted file mode 100644 index 9d7f4bb..0000000 --- a/code/TIBERIANDAWN/GOPTIONS.CPP +++ /dev/null @@ -1,584 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\goptions.cpv 2.17 16 Oct 1995 16:50:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : July 27, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * OptionsClass::Process -- Handles all the options graphic interface. * - * Draw_Caption -- Draws a caption on a dialog box. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#include "goptions.h" -#include "loaddlg.h" -#include "sounddlg.h" -#include "visudlg.h" -#include "gamedlg.h" -#include "textbtn.h" -#include "confdlg.h" -#include "descdlg.h" - -void GameOptionsClass::Adjust_Variables_For_Resolution(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - OptionWidth = (216+8) * factor; - OptionHeight = 100 * factor; - OptionX = ((SeenBuff.Get_Width() - OptionWidth) / 2); - OptionY = ((SeenBuff.Get_Height() - OptionHeight) / 2); - ButtonWidth = 130 * factor; - OButtonHeight = 9 * factor; - CaptionYPos = 5 * factor; - ButtonY = 21 * factor; - Border1Len = 72 * factor; - Border2Len = 16 * factor; - ButtonResumeY = (OptionHeight - (15 * factor)); -} -/*********************************************************************************************** - * OptionsClass::Process -- Handles all the options graphic interface. * - * * - * This routine is the main control for the visual representation of the options * - * screen. It handles the visual overlay and the player input. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: 12/31/1994 MML : Created. * - * 06/23/1995 JLB : Handles restating the mission objective. * - * 07/27/1995 JLB : Adjusts menu for multiplay mode. * - *=============================================================================================*/ -void GameOptionsClass::Process(void) -{ - static struct { - int ID; // Button ID to use. - int Text; // Text number to use for this button. - bool Multiplay; // Allowed in multiplayer version? - } _constants[] = { - {BUTTON_LOAD, TXT_LOAD_MISSION, false}, - {BUTTON_SAVE, TXT_SAVE_MISSION, false}, - {BUTTON_DELETE, TXT_DELETE_MISSION, true}, - {BUTTON_GAME, TXT_GAME_CONTROLS, true}, - {BUTTON_QUIT, TXT_QUIT_MISSION, true}, - {BUTTON_RESUME, TXT_RESUME_MISSION, true}, - {BUTTON_RESTATE, TXT_RESTATE_MISSION, false}, - }; - - /* - ** Variables. - */ - TextButtonClass * buttons = 0; - int selection; - bool pressed; - int curbutton = 6; - int y; - TextButtonClass *buttonsel[sizeof(_constants)/sizeof(_constants[0])]; - - Set_Logic_Page(SeenBuff); - - /* - ** Build the button list for all of the buttons for this dialog. - */ - int maxwidth = 0; - int resfactor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - for (int index = 0; index < sizeof(_constants)/sizeof(_constants[0]); index++ ) { - int text = _constants[index].Text; - buttonsel[index] = NULL; - - if (GameToPlay != GAME_NORMAL && !_constants[index].Multiplay) { - buttonsel[index] = 0; - continue; - } - - if (GameToPlay != GAME_NORMAL && text == TXT_DELETE_MISSION) { - text = TXT_RESIGN; - } - - if (index < 5) { - y = (SeenBuff.Get_Height() - OptionHeight)/2 + ButtonY + ((OButtonHeight+2) * index); - } else { - y = OptionY + ButtonResumeY; - } - - TextButtonClass * g = new TextButtonClass(_constants[index].ID, - text, TPF_6PT_GRAD|TPF_NOSHADOW, 0, y); - - if (g->Width > maxwidth) { - maxwidth = g->Width; - } - if (!buttons) { - buttons = g; - } else { - g->Add_Tail(*buttons); - } - - buttonsel[index] = g; - } - - buttonsel[curbutton-1]->Turn_On(); - - /* - ** Force all button lengths to match the maximum length of the widest button. - */ - GadgetClass * g = buttons; - while (g) { - g->Width = MAX(maxwidth, 90 * resfactor); - g->X = OptionX+(OptionWidth-g->Width)/2; - g = g->Get_Next(); - } -#ifdef FRENCH - buttonsel[BUTTON_RESUME-1]->Width = 104 *resfactor; -#else - buttonsel[BUTTON_RESUME-1]->Width = 90 *resfactor; -#endif - buttonsel[BUTTON_RESUME-1]->X = OptionX+(5 * resfactor); - - if (GameToPlay == GAME_NORMAL) { - buttonsel[BUTTON_RESTATE-1]->Width = 90 * resfactor; - buttonsel[BUTTON_RESTATE-1]->X = OptionX+OptionWidth-(buttonsel[BUTTON_RESTATE-1]->Width+(5 * resfactor)); - } - - /* - ** This causes left mouse button clicking within the confines of the dialog to - ** be ignored if it wasn't recognized by any other button or slider. - */ - (new GadgetClass(OptionX, OptionY, OptionWidth, OptionHeight, GadgetClass::LEFTPRESS))->Add_Tail(*buttons); - - /* - ** This cause a right click anywhere or a left click outside the dialog region - ** to be equivalent to clicking on the return to game button. - */ - (new ControlClass(BUTTON_RESUME, 0, 0, SeenBuff.Get_Width(), SeenBuff.Get_Height(), GadgetClass::LEFTPRESS|GadgetClass::RIGHTPRESS))->Add_Tail(*buttons); - - Keyboard::Clear(); - - Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - - /* - ** Main Processing Loop. - */ - bool display = true; - bool process = true; - pressed = false; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Invoke game callback. - */ - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - } - } - - /* - ** Refresh display if needed. - */ - if (display) { - - /* - ** Redraw the map. - */ - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); - - /* - ** Reset up the window. Window x-coords are in bytes not pixels. - */ - Set_Window(WINDOW_EDITOR, OptionX, OptionY, OptionWidth, OptionHeight); - Hide_Mouse(); - - /* - ** Draw the background. - */ - Window_Box (WINDOW_EDITOR, BOXSTYLE_GREEN_BORDER); // has border, raised up - - /* - ** Draw the arrows border if requested. - */ - Draw_Caption(TXT_OPTIONS, OptionX, OptionY, OptionWidth); - - /* - ** Display the version number at the bottom of the dialog box. - */ -#ifdef DEMO - Version_Number(); - Fancy_Text_Print("DEMO%s", - ((WindowList[WINDOW_EDITOR][WINDOWX]+WindowList[WINDOW_EDITOR][WINDOWWIDTH])<<3)-3*resfactor, - WindowList[WINDOW_EDITOR][WINDOWY]+WindowList[WINDOW_EDITOR][WINDOWHEIGHT]-((GameToPlay == GAME_NORMAL) ? (32*resfactor) : (24*resfactor)), - DKGREY, TBLACK, - TPF_6POINT|TPF_NOSHADOW|TPF_RIGHT, - ScenarioName, - VersionText); -#else - Fancy_Text_Print("%s\rV.%d%s", - ((WindowList[WINDOW_EDITOR][WINDOWX]+WindowList[WINDOW_EDITOR][WINDOWWIDTH])<<3)-3*resfactor, - WindowList[WINDOW_EDITOR][WINDOWY]+WindowList[WINDOW_EDITOR][WINDOWHEIGHT]-((GameToPlay == GAME_NORMAL) ? (32*resfactor) : (24*resfactor)), - DKGREY, TBLACK, - TPF_6POINT|TPF_NOSHADOW|TPF_RIGHT, - ScenarioName, - Version_Number(), - VersionText); -#endif - - buttons->Draw_All(); - TabClass::Hilite_Tab(0); - Show_Mouse(); - display = false; - } - - /* - ** Get user input. - */ - KeyNumType input = buttons->Input(); - - /* - ** Process Input. - */ - switch (input) { - case (BUTTON_RESTATE | KN_BUTTON): - selection = BUTTON_RESTATE; - pressed = true; - break; - - case (BUTTON_LOAD | KN_BUTTON): - selection = BUTTON_LOAD; - pressed = true; - break; - - case (BUTTON_SAVE | KN_BUTTON): - selection = BUTTON_SAVE; - pressed = true; - break; - - case (BUTTON_DELETE | KN_BUTTON): - selection = BUTTON_DELETE; - pressed = true; - break; - - case (BUTTON_QUIT | KN_BUTTON): - selection = BUTTON_QUIT; - pressed = true; - break; - - case (BUTTON_GAME | KN_BUTTON): - selection = BUTTON_GAME; - pressed = true; - break; - - case (KN_ESC): - case (BUTTON_RESUME | KN_BUTTON): - selection = BUTTON_RESUME; - pressed = true; - break; - - case (KN_UP): - buttonsel[curbutton-1]->Turn_Off(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - curbutton--; - if (GameToPlay == GAME_NORMAL) { - if (curbutton < BUTTON_LOAD) { - curbutton = (BUTTON_COUNT - 1); - } - } else { - if (curbutton < BUTTON_DELETE) { - curbutton = BUTTON_RESUME; -// curbutton = (BUTTON_COUNT-1); - } - } - buttonsel[curbutton-1]->Turn_On(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - break; - - case (KN_DOWN): - buttonsel[curbutton-1]->Turn_Off(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - curbutton++; - if (GameToPlay == GAME_NORMAL) { - if (curbutton >= BUTTON_COUNT) { - curbutton = BUTTON_LOAD; - } - } else { - if (curbutton > BUTTON_RESUME) { - curbutton = BUTTON_DELETE; - } - } - buttonsel[curbutton-1]->Turn_On(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - break; - - case (KN_RETURN): - buttonsel[curbutton-1]->IsPressed = true; - buttonsel[curbutton-1]->Draw_Me(true); - selection = curbutton; - pressed = true; - break; - - default: - break; - } - - if (pressed) { - buttonsel[curbutton-1]->Turn_Off(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - curbutton = selection; - buttonsel[curbutton-1]->Turn_On(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - - switch (selection) { - case BUTTON_RESTATE: - display = true; -#ifdef JAPANESE - if (!Restate_Mission(ScenarioName, TXT_VIDEO, TXT_TAB_BUTTON_CONTROLS)) { -#else - if (!Restate_Mission(ScenarioName, TXT_VIDEO, TXT_OPTIONS)) { -#endif - BreakoutAllowed = true; - char buffer[25]; - sprintf(buffer, "%s.VQA", BriefMovie); - if (CCFileClass(buffer).Is_Available()) { - Play_Movie(BriefMovie); - } else { - Play_Movie(ActionMovie); - } - //BreakoutAllowed = false; - memset(BlackPalette, 0x01, 768); - Set_Palette(BlackPalette); - memset(BlackPalette, 0x00, 768); - Set_Palette(BlackPalette); - Map.Flag_To_Redraw(true); - Theme.Queue_Song(THEME_PICK_ANOTHER); - process = false; - } - break; - - case (BUTTON_LOAD): - display = true; - if (LoadOptionsClass(LoadOptionsClass::LOAD).Process()) { - process = false; - } - break; - - case (BUTTON_SAVE): - display = true; - LoadOptionsClass(LoadOptionsClass::SAVE).Process(); - break; - - case (BUTTON_DELETE): - display = true; - if (GameToPlay != GAME_NORMAL) { - if (Surrender_Dialog()) { - OutList.Add(EventClass(EventClass::DESTRUCT)); - } - process = false; - } else { - LoadOptionsClass(LoadOptionsClass::WWDELETE).Process(); - } - break; - - case (BUTTON_QUIT): - if (GameToPlay == GAME_NORMAL) { -#ifdef JAPANESE - switch (CCMessageBox().Process(TXT_CONFIRM_EXIT, TXT_YES, TXT_NO, TXT_RESTART)) { -#else - switch (CCMessageBox().Process(TXT_CONFIRM_EXIT, TXT_ABORT, TXT_CANCEL, TXT_RESTART)) { -#endif - case 2: - display = true; - break; - - case 0: - process = false; - Queue_Exit(); - break; - - case 1: - PlayerRestarts = true; - process = false; - break; - } - } else { - if (ConfirmationClass().Process(TXT_CONFIRM_EXIT)) { - process = false; - Queue_Exit(); - } else { - display = true; - } - } - break; - - case (BUTTON_GAME): - display = true; - GameControlsClass().Process(); - break; - - case (BUTTON_RESUME): - //Save_Settings(); - process = false; - display = true; - break; - } - - pressed = false; - buttonsel[curbutton-1]->IsPressed = false; - //buttonsel[curbutton-1]->Turn_Off(); - buttonsel[curbutton-1]->Turn_On(); - buttonsel[curbutton-1]->Flag_To_Redraw(); - } - } - - /* - ** Clean up and re-enter the game. - */ - buttons->Delete_List(); - - /* - ** Redraw the map. - */ - Keyboard::Clear(); - Call_Back(); - HiddenPage.Clear(); - Call_Back(); - Map.Flag_To_Redraw(true); - Map.Render(); -} - - -/*********************************************************************************************** - * Draw_Caption -- Draws a caption on a dialog box. * - * * - * This routine draws the caption text and any fancy filigree that the dialog may require. * - * * - * INPUT: text -- The text of the caption. This is the text number. * - * * - * x,y -- The dialog box X and Y pixel coordinate of the upper left corner. * - * * - * w -- The width of the dialog box (in pixels). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/23/1995 JLB : Created. * - *=============================================================================================*/ -void Draw_Caption(int text, int x, int y, int w) -{ - OptionControlType option = OPTION_NONE; - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - - /* - ** Determine the filigree to use depending on the text of the caption. - */ - switch (text) { - case TXT_GAME_CONTROLS: - case TXT_OPTIONS: - option = OPTION_CONTROLS; - break; - - case TXT_LOAD_MISSION: - case TXT_SAVE_MISSION: - case TXT_DELETE_MISSION: - option = OPTION_DELETE; - break; - - case TXT_NONE: - case TXT_MODEM_SERIAL: - case TXT_SELECT_MPLAYER_GAME: - case TXT_SELECT_SERIAL_GAME: - option = OPTION_DIALOG; - break; - - case TXT_HOST_SERIAL_GAME: - case TXT_JOIN_SERIAL_GAME: - option = OPTION_SERIAL; - break; - - case TXT_SETTINGS: - case TXT_PHONE_LIST: - case TXT_PHONE_LISTING: - option = OPTION_PHONE; - break; - - case TXT_JOIN_NETWORK_GAME: - option = OPTION_JOIN_NETWORK; - break; - - case TXT_NETGAME_SETUP: - option = OPTION_NETWORK; - break; - - case TXT_VISUAL_CONTROLS: - option = OPTION_VISUAL; - break; - - case TXT_SOUND_CONTROLS: - option = OPTION_SOUND; - break; - - default: - option = OPTION_DIALOG; - break; - } - - /* - ** Draw the filigree at the corners of the dialog. - */ - if (option != OPTION_NONE) { - CC_Draw_Shape(MixFileClass::Retrieve("OPTIONS.SHP"), (int)option, x+12, y+11, WINDOW_MAIN, SHAPE_CENTER); - CC_Draw_Shape(MixFileClass::Retrieve("OPTIONS.SHP"), (int)option+1, x+w-14, y+11, WINDOW_MAIN, SHAPE_CENTER); - } - - /* - ** Draw the caption. - */ - if (text != TXT_NONE) { - Fancy_Text_Print(text, w/2 + x, 5*factor + y, CC_GREEN, TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - - int length = String_Pixel_Width(Text_String(text)); - LogicPage->Draw_Line((x+(w/2))-(length/2), y+FontHeight+FontYSpacing + 5*factor, (x+(w/2))+(length/2), y+FontHeight+FontYSpacing + 5*factor, CC_GREEN); - } -} diff --git a/code/TIBERIANDAWN/GOPTIONS.H b/code/TIBERIANDAWN/GOPTIONS.H deleted file mode 100644 index 03b52a2..0000000 --- a/code/TIBERIANDAWN/GOPTIONS.H +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\goptions.h_v 2.19 16 Oct 1995 16:46:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : June 8, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GOPTIONS_H -#define GOPTIONS_H - -#include "options.h" -#include "gadget.h" - - -class GameOptionsClass : public OptionsClass { - enum GameOptionsButtonEnum { - BUTTON_LOAD=1, - BUTTON_SAVE, - BUTTON_DELETE, - BUTTON_GAME, - BUTTON_QUIT, - BUTTON_RESUME, - BUTTON_RESTATE, - - BUTTON_COUNT, - }; - - enum GameOptionsEnum { - #if(0) - - OPTION_WIDTH=(216+8), - OPTION_HEIGHT=100, - OPTION_X=((320 - OPTION_WIDTH) / 2), - OPTION_Y=((200 - OPTION_HEIGHT) / 2), -#ifdef FRENCH - BUTTON_WIDTH=142, -#else - BUTTON_WIDTH=130, -#endif -// OBUTTON_HEIGHT=13, - NUMBER_OF_BUTTONS=6, - CAPTION_Y_POS=5, - BUTTON_Y=21, - BORDER1_LEN=72, - BORDER2_LEN=16, - BUTTON_RESUME_Y=(OPTION_HEIGHT-15) - - #endif - }; - - public: - GameOptionsClass(void): OptionsClass () { }; - void Adjust_Variables_For_Resolution(void); - void Process(void); - - private: - int OptionWidth; - int OptionHeight; - int OptionX; - int OptionY; - int ButtonWidth; - int OButtonHeight; - int CaptionYPos; - int ButtonY; - int Border1Len; - int Border2Len; - int ButtonResumeY; -}; - -#endif diff --git a/code/TIBERIANDAWN/GSCREEN.CPP b/code/TIBERIANDAWN/GSCREEN.CPP deleted file mode 100644 index e241d0c..0000000 --- a/code/TIBERIANDAWN/GSCREEN.CPP +++ /dev/null @@ -1,529 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gscreen.cpv 2.17 16 Oct 1995 16:51:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GSCREEN.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : January 19, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * GScreenClass::GScreenClass -- Default constructor for GScreenClass. * - * GScreenClass::One_Time -- Handles one time class setups. * - * GScreenClass::Init -- Init's the entire display hierarchy by calling all Init routines. * - * GScreenClass::Init_Clear -- Sets the map to a known state. * - * GScreenClass::Init_Theater -- Performs theater-specific initializations. * - * GScreenClass::Init_IO -- Initializes the Button list ('Buttons'). * - * GScreenClass::Flag_To_Redraw -- Flags the display to be redrawn. * - * GScreenClass::Blit_Display -- Redraw the display from the hidpage to the seenpage. * - * GScreenClass::Render -- General drawing dispatcher an display update function. * - * GScreenClass::Input -- Fetches input and processes gadgets. * - * GScreenClass::Add_A_Button -- Add a gadget to the game input system. * - * GScreenClass::Remove_A_Button -- Removes a gadget from the game input system. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#include - -GadgetClass * GScreenClass::Buttons = 0; - -GraphicBufferClass * GScreenClass::ShadowPage = 0; - - -/*********************************************************************************************** - * GScreenClass::GScreenClass -- Default constructor for GScreenClass. * - * * - * This constructor merely sets the display system, so that it will redraw the first time * - * the render function is called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ -GScreenClass::GScreenClass(void) -{ - IsToUpdate = true; - IsToRedraw = true; -} - - -/*********************************************************************************************** - * GScreenClass::One_Time -- Handles one time class setups. * - * * - * This routine (and all those that overload it) must perform truly one-time initialization. * - * Such init's would normally be done in the constructor, but other aspects of the game may * - * not have been initialized at the time the constructors are called (such as the file system, * - * the display, or other WWLIB subsystems), so many initializations should be deferred to the * - * One_Time init's. * - * * - * Any variables set in this routine should be declared as static, so they won't be modified * - * by the load/save process. Non-static variables will be over-written by a loaded game. * - * * - * This function allocates the shadow buffer that is used for quick screen updates. If * - * there were any data files to load, they would be loaded at this time as well. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Call this routine only ONCE at the beginning of the game. * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ -void GScreenClass::One_Time(void) -{ - /* - ** Allocate the screen shadow page. This page is used to reduce access to the - ** actual screen memory. It contains a duplicate of what the SEENPAGE is. - */ - Buttons = 0; - ShadowPage = new GraphicBufferClass(320,200); - if (ShadowPage) { - ShadowPage->Clear(); - HiddenPage.Clear(); - } -} - - -/*********************************************************************************************** - * GScreenClass::Init -- Init's the entire display hierarchy by calling all Init routines. * - * * - * This routine shouldn't be overloaded. It's the main map initialization routine, and will * - * perform a complete map initialization, from mixfiles to clearing the buffers. Calling this * - * routine results in calling every initialization routine in the entire map hierarchy. * - * * - * INPUT: * - * theater theater to initialize to * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/28/1994 BR : Created. * - *=============================================================================================*/ -void GScreenClass::Init(TheaterType theater) -{ - Init_Clear(); - Init_IO(); - Init_Theater(theater); -} - - -/*********************************************************************************************** - * GScreenClass::Init_Clear -- Sets the map to a known state. * - * * - * This routine (and those that overload it) clears any buffers and variables to a known * - * state. It assumes that all buffers are allocated & valid. The map should be displayable * - * after calling this function, and should draw basically an empty display. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/28/1994 BR : Created. * - *=============================================================================================*/ -void GScreenClass::Init_Clear(void) -{ - /* - ** Clear the ShadowPage & HidPage to force a complete shadow blit. - */ - if (ShadowPage) { - ShadowPage->Clear(); - HiddenPage.Clear(); - } - - IsToRedraw = true; -} - - -/*********************************************************************************************** - * GScreenClass::Init_Theater -- Performs theater-specific initializations. * - * * - * This routine (and those that overload it) performs any theater-specific initializations * - * needed. This will include setting the palette, setting up remap tables, etc. This routine * - * only needs to be called when the theater has changed. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/28/1994 BR : Created. * - *=============================================================================================*/ -void GScreenClass::Init_Theater(TheaterType ) -{ -} - - -/*********************************************************************************************** - * GScreenClass::Init_IO -- Initializes the Button list ('Buttons'). * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/28/1994 BR : Created. * - *=============================================================================================*/ -void GScreenClass::Init_IO(void) -{ - /* - ** Reset the button list. This means that any other elements of the map that need - ** buttons must attach them after this routine is called! - */ - Buttons = 0; - -} - - -/*********************************************************************************************** - * GScreenClass::Flag_To_Redraw -- Flags the display to be redrawn. * - * * - * This function is used to flag the display system whether any rendering is needed. The * - * parameter tells the system either to redraw EVERYTHING, or just that something somewhere * - * has changed and the individual Draw_It functions must be called. When a sub system * - * determines that it needs to render something local to itself, it would call this routine * - * with a false parameter. If the entire screen gets trashed or needs to be rebuilt, then * - * this routine will be called with a true parameter. * - * * - * INPUT: complete -- bool; Should the ENTIRE screen be redrawn? * - * * - * OUTPUT: none * - * * - * WARNINGS: This doesn't actually draw the screen, it merely sets flags so that when the * - * Render() function is called, the appropriate drawing steps will be performed. * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ -void GScreenClass::Flag_To_Redraw(bool complete) -{ - IsToUpdate = true; - if (complete) { - IsToRedraw = true; - } -} - - -/*********************************************************************************************** - * GScreenClass::Input -- Fetches input and processes gadgets. * - * * - * This routine will fetch the keyboard/mouse input and dispatch this through the gadget * - * system. * - * * - * INPUT: key -- Reference to the key code (for future examination). * - * * - * x,y -- Reference to mouse coordinates (for future examination). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void GScreenClass::Input(KeyNumType & key, int & x, int & y) -{ - key = Keyboard::Check(); - - x = Keyboard::Mouse_X(); - y = Keyboard::Mouse_Y(); - - if (Buttons) { - - /* - ** If any buttons need redrawing, they will do so in the Input routine, and - ** they should draw themselves to the HidPage. So, flag ourselves for a Blit - ** to show the newly drawn buttons. - */ - if (Buttons->Is_List_To_Redraw()) { - Flag_To_Redraw(false); - } - - GraphicViewPortClass * oldpage= Set_Logic_Page(HidPage); - - key = Buttons->Input(); - - Set_Logic_Page(oldpage); - - } else { - if (key) { - key = Keyboard::Get(); - } - } - AI(key, x, y); - -} - - -/*********************************************************************************************** - * GScreenClass::Add_A_Button -- Add a gadget to the game input system. * - * * - * This will add a gadget to the game input system. The gadget will be processed in * - * subsiquent calls to the GScreenClass::Input() function. * - * * - * INPUT: gadget -- Reference to the gadget that will be added to the input system. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void GScreenClass::Add_A_Button(GadgetClass & gadget) -{ - /*------------------------------------------------------------------------ - If this gadget is already in the list, remove it before adding it in: - - If 1st gadget in list, use Remove_A_Button to remove it, to reset the - value of 'Buttons' appropriately - - Otherwise, just call the Remove function for that gadget to remove it - from any list it may be in - ------------------------------------------------------------------------*/ - if (Buttons == &gadget) { - Remove_A_Button(gadget); - } else { - gadget.Remove(); - } - - /*------------------------------------------------------------------------ - Now add the gadget to our list: - - If there are not buttons, start the list with this one - - Otherwise, add it to the tail of the existing list - ------------------------------------------------------------------------*/ - if (Buttons) { - gadget.Add_Tail(*Buttons); - } else { - Buttons = &gadget; - } -} - - -/*********************************************************************************************** - * GScreenClass::Remove_A_Button -- Removes a gadget from the game input system. * - * * - * INPUT: gadget -- Reference to the gadget that will be removed from the input system. * - * * - * OUTPUT: none * - * * - * WARNINGS: 'gadget' MUST be already a part of 'Buttons', or the new value of 'Buttons' * - * will be invalid! * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void GScreenClass::Remove_A_Button(GadgetClass & gadget) -{ - Buttons = gadget.Remove(); -} - - -/*********************************************************************************************** - * GScreenClass::Render -- General drawing dispatcher an display update function. * - * * - * This routine should be called in the main game loop (once every game frame). It will * - * call the Draw_It() function if necessary. All rendering is performed to the LogicPage * - * which is set to the HIDPAGE. After rendering has been performed, the HIDPAGE is * - * copied to the visible page. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This actually updates the graphic display. As a result it can take quite a * - * while to perform. * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ -void GScreenClass::Render(void) -{ - //if (Buttons && Buttons->Is_List_To_Redraw()) { - // IsToRedraw = true; - //} - - - if (IsToUpdate || IsToRedraw) { - - //WWMouse->Erase_Mouse(&HidPage, TRUE); - GraphicViewPortClass * oldpage= Set_Logic_Page(HidPage); - - //if (IsToRedraw) { - // Hide_Mouse(); - // SeenBuff.To_Buffer(0, 0, 320, 200, ShadowPage); - // Show_Mouse(); - //} - Draw_It(IsToRedraw); - - if (Buttons) Buttons->Draw_All(false); - -#ifdef SCENARIO_EDITOR - /* - ** Draw the Editor's buttons - */ - if (Debug_Map) { - if (Buttons) { - Buttons->Draw_All(); - } - } -#endif - /* - ** Draw the multiplayer message system to the Hidpage at this point. - ** This way, they'll Blit along with the rest of the map. - */ - if (Messages.Num_Messages() > 0) { - Messages.Set_Width(Lepton_To_Cell(Map.TacLeptonWidth) * ICON_PIXEL_W); - } - Messages.Draw(); - - //Blit_Display(); // 5/19/20 SKY - Skip copying to scene page, we can get the data directly from hidden page - IsToUpdate = false; - IsToRedraw = false; - - Set_Logic_Page(oldpage); - } -} - - - -#ifdef CHEAT_KEYS - -#define MAX_SCREENS_SAVED 30*15 // Enough for 30 seconds @ 15 fps - -GraphicBufferClass *ScreenList[MAX_SCREENS_SAVED]; -int CurrentScreen = 0; -bool ScreenRecording = false; - -void Add_Current_Screen(void) -{ -#if (0) // ST - 1/2/2019 5:51PM - if (ScreenRecording){ - ScreenList[CurrentScreen] = new GraphicBufferClass; - ScreenList[CurrentScreen]->Init ( SeenBuff.Get_Width(), SeenBuff.Get_Height(), NULL, 0, (GBC_Enum) 0); - SeenBuff.Blit (*ScreenList[CurrentScreen]); - - CurrentScreen++; - - if (CurrentScreen == MAX_SCREENS_SAVED){ - - char filename[20]; - for (int i = 0 ; i < MAX_SCREENS_SAVED ; i++){ - sprintf (filename, "SCRN%04d.PCX", i); - Write_PCX_File (filename,*ScreenList[i], (unsigned char *)CurrentPalette); - delete ScreenList[i]; - } - - CurrentScreen = 0; - ScreenRecording = 0; - - } - } -#endif -} - -#endif //CHEAT_KEYS - - -extern bool CanVblankSync; - -/*********************************************************************************************** - * GScreenClass::Blit_Display -- Redraw the display from the hidpage to the seenpage. * - * * - * This routine is used to copy the correct display from the HIDPAGE * - * to the SEENPAGE. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/14/1994 JLB : Created. * - * 05/01/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void GScreenClass::Blit_Display(void) -{ -#if 0 // jmarshall - no longer used and saves on performance to disable it(3.6%). - if (SeenBuff.Get_Width()!=320){ -#if (0) - if (HidPage.Get_IsDirectDraw() && (Options.GameSpeed >1 || Options.ScrollRate==6 && CanVblankSync) ){ - WWMouse->Draw_Mouse(&HidPage); - SeenBuff.Get_Graphic_Buffer()->Get_DD_Surface()->Flip(NULL , DDFLIP_WAIT); - SeenBuff.Blit (HidPage , 0 , 0 , 0 , 0 , SeenBuff.Get_Width() , SeenBuff.Get_Height() , (BOOL) FALSE ); -#ifdef CHEAT_KEYS - Add_Current_Screen(); -#endif - //HidPage.Blit ( SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE ); - WWMouse->Erase_Mouse(&HidPage, FALSE); - }else{ -#else //(0) - WWMouse->Draw_Mouse(&HidPage); - HidPage.Blit ( SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE ); -#ifdef CHEAT_KEYS - Add_Current_Screen(); -#endif - WWMouse->Erase_Mouse(&HidPage, FALSE); -#endif //(0) -#if (0) - } -#endif //(0) - - } else { - // ST - 1/2/2019 5:26PM - //ModeX_Blit (&HiddenPage); - } -#endif -} - - - - diff --git a/code/TIBERIANDAWN/GSCREEN.H b/code/TIBERIANDAWN/GSCREEN.H deleted file mode 100644 index 571c69c..0000000 --- a/code/TIBERIANDAWN/GSCREEN.H +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\gscreen.h_v 2.17 16 Oct 1995 16:45:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : GSCREEN.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : December 15, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GSCREEN_H -#define GSCREEN_H - -#include "function.h" -#include "cell.h" - -class GScreenClass : public VectorClass -{ - public: - - GScreenClass(void); - - /* - ** Initialization - */ - virtual void One_Time(void); // One-time initializations - virtual void Init(TheaterType = THEATER_NONE); // Inits everything - virtual void Init_Clear(void); // Clears all to known state - virtual void Init_IO(void); // Inits button list - virtual void Init_Theater(TheaterType theater); // Theater-specific inits - - /* - ** Player I/O is routed through here. It is called every game tick. - */ - virtual void Input(KeyNumType & key, int & x, int & y); - virtual void AI(KeyNumType &, int, int) {}; - virtual void Add_A_Button(GadgetClass & gadget); - virtual void Remove_A_Button(GadgetClass & gadget); - - /* - ** Called when map needs complete updating. - */ - virtual void Flag_To_Redraw(bool complete=false); - - /* - ** Render maintenance routine (call every game tick). Probably no need - ** to override this in derived classes. - */ - virtual void Render(void); - - /* - ** Is called when actual drawing is required. This is the function to - ** override in derived classes. - */ - virtual void Draw_It(bool =false) {}; - - /* - ** This moves the hidpage up to the seenpage. - */ - static void Blit_Display(void); - - /* - ** Changes the mouse shape as indicated. - */ - virtual void Set_Default_Mouse(MouseType mouse, bool wwsmall) = 0; - virtual bool Override_Mouse_Shape(MouseType mouse, bool wwsmall) = 0; - virtual void Revert_Mouse_Shape(void) = 0; - virtual void Mouse_Small(bool wwsmall) = 0; - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Misc routines. - */ - virtual void * Shadow_Address(void) {return(ShadowPage);}; - - /* - ** This points to the buttons that are used for input. All of the derived classes will - ** attached their specific buttons to this list. - */ - static GadgetClass * Buttons; - - private: - - /* - ** If the entire map is required to redraw, then this flag is true. This flag - ** is set by the Flag_To_Redraw function. Typically, this occurs when the screen - ** has been trashed or is first created. - */ - unsigned IsToRedraw:1; - - /* - ** If only a sub-system of the map must be redrawn, then this flag will be set. - ** An example of something that would set this flag would be an animating icon - ** in the sidebar. In such a case, complete redrawing of the entire display is not - ** necessary, but the Draw_It function should still be called so that the appropriate - ** class can perform it's rendering. - */ - unsigned IsToUpdate:1; - - /* - ** Pointer to an exact copy of the visible graphic page. This copy is used to speed - ** display rendering by using an only-update-changed-pixels algorithm. - */ - public: - static GraphicBufferClass * ShadowPage; - private: - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[1024]; - -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/HDATA.CPP b/code/TIBERIANDAWN/HDATA.CPP deleted file mode 100644 index d670d42..0000000 --- a/code/TIBERIANDAWN/HDATA.CPP +++ /dev/null @@ -1,322 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\hdata.cpv 2.17 16 Oct 1995 16:48:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HDATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 22, 1994 * - * * - * Last Update : January 23, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * HouseTypeClass::From_Name -- Fetch house pointer from its name. * - * HouseTypeClass::As_Reference -- Fetches a reference to the house specified. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** These are the colors used to identify the various owners. -*/ -const int COLOR_GOOD = 180; // GOLD -const int COLOR_BRIGHT_GOOD = 176; // GOLD -const int COLOR_BAD = 123; //RED; -const int COLOR_BRIGHT_BAD = 127; //RED; -const int COLOR_NEUTRAL = 205; //WHITE; -const int COLOR_BRIGHT_NEUTRAL = 202; //WHITE; - - -static HouseTypeClass const HouseGood( - HOUSE_GOOD, - "GoodGuy", // NAME: House name. - TXT_GDI, // FULLNAME: Translated house name. - "GDI", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_GOOD, // COLOR: Dark Radar map color. - COLOR_BRIGHT_GOOD, // COLOR: Bright Radar map color. - REMAP_GOLD, // Remap color ID number. - RemapGold, // Default remap table. - 'G' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseBad( - HOUSE_BAD, - "BadGuy", // NAME: House name. - TXT_NOD, // FULLNAME: Translated house name. - "NOD", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_BAD, // COLOR: Dark Radar map color. - COLOR_BRIGHT_BAD, // COLOR: Bright Radar map color. - REMAP_LTBLUE, // Remap color ID number. - RemapLtBlue, // Default remap table. - 'B' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseCivilian( - HOUSE_NEUTRAL, - "Neutral", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "CIV", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Dark Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_GOLD, // Remap color ID number. - RemapNone, // Default remap table. - 'C' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseJP( - HOUSE_JP, - "Special", // NAME: House name. - TXT_JP, // FULLNAME: Translated house name. - "JP", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Dark Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_GOLD, // Remap color ID number. - RemapNone, // Default remap table. - 'J' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseMulti1( - HOUSE_MULTI1, - "Multi1", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "MP1", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_LTBLUE, // Remap color ID number. - RemapLtBlue, // Default remap table. - 'M' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseMulti2( - HOUSE_MULTI2, - "Multi2", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "MP2", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_ORANGE, // Remap color ID number. - RemapOrange, // Default remap table. - 'M' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseMulti3( - HOUSE_MULTI3, - "Multi3", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "MP3", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_GREEN, // Remap color ID number. - RemapGreen, // Default remap table. - 'M' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseMulti4( - HOUSE_MULTI4, - "Multi4", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "MP4", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_BLUE, // Remap color ID number. - RemapBlue, // Default remap table. - 'M' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseMulti5( - HOUSE_MULTI5, - "Multi5", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "MP5", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_GOLD, // Remap color ID number. - RemapGold, // Default remap table. - 'M' // VOICE: Voice prefix character. -); - -static HouseTypeClass const HouseMulti6( - HOUSE_MULTI6, - "Multi6", // NAME: House name. - TXT_CIVILIAN, // FULLNAME: Translated house name. - "MP6", // SUFFIX: House file suffix. - 0, // LEMON: Lemon vehicle frequency. - COLOR_NEUTRAL, // COLOR: Radar map color. - COLOR_BRIGHT_NEUTRAL, // COLOR: Bright Radar map color. - REMAP_RED, // Remap color ID number. - RemapRed, // Default remap table. - 'M' // VOICE: Voice prefix character. -); - -HouseTypeClass const * const HouseTypeClass::Pointers[HOUSE_COUNT] = { - &HouseGood, - &HouseBad, - &HouseCivilian, - &HouseJP, - &HouseMulti1, - &HouseMulti2, - &HouseMulti3, - &HouseMulti4, - &HouseMulti5, - &HouseMulti6, -}; - - -/*********************************************************************************************** - * HouseTypeClass::HouseTypeClass -- Constructor for house type objects. * - * * - * This is the constructor for house type objects. This object holds the constant data * - * for the house type. * - * * - * INPUT: house -- The ID number for this house type. * - * ini -- The INI name of this house. * - * fullname -- The text number representing the complete name of the house. * - * ext -- The filename extension used when loading data files. * - * lemon -- The percentage for objects of this ownership to be lemon. * - * remapc -- The remap color number to use. * - * color -- The radar color to use for this "house". * - * prefix -- A unique prefix letter used when building custom filenames. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/21/1994 JLB : Created. * - *=============================================================================================*/ -HouseTypeClass::HouseTypeClass(HousesType house, - char const * ini, - int fullname, - char const * ext, - int lemon, - int color, - int bright_color, - PlayerColorType remapcolor, - unsigned char const * remap, - char prefix) -{ - RemapTable = remap; - RemapColor = remapcolor; - House = house; - IniName = ini; - FullName = fullname; - strncpy(Suffix, ext, 3); - Suffix[3] = '\0'; - Lemon = lemon; - Color = color; - BrightColor = bright_color; - Prefix = prefix; - FirepowerBias = 1; - GroundspeedBias = 1; - AirspeedBias = 1; - ArmorBias = 1; - ROFBias = 1; - CostBias = 1; - BuildSpeedBias = 1; -} - - -/*********************************************************************************************** - * HouseTypeClass::From_Name -- Fetch house pointer from its name. * - * * - * This routine will convert the ASCII house name specified into a * - * real house number. Typically, this is used when processing a * - * scenario INI file. * - * * - * INPUT: name -- ASCII name of house to process. * - * * - * OUTPUT: Returns with actual house number represented by the ASCII * - * name specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 05/21/1994 JLB : Converted to member function. * - *=============================================================================================*/ -HousesType HouseTypeClass::From_Name(char const *name) -{ - if (name) { - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - if (stricmp(Pointers[house]->IniName, name) == 0) { - return(house); - } - } - } - return(HOUSE_NONE); -} - - -/*********************************************************************************************** - * HouseTypeClass::One_Time -- One-time initialization * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/21/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void HouseTypeClass::One_Time(void) -{ - /* - ** Change the radar color for special units; otherwise, they'll be the same - ** color as the player! - */ - //if (Special.IsJurassic && AreThingiesEnabled) { // Assume funpark mode might be required. ST - 10/14/2019 11:53AM - ((unsigned char &)HouseJP.Color) = (unsigned char)COLOR_BAD; - ((unsigned char &)HouseJP.BrightColor) = (unsigned char)COLOR_BRIGHT_BAD; - //} -} - - -/*********************************************************************************************** - * HouseTypeClass::As_Reference -- Fetches a reference to the house specified. * - * * - * Use this routine to fetch a reference to the house number specified. * - * * - * INPUT: house -- The house number (HousesType) to look up. * - * * - * OUTPUT: Returns with a reference to the HouseTypeClass object that matches the house * - * number specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -HouseTypeClass const & HouseTypeClass::As_Reference(HousesType house) -{ - return(*Pointers[house]); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/HEAP.CPP b/code/TIBERIANDAWN/HEAP.CPP deleted file mode 100644 index 6817e7a..0000000 --- a/code/TIBERIANDAWN/HEAP.CPP +++ /dev/null @@ -1,556 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\heap.cpv 2.18 16 Oct 1995 16:49:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HEAP.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 02/18/95 * - * * - * Last Update : May 22, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * FixedIHeapClass::Free -- Frees an object in the heap. * - * FixedHeapClass::FixedHeapClass -- Normal constructor for heap management class. * - * FixedHeapClass::~FixedHeapClass -- Destructor for the heap manager class. * - * FixedHeapClass::Set_Heap -- Assigns a memory block for this heap manager. * - * FixedHeapClass::Allocate -- Allocate a sub-block from the heap. * - * FixedHeapClass::Free -- Frees a sub-block in the heap. * - * FixedHeapClass::ID -- Converts a pointer to a sub-block index number. * - * FixedHeapClass::Clear -- Clears (and frees) the heap manager memory. * - * TFixedIHeapClass::Save -- Saves all active objects * - * TFixedIHeapClass::Load -- Loads all active objects * - * TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save * - * TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading * - * FixedHeapClass::Free_All -- Frees all objects in the fixed heap. * - * FixedIHeapClass::Free_All -- Frees all objects out of the indexed heap. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" -#include "heap.h" -//#include -#include -#include -#include -#include - - -/*********************************************************************************************** - * FixedHeapClass::FixedHeapClass -- Normal constructor for heap management class. * - * * - * This is the normal constructor used for the heap manager class. This initializes * - * the class but doesn't yet assign actual heap memory to this manager. That is handled * - * by the Set_Heap() function. * - * * - * INPUT: size -- The size of the individual sub-blocks in this heap. This value is * - * typically the size of some class or structure. * - * * - * OUTPUT: none * - * * - * WARNINGS: The heap must first be assigned a block of memory to manage before it can * - * be used. * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -FixedHeapClass::FixedHeapClass(int size) -{ - Size = size; - Buffer = 0; - IsAllocated = false; - TotalCount = 0; - ActiveCount = 0; -} - - -/*********************************************************************************************** - * FixedHeapClass::~FixedHeapClass -- Destructor for the heap manager class. * - * * - * This is the default constructor for the heap manager class. It handles freeing the * - * memory assigned to this heap. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -FixedHeapClass::~FixedHeapClass(void) -{ - FixedHeapClass::Clear(); -} - - -/*********************************************************************************************** - * FixedHeapClass::Set_Heap -- Assigns a memory block for this heap manager. * - * * - * This routine is used to assign a memory heap to this object. A memory heap so assigned * - * will start with all sub-blocks unallocated. After this routine is called, normal * - * allocation and freeing may occur. This routine will allocate necessary memory if the * - * buffer parameter is NULL. * - * * - * INPUT: count -- The number of objects that this heap should manage. * - * * - * buffer -- Pointer to pre-allocated buffer that this manager will use. If this * - * parameter is NULL, then memory will be automatically allocated. * - * * - * OUTPUT: bool; Was the heap successfully initialized? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -int FixedHeapClass::Set_Heap(int count, void * buffer) -{ - /* - ** Clear out the old heap data. - */ - Clear(); - - /* - ** If there is no size to the objects in the heap, then this block memory - ** handler can NEVER function. Return with a failure condition. - */ - if (!Size) return(false); - - /* - ** If there is no count specified, then this indicates that the heap should - ** be disabled. - */ - if (!count) return(true); - - /* - ** Initialize the free boolean vector and the buffer for the actual - ** allocation objects. - */ - if (FreeFlag.Resize(count)) { - if (!buffer) { - buffer = new char[count * Size]; - if (!buffer) { - FreeFlag.Clear(); - return(false); - } - IsAllocated = true; - } - Buffer = buffer; - TotalCount = count; - - memset((unsigned char *)Buffer, 0x00, count * Size); // Added. Needed to identify bad states in saved games. ST - 10/3/2019 11:49AM - - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * FixedHeapClass::Allocate -- Allocate a sub-block from the heap. * - * * - * Finds the first available sub-block in the heap and returns a pointer to it. The sub- * - * block is marked as allocated by this routine. If there are no more sub-blocks * - * available, then this routine will return NULL. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the newly allocated sub-block. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -void * FixedHeapClass::Allocate(void) -{ - if (ActiveCount < TotalCount) { - int index = FreeFlag.First_False(); - - if (index != -1) { - ActiveCount++; - FreeFlag[index] = true; - return((*this)[index]); - } - } - return(0); -} - - -/*********************************************************************************************** - * FixedHeapClass::Free -- Frees a sub-block in the heap. * - * * - * Use this routine to free a previously allocated sub-block in the heap. * - * * - * INPUT: pointer -- A pointer to the sub-block to free. This is the same pointer that * - * was returned from the Allocate() function. * - * * - * OUTPUT: bool; Was the deallocation successful? Failure could indicate a pointer that * - * doesn't refer to this heap or a null pointer. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -int FixedHeapClass::Free(void * pointer) -{ - if (pointer && ActiveCount) { - int index = ID(pointer); - - if (index < TotalCount) { - if (FreeFlag[index]) { - ActiveCount--; - FreeFlag[index] = false; - - return(true); - } - } - } - return(false); -} - - -/*********************************************************************************************** - * FixedHeapClass::ID -- Converts a pointer to a sub-block index number. * - * * - * Use this routine to convert a pointer (returned by Allocate) into the sub-block * - * index number. This index number can be used as a form of identifier for the block. * - * * - * INPUT: pointer -- A pointer to the sub-block to conver into an ID number. * - * * - * OUTPUT: Returns with the index (ID) number for the sub-block specified. This number will * - * range between 0 and the sub-block max -1. If -1 is returned, then the pointer * - * was invalid. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -int FixedHeapClass::ID(void const * pointer) -{ - if (pointer && Size) { - return((int)(((char *)pointer - (char *)Buffer) / Size)); - } - return(-1); -} - - -/*********************************************************************************************** - * FixedHeapClass::Clear -- Clears (and frees) the heap manager memory. * - * * - * This routine is used to bring the heap manager back into a non-functioning state. All * - * memory allocated by this manager is freeed. Any previous pointers to allocated blocks * - * from this heap are now invalid. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -void FixedHeapClass::Clear(void) -{ - /* - ** Free the old buffer (if present). - */ - if (Buffer && IsAllocated) { - delete[] Buffer; - } - Buffer = 0; - IsAllocated = false; - ActiveCount = 0; - TotalCount = 0; - FreeFlag.Clear(); -} - - -/*********************************************************************************************** - * FixedHeapClass::Free_All -- Frees all objects in the fixed heap. * - * * - * This routine will free all previously allocated objects out of the heap. Use this * - * routine to ensure that the heap is empty. * - * * - * INPUT: none * - * * - * OUTPUT: Was the heap successfully cleared of all objects? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - *=============================================================================================*/ -int FixedHeapClass::Free_All(void) -{ - ActiveCount = 0; - FreeFlag.Reset(); - return(true); -} - - -///////////////////////////////////////////////////////////////////// - - -/*********************************************************************************************** - * FixedIHeapClass::Free_All -- Frees all objects out of the indexed heap. * - * * - * Use this routine to free all previously allocated objects in the heap. This routine will * - * also clear out the allocated object vector as well. * - * * - * INPUT: none * - * * - * OUTPUT: Was the heap successfully cleared of objects? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - *=============================================================================================*/ -int FixedIHeapClass::Free_All(void) -{ - ActivePointers.Delete_All(); - return(FixedHeapClass::Free_All()); -} - - -void FixedIHeapClass::Clear(void) -{ - FixedHeapClass::Clear(); - ActivePointers.Clear(); -} - - -int FixedIHeapClass::Set_Heap(int count, void * buffer) -{ - Clear(); - if (FixedHeapClass::Set_Heap(count, buffer)) { - ActivePointers.Resize(count); - return(true); - } - return(false); -} - - -void * FixedIHeapClass::Allocate(void) -{ - void * ptr = FixedHeapClass::Allocate(); - if (ptr) { - ActivePointers.Add(ptr); - memset (ptr, 0, Size); - } - return(ptr); -} - - -/*********************************************************************************************** - * FixedIHeapClass::Free -- Frees an object in the heap. * - * * - * This routine is used to free an object in the heap. Freeing is accomplished by marking * - * the object's memory as free to be reallocated. The object is also removed from the * - * allocated object pointer vector. * - * * - * INPUT: pointer -- Pointer to the object that is to be removed from the heap. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/21/1995 JLB : Created. * - *=============================================================================================*/ -int FixedIHeapClass::Free(void * pointer) -{ - if (FixedHeapClass::Free(pointer)) { - ActivePointers.Delete(pointer); - } - return(false); -} - -#if (0) -/*********************************************************************************************** - * TFixedIHeapClass::Save -- Saves all active objects * - * * - * INPUT: file file to write to * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -int TFixedIHeapClass::Save(FileClass &file) -{ - int i; // loop counter - int idx; // object index - - /* - ** Save the number of instances of this class - */ - if (file.Write(&ActiveCount, sizeof(ActiveCount)) != sizeof(ActiveCount)) { - return(false); - } - - /* - ** Save each instance of this class - */ - for (i = 0; i < ActiveCount; i++) { - /* - ** Save the array index of the object, so it can be loaded back into the - ** same array location (so TARGET translations will work) - */ - idx = ID(Ptr(i)); - if (file.Write(&idx, sizeof(idx)) != sizeof(idx)) { - return(false); - } - - /* - ** Save the object itself - */ - if (!Ptr(i)->Save(file)) { - return(false); - } - } - - return(true); -} - - -/*********************************************************************************************** - * TFixedIHeapClass::Load -- Loads all active objects * - * * - * INPUT: file file to read from * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -int TFixedIHeapClass::Load(FileClass &file) -{ - int i; // loop counter - int idx; // object index - T *ptr; // object pointer - int a_count; - - /* - ** Read the number of instances of this class - */ - if (file.Read(&a_count, sizeof(a_count)) != sizeof(a_count)) { - return(false); - } - - /* - ** Error if more objects than we can hold - */ - if (a_count > TotalCount) { - return(false); - } - - /* - ** Read each class instance - */ - for (i = 0; i < a_count; i++) { - /* - ** Read the object's array index - */ - if (file.Read (&idx, sizeof(idx)) != sizeof(idx)) { - return(false); - } - - /* - ** Get a pointer to the object, activate that object - */ - ptr = (T *)(*this)[idx]; - FreeFlag[idx] = true; - ActiveCount++; - ActivePointers.Add(ptr); - - /* - ** Load the object - */ - if (!ptr->Load(file)) { - return(false); - } - } - - return(true); -} - - -/*********************************************************************************************** - * TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save * - * * - * INPUT: file file to read from * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -void TFixedIHeapClass::Code_Pointers(void) -{ - int i; - - for (i = 0; i < ActiveCount; i++) { - Ptr(i)->Code_Pointers(); - } -} - - -/*********************************************************************************************** - * TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading * - * * - * INPUT: file file to read from * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -void TFixedIHeapClass::Decode_Pointers(void) -{ - int i; - - for (i = 0; i < ActiveCount; i++) { - Ptr(i)->Decode_Pointers(); - } -} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/HEAP.H b/code/TIBERIANDAWN/HEAP.H deleted file mode 100644 index 690dd70..0000000 --- a/code/TIBERIANDAWN/HEAP.H +++ /dev/null @@ -1,349 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\heap.h_v 2.15 16 Oct 1995 16:47:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HEAP.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 02/18/95 * - * * - * Last Update : February 18, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef HEAP_H -#define HEAP_H - -#include "vector.h" - -/************************************************************************** -** This is a block memory managment handler. It is used when memory is to -** be treated as a series of blocks of fixed size. This is similar to an -** array of integral types, but unlike such an array, the memory blocks -** are annonymous. This facilitates the use of this class when overloading -** the new and delete operators for a normal class object. -*/ -class FixedHeapClass -{ - public: - FixedHeapClass(int size); - virtual ~FixedHeapClass(void); - - int ID(void const * pointer); - int Count(void) {return ActiveCount;}; - int Length(void) {return TotalCount;}; - int Avail(void) {return TotalCount-ActiveCount;}; - - virtual int Set_Heap(int count, void * buffer=0); - virtual void * Allocate(void); - virtual void Clear(void); - virtual int Free(void * pointer); - virtual int Free_All(void); - - protected: - void * operator[](int index) {return ((char *)Buffer) + (index * Size);}; - - /* - ** If the memory block buffer was allocated by this class, then this flag - ** will be true. The block must be deallocated by this class if true. - */ - unsigned IsAllocated:1; - - /* - ** This is the size of each sub-block within the buffer. - */ - int Size; - - /* - ** This records the absolute number of sub-blocks in the buffer. - */ - int TotalCount; - - /* - ** This is the total blocks allocated out of the heap. This number - ** will never exceed Count. - */ - int ActiveCount; - - /* - ** Pointer to the heap's memory buffer. - */ - void * Buffer; - - /* - ** This is a boolean vector array of allocation flag bits. - */ - BooleanVectorClass FreeFlag; - - private: - // The assignment operator is not supported. - FixedHeapClass & operator = (FixedHeapClass const &); - - // The copy constructor is not supported. - FixedHeapClass(FixedHeapClass const &); -}; - - -/************************************************************************** -** This template serves only as an interface to the heap manager class. By -** using this template, the object pointers are automatically converted -** to the correct type without any code overhead. -*/ -template -class TFixedHeapClass : public FixedHeapClass -{ - public: - TFixedHeapClass(void) : FixedHeapClass(sizeof(T)) {}; - virtual ~TFixedHeapClass(void) {}; - - int ID(T const * pointer) {return FixedHeapClass::ID(pointer);}; - - virtual T * Alloc(void) {return (T*)FixedHeapClass::Allocate();}; - virtual int Free(T * pointer) {FixedHeapClass::Free(pointer);}; - - protected: - T & operator[](int index) {return *(((char *)Buffer) + (index * Size));}; -}; - - -/************************************************************************** -** This is a derivative of the fixed heap class. This class adds the -** ability to quickly iterate through the active (allocated) objects. Since the -** active array is a sequence of pointers, the overhead of this class -** is 4 bytes per potential allocated object (be warned). -*/ -class FixedIHeapClass : public FixedHeapClass -{ - public: - FixedIHeapClass(int size) : FixedHeapClass(size) {}; - virtual ~FixedIHeapClass(void) {}; - - virtual int Set_Heap(int count, void * buffer=0); - virtual void * Allocate(void); - virtual void Clear(void); - virtual int Free(void * pointer); - virtual int Free_All(void); - - virtual void * Active_Ptr(int index) {return ActivePointers[index];}; - - /* - ** This is an array of pointers to allocated objects. Using this array - ** to control iteration through the objects ensures a minimum of processing. - ** It also allows access to this array so that custom sorting can be - ** performed. - */ - DynamicVectorClass ActivePointers; -}; - - -/************************************************************************** -** This template serves only as an interface to the iteratable heap manager -** class. By using this template, the object pointers are automatically converted -** to the correct type without any code overhead. -*/ -template -class TFixedIHeapClass : public FixedIHeapClass -{ - public: - TFixedIHeapClass(void) : FixedIHeapClass(sizeof(T)) {}; - virtual ~TFixedIHeapClass(void) {}; - - int ID(T const * pointer) {return FixedIHeapClass::ID(pointer);}; - virtual T * Alloc(void) {return (T*)FixedIHeapClass::Allocate();}; - virtual int Free(T * pointer) {return FixedIHeapClass::Free(pointer);}; - virtual int Free(void * pointer) {return FixedIHeapClass::Free(pointer);}; - virtual int Save(FileClass & ); - virtual int Load(FileClass & ); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - virtual T * Ptr(int index) {return (T*)FixedIHeapClass::ActivePointers[index];}; - virtual T * Raw_Ptr(int index) {return (index >= 0 && index < Length()) ? (T*)((*this)[index]) : NULL;}; -}; - - -/*********************************************************************************************** - * TFixedIHeapClass::Save -- Saves all active objects * - * * - * INPUT: file file to write to * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -int TFixedIHeapClass::Save(FileClass &file) -{ - int i; // loop counter - int idx; // object index - - /* - ** Save the number of instances of this class - */ - if (file.Write(&ActiveCount, sizeof(ActiveCount)) != sizeof(ActiveCount)) { - return(false); - } - - /* - ** Save each instance of this class - */ - for (i = 0; i < ActiveCount; i++) { - /* - ** Save the array index of the object, so it can be loaded back into the - ** same array location (so TARGET translations will work) - */ - idx = ID(Ptr(i)); - if (file.Write(&idx, sizeof(idx)) != sizeof(idx)) { - return(false); - } - - /* - ** Save the object itself - */ - if (!Ptr(i)->Save(file)) { - return(false); - } - } - - return(true); -} - - -/*********************************************************************************************** - * TFixedIHeapClass::Load -- Loads all active objects * - * * - * INPUT: file file to read from * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -int TFixedIHeapClass::Load(FileClass &file) -{ - int i; // loop counter - int idx; // object index - T *ptr; // object pointer - int a_count; - - /* - ** Read the number of instances of this class - */ - if (file.Read(&a_count, sizeof(a_count)) != sizeof(a_count)) { - return(false); - } - - /* - ** Error if more objects than we can hold - */ - if (a_count > TotalCount) { - return(false); - } - - /* - ** Read each class instance - */ - for (i = 0; i < a_count; i++) { - /* - ** Read the object's array index - */ - if (file.Read (&idx, sizeof(idx)) != sizeof(idx)) { - return(false); - } - - /* - ** Get a pointer to the object, activate that object - */ - ptr = (T *)(*this)[idx]; - FreeFlag[idx] = true; - ActiveCount++; - ActivePointers.Add(ptr); - - /* - ** Load the object - */ - if (!ptr->Load(file)) { - return(false); - } - } - - return(true); -} - - -/*********************************************************************************************** - * TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save * - * * - * INPUT: file file to read from * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -void TFixedIHeapClass::Code_Pointers(void) -{ - int i; - - for (i = 0; i < ActiveCount; i++) { - Ptr(i)->Code_Pointers(); - } -} - - -/*********************************************************************************************** - * TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading * - * * - * INPUT: file file to read from * - * * - * OUTPUT: true = OK, false = error * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 BRR : Created. * - *=============================================================================================*/ -template -void TFixedIHeapClass::Decode_Pointers(void) -{ - int i; - - for (i = 0; i < ActiveCount; i++) { - Ptr(i)->Decode_Pointers(); - } -} - - -#endif - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/HELP.CPP b/code/TIBERIANDAWN/HELP.CPP deleted file mode 100644 index 137539b..0000000 --- a/code/TIBERIANDAWN/HELP.CPP +++ /dev/null @@ -1,403 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\help.cpv 2.18 16 Oct 1995 16:51:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HELP.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 11/18/94 * - * * - * Last Update : July 16, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * HelpClass::Draw_Help -- Display the help message (if necessary). * - * HelpClass::HelpClass -- Default constructor for the help processor. * - * HelpClass::Help_AI -- Handles the help text logic. * - * HelpClass::Help_Text -- Assigns text as the current help text. * - * HelpClass::Init_Clear -- Sets help system to a known state. * - * HelpClass::Overlap_List -- Returns with offset list for cells under help text. * - * HelpClass::Scroll_Map -- Makes sure scrolling doesn't leave text shards. * - * HelpClass::Set_Cost -- Initiates the second line of help text showing item cost. * - * HelpClass::Set_Tactical_Position -- Sets the tactial map position. * - * HelpClass::Set_Tactical_Position -- Sets the tactical map position. * - * HelpClass::Set_Text -- Determines the overlap list and draw coordinates. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** This is the holding buffer for the text overlap list. This buffer must be in the near -** data segment. It will be filled in by the Set_Text() function. -*/ -//short const HelpClass::OverlapList[30] = { // Can't be const - it's expected to be written to. ST - 2/7/2019 5:16PM -short HelpClass::OverlapList[30] = { - REFRESH_EOL -}; - -char const * HelpClass::HelpText; - - -CountDownTimerClass HelpClass::CountDownTimer; - - -/*********************************************************************************************** - * HelpClass::HelpClass -- Default constructor for the help processor. * - * * - * The help processor is initialized by this routine. It merely sets up the help engine * - * to the default state. The default state will not display any help text. Call the * - * Help_Text() function to enable help processing. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/18/1994 JLB : Created. * - *=============================================================================================*/ -HelpClass::HelpClass(void) -{ - X = 0; - Y = 0; - Width = 0; - Text = TXT_NONE; - Color = LTGREY; - CountDownTimer.Set(0); - IsRight = false; - Cost = 0; -} - - -/*********************************************************************************************** - * HelpClass::Init_Clear -- Sets help system to a known state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void HelpClass::Init_Clear(void) -{ - TabClass::Init_Clear(); - - Set_Text(TXT_NONE); -} - - -/*********************************************************************************************** - * HelpClass::Overlap_List -- Returns with offset list for cells under help text. * - * * - * Use this routine to fetch an offset list for the cells under the text displayed. If * - * there is no text displayed, then the list will consist of just the terminator code. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the offset list for the help text overlap. The offset * - * list is based on the tactical map upper left corner cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/18/1994 JLB : Created. * - *=============================================================================================*/ -short const * HelpClass::Overlap_List(void) const -{ - if (Text == TXT_NONE || CountDownTimer.Time()) { - ((short &)(OverlapList[0])) = REFRESH_EOL; - } - return(OverlapList); -} - - -/*********************************************************************************************** - * HelpClass::Help_AI -- Handles the help text logic. * - * * - * This routine handles tracking the mouse position to see if the mouse remains stationary * - * for the required amount of time. If the time requirement has been met, then it flags * - * the help system to display the help text the next time the Draw_Help() function is * - * called. * - * * - * INPUT: key -- Keyboard input code. * - * * - * x,y -- Mouse coordinates. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine must be called once and only once per game frame (15 times per * - * second). * - * * - * HISTORY: * - * 11/18/1994 JLB : Created. * - * 12/31/1994 JLB : Uses mouse coordinates as passed in. * - *=============================================================================================*/ -void HelpClass::AI(KeyNumType &key, int x, int y) -{ - /* - ** If there is any keyboard input, then the help text goes away. - */ -// if (key) { -// Help_Text(TXT_NONE); -// } - - if (!CountDownTimer.Time() && !IsRight && (x != X || y != Y)) { - Help_Text(TXT_NONE); - } - - /* - ** Process the countdown timer only if it hasn't already expired and there is - ** a real help text message to display. - */ - if (CountDownTimer.Time() && !HelpText && Text != TXT_NONE) { - - /* - ** If the mouse has moved, then reset the timer since a moving mouse is not - ** supposed to bring up the help text. - */ - if (!IsRight && (X != x || Y != y)) { - X = x; - Y = y; - CountDownTimer.Start(); - CountDownTimer.Set(HELP_DELAY); - Set_Text(TXT_NONE); - } else { - - /* - ** If the delay has expired, then the text must be drawn. Build the help text - ** overlay list at this time. Better to do it now, when we KNOW it is needed, then - ** to do it earlier when it might not be needed. - */ - Set_Text(Text); - } - } - - TabClass::AI(key, x, y); -} - - -/*********************************************************************************************** - * HelpClass::Help_Text -- Assigns text as the current help text. * - * * - * Use this routine to change the help text that will pop up if the cursor isn't moved * - * for the help delay duration. Call this routine as often as desired. * - * * - * INPUT: text -- The text number for the help text to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/18/1994 JLB : Created. * - *=============================================================================================*/ -void HelpClass::Help_Text(int text, int x, int y, int color, bool quick, int cost) -{ - if (text != Text) { - - /* - ** If there is an existing text message, then flag the map to redraw the underlying - ** icons so that the text message is erased. - */ - if (Text != TXT_NONE) { - Refresh_Cells(Coord_Cell(TacticalCoord), &OverlapList[0]); - } - - /* - ** Record the position of the mouse. This recorded position will be used to determine - ** if the mouse has moved. A moving mouse prevents the help text from popping up. - */ - X = x; - if (x == -1) X = Get_Mouse_X(); - Y = y; - if (y == -1) Y = Get_Mouse_Y(); - IsRight = (y != -1) || (x != -1); - - if (quick) { - CountDownTimer.Set(1); - } else { - CountDownTimer.Set(HELP_DELAY); - } - - Color = color; - Text = text; - Cost = cost; - } -} - - -/*********************************************************************************************** - * HelpClass::Draw_Help -- Display the help message (if necessary). * - * * - * This function will print the help text if it thinks it should. The timer and text * - * message can control whether this occurs. If there is no help text or the countdown timer * - * has not expired, then no text will be printed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/18/1994 JLB : Created. * - *=============================================================================================*/ -void HelpClass::Draw_It(bool forced) -{ - TabClass::Draw_It(forced); - - if (Text != TXT_NONE && (forced || !CountDownTimer.Time())) { - - if (LogicPage->Lock()){ - - // Fancy_Text_Print(Text, DrawX, DrawY, Color, BLACK, TPF_6POINT|TPF_NOSHADOW); - Fancy_Text_Print(Text, DrawX, DrawY, Color, BLACK, TPF_MAP|TPF_NOSHADOW); - LogicPage->Draw_Rect(DrawX-1, DrawY-1, DrawX+Width+1, DrawY+FontHeight, Color); - - if (Cost) { - char buffer[15]; - sprintf(buffer, "$%d", Cost); - int width = String_Pixel_Width(buffer); - - // Fancy_Text_Print(buffer, DrawX, DrawY+FontHeight, Color, BLACK, TPF_6POINT|TPF_NOSHADOW); - Fancy_Text_Print(buffer, DrawX, DrawY+FontHeight, Color, BLACK, TPF_MAP|TPF_NOSHADOW); - LogicPage->Draw_Rect(DrawX-1, DrawY+FontHeight, DrawX+width+1, DrawY+FontHeight+FontHeight-1, Color); - LogicPage->Draw_Line(DrawX, DrawY+FontHeight, DrawX+MIN(width+1, Width) - 1, DrawY+FontHeight, BLACK); - } - - LogicPage->Unlock(); - } - } - // if (!In_Debugger) HidPage.Unlock(); -} - - -/*********************************************************************************************** - * HelpClass::Set_Text -- Determines the overlap list and draw coordinates. * - * * - * This routine is used to build the overlap list -- used for icon refreshing. It also * - * determines if the text can fit on the screen and makes adjustments so that it will. * - * * - * INPUT: text -- The text number to set the help system to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/18/1994 JLB : Created. * - * 12/11/1994 JLB : Won't draw past tactical map edges. * - *=============================================================================================*/ -void HelpClass::Set_Text(int text) -{ - if (text != TXT_NONE) { - Text = text; -// Fancy_Text_Print(TXT_NONE, 0, 0, 0, 0, TPF_6POINT|TPF_NOSHADOW); - Fancy_Text_Print(TXT_NONE, 0, 0, 0, 0, TPF_MAP|TPF_NOSHADOW); - Width = String_Pixel_Width(Text_String(Text)); - if (IsRight) { - DrawX = X - Width; - DrawY = Y; - } else { - int right = TacPixelX + Lepton_To_Pixel(TacLeptonWidth) - 3; - int bottom = TacPixelY + Lepton_To_Pixel(TacLeptonHeight) - 1; - - DrawX = X+X_OFFSET; - DrawY = Y+Y_OFFSET; - if (DrawX + Width > right) { - DrawX -= (DrawX+Width) - right; - } - if (DrawY + FontHeight > bottom) { - DrawY -= (DrawY+FontHeight) - bottom; - } - if (DrawX < TacPixelX+1) DrawX = TacPixelX+1; - if (DrawY < TacPixelY+1) DrawY = TacPixelY+1; - } - int lines = (Cost) ? 2 : 1; - memcpy((void*)OverlapList, Text_Overlap_List(Text_String(Text), DrawX-1, DrawY, lines), sizeof(OverlapList)); - } -} - - -/*********************************************************************************************** - * HelpClass::Scroll_Map -- Makes sure scrolling doesn't leave text shards. * - * * - * This routine intercepts the map scrolling request and then makes sure that if, in fact, * - * the map is going to scroll, then reset and erase the help text so that it doesn't * - * mess up the display. * - * * - * INPUT: facing -- The direction to scroll (unused by this routine). * - * * - * really -- If the scroll is actually going to occur, rather than just be examined * - * for legality, then this parameter will be true. If this parameter is * - * true, then the help text is reset. * - * * - * OUTPUT: Returns if it can, or did, scroll in the requested direction. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ -bool HelpClass::Scroll_Map(DirType facing, int & distance, bool really) -{ - if (really) { - Help_Text(TXT_NONE); - } - return(TabClass::Scroll_Map(facing, distance, really)); -} - - -/*********************************************************************************************** - * HelpClass::Set_Cost -- Initiates the second line of help text showing item cost. * - * * - * Use this routine after the Help_Text() function to activate the second line. The second * - * line displays a cost. Typically, this is used by the sidebar to display the cost of the * - * specified item. * - * * - * INPUT: cost -- The cost to associate with this help text. If this value is zero, then * - * no second line is displayed, so don't pass in zero. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/09/1995 JLB : Created. * - *=============================================================================================*/ -void HelpClass::Set_Cost(int cost) -{ - Cost = cost; -} - - -void HelpClass::Set_Tactical_Position(COORDINATE coord) -{ - if (TacticalCoord != coord) { - Help_Text(TXT_NONE); - } - TabClass::Set_Tactical_Position(coord); -} diff --git a/code/TIBERIANDAWN/HELP.H b/code/TIBERIANDAWN/HELP.H deleted file mode 100644 index 8ada3a2..0000000 --- a/code/TIBERIANDAWN/HELP.H +++ /dev/null @@ -1,142 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\help.h_v 2.17 16 Oct 1995 16:46:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HELP.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 11/18/94 * - * * - * Last Update : November 18, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef HELP_H -#define HELP_H - -#include "tab.h" - -class HelpClass: public TabClass -{ - public: - HelpClass(void); - - /* - ** Initialization - */ - virtual void Init_Clear(void); // Clears all to known state - - virtual void Draw_It(bool complete=false); - virtual void AI(KeyNumType &input, int x, int y); - virtual bool Scroll_Map(DirType facing, int &distance, bool really); - virtual void Set_Tactical_Position(COORDINATE coord); - - void Help_Text(int text, int x=-1, int y=-1, int color=LTGREY, bool quick=false, int cost = 0); - void Set_Cost(int cost); - short const * Overlap_List(void) const; - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - private: - - static char const *HelpText; - int HelpX; - int HelpY; - int HelpWidth; - - - void Set_Text(int text); - - /* - ** If the help text is right justified (as with the help text that pops up over the - ** sidebar icons), then this flag is set to true. - */ - unsigned IsRight:1; - - /* - ** If the optional second line of text that displays cost is desired, then this - ** value will be non-zero. Typically, this is true when the help text is associated - ** with one of the sidebar construction icons. - */ - int Cost; - - /* - ** This is the recorded position of the cursor at the time the help text - ** pops up. The help text is rendered as an offset from this pixel position. - */ - int X; - int Y; - - /* - ** This is the draw X and Y coordinate. This position is relative to the X and - ** Y coordinates but adjusted for screen edges as necessary. - */ - int DrawX; - int DrawY; - - /* - ** The width of the help text (in pixels) is stored here. This is a convenience - ** since calculating the width takes a bit of time. - */ - int Width; - - /* - ** The text number of the help text to display is held here. If no text is to be - ** displayed, then this value will be TXT_NONE. - */ - int Text; - - /* - ** This is the background color to use for the help text. It can change according - ** to the message displayed. - */ - int Color; - - /* - ** This countdown timer controls when the help text will pop up. If the mouse - ** remains stationary while this countdown timer expires, then the help text - ** will pop up. - */ - static CountDownTimerClass CountDownTimer; - - /* - ** This is a calculated cell offset list (from the Map.TacticalCell) that indicates - ** which cells are under the help text and thus which cells need to be redrawn if - ** the help text is to be erased. - */ - //static short const OverlapList[30]; - static short OverlapList[30]; // Can't be const - it's expected to be written to. ST - 2/7/2019 5:16PM - - enum HelpClassEnum { - HELP_DELAY=TIMER_SECOND*1, // The countdown timer delay before help text pops up. - Y_OFFSET=0, // The Y pixel offset from cursor for help text print. - X_OFFSET=10, // The X pixel offset from cursor for help text print. - }; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/HOUSE.CPP b/code/TIBERIANDAWN/HOUSE.CPP deleted file mode 100644 index c96650c..0000000 --- a/code/TIBERIANDAWN/HOUSE.CPP +++ /dev/null @@ -1,8640 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\house.cpv 2.13 02 Aug 1995 17:03:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HOUSE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 21, 1994 * - * * - * Last Update : August 12, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * HouseClass::AI -- Process house logic. * - * HouseClass::Abandon_Production -- Abandons production of item type specified. * - * HouseClass::Add_Nuke_Piece -- Add a nuclear piece to the collection. * - * HouseClass::Adjust_Capacity -- Adjusts the house Tiberium storage capacity. * - * HouseClass::Adjust_Threat -- Adjust threat for the region specified. * - * HouseClass::As_Pointer -- Converts a house number into a house object pointer. * - * HouseClass::Assign_Handicap -- Assigns the specified handicap rating to the house. * - * HouseClass::Attacked -- Lets player know if base is under attack. * - * HouseClass::Available_Money -- Fetches the total credit worth of the house. * - * HouseClass::Begin_Production -- Starts production of the specified object type. * - * HouseClass::Blowup_All -- blows up everything * - * HouseClass::Can_Build -- Determines if the aircraft type can be built. * - * HouseClass::Can_Build -- Determines if the building type can be built. * - * HouseClass::Can_Build -- Determines if the infantry unit can be built by this house. * - * HouseClass::Can_Build -- Determines if the unit can be built by this house. * - * HouseClass::Can_Build -- General purpose build legality checker. * - * HouseClass::Clobber_All -- removes house & all its objects * - * HouseClass::Debug_Dump -- Dumps the house status data to the mono screen. * - * HouseClass::Detach -- Removes specified object from house tracking systems. * - * HouseClass::Does_Enemy_Building_Exist -- Checks for enemy building of specified type. * - * HouseClass::Flag_Attach -- Attach flag to specified cell (or thereabouts). * - * HouseClass::Flag_Attach -- Attaches the house flag the specified unit. * - * HouseClass::Flag_Remove -- Removes the flag from the specified target. * - * HouseClass::Flag_To_Die -- Flags the house to blow up soon. * - * HouseClass::Flag_To_Lose -- Flags the house to die soon. * - * HouseClass::Flag_To_Win -- Flags the house to win soon. * - * HouseClass::Harvested -- Adds Tiberium to the harvest storage. * - * HouseClass::Has_Nuke_Device -- Deteremines if the house has a nuclear device. * - * HouseClass::HouseClass -- Constructor for a house object. * - * HouseClass::Init -- init's in preparation for new scenario * - * HouseClass::Init_Air_Strike -- Add (or reset) the air strike sidebar button. * - * HouseClass::Init_Data -- Initializes the multiplayer color data. * - * HouseClass::Init_Ion_Cannon -- Initialize the ion cannon countdown. * - * HouseClass::Init_Nuke_Bomb -- Adds (if necessary) the atom bomb to the sidebar. * - * HouseClass::Is_Ally -- Checks to see if the object is an ally. * - * HouseClass::Is_Ally -- Determines if the specified house is an ally. * - * HouseClass::Is_Ally -- Determines if the specified house is an ally. * - * HouseClass::MPlayer_Defeated -- multiplayer; house is defeated * - * HouseClass::Make_Air_Strike_Available -- Make the airstrike available. * - * HouseClass::Make_Ally -- Make the specified house an ally. * - * HouseClass::Make_Enemy -- Make an enemy of the house specified. * - * HouseClass::Manual_Place -- Inform display system of building placement mode. * - * HouseClass::One_Time -- Handles one time initialization of the house array. * - * HouseClass::Place_Object -- Places the object (building) at location specified. * - * HouseClass::Place_Special_Blast -- Place a special blast effect at location specified. * - * HouseClass::Power_Fraction -- Fetches the current power output rating. * - * HouseClass::Read_INI -- Reads house specific data from INI. * - * HouseClass::Refund_Money -- Refunds money to back to the house. * - * HouseClass::Remap_Table -- Fetches the remap table for this house object. * - * HouseClass::Remove_Air_Strike -- Removes the air strike button from the sidebar. * - * HouseClass::Remove_Ion_Cannon -- Disables the ion cannon. * - * HouseClass::Remove_Nuke_Bomb -- Removes the nuclear bomb from the sidebar. * - * HouseClass::Sell_Wall -- Tries to sell the wall at the specified location. * - * HouseClass::Silo_Redraw_Check -- Flags silos to be redrawn if necessary. * - * HouseClass::Special_Weapon_AI -- Fires special weapon. * - * HouseClass::Spend_Money -- Removes money from the house. * - * HouseClass::Suggest_New_Object -- Determine what would the next buildable object be. * - * HouseClass::Suggested_New_Team -- Determine what team should be created. * - * HouseClass::Suspend_Production -- Temporarily puts production on hold. * - * HouseClass::Validate -- validates house pointer * - * HouseClass::Write_INI -- Writes house specific data into INI file. * - * HouseClass::delete -- Deallocator function for a house object. * - * HouseClass::new -- Allocator for a house class. * - * HouseClass::operator HousesType -- Conversion to HousesType operator. * - * HouseClass::~HouseClass -- Default destructor for a house object. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** New sidebar for GlyphX multiplayer. ST - 3/26/2019 12:24PM -*/ -#include "SidebarGlyphx.h" -#include "defines.h" - - -/*********************************************************************************************** - * HouseClass::Validate -- validates house pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int HouseClass::Validate(void) const -{ - int num; - - num = Houses.ID(this); - if (num < 0 || num >= HOUSE_MAX) { - Validate_Error("HOUSE"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * HouseClass::operator HousesType -- Conversion to HousesType operator. * - * * - * This operator will automatically convert from a houses class object into the HousesType * - * enumerated value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the object's HousesType value. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -HouseClass::operator HousesType(void) const -{ - Validate(); - return(Class->House); -} - - -/*********************************************************************************************** - * HouseClass::As_Pointer -- Converts a house number into a house object pointer. * - * * - * Use this routine to convert a house number into the house pointer that it represents. * - * A simple index into the Houses template array is not sufficient, since the array order * - * is arbitrary. An actual scan through the house object is required in order to find the * - * house object desired. * - * * - * INPUT: house -- The house type number to look up. * - * * - * OUTPUT: Returns with a pointer to the house object that the house number represents. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -HouseClass * HouseClass::As_Pointer(HousesType house) -{ - for (int index = 0; index < Houses.Count(); index++) { - if (Houses.Ptr(index)->Class->House == house) { - return(Houses.Ptr(index)); - } - } - return(0); -} - - -/*********************************************************************************************** - * HouseClass::One_Time -- Handles one time initialization of the house array. * - * * - * This basically calls the constructor for each of the houses in the game. All other * - * data specific to the house is initialized when the scenario is loaded. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Only call this ONCE at the beginning of the game. * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -void HouseClass::One_Time(void) -{ -// for (HousesType index = HOUSE_FIRST; index < HOUSE_COUNT; index++) { -// new(index) HouseClass; -// } - -#ifdef USE_RA_AI - /* - ** Required for Red Alert AI. ST - 7/23/2019 3:21PM - */ - BuildChoice.Set_Heap(STRUCT_COUNT); -#endif -} - - -/*********************************************************************************************** - * HouseClass::Assign_Handicap -- Assigns the specified handicap rating to the house. * - * * - * The handicap rating will affect combat, movement, and production for the house. It can * - * either make it more or less difficult for the house (controlled by the handicap value). * - * * - * INPUT: handicap -- The handicap value to assign to this house. The default value for * - * a house is DIFF_NORMAL. * - * * - * OUTPUT: Returns with the old handicap value. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/09/1996 JLB : Created. * - * 10/22/1996 JLB : Uses act like value for multiplay only. * - *=============================================================================================*/ -DiffType HouseClass::Assign_Handicap(DiffType handicap) -{ - DiffType old = Difficulty; - Difficulty = handicap; - - if (GameToPlay != GAME_NORMAL) { - HouseTypeClass const * hptr = &HouseTypeClass::As_Reference(ActLike); - FirepowerBias = hptr->FirepowerBias * Rule.Diff[handicap].FirepowerBias; - GroundspeedBias = hptr->GroundspeedBias * Rule.Diff[handicap].GroundspeedBias; - AirspeedBias = hptr->AirspeedBias * Rule.Diff[handicap].AirspeedBias; - ArmorBias = hptr->ArmorBias * Rule.Diff[handicap].ArmorBias; - ROFBias = hptr->ROFBias * Rule.Diff[handicap].ROFBias; - CostBias = hptr->CostBias * Rule.Diff[handicap].CostBias; - RepairDelay = Rule.Diff[handicap].RepairDelay; - BuildDelay = Rule.Diff[handicap].BuildDelay; - BuildSpeedBias = hptr->BuildSpeedBias * Rule.Diff[handicap].BuildSpeedBias; - } else { - FirepowerBias = Rule.Diff[handicap].FirepowerBias; - GroundspeedBias = Rule.Diff[handicap].GroundspeedBias; - AirspeedBias = Rule.Diff[handicap].AirspeedBias; - ArmorBias = Rule.Diff[handicap].ArmorBias; - ROFBias = Rule.Diff[handicap].ROFBias; - CostBias = Rule.Diff[handicap].CostBias; - RepairDelay = Rule.Diff[handicap].RepairDelay; - BuildDelay = Rule.Diff[handicap].BuildDelay; - BuildSpeedBias = Rule.Diff[handicap].BuildSpeedBias; - } - - return(old); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * HouseClass::Debug_Dump -- Dumps the house status data to the mono screen. * - * * - * This utility function will output the current status of the house class to the mono * - * screen. Through this information bugs may be fixed or detected. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Debug_Dump(MonoClass *) const -{ - Validate(); -} -#endif - - -/*********************************************************************************************** - * HouseClass::new -- Allocator for a house class. * - * * - * This is the allocator for a house class. Since there can be only * - * one of each type of house, this is allocator has restricted * - * functionality. Any attempt to allocate a house structure for a * - * house that already exists, just returns a pointer to the previously * - * allocated house. * - * * - * INPUT: house -- The house to allocate a class object for. * - * * - * OUTPUT: Returns with a pointer to the allocated class object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1994 JLB : Created. * - *=============================================================================================*/ -void * HouseClass::operator new(size_t) -{ - void * ptr = Houses.Allocate(); - if (ptr) { - ((HouseClass *)ptr)->IsActive = true; - } - return(ptr); -} - - -/*********************************************************************************************** - * HouseClass::delete -- Deallocator function for a house object. * - * * - * This function marks the house object as "deallocated". Such a * - * house object is available for reallocation later. * - * * - * INPUT: ptr -- Pointer to the house object to deallocate. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1994 JLB : Created. * - *=============================================================================================*/ -void HouseClass::operator delete(void *ptr) -{ - if (ptr) { - ((HouseClass *)ptr)->IsActive = false; - } - Houses.Free((HouseClass *)ptr); -} - - -/*********************************************************************************************** - * HouseClass::HouseClass -- Constructor for a house object. * - * * - * This function is the constructor and it marks the house object * - * as being allocated. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1994 JLB : Created. * - *=============================================================================================*/ -HouseClass::HouseClass(HousesType house) : - Class(&HouseTypeClass::As_Reference(house)), - IonCannon(ION_CANNON_GONE_TIME, VOX_ION_READY, VOX_ION_CHARGING, VOX_ION_CHARGING, VOX_NO_POWER), - AirStrike(AIR_CANNON_GONE_TIME, VOX_AIRSTRIKE_READY, VOX_NONE, VOX_NOT_READY, VOX_NOT_READY), - NukeStrike(NUKE_GONE_TIME, VOX_NUKE_AVAILABLE, VOX_NONE, VOX_NOT_READY, VOX_NO_POWER) -{ - - for (HousesType i = HOUSE_FIRST; i < HOUSE_COUNT; i++) { - UnitsKilled[i] = 0; - BuildingsKilled[i] = 0; - } - WhoLastHurtMe = house; // init this to myself - - IsVisionary = false; - IsFreeHarvester = false; - Blockage = 0; - UnitsLost = 0; - BuildingsLost = 0; - - NewActiveBScan = 0; - ActiveBScan = 0; - NewActiveUScan = 0; - ActiveUScan = 0; - NewActiveIScan = 0; - ActiveIScan = 0; - NewActiveAScan = 0; - ActiveAScan = 0; - - strcpy((char *)Name, "Computer"); // Default computer name. - JustBuilt = STRUCT_NONE; - AlertTime = 0; - IsAlerted = false; - IsAirstrikePending = false; - AircraftFactory = -1; - AircraftFactories = 0; - ActLike = Class->House; - Allies = 0; - AScan = 0; - NukeDest = 0; - BlitzTime.Clear(); - ScreenShakeTime.Clear(); - BScan = 0; - BuildingFactories = 0; - BuildingFactory = -1; - Capacity = 0; - Credits = 0; - CreditsSpent = 0; - CurBuildings = 0; - CurUnits = 0; - DamageTime = DAMAGE_DELAY; - Drain = 0; - Edge = SOURCE_NORTH; - FlagHome = 0; - FlagLocation = TARGET_NONE; - HarvestedCredits = 0; - HouseTriggers[house].Clear(); - IGaveUp = false; - InfantryFactories = 0; - InfantryFactory = -1; - InitialCredits = 0; - InitialCredits = 0; - IScan = 0; - IsRecalcNeeded = true; - IsCivEvacuated = false; - IsDefeated = false; - IsDiscovered = false; - IsHuman = false; - WasHuman = false; - IsMaxedOut = false; - IsStarted = false; - IsToDie = false; - IsToLose = false; - IsToWin = false; - Make_Ally(house); - MaxBuilding = 0; - MaxUnit = 0; - NewAScan = 0; - NewBScan = 0; - NewIScan = 0; - NewUScan = 0; - NukePieces = 0x07; - Power = 0; - Radar = RADAR_NONE; - RemapTable = Class->RemapTable; - RemapColor = Class->RemapColor; - Resigned = false; - SpeakAttackDelay = 1; - SpeakMaxedDelay = 1; - - SpeakMoneyDelay = 1; - SpeakMoneyDelay.Set(Options.Normalize_Delay(SPEAK_DELAY)); // 2 minutes - - SpeakPowerDelay = 1; - SpecialFactories = 0; - SpecialFactory = -1; - TeamTime = TEAM_DELAY; - Tiberium = 0; - TriggerTime = 0; - UnitFactories = 0; - UnitFactory = -1; - UScan = 0; - memset((void *)&Regions[0], 0x00, sizeof(Regions)); - - Init_Unit_Trackers(); - - DebugUnlockBuildables = false; - - StartLocationOverride = -1; - - /* - ** New AI variables from RA. Need to add to save/load? - */ -#ifdef USE_RA_AI - - IsBaseBuilding = true; - Center = 0; - Radius = 0; - for (ZoneType zone = ZONE_FIRST; zone < ZONE_COUNT; zone++) { - ZoneInfo[zone].AirDefense = 0; - ZoneInfo[zone].ArmorDefense = 0; - ZoneInfo[zone].InfantryDefense = 0; - } - - - LATime = 0; - LAType = RTTI_NONE; - LAZone = ZONE_NONE; - LAEnemy = HOUSE_NONE; - - ToCapture = TARGET_NONE; - - RadarSpied = 0; - PointTotal = 0; - - memset(BQuantity, '\0', sizeof(BQuantity)); - memset(UQuantity, '\0', sizeof(UQuantity)); - memset(IQuantity, '\0', sizeof(IQuantity)); - memset(AQuantity, '\0', sizeof(AQuantity)); - - Attack = 0; - - Enemy = HOUSE_NONE; - - AITimer = 0; - - BuildStructure = STRUCT_NONE; - BuildUnit = UNIT_NONE; - BuildInfantry = INFANTRY_NONE; - BuildAircraft = AIRCRAFT_NONE; - - State = STATE_BUILDUP; - - IsTiberiumShort = false; - - IQ = Rule.MaxIQ; - - IsParanoid = false; - - OldBScan = 0; - - Assign_Handicap(DIFF_NORMAL); - -#endif - -} - - -HouseClass::~HouseClass (void) -{ - Free_Unit_Trackers(); -} - -/*********************************************************************************************** - * HouseClass::Can_Build -- General purpose build legality checker. * - * * - * This routine is called when it needs to be determined if the specified object type can * - * be built by this house. Production and sidebar maintenance use this routine heavily. * - * * - * INPUT: type -- Pointer to the type of object that legality is to be checked for. * - * * - * house -- This is the house to check for legality against. Note that this might * - * not be 'this' house since the check could be from a captured factory. * - * Captured factories build what the original owner of them could build. * - * * - * OUTPUT: Can the specified object be built? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - * 08/12/1995 JLB : Updated for GDI building sandbag walls in #9. * - *=============================================================================================*/ -bool HouseClass::Can_Build(TechnoTypeClass const * type, HousesType house) const -{ - Validate(); - if (!type || !type->IsBuildable || !((1L << house) & type->Ownable)) return(false); - - /* - ** The computer can always build everthing. - */ -#ifdef USE_RA_AI - if (!IsHuman && GameToPlay == GAME_NORMAL) return(true); // Added game type check for AI from RA. ST - 7/25/2019 3:25PM -#else - if (!IsHuman) return(true); -#endif - - /* - ** Perform some equivalency fixups for the building existance flags. - */ - long flags = ActiveBScan; - -#ifdef USE_RA_AI - // OldBScan Copied from RA for AI. ST - 7/25/2019 3:27PM - /* - ** The computer records prerequisite buildings because it can't relay on the - ** sidebar to keep track of this information. - */ - if (!IsHuman) { - flags = OldBScan; - } -#endif - - int pre = type->Pre; - if (flags & STRUCTF_ADVANCED_POWER) flags |= STRUCTF_POWER; - if (flags & STRUCTF_HAND) flags |= STRUCTF_BARRACKS; - if (flags & STRUCTF_OBELISK) flags |= STRUCTF_ATOWER; - if (flags & STRUCTF_TEMPLE) flags |= STRUCTF_EYE; - if (flags & STRUCTF_AIRSTRIP) flags |= STRUCTF_WEAP; - if (flags & STRUCTF_SAM) flags |= STRUCTF_HELIPAD; - - /* - ** Multiplayer game uses a different legality check for building. - */ - if (GameToPlay != GAME_NORMAL || (Special.IsJurassic && AreThingiesEnabled)) { - if (DebugUnlockBuildables) { - return true; - } - return((pre & flags) == pre && type->Level <= BuildLevel); - } - -#ifdef NEWMENU - int level = BuildLevel; -#else - int level = Scenario; -#endif - - /* - ** Special check to make the mission objective buildings the prerequisite - ** for the stealth tank in mission #11 only. - */ - if (house == HOUSE_BAD && - type->What_Am_I() == RTTI_UNITTYPE && - ((UnitTypeClass const *)type)->Type == UNIT_STANK && - level == 11) { - - pre = STRUCTF_MISSION; - level = type->Scenario; - } - - /* - ** Special case check to ensure that GDI doesn't get the bazooka guy - ** until mission #8. - */ - if (house == HOUSE_GOOD && - type->What_Am_I() == RTTI_INFANTRYTYPE && - ((InfantryTypeClass const *)type)->Type == INFANTRY_E3 && - level < 7) { - - return(false); - } - - /* - ** Special check to allow GDI to build the MSAM by mission #9 - ** and no sooner. - */ - if (house == HOUSE_GOOD && - type->What_Am_I() == RTTI_UNITTYPE && - ((UnitTypeClass const *)type)->Type == UNIT_MLRS && - level < 9) { - - return(false); - } - - /* - ** Special case to disable the APC from the Nod player. - */ - if (house == HOUSE_BAD && - type->What_Am_I() == RTTI_UNITTYPE && - ((UnitTypeClass const *)type)->Type == UNIT_APC) { - - return(false); - } - - /* - ** Ensure that the Temple of Nod cannot be built by GDI even - ** if GDI has captured the Nod construction yard. - */ - if (type->What_Am_I() == RTTI_BUILDINGTYPE && - (((BuildingTypeClass const *)type)->Type == STRUCT_TEMPLE || ((BuildingTypeClass const *)type)->Type == STRUCT_OBELISK) && - Class->House == HOUSE_GOOD) { - - return(false); - } - - /* - ** Ensure that the rocket launcher tank cannot be built by Nod. - */ - if (type->What_Am_I() == RTTI_UNITTYPE && - ((UnitTypeClass const *)type)->Type == UNIT_MLRS && - Class->House == HOUSE_BAD) { - - return(false); - } - - /* - ** Ensure that the ion cannon cannot be built if - ** Nod has captured the GDI construction yard. - */ - if (type->What_Am_I() == RTTI_BUILDINGTYPE && - (((BuildingTypeClass const *)type)->Type == STRUCT_EYE) && - Class->House == HOUSE_BAD) { - - return(false); - } - - /* - ** Nod can build the advanced power plant at scenario #12. - */ - if (house == HOUSE_BAD && - level >= 12 && - type->What_Am_I() == RTTI_BUILDINGTYPE && - ((BuildingTypeClass const *)type)->Type == STRUCT_ADVANCED_POWER) { - - level = type->Scenario; - } - - /* - ** Nod cannot build a helipad in the normal game. - */ - if (house == HOUSE_BAD && - type->What_Am_I() == RTTI_BUILDINGTYPE && - ((BuildingTypeClass const *)type)->Type == STRUCT_HELIPAD) { - - return(false); - } - - /* - ** GDI can build the sandbag wall only from scenario #9 onwards. - */ - if (house == HOUSE_GOOD && - level < 8 && - type->What_Am_I() == RTTI_BUILDINGTYPE && - ((BuildingTypeClass const *)type)->Type == STRUCT_SANDBAG_WALL) { - - return(false); - } - - /* - ** GDI has a special second training mission. Adjust the scenario level so that - ** scenario two will still feel like scenario #1. - */ - if (house == HOUSE_GOOD && level == 2) { - level = 1; - } - - // ST - 8/23/2019 4:53PM - if (DebugUnlockBuildables) { - level = 98; - pre = 0; - } - - if (Debug_Cheat) level = 98; - return((pre & flags) == pre && type->Scenario <= level); -} - - -/*********************************************************************************************** - * HouseClass::Can_Build -- Determines if the building type can be built. * - * * - * This routine is used by the construction preparation code to building a list of building * - * types that can be built. It determines if a building can be built by checking if the * - * prerequisite buildings have been built (and still exist) as well as checking to see if * - * the house can build the specified structure. * - * * - * INPUT: s -- The structure type number that is being checked. * - * * - * house -- The house number to use when determining if the object can be built. * - * This is necessary because the current owner of the factory doesn't * - * control what the factory can produce. Rather, the original builder of * - * the factory controls this. * - * * - * OUTPUT: bool; Can this structure type be built at this time? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/08/1994 JLB : Created. * - * 05/31/1995 JLB : Handles specified ownership override. * - *=============================================================================================*/ -bool HouseClass::Can_Build(StructType s, HousesType house) const -{ - Validate(); - return(Can_Build(&BuildingTypeClass::As_Reference(s), house)); -} - - -/*********************************************************************************************** - * HouseClass::Can_Build -- Determines if the infantry unit can be built by this house. * - * * - * Use this routine to determine if the infantry type specified can be built by this * - * house. It determines this by checking the ownership allowed bits in the infantry * - * type class. * - * * - * INPUT: infantry -- The infantry type to check against this house. * - * * - * house -- The house number to use when determining if the object can be built. * - * This is necessary because the current owner of the factory doesn't * - * control what the factory can produce. Rather, the original builder of * - * the factory controls this. * - * * - * OUTPUT: bool; Can the infantry be produced by this house? * - * * - * WARNINGS: It does not check to see if there is a functional barracks available, but * - * merely checks to see if it is legal for this house to build that infantry * - * type. * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - * 05/31/1995 JLB : Handles specified ownership override. * - *=============================================================================================*/ -bool HouseClass::Can_Build(InfantryType infantry, HousesType house) const -{ - Validate(); - return(Can_Build(&InfantryTypeClass::As_Reference(infantry), house)); -} - - -/*********************************************************************************************** - * HouseClass::Can_Build -- Determines if the unit can be built by this house. * - * * - * This routine is used to determine if the unit type specified can in fact be built by * - * this house. It checks the ownable bits in the unit's type to determine this. * - * * - * INPUT: unit -- The unit type to check against this house. * - * * - * house -- The house number to use when determining if the object can be built. * - * This is necessary because the current owner of the factory doesn't * - * control what the factory can produce. Rather, the original builder of * - * the factory controls this. * - * * - * OUTPUT: bool; Can the unit be built by this house? * - * * - * WARNINGS: This doesn't check to see if there is a functional factory that can build * - * this unit, but merely if the unit can be built according to ownership rules. * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - * 05/31/1995 JLB : Handles specified ownership override. * - *=============================================================================================*/ -bool HouseClass::Can_Build(UnitType unit, HousesType house) const -{ - Validate(); - return(Can_Build(&UnitTypeClass::As_Reference(unit), house)); -} - - -/*********************************************************************************************** - * HouseClass::Can_Build -- Determines if the aircraft type can be built. * - * * - * Use this routine to determine if the specified aircraft type can be built. This routine * - * is used by the sidebar and factory to determine what can be built. * - * * - * INPUT: aircraft -- The aircraft type to check for build legality. * - * * - * house -- The house that is performing the check. This is typically the house * - * of the original building of the factory rather than the current * - * owner. * - * * - * OUTPUT: Can this aircraft type be built by the house specified? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Can_Build(AircraftType aircraft, HousesType house) const -{ - Validate(); - return(Can_Build(&AircraftTypeClass::As_Reference(aircraft), house)); -} - - -/*************************************************************************** - * HouseClass::Init -- init's in preparation for new scenario * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - * 12/17/1994 JLB : Resets tracker bits. * - *=========================================================================*/ -void HouseClass::Init(void) -{ - Houses.Free_All(); - - for (HousesType index = HOUSE_FIRST; index < HOUSE_COUNT; index++) { - HouseTriggers[index].Clear(); - } -} - - -// Object selection list is switched with player context for GlyphX. ST - 4/17/2019 9:42AM -extern void Logic_Switch_Player_Context(HouseClass *house); - -/*********************************************************************************************** - * HouseClass::AI -- Process house logic. * - * * - * This handles the AI for the house object. It should be called once per house per game * - * tick. It processes all house global tasks such as low power damage accumulation and * - * house specific trigger events. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - * 07/17/1995 JLB : Limits EVA speaking unless the player can do something. * - *=============================================================================================*/ -extern void Recalculate_Placement_Distances(); -extern void On_Message(const char* message, float timeout_seconds, long long message_id); - -void HouseClass::AI(void) -{ - Validate(); - - // Set PlayerPtr to be this house. Not really keen on this solution but it means I have to make fewer code changes to the original code. ST - 4/17/2019 4:32PM - Logic_Switch_Player_Context(this); - - /* - ** Reset the scan accumulation bits for the next logic pass. - */ - IScan = NewIScan; - BScan = NewBScan; - UScan = NewUScan; - AScan = NewAScan; - ActiveIScan = NewActiveIScan; - ActiveBScan = NewActiveBScan; - ActiveUScan = NewActiveUScan; - ActiveAScan = NewActiveAScan; - NewIScan = 0; - NewBScan = 0; - NewUScan = 0; - NewAScan = 0; - NewActiveIScan = 0; - NewActiveBScan = 0; - NewActiveUScan = 0; - NewActiveAScan = 0; - -#ifdef USE_RA_AI - // - // Copied from RA for AI. ST - 7/25/2019 3:58PM - // - /* - ** If base building has been turned on by a trigger, then force the house to begin - ** production and team creation as well. This is also true if the IQ is high enough to - ** being base building. - */ - if (!IsHuman && GameToPlay != GAME_NORMAL && (IsBaseBuilding || IQ >= Rule.IQProduction)) { - IsBaseBuilding = true; - IsStarted = true; - IsAlerted = true; - } -#endif - - /* - ** Check to see if the house wins. - */ - if (GameToPlay == GAME_NORMAL && IsToWin && BorrowedTime.Expired() && Blockage <= 0) { - IsToWin = false; - if (this == PlayerPtr) { - PlayerWins = true; - } else { - PlayerLoses = true; - } - } - - /* - ** Check to see if the house loses. - */ - if (GameToPlay == GAME_NORMAL && IsToLose && BorrowedTime.Expired()) { - IsToLose = false; - if (this == PlayerPtr) { - PlayerLoses = true; - } else { - PlayerWins = true; - } - } - - /* - ** Check to see if all objects of this house should be blown up. - */ - if (IsToDie && BorrowedTime.Expired()) { - IsToDie = false; - Blowup_All(); - } - - /* - ** Double check power values to correct illegal conditions. It is possible to - ** get a power output of negative (one usually) as a result of damage sustained - ** and the fixed point fractional math involved with power adjustements. If the - ** power rating drops below zero, then make it zero. - */ - if (GameToPlay == GAME_NORMAL) { - Power = MAX(Power, 0); - Drain = MAX(Drain, 0); - } - - /* - ** If the base has been alerted to the enemy and should be attacking, then - ** see if the attack timer has expired. If it has, then create the attack - ** teams. - */ - if (IsAlerted && AlertTime.Expired()) { - - /* - ** Adjusted to reduce maximum number of teams created. - */ - int maxteams = Random_Pick(2, (int)(((BuildLevel-1)/3)+1)); - for (int index = 0; index < maxteams; index++) { - TeamTypeClass const * ttype = Suggested_New_Team(true); - if (ttype) { - ScenarioInit++; - ttype->Create_One_Of(); - ScenarioInit--; - } - } - if (GameToPlay == GAME_NORMAL && PlayerPtr->Difficulty == DIFF_HARD) { - AlertTime = (TICKS_PER_MINUTE * Random_Pick(4, 10)); - } else { - if (GameToPlay == GAME_NORMAL && PlayerPtr->Difficulty == DIFF_EASY) { - AlertTime = (TICKS_PER_MINUTE * Random_Pick(16, 40)); - } else { - AlertTime = (TICKS_PER_MINUTE * Random_Pick(5, 20)); - } - } - } - - /* - ** Create teams for this house if necessary. - ** (Use the same timer for some extra capture-the-flag logic.) - */ - if (TeamTime.Expired()) { - TeamTypeClass const * ttype = Suggested_New_Team(false); - if (ttype) { - ttype->Create_One_Of(); - } - - /* - ** Also use this timer to detect if someone is sitting on my flag cell. - */ - if (Special.IsCaptureTheFlag && GameToPlay != GAME_NORMAL) { - TechnoClass *techno; - int moving; - - /* - ** If this house's flag waypoint is a valid cell, see if there's - ** someone sitting on it. If so, make the scatter. - */ - if (FlagHome) { - techno = Map[FlagHome].Cell_Techno(); - if (techno) { - moving = false; - if (techno->What_Am_I() == RTTI_INFANTRY || - techno->What_Am_I() == RTTI_UNIT) { - if (Target_Legal(((FootClass *)techno)->NavCom)) { - moving = true; - } - } - - if (!moving) { - techno->Scatter(0,true,true); - } - } - } - } - - /* - ** Randomly create a Visceroid or other disastrous multiplayer object. - ** Create the object, and use Scan_Place_Object to place the object near - ** the center of the map. - */ - if (GameToPlay != GAME_NORMAL && Class->House==HOUSE_JP) { - int rlimit; - - if (Special.IsJurassic && AreThingiesEnabled) { - rlimit = 450; - } else { - rlimit = 1000; - } - - //if (IRandom(0, rlimit) == 0) { - if (IRandom(0, rlimit) <= 5) { // More visceroids! ST - 3/3/2020 4:34PM - UnitClass *obj = NULL; - CELL cell; - - if (Special.IsJurassic && AreThingiesEnabled) { - obj = new UnitClass(Random_Pick(UNIT_TRIC, UNIT_STEG), HOUSE_JP); - } else if (Special.IsVisceroids) { - if (BuildLevel >= 7) { - if (!(UScan & UNITF_VICE)) { - obj = new UnitClass(UNIT_VICE, HOUSE_JP); - } - } - } - - if (obj) { - cell = XY_Cell (Map.MapCellX + Random_Pick(0, Map.MapCellWidth - 1), - Map.MapCellY + Random_Pick(0, Map.MapCellHeight - 1)); - if (!Scan_Place_Object(obj, cell)) { - delete obj; - } - } - } - } - - TeamTime.Set(TEAM_DELAY); - } - - /* - ** If there is insufficient power, then all buildings that are above - ** half strength take a little bit of damage. - */ - if (DamageTime.Expired()) { - -/* -** No free harvesters for computer or player. - 8/16/95 -*/ -#ifdef OBSOLETE - /* - ** Replace the last harvester if there is a refinery present. - */ - if (GameToPlay == GAME_NORMAL && - Frame > 5 && - (!IsHuman && BuildLevel <= 6) && - (ActiveBScan & STRUCTF_REFINERY) != 0 && - (UScan & UNITF_HARVESTER) == 0 && - !IsFreeHarvester) { - - IsFreeHarvester = true; - FreeHarvester = TICKS_PER_MINUTE * 2; - } -#endif - - /* - ** If a free harvester is to be created and the time is right, then create - ** the harvester and clear the free harvester pending flag. - */ - if (IsFreeHarvester && FreeHarvester.Expired()) { - IsFreeHarvester = false; - Create_Special_Reinforcement(this, (TechnoTypeClass *)&UnitTypeClass::As_Reference(UNIT_HARVESTER), NULL); - } - - /* - ** When the power is below required, then the buildings will take damage over - ** time. - */ - if (Power_Fraction() < 0x100) { - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass & b = *Buildings.Ptr(index); - - if (b.House == this && b.Health_Ratio() > 0x080) { - if (b.Class->Drain) { - int damage = 1; - b.Take_Damage(damage, 0, WARHEAD_AP, 0); - } - } - } - } - DamageTime.Set(DAMAGE_DELAY); - } - - /* - ** If there are no more buildings to sell, then automatically cancel the - ** sell mode. - */ - if (PlayerPtr == this && !BScan && Map.IsSellMode) { - Map.Sell_Mode_Control(0); - } - - /* - ** Various base conditions may be announced to the player. - */ - if (PlayerPtr == this) { - - if (SpeakMoneyDelay.Expired() && Available_Money() < 100 && UnitFactories+BuildingFactories+InfantryFactories > 0) { - - // MBL 03.23.2020 - Change "Need more funds" to "Insufficient funds" per https://jaas.ea.com/browse/TDRA-5370 - // Speak(VOX_NEED_MO_MONEY); - Speak(VOX_NO_CASH); - - // - // !!! MBL 03.18.2020: - // !!! Changing "Insufficient Funds" speak delay for this case to 1 minute instead of 2. - // !!! Note that all other speak delays are 2 minutes in TD (SPEAK_DELAY) and RA (Rule.SpeakDelay) - // !!! This is per https://jaas.ea.com/browse/TDRA-4659 (Ted and Jim) - // !!! I Checked with Joe mostly okay with this change, but want to note that we are changing original behavior - // !!! All other speak delays in TD and RA (max capacity and low power) remain at 2 minutes. - // !!! Also, in Red Alert, this is still 2 minutes from Rules.ini (SpeakDelay variable) - // - // SpeakMoneyDelay.Set(Options.Normalize_Delay(SPEAK_DELAY)); // 2 minutes - // - // MBL 05.18.2020: Setting back to 2 minutes as requested per https://jaas.ea.com/browse/TDRA-5834 - // - // SpeakMoneyDelay.Set(Options.Normalize_Delay(SPEAK_DELAY / 2)); // 1 minute (new) - SpeakMoneyDelay.Set(Options.Normalize_Delay(SPEAK_DELAY)); // 2 minutes (original) - - int text_id = TXT_INSUFFICIENT_FUNDS; - char const * text = Text_String(TXT_INSUFFICIENT_FUNDS); - if (text != NULL) { - On_Message(text, 35.0f, text_id); - } - } - if (SpeakMaxedDelay.Expired() && IsMaxedOut) { - IsMaxedOut = false; - if ((Capacity - Tiberium) < 300 && Capacity > 500 && (BScan & (STRUCTF_REFINERY | STRUCTF_CONST))) { - Speak(VOX_NEED_MO_CAPACITY); - SpeakMaxedDelay.Set(Options.Normalize_Delay(SPEAK_DELAY)); - } - } - if (SpeakPowerDelay.Expired() && Power_Fraction() < 0x0100) { - if (BScan & STRUCTF_CONST) { - Speak(VOX_LOW_POWER); - SpeakPowerDelay.Set(Options.Normalize_Delay(SPEAK_DELAY)); - - int text_id = TXT_LOW_POWER; - char const * text = Text_String(TXT_LOW_POWER); - if (text != NULL) { - On_Message(text, 35.0f, text_id); - } - } - } - } - - /* - ** If there is a flag associated with this house, then mark it to be - ** redrawn. - */ - if (Target_Legal(FlagLocation)) { - UnitClass * unit = As_Unit(FlagLocation); - if (unit) { - unit->Mark(MARK_CHANGE); - } else { - CELL cell = As_Cell(FlagLocation); - Map[cell].Flag_Update(); - Map[cell].Redraw_Objects(); - } - } - - bool is_time = false; - - /* - ** Triggers are only checked every so often. If the trigger timer has expired, - ** then set the trigger processing flag. - */ - if (TriggerTime.Expired()) { - is_time = true; - TriggerTime = TICKS_PER_MINUTE/10; - } - - /* - ** Check to see if the ion cannon should be removed from the sidebar - ** because of outside circumstances. The advanced communications facility - ** being destroyed is a good example of this. - */ - if (IonCannon.Is_Present()) { - if (!(ActiveBScan & STRUCTF_EYE) && !IonCannon.Is_One_Time()) { - - /* - ** Remove the ion cannon when there is no advanced communication facility. - ** Note that this will not remove the one time created ion cannon. - */ - if (IonCannon.Remove()) { - if (this == PlayerPtr) Map.Column[1].Flag_To_Redraw(); - IsRecalcNeeded = true; - } - } else { - - /* - ** Turn the ion cannon suspension on or off depending on the available - ** power. Note that one time ion cannon will not be affected by this. - */ - IonCannon.Suspend(Power_Fraction() < 0x0100); - - /* - ** Process the ion cannon AI and if something changed that would affect - ** the sidebar, then flag the sidebar to be redrawn. - */ - if (IonCannon.AI(this == PlayerPtr)) { - if (this == PlayerPtr) Map.Column[1].Flag_To_Redraw(); - } - } - - /* - ** The computer may decide to fire the ion cannon if it is ready. - */ - if (IonCannon.Is_Ready() && !IsHuman) { - Special_Weapon_AI(SPC_ION_CANNON); - } - - } else { - - /* - ** If there is no ion cannon present, but there is an advanced communcation - ** center available, then make the ion cannon available as well. - */ - if ((GameToPlay == GAME_NORMAL || Rule.AllowSuperWeapons) && - (ActiveBScan & STRUCTF_EYE) && - (ActLike == HOUSE_GOOD || GameToPlay != GAME_NORMAL) && - (IsHuman || GameToPlay != GAME_NORMAL)) { - - IonCannon.Enable(false, this == PlayerPtr, Power_Fraction() < 0x0100); - - /* - ** Flag the sidebar to be redrawn if necessary. - */ - // Add to Glyphx multiplayer sidebar. ST - 3/22/2019 1:50PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (IsHuman) { - Sidebar_Glyphx_Add(RTTI_SPECIAL, SPC_ION_CANNON, this); - } - } else { - if (this == PlayerPtr) { - Map.Add(RTTI_SPECIAL, SPC_ION_CANNON); - Map.Column[1].Flag_To_Redraw(); - } - } - } - } - - /* - ** Check to see if the nuke strike should be removed from the sidebar - ** because of outside circumstances. The Temple of Nod - ** being destroyed is a good example of this. - */ - if (NukeStrike.Is_Present()) { - if (!(ActiveBScan & STRUCTF_TEMPLE) && (!NukeStrike.Is_One_Time() || GameToPlay == GAME_NORMAL)) { - - /* - ** Remove the nuke strike when there is no Temple of Nod. - ** Note that this will not remove the one time created nuke strike. - */ - if (NukeStrike.Remove(true)) { - IsRecalcNeeded = true; - if (this == PlayerPtr) Map.Column[1].Flag_To_Redraw(); - } - } else { - - /* - ** Turn the nuke strike suspension on or off depending on the available - ** power. Note that one time nuke strike will not be affected by this. - */ - NukeStrike.Suspend(Power_Fraction() < 0x0100); - - /* - ** Process the nuke strike AI and if something changed that would affect - ** the sidebar, then flag the sidebar to be redrawn. - */ - if (NukeStrike.AI(this == PlayerPtr)) { - if (this == PlayerPtr) Map.Column[1].Flag_To_Redraw(); - } - } - - /* - ** The computer may decide to fire the nuclear missile if it is ready. - */ - if (NukeStrike.Is_Ready() && !IsHuman) { - Special_Weapon_AI(SPC_NUCLEAR_BOMB); - } - - } else { - - /* - ** If there is no nuke strike present, but there is a Temple of Nod - ** available, then make the nuke strike strike available. - */ - if ((GameToPlay == GAME_NORMAL || Rule.AllowSuperWeapons) && (ActiveBScan & STRUCTF_TEMPLE) && Has_Nuke_Device() && IsHuman) { - NukeStrike.Enable((GameToPlay == GAME_NORMAL), this == PlayerPtr); - - /* - ** Flag the sidebar to be redrawn if necessary. - */ - // Add to Glyphx multiplayer sidebar. ST - 3/22/2019 1:50PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (IsHuman) { - Sidebar_Glyphx_Add(RTTI_SPECIAL, SPC_NUCLEAR_BOMB, this); - } - } else { - if (this == PlayerPtr) { - Map.Add(RTTI_SPECIAL, SPC_NUCLEAR_BOMB); - Map.Column[1].Flag_To_Redraw(); - } - } - } - } - - /* - ** Process the airstrike AI and if something changed that would affect - ** the sidebar, then flag the sidebar to be redrawn. - */ - if (AirStrike.Is_Present()) { - if (AirStrike.AI(this == PlayerPtr)) { - if (this == PlayerPtr) Map.Column[1].Flag_To_Redraw(); - } - - /* - ** The computer may decide to call in the airstrike if it is ready. - */ - if (AirStrike.Is_Ready() && !IsHuman) { - Special_Weapon_AI(SPC_AIR_STRIKE); - } - } - - /* - ** Add the airstrike option if it is pending. - */ - if (IsAirstrikePending) { - IsAirstrikePending = false; - if (AirStrike.Enable(false, this == PlayerPtr)) { - AirStrike.Forced_Charge(this == PlayerPtr); - // Add to Glyphx multiplayer sidebar. ST - 3/22/2019 1:50PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (IsHuman) { - Sidebar_Glyphx_Add(RTTI_SPECIAL, SPC_AIR_STRIKE, this); - } - } else { - if (this == PlayerPtr) { - Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE); - Map.Column[1].Flag_To_Redraw(); - } - } - } - } - -#ifdef NEVER - /* - ** The following logic deals with the nuclear warhead state machine. It - ** handles all the different stages of the temple firing and the rocket - ** travelling up and down. The rocket explosion is handled by the anim - ** which is attached to the bullet. - */ - if (!IsHuman && NukePresent) { - Special_Weapon_AI(SPC_NUCLEAR_BOMB); - - } -#endif - - if (GameToPlay != GAME_NORMAL) { - Check_Pertinent_Structures(); - } - - /* - ** Special win/lose check for multiplayer games; by-passes the - ** trigger system. We must wait for non-zero frame, because init - ** may not properly set IScan etc for each house; you have to go - ** through each object's AI before it will be properly set. - */ - if (GameToPlay != GAME_NORMAL && !IsDefeated && - !ActiveBScan && !ActiveAScan && !UScan && !ActiveIScan && Frame > 0) { - MPlayer_Defeated(); - } - - for (int index = 0; index < HouseTriggers[Class->House].Count(); index++) { - TriggerClass * t = HouseTriggers[Class->House][index]; - - /* - ** Check for just built the building trigger event. - */ - if (JustBuilt != STRUCT_NONE) { - if (t->Spring(EVENT_BUILD, Class->House, JustBuilt)) { - JustBuilt = STRUCT_NONE; - continue; - } - } - - /* - ** Check for civilian evacuation trigger event. - */ - if (IsCivEvacuated && t->Spring(EVENT_EVAC_CIVILIAN, Class->House)) { - continue; - } - - /* - ** Number of buildings destroyed checker. - */ - if (t->Spring(EVENT_NBUILDINGS_DESTROYED, Class->House, BuildingsLost)) { - continue; - } - - /* - ** Number of units destroyed checker. - */ - if (t->Spring(EVENT_NUNITS_DESTROYED, Class->House, UnitsLost)) { - continue; - } - - /* - ** House has been revealed trigger event. - */ - if (IsDiscovered && t->Spring(EVENT_HOUSE_DISCOVERED, Class->House)) { - IsDiscovered = false; - continue; - } - - /* - ** The "all destroyed" triggers are only processed after a certain - ** amount of safety time has expired. - */ - if (!EndCountDown) { - - /* - ** All buildings destroyed checker. - */ - if (!ActiveBScan) { - if (t->Spring(EVENT_BUILDINGS_DESTROYED, Class->House)) { - continue; - } - } - - /* - ** All units destroyed checker. - */ - if (!((ActiveUScan & ~(UNITF_GUNBOAT)) | IScan | (ActiveAScan & ~(AIRCRAFTF_TRANSPORT|AIRCRAFTF_CARGO|AIRCRAFTF_A10)))) { - if (t->Spring(EVENT_UNITS_DESTROYED, Class->House)) { - continue; - } - } - - /* - ** All buildings AND units destroyed checker. - */ - if (!(ActiveBScan | (ActiveUScan & ~(UNITF_GUNBOAT)) | IScan | (ActiveAScan & ~(AIRCRAFTF_TRANSPORT|AIRCRAFTF_CARGO|AIRCRAFTF_A10)))) { - if (t->Spring(EVENT_ALL_DESTROYED, Class->House)) { - continue; - } - } - } - - /* - ** Credit check. - */ - if (t->Spring(EVENT_CREDITS, Class->House, Credits)) { - continue; - } - - /* - ** Timeout check. - */ - if (is_time && t->Spring(EVENT_TIME, Class->House)) { - continue; - } - - /* - ** All factories destroyed check. - */ - if (!(BScan & (STRUCTF_AIRSTRIP|STRUCTF_HAND|STRUCTF_WEAP|STRUCTF_BARRACKS)) && t->Spring(EVENT_NOFACTORIES, Class->House)) { - continue; - } - } - - /* - ** If a radar facility is not present, but the radar is active, then turn the radar off. - ** The radar also is turned off when the power gets below 100% capacity. - */ - if (PlayerPtr == this) { - if (Map.Is_Radar_Active()) { - if (BScan & (STRUCTF_RADAR|STRUCTF_EYE)) { - if (Power_Fraction() < 0x0100) { - Map.Radar_Activate(0); - } - } else { - Map.Radar_Activate(0); - } - } else { - if (BScan & (STRUCTF_RADAR|STRUCTF_EYE)) { - if (Power_Fraction() >= 0x0100) { - Map.Radar_Activate(1); - } - } else { - if (Map.Is_Radar_Existing()) { - Map.Radar_Activate(4); - } - } - } - if (!(BScan & (STRUCTF_RADAR|STRUCTF_EYE))) { - Radar = RADAR_NONE; - } else { - Radar = (Map.Is_Radar_Active() || Map.Is_Radar_Activating()) ? RADAR_ON : RADAR_OFF; - } - } - - - VisibleCredits.AI(false, this, true); - - - /* - ** Copied from Red Alert for multiplayer AI. ST - 7/23/2019 3:02PM - ** - ** - ** - */ -#ifdef USE_RA_AI - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER && IsHuman == false) { - - /* - ** Perform any expert system AI processing. - */ - if (IsBaseBuilding && AITimer == 0) { - AITimer = Expert_AI(); - } - - if (!IsBaseBuilding && State == STATE_ENDGAME) { - Fire_Sale(); - Do_All_To_Hunt(); - } - - AI_Building(); - AI_Unit(); - AI_Vessel(); - AI_Infantry(); - AI_Aircraft(); - } -#endif - - /* - ** If the production possibilities need to be recalculated, then do so now. This must - ** occur after the scan bits have been properly updated. - */ - if (PlayerPtr == this && IsRecalcNeeded) { - IsRecalcNeeded = false; - Map.Recalc(); - -#ifdef NEVER - /* - ** Remove the ion cannon if necessary. - */ - if (IonCannon.Is_Present() && !(BScan & STRUCTF_EYE)) { - IonCannon.Remove(); - } - - /* - ** Remove the nuclear bomb if necessary. - */ - if (NukeStrike.Is_Present() && !(BScan & STRUCTF_TEMPLE)) { - NukeStrike.Remove(); - } -#endif - - /* - ** This placement might affect any prerequisite requirements for construction - ** lists. Update the buildable options accordingly. - */ - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - if (building && building->Owner() == Class->House) { - - building->Update_Specials(); - if (PlayerPtr == building->House) { - building->Update_Buildables(); - } - } - } - - Recalculate_Placement_Distances(); - } -} - - -/*********************************************************************************************** - * HouseClass::Attacked -- Lets player know if base is under attack. * - * * - * Call this function whenever a building is attacked (with malice). This function will * - * then announce to the player that his base is under attack. It checks to make sure that * - * this is referring to the player's house rather than the enemy's. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/27/1994 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Attacked(BuildingClass* source) -{ - Validate(); - if (SpeakAttackDelay.Expired() && PlayerPtr->Class->House == Class->House) { - Speak(VOX_BASE_UNDER_ATTACK, NULL, source ? source->Center_Coord() : 0); - - // MBL 06.13.2020 - Timing change from 2 minute cooldown, per https://jaas.ea.com/browse/TDRA-6784 - // SpeakAttackDelay.Set(Options.Normalize_Delay(SPEAK_DELAY)); // 2 minutes - // SpeakAttackDelay.Set(Options.Normalize_Delay(TICKS_PER_MINUTE/2)); // 30 seconds as requested - SpeakAttackDelay.Set(Options.Normalize_Delay( (TICKS_PER_MINUTE/2)+(TICKS_PER_SECOND*5) )); // Tweaked for accuracy - - /* - ** If there is a trigger event associated with being attacked, process it - ** now. - */ - for (int index = 0; index < HouseTriggers[Class->House].Count(); index++) { - HouseTriggers[Class->House][index]->Spring(EVENT_ATTACKED, Class->House); - } - } -} - - -/*********************************************************************************************** - * HouseClass::Harvested -- Adds Tiberium to the harvest storage. * - * * - * Use this routine whenever Tiberium is harvested. The Tiberium is stored equally between * - * all storage capable buildings for the house. Harvested Tiberium adds to the credit * - * value of the house, but only up to the maximum storage capacity that the house can * - * currently maintain. * - * * - * INPUT: tiberium -- The number of Tiberium credits to add to the House's total. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Harvested(unsigned tiberium) -{ - Validate(); - long oldtib = Tiberium; - - Tiberium += tiberium; - if (Tiberium > Capacity) { - Tiberium = Capacity; - IsMaxedOut = true; - } - HarvestedCredits += tiberium; - Silo_Redraw_Check(oldtib, Capacity); -} - - -/*********************************************************************************************** - * HouseClass::Available_Money -- Fetches the total credit worth of the house. * - * * - * Use this routine to determine the total credit value of the house. This is the sum of * - * the harvested Tiberium in storage and the initial unspent cash reserves. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the total credit value of the house. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - *=============================================================================================*/ -long HouseClass::Available_Money(void) const -{ - Validate(); - return(Tiberium + Credits); -} - - -/*********************************************************************************************** - * HouseClass::Spend_Money -- Removes money from the house. * - * * - * Use this routine to extract money from the house. Typically, this is a result of * - * production spending. The money is extracted from available cash reserves first. When * - * cash reserves are exhausted, then Tiberium is consumed. * - * * - * INPUT: money -- The amount of money to spend. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - * 06/20/1995 JLB : Spends Tiberium before spending cash. * - *=============================================================================================*/ -void HouseClass::Spend_Money(unsigned money) -{ - Validate(); - long oldtib = Tiberium; - if ((int)money > Tiberium) { - money -= (unsigned)Tiberium; - Tiberium = 0; - Credits -= money; - } else { - Tiberium -= money; - } - Silo_Redraw_Check(oldtib, Capacity); - CreditsSpent += money; -} - - -/*********************************************************************************************** - * HouseClass::Refund_Money -- Refunds money to back to the house. * - * * - * Use this routine when money needs to be refunded back to the house. This can occur when * - * construction is aborted. At this point, the exact breakdown of Tiberium or initial * - * credits used for the orignal purchase is lost. Presume as much of the money is in the * - * form of Tiberium as storage capacity will allow. * - * * - * INPUT: money -- The number of credits to refund back to the house. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - * 06/01/1995 JLB : Refunded money is never lost * - *=============================================================================================*/ -void HouseClass::Refund_Money(unsigned money) -{ - Validate(); - Credits += money; -} - - -/*********************************************************************************************** - * HouseClass::Adjust_Capacity -- Adjusts the house Tiberium storage capacity. * - * * - * Use this routine to adjust the maximum storage capacity for the house. This storage * - * capacity will limit the number of Tiberium credits that can be stored at any one time. * - * * - * INPUT: adjust -- The adjustment to the Tiberium storage capacity. * - * * - * inanger -- Is this a forced adjustment to capacity due to some hostile event? * - * * - * OUTPUT: Returns with the number of Tiberium credits lost. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/25/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::Adjust_Capacity(int adjust, bool inanger) -{ - Validate(); - long oldcap = Capacity; - int retval = 0; - - Capacity += adjust; - Capacity = MAX(Capacity, 0L); - if (Tiberium > Capacity) { - retval = Tiberium - Capacity; - Tiberium = Capacity; - if (!inanger) { - Refund_Money(retval); - retval = 0; - } else { - IsMaxedOut = true; - } - } - Silo_Redraw_Check(Tiberium, oldcap); - return(retval); -} - - -/*********************************************************************************************** - * HouseClass::Silo_Redraw_Check -- Flags silos to be redrawn if necessary. * - * * - * Call this routine when either the capacity or tiberium levels change for a house. This * - * routine will determine if the aggregate tiberium storage level will result in the * - * silos changing their imagery. If this is detected, then all the silos for this house * - * are flagged to be redrawn. * - * * - * INPUT: oldtib -- Pre-change tiberium level. * - * * - * oldcap -- Pre-change tiberium storage capacity. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/02/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Silo_Redraw_Check(long oldtib, long oldcap) -{ - Validate(); - int oldratio = 0; - if (oldcap) oldratio = (oldtib * 5) / oldcap; - int newratio = 0; - if (Capacity) newratio = (Tiberium * 5) / Capacity; - - if (oldratio != newratio) { - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * b = Buildings.Ptr(index); - if (b && !b->IsInLimbo && b->House == this && *b == STRUCT_STORAGE) { - b->Mark(MARK_CHANGE); - } - } - } -} - - -/*********************************************************************************************** - * HouseClass::Read_INI -- Reads house specific data from INI. * - * * - * This routine reads the house specific data for a particular * - * scenario from the scenario INI file. Typical data includes starting * - * credits, maximum unit count, etc. * - * * - * INPUT: buffer -- Pointer to loaded scenario INI file. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - * 05/18/1995 JLB : Creates all houses. * - *=============================================================================================*/ -void HouseClass::Read_INI(char *buffer) -{ - HouseClass *p; // Pointer to current player data. - char const *hname; // Pointer to house name. - char buf[128]; - - for (HousesType index = HOUSE_FIRST; index < HOUSE_COUNT; index++) { - hname = HouseTypeClass::As_Reference(index).IniName; - int maxunit = WWGetPrivateProfileInt(hname, "MaxUnit", EACH_UNIT_MAX, buffer); - - maxunit = MAX(maxunit, 150); - - int maxbuilding = WWGetPrivateProfileInt(hname, "MaxBuilding", EACH_BUILDING_MAX, buffer); - - maxbuilding = MAX(maxbuilding, 150); - - int credits = WWGetPrivateProfileInt(hname, "Credits", 0, buffer); - - p = new HouseClass(index); - - p->MaxBuilding = maxbuilding; - p->MaxUnit = maxunit; - p->Credits = (long)credits * 100; - p->InitialCredits = p->Credits; - WWGetPrivateProfileString(hname, "Edge", "", buf, sizeof(buf)-1, buffer); - p->Edge = Source_From_Name(buf); - if (p->Edge == SOURCE_NONE) { - p->Edge = SOURCE_NORTH; - } - - if (GameToPlay == GAME_NORMAL) { - WWGetPrivateProfileString(hname, "Allies", "", buf, sizeof(buf)-1, buffer); - if (strlen(buf)) { - char * tok = strtok(buf, ", \t"); - while (tok) { - HousesType h = HouseTypeClass::From_Name(tok); - p->Make_Ally(h); - tok = strtok(NULL, ", \t"); - } - - } else { - - /* - ** Special case for when no allies are specified in the INI file. - ** The GDI side defaults to considering the neutral side to be - ** friendly. - */ - if (p->Class->House == HOUSE_GOOD) { - p->Make_Ally(HOUSE_NEUTRAL); - } - } - } - } -} - - -/*********************************************************************************************** - * HouseClass::Write_INI -- Writes house specific data into INI file. * - * * - * Use this routine to write the house specific data (for all houses) into the INI file. * - * It is used by the scenario editor when saving the scenario. * - * * - * INPUT: buffer -- INI file staging buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Write_INI(char *buffer) -{ - for (HousesType i = HOUSE_FIRST; i < HOUSE_COUNT; i++) { - HouseClass * p = As_Pointer(i); - - if (p) { - WWWritePrivateProfileInt(p->Class->IniName, "Credits", (int)(p->Credits / 100), buffer); - WWWritePrivateProfileString(p->Class->IniName, "Edge", Name_From_Source(p->Edge), buffer); - WWWritePrivateProfileInt(p->Class->IniName, "MaxUnit", p->MaxUnit, buffer); - WWWritePrivateProfileInt(p->Class->IniName, "MaxBuilding", p->MaxBuilding, buffer); - - bool first = true; - char sbuffer[100] = ""; - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - if (p->Is_Ally(house)) { - if (!first) strcat(sbuffer, ","); - strcat(sbuffer, As_Pointer(house)->Class->IniName); - first = false; - } - } - WWWritePrivateProfileString(p->Class->IniName, "Allies", sbuffer, buffer); - } - } -} - - -/*********************************************************************************************** - * HouseClass::Is_Ally -- Determines if the specified house is an ally. * - * * - * This routine will determine if the house number specified is a ally to this house. * - * * - * INPUT: house -- The house number to check to see if it is an ally. * - * * - * OUTPUT: Is the house an ally? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Is_Ally(HousesType house) const -{ - Validate(); - if (house != HOUSE_NONE) { - return(((1<Class->House)); - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::Is_Ally -- Checks to see if the object is an ally. * - * * - * This routine will examine the specified object and return whether it is an ally or not. * - * * - * INPUT: object -- The object to examine to see if it is an ally. * - * * - * OUTPUT: Is the specified object an ally? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Is_Ally(ObjectClass const * object) const -{ - Validate(); - if (object) { - return(Is_Ally(object->Owner())); - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::Make_Ally -- Make the specified house an ally. * - * * - * This routine will make the specified house an ally to this house. An allied house will * - * not be considered a threat or potential target. * - * * - * INPUT: house -- The house to make an ally of this house. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - * 08/08/1995 JLB : Breaks off combat when ally commences. * - *=============================================================================================*/ -void HouseClass::Make_Ally(HousesType house) -{ - Validate(); - if (house != HOUSE_NONE && !Is_Ally(house)) { - - /* - ** If in normal game play but the house is defeated, then don't allow the ally - ** key to work. - */ - if (!ScenarioInit && (IsDefeated || house == HOUSE_JP)) return; - - Allies |= (1 << house); - -#ifdef CHEAT_KEYS - if (Debug_Flag) { - HouseClass * enemy = HouseClass::As_Pointer(house); - if (enemy && !enemy->Is_Ally(this)) { - enemy->Make_Ally(Class->House); - } - } -#endif - - if ((Debug_Flag || GameToPlay != GAME_NORMAL) && !ScenarioInit) { - char buffer[80]; - - /* - ** Sweep through all techno objects and perform a cheeseball tarcom clear to ensure - ** that fighting will most likely stop when the cease fire begins. - */ - for (int index = 0; index < Logic.Count(); index++) { - ObjectClass * object = Logic[index]; - - if (object && !object->IsInLimbo && object->Owner() == Class->House) { - TARGET target = ((TechnoClass *)object)->TarCom; - if (Target_Legal(target) && As_Techno(target)) { - if (Is_Ally(As_Techno(target))) { - ((TechnoClass *)object)->TarCom = TARGET_NONE; - } - } - } - } - - sprintf(buffer, Text_String(TXT_HAS_ALLIED), Name, HouseClass::As_Pointer(house)->Name); - Messages.Add_Message(buffer, MPlayerTColors[RemapColor], TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW, 1200, 0, 0); - Map.Flag_To_Redraw(false); - } - } -} - - -/*********************************************************************************************** - * HouseClass::Make_Enemy -- Make an enemy of the house specified. * - * * - * This routine will flag the house specified so that it will be an enemy to this house. * - * Enemy houses are legal targets for attack. * - * * - * INPUT: house -- The house to make an enemy of this house. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - * 07/27/1995 JLB : Making war is a bilateral aaction. * - *=============================================================================================*/ -void HouseClass::Make_Enemy(HousesType house) -{ - Validate(); - if (house != HOUSE_NONE && Is_Ally(house)) { - HouseClass * enemy = HouseClass::As_Pointer(house); - Allies &= ~(1 << house); - if (enemy && enemy->Is_Ally(this)) { - enemy->Allies &= ~(1 << Class->House); - } - - if ((Debug_Flag || GameToPlay != GAME_NORMAL) && !ScenarioInit) { - char buffer[80]; - - sprintf(buffer, Text_String(TXT_AT_WAR), Name, enemy->Name); - Messages.Add_Message(buffer, MPlayerTColors[RemapColor], TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - } - } -} - - -/*********************************************************************************************** - * HouseClass::Remap_Table -- Fetches the remap table for this house object. * - * * - * This routine will return with the remap table to use when displaying an object owned * - * by this house. If the object is blushing (flashing), then the lightening remap table is * - * always used. The "unit" parameter allows proper remap selection for those houses that * - * have a different remap table for buildings or units. * - * * - * INPUT: blushing -- Is the object blushing (flashing)? * - * * - * unit -- Is the object a vehicle or infantry? * - * * - * OUTPUT: Returns with a pointer to the remap table to use when drawing this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -unsigned char const * HouseClass::Remap_Table(bool blushing, bool unit) const -{ - Validate(); - if (blushing) return(&Map.FadingLight[0]); - - /* - ** For normal game play, return the TypeClass's remap table for this - ** house type - */ - if (GameToPlay == GAME_NORMAL) { - /* - ** Special case exception for Nod and single player only. Remap - ** buildings to red as opposed to the default color of bluegrey. - */ - if (!unit && Class->House == HOUSE_BAD) { - return(RemapRed); - } - - /* - ** Special case Jurassic missions to use the bluegrey remapping - */ - if (Special.IsJurassic && Class->House == HOUSE_MULTI4) { - return(RemapLtBlue); - } - - return(Class->RemapTable); - } else { - - /* - ** For multiplayer games, return the remap table for this exact house instance. - */ - return(RemapTable); - } -} - - -/*********************************************************************************************** - * HouseClass::Suggested_New_Team -- Determine what team should be created. * - * * - * This routine examines the house condition and returns with the team that it thinks * - * should be created. The units that are not currently a member of a team are examined * - * to determine the team needed. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the team type that should be created. If no team should * - * be created, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -TeamTypeClass const * HouseClass::Suggested_New_Team(bool alertcheck) -{ - Validate(); - return(TeamTypeClass::Suggested_New_Team(this, UScan, IScan, IsAlerted && alertcheck)); -} - - -/*********************************************************************************************** - * HouseClass::Adjust_Threat -- Adjust threat for the region specified. * - * * - * This routine is called when the threat rating for a region needs to change. The region * - * and threat adjustment are provided. * - * * - * INPUT: region -- The region that adjustment is to occur on. * - * * - * threat -- The threat adjustment to perform. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Adjust_Threat(int region, int threat) -{ - Validate(); - static int _val[] = { - -MAP_REGION_WIDTH - 1, -MAP_REGION_WIDTH, -MAP_REGION_WIDTH + 1, - -1, 0, 1, - MAP_REGION_WIDTH -1, MAP_REGION_WIDTH, MAP_REGION_WIDTH +1 - }; - static int _thr[] = { - 2, 1, 2, - 1, 0, 1, - 2, 1, 2 - }; - int neg; - int *val = &_val[0]; - int *thr = &_thr[0]; - - if (threat < 0) { - threat = -threat; - neg = true; - } else { - neg = false; - } - - for (int lp = 0; lp < 9; lp ++) { - Regions[region + *val].Adjust_Threat(threat >> *thr, neg); - val++; - thr++; - } -} - - -/*********************************************************************************************** - * HouseClass::Begin_Production -- Starts production of the specified object type. * - * * - * This routine is called from the event system. It will start production for the object * - * type specified. This will be reflected in the sidebar as well as the house factory * - * tracking variables. * - * * - * INPUT: type -- The type of object to begin production on. * - * * - * id -- The subtype of object. * - * * - * OUTPUT: Returns with the reason why, or why not, production was started. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -ProdFailType HouseClass::Begin_Production(RTTIType type, int id) -{ - Validate(); - int * factory = 0; - int result = true; - bool initial_start = false; - FactoryClass * fptr; - TechnoTypeClass const * tech = Fetch_Techno_Type(type, id); - - switch (type) { - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - factory = &AircraftFactory; - break; - - case RTTI_UNIT: - case RTTI_UNITTYPE: - factory = &UnitFactory; - break; - - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - factory = &BuildingFactory; - break; - - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - factory = &InfantryFactory; - break; - - case RTTI_SPECIAL: - factory = &SpecialFactory; - break; - } - - /* - ** Check for legality of the production object type suggested. - */ - if (!factory) return(PROD_ILLEGAL); - - /* - ** If the house is already busy producing the requested object, then - ** return with this failure code, unless we are restarting production. - */ - if (*factory != -1) { - fptr = Factories.Raw_Ptr(*factory); - if (fptr->Is_Building()) - return(PROD_CANT); - } else { - fptr = new FactoryClass(); - if (!fptr) return(PROD_CANT); - *factory = Factories.ID(fptr); - result = (tech) ? fptr->Set(*tech, *this) : fptr->Set(id, *this); - initial_start = true; - - /* - ** If set failed, we probably reached the production cap. Don't let the factory linger, preventing further production attempts. - ** ST - 3/17/2020 2:03PM - */ - if (!result) { - delete fptr; - fptr = NULL; - *factory = -1; - } - } - - if (result) { - fptr->Start(); - - /* - ** Link this factory to the sidebar so that proper graphic feedback - ** can take place. - */ - // Handle Glyphx multiplayer sidebar. ST - 3/26/2019 1:27PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (IsHuman) { - Sidebar_Glyphx_Factory_Link(*factory, type, id, this); - } - } else { - if (PlayerPtr == this) { - Map.Factory_Link(*factory, type, id); - } - } - - return(PROD_OK); - } - return(PROD_CANT); -} - - -/*********************************************************************************************** - * HouseClass::Suspend_Production -- Temporarily puts production on hold. * - * * - * This routine is called from the event system whenever the production of the specified * - * type needs to be suspended. The suspended production will be reflected in the sidebar * - * as well as in the house control structure. * - * * - * INPUT: type -- The type of object that production is being suspended for. * - * * - * OUTPUT: Returns why, or why not, production was suspended. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -ProdFailType HouseClass::Suspend_Production(RTTIType type) -{ - Validate(); - int * factory = 0; - - switch (type) { - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - factory = &AircraftFactory; - break; - - case RTTI_UNIT: - case RTTI_UNITTYPE: - factory = &UnitFactory; - break; - - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - factory = &BuildingFactory; - break; - - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - factory = &InfantryFactory; - break; - - case RTTI_SPECIAL: - factory = &SpecialFactory; - break; - } - - /* - ** Check for legality of the production object type suggested. - */ - if (!factory) return(PROD_ILLEGAL); - - /* - ** If the house is already busy producing the requested object, then - ** return with this failure code. - */ - if (*factory == -1) return(PROD_CANT); - - /* - ** Create the factory pointer object. - ** If the factory could not be created, then report this error condition. - */ - FactoryClass * fptr = Factories.Raw_Ptr(*factory); - if (!fptr) return(PROD_CANT); - - /* - ** Actually suspend the production. - */ - fptr->Suspend(); - - /* - ** Tell the sidebar that it needs to be redrawn because of this. - */ - if (PlayerPtr == this) { - Map.SidebarClass::IsToRedraw = true; - Map.SidebarClass::Column[0].IsToRedraw = true; - Map.SidebarClass::Column[1].IsToRedraw = true; - Map.Flag_To_Redraw(false); - } - - return(PROD_OK); -} - - -/*********************************************************************************************** - * HouseClass::Abandon_Production -- Abandons production of item type specified. * - * * - * This routine is called from the event system whenever production must be abandoned for * - * the type specified. This will remove the factory and pending object from the sidebar as * - * well as from the house factory record. * - * * - * INPUT: type -- The object type that production is being suspended for. * - * * - * OUTPUT: Returns the reason why or why not, production was suspended. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -ProdFailType HouseClass::Abandon_Production(RTTIType type) -{ - Validate(); - int * factory = 0; - - switch (type) { - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - factory = &AircraftFactory; - break; - - case RTTI_UNIT: - case RTTI_UNITTYPE: - factory = &UnitFactory; - break; - - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - factory = &BuildingFactory; - break; - - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - factory = &InfantryFactory; - break; - - case RTTI_SPECIAL: - factory = &SpecialFactory; - break; - } - - /* - ** Check for legality of the production object type suggested. - */ - if (!factory) return(PROD_ILLEGAL); - - /* - ** If there is no factory to abandon, then return with a failure code. - */ - if (*factory == -1) return(PROD_CANT); - - /* - ** Fetch the factory pointer object. - */ - FactoryClass * fptr = Factories.Raw_Ptr(*factory); - if (!fptr) return(PROD_CANT); - - /* - ** Tell the sidebar that it needs to be redrawn because of this. - */ - // Handle Glyphx multiplayer sidebar. ST - 3/22/2019 2:01PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - if (IsHuman) { - Sidebar_Glyphx_Abandon_Production(type, *factory, this); - // Need to clear pending object here? - } - } else { - - if (PlayerPtr == this) { - Map.Abandon_Production(type, *factory); - - if (type == RTTI_BUILDINGTYPE || type == RTTI_BUILDING) { - Map.PendingObjectPtr = 0; - Map.PendingObject = 0; - Map.PendingHouse = HOUSE_NONE; - Map.Set_Cursor_Shape(0); - } - } - } - - /* - ** Abandon production of the object. - */ - fptr->Abandon(); - delete fptr; - *factory = -1; - - return(PROD_OK); -} - - -/*********************************************************************************************** - * HouseClass::Special_Weapon_AI -- Fires special weapon. * - * * - * This routine will pick a good target to fire the special weapon specified. * - * * - * INPUT: id -- The special weapon id to fire. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 PWG : Created. * - *=============================================================================================*/ -void HouseClass::Special_Weapon_AI(SpecialWeaponType id) -{ - Validate(); - /* - ** Loop through all of the building objects on the map - ** and see which ones are available. - */ - BuildingClass * bestptr = NULL; - int best = -1; - - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * b = Buildings.Ptr(index); - - /* - ** If the building is valid, not in limbo, not in the process of - ** being destroyed and not our ally, then we can consider it. - */ - if (b && !b->IsInLimbo && b->Strength && !Is_Ally(b)) { - if (b->Value() > best || best == -1) { - best = b->Value(); - bestptr = b; - } - } - } - - if (bestptr) { - CELL cell = Coord_Cell(bestptr->Center_Coord()); - Place_Special_Blast(id, cell); - } -} - - -/*********************************************************************************************** - * HouseClass::Place_Special_Blast -- Place a special blast effect at location specified. * - * * - * This routine will create a blast effect at the cell specified. This is the result of * - * the special weapons. * - * * - * INPUT: id -- The special weapon id number. * - * * - * cell -- The location where the special weapon attack is to occur. * - * * - * OUTPUT: Was the special weapon successfully fired at the location specified? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented. * - * 07/25/1995 JLB : Added scatter effect for nuclear bomb. * - * 07/28/1995 JLB : Revamped to use super weapon class controller. * - *=============================================================================================*/ -bool HouseClass::Place_Special_Blast(SpecialWeaponType id, CELL cell) -{ - Validate(); - BuildingClass * launchsite = 0; - AnimClass * anim = 0; - - // Added. ST - 12/2/2019 11:26AM - bool fired = false; - const char *what = NULL; - - int index; - switch (id) { - - case SPC_ION_CANNON: - if (IonCannon.Is_Ready()) { - anim = new AnimClass(ANIM_ION_CANNON, Cell_Coord(cell)); - if (anim) anim->OwnerHouse = Class->House; - if (this == PlayerPtr) { - Map.IsTargettingMode = false; - } - IonCannon.Discharged(PlayerPtr == this); - IsRecalcNeeded = true; - fired = true; - what = "ION"; - } - break; - - case SPC_NUCLEAR_BOMB: - if (NukeStrike.Is_Ready()) { - - -#ifdef NEVER - /* - ** Scatter the nuclear bomb impact point into an adjacent cell. - */ - for (;;) { - CELL newcell = Adjacent_Cell(cell, Random_Pick(FACING_N, FACING_COUNT)); - if (Map.In_Radar(newcell)) { - cell = newcell; - break; - } - } -#endif - - /* - ** Search for a suitable launch site for this missile. - */ - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass * b = Buildings.Ptr(index); - if (b && !b->IsInLimbo && b->House == this && *b == STRUCT_TEMPLE) { - launchsite = b; - break; - } - } - - /* - ** If a launch site was found, then proceed with the normal launch - ** sequence. - */ - if (launchsite) { - launchsite->Assign_Mission(MISSION_MISSILE); - launchsite->Commence(); - NukeDest = cell; - NukePieces = 0; - - } else { - - /* - ** Only in the multiplayer version can the nuclear bomb be - ** sent from some off screen source. - */ - if (GameToPlay == GAME_NORMAL) return(false); - - /* - ** Since no launch site was found, just bring the missile in - ** directly from the North map edge. - */ - BulletClass *bullet = new BulletClass(BULLET_NUKE_DOWN); - if (bullet) { - COORDINATE start = Cell_Coord(XY_Cell(Cell_X(cell), 0)); - bullet->Assign_Target(::As_Target(cell)); - bullet->Payback = NULL; - bullet->Strength = 1; - if (!bullet->Unlimbo(start, DIR_S)) { - delete bullet; - } else { - bullet->PrimaryFacing.Set_Current(DIR_S); - } - Speak(VOX_INCOMING_NUKE); // "Nuclear Warhead Approaching" - "NUKE1" - Sound_Effect(VOC_NUKE_FIRE, start); - } - } - if (this == PlayerPtr) { - Map.IsTargettingMode = false; - } - NukeStrike.Discharged(this == PlayerPtr); - IsRecalcNeeded = true; - fired = true; - what = "NUKE"; - } - break; - - case SPC_AIR_STRIKE: - if (AirStrike.Is_Ready()) { - int strike = 1; - if (GameToPlay == GAME_NORMAL) { - strike = Bound(BuildLevel/3, 1, 3); - } else { - strike = Bound(MPlayerUnitCount/5, 1, 3); - } - Create_Air_Reinforcement(this, AIRCRAFT_A10, strike, MISSION_HUNT, ::As_Target(cell), TARGET_NONE); - if (this == PlayerPtr) { - Map.IsTargettingMode = false; - } - AirStrike.Discharged(this == PlayerPtr); - IsRecalcNeeded = true; - fired = true; - what = "AIR"; - } - break; - } - - /* - ** Maybe trigger an achivement. ST - 12/2/2019 11:25AM - */ - if (IsHuman && fired && what) { - On_Achievement_Event(this, "SUPERWEAPON_FIRED", what); - } - - return(true); -} - - -/*********************************************************************************************** - * HouseClass::Place_Object -- Places the object (building) at location specified. * - * * - * This routine is called when a building has been produced and now must be placed on * - * the map. When the player clicks on the map, this routine is ultimately called when the * - * event passes through the event queue system. * - * * - * INPUT: type -- The object type to place. The actual object is lifted from the sidebar. * - * * - * * - * cell -- The location to place the object on the map. * - * * - * OUTPUT: Was the placement successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -extern void On_Ping(const HouseClass* player_ptr, COORDINATE coord); - -bool HouseClass::Place_Object(RTTIType type, CELL cell) -{ - Validate(); - TechnoClass * tech = 0; - FactoryClass * factory = 0; - - switch (type) { - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - if (AircraftFactory != -1) { - factory = Factories.Raw_Ptr(AircraftFactory); - } - break; - - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - if (InfantryFactory != -1) { - factory = Factories.Raw_Ptr(InfantryFactory); - } - break; - - case RTTI_UNIT: - case RTTI_UNITTYPE: - if (UnitFactory != -1) { - factory = Factories.Raw_Ptr(UnitFactory); - } - break; - - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - if (BuildingFactory != -1) { - factory = Factories.Raw_Ptr(BuildingFactory); - } - break; - } - - /* - ** Only if there is a factory active for this type, can it be "placed". - ** In the case of a missing factory, then this request is completely bogus -- - ** ignore it. This might occur if, between two events to exit the same - ** object, the mouse was clicked on the sidebar to start building again. - ** The second placement event should NOT try to place the object that is - ** just starting construction. - */ - if (factory && factory->Has_Completed()) { - tech = factory->Get_Object(); - - if (cell == -1) { - TechnoClass * pending = factory->Get_Object(); - if (pending) { - TechnoClass * builder = pending->Who_Can_Build_Me(false, false); - TechnoTypeClass const *object_type = pending->Techno_Type_Class(); - - if (builder && builder->Exit_Object(pending)) { - - /* - ** Since the object has left the factory under its own power, delete - ** the production manager tied to this slot in the sidebar. Its job - ** has been completed. - */ - factory->Set_Is_Blocked(false); - factory->Completed(); - Abandon_Production(type); - - /* - ** Could be tied to an achievement. ST - 11/11/2019 11:56AM - */ - if (IsHuman) { - if (object_type) { - On_Achievement_Event(this, "UNIT_CONSTRUCTED", object_type->IniName); - } - if (pending->IsActive) { - On_Ping(this, pending->Center_Coord()); - } - } - - } else { - - /* - ** The object could not leave under it's own power. Just wait - ** until the player tries to place the object again. - */ - - /* - ** Flag that it's blocked so we can re-try the exit later. - ** This would have been a bad idea under the old peer-peer code since it would have pumped events into - ** the queue too often. ST - 2/25/2020 11:56AM - */ - factory->Set_Is_Blocked(true); - return(false); - } - } - - } else { - - if (tech) { - TechnoClass * builder = tech->Who_Can_Build_Me(false, false); - if (builder) { - - /* - ** Ensures that the proximity check is performed even when the building is - ** placed by way of a remote event. - */ - if (tech->What_Am_I() != RTTI_BUILDING || ((BuildingClass *)tech)->Passes_Proximity_Check(cell)) { - builder->Transmit_Message(RADIO_HELLO, tech); - if (tech->Unlimbo(Cell_Coord(cell))) { - factory->Completed(); - Abandon_Production(type); - - if (PlayerPtr == this) { - Sound_Effect(VOC_SLAM); - Map.Set_Cursor_Shape(0); - Map.PendingObjectPtr = 0; - Map.PendingObject = 0; - Map.PendingHouse = HOUSE_NONE; - } - return(true); - } else { - if (this == PlayerPtr) { - Speak(VOX_DEPLOY); - } - } - builder->Transmit_Message(RADIO_OVER_OUT); - } - } - return(false); - - } else { - - // Play a bad sound here? - return(false); - } - } - } - - return(true); -} - - -/*********************************************************************************************** - * HouseClass::Manual_Place -- Inform display system of building placement mode. * - * * - * This routine will inform the display system that building placement mode has begun. * - * The cursor will be created that matches the layout of the building shape. * - * * - * INPUT: builder -- The factory that is building this object. * - * * - * object -- The building that is going to be placed down on the map. * - * * - * OUTPUT: Was the building placement mode successfully initiated? * - * * - * WARNINGS: This merely adjusts the cursor shape. Nothing that affects networked games * - * is affected. * - * * - * HISTORY: * - * 05/04/1995 JLB : Created. * - * 05/30/1995 JLB : Uses the Bib_And_Offset() function to determine bib size. * - *=============================================================================================*/ -bool HouseClass::Manual_Place(BuildingClass * builder, BuildingClass * object) -{ - Validate(); - if (this == PlayerPtr && !Map.PendingObject && builder && object) { - - /* - ** Ensures that object selection doesn't remain when - ** building placement takes place. - */ - Unselect_All(); - - Map.Repair_Mode_Control(0); - Map.Sell_Mode_Control(0); - - Map.PendingObject = object->Class; - Map.PendingObjectPtr = object; - Map.PendingHouse = Class->House; - - Map.Set_Cursor_Shape(object->Occupy_List(true)); - Map.Set_Cursor_Pos(Coord_Cell(builder->Coord)); - builder->Mark(MARK_CHANGE); - return(true); - } - return(false); -} - - -#ifdef OBSOLETE -/*********************************************************************************************** - * HouseClass::Init_Ion_Cannon -- Initialize the ion cannon countdown. * - * * - * This routine will initiate the ion cannon charging countdown. It will add the ion * - * cannon to the sidebar if it isn't there and it is specified to be added. * - * * - * INPUT: first_time -- Set to true if the ion cannon must be added to the sidebar. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - *=============================================================================================*/ -void HouseClass::Init_Ion_Cannon(SpecialControlType control) -{ - Validate(); - switch (control) { - case CONTROL_RESET: - if (IonCannonPresent) { - IonOldStage = -1; - IonControl.Set(ION_CANNON_GONE_TIME); - if (PlayerPtr == this) { - Map.Add(RTTI_SPECIAL, SPC_ION_CANNON); - if (!ScenarioInit) { - Speak(VOX_ION_CHARGING); - } - } - } - break; - - /* - ** Adds the special no-prerequisite ion cannon option. - */ - case CONTROL_ONE_TIME: - if (!IonCannonPresent) { - Init_Ion_Cannon(CONTROL_ADD); - IonOneTimeFlag = true; - } - break; - - /* - ** Adds the normal legitimate ion cannon option. If there was - ** already a one-time ion cannon available, the charging state - ** is NOT interrupted. - */ - case CONTROL_ADD: - IonOneTimeFlag = false; - if (!IconCannonPresent) { - IonCannonPresent = true; - IonReady = false; - Init_Ion_Cannon(CONTROL_RESET); - } - break; - - case CONTROL_REMOVE: - break; - } - - - if (!(first_time && IonCannonPresent)) { - - if (IonCannonPresent && IonOneTimeFlag) { - IonOneTimeFlag = false; - if (this == PlayerPtr) Map.Recalc(); - return; - } - - if (first_time && this == PlayerPtr) { - Map.Add(RTTI_SPECIAL, SPC_ION_CANNON); - } - - if (!ScenarioInit) { - if (this == PlayerPtr) { - Speak(VOX_ION_CHARGING); - } - } - - IonControl.Set(ION_CANNON_GONE_TIME); - IonCannonPresent = true; - IonReady = false; - IonOldStage = -1; - IonOneTimeFlag = one_time_effect; - } else { - if (first_time && IonCannonPresent && !one_time_effect && IonOneTimeFlag) { - IonOneTimeFlag = false; - } - } -} -#ifdef NEVER -void HouseClass::Init_Ion_Cannon(bool first_time, bool one_time_effect) -{ - Validate(); - if (!(first_time && IonCannonPresent)) { - - if (IonCannonPresent && IonOneTimeFlag) { - IonOneTimeFlag = false; - if (this == PlayerPtr) Map.Recalc(); - return; - } - - if (first_time && this == PlayerPtr) { - Map.Add(RTTI_SPECIAL, SPC_ION_CANNON); - } - - if (!ScenarioInit) { - if (this == PlayerPtr) { - Speak(VOX_ION_CHARGING); - } - } - - IonControl.Set(ION_CANNON_GONE_TIME); - IonCannonPresent = true; - IonReady = false; - IonOldStage = -1; - IonOneTimeFlag = one_time_effect; - } else { - if (first_time && IonCannonPresent && !one_time_effect && IonOneTimeFlag) { - IonOneTimeFlag = false; - } - } -} -#endif - - -/*********************************************************************************************** - * HouseClass::Remove_Ion_Cannon -- Disables the ion cannon. * - * * - * This routine will disable the ion cannon. It is called when the ion cannon cannot * - * establish a command link to the ground (usually when there is insufficient power). * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - *=============================================================================================*/ -void HouseClass::Remove_Ion_Cannon(void) -{ - Validate(); - if (IonCannonPresent) { - IonCannonPresent = false; - IonOneTimeFlag = false; - IonReady = false; - IonControl.Clear(); - IonOldStage = -1; - } -} -#endif - - -/*************************************************************************** - * HouseClass::Clobber_All -- removes house & all its objects * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/16/1995 BRR : Created. * - * 06/09/1995 JLB : Handles aircraft. * - *=========================================================================*/ -void HouseClass::Clobber_All(void) -{ - Validate(); - int i; - - for (i = 0; i < ::Aircraft.Count(); i++) { - if (::Aircraft.Ptr(i)->House == this) { - delete ::Aircraft.Ptr(i); - i--; - } - } - for (i = 0; i < ::Units.Count(); i++) { - if (::Units.Ptr(i)->House == this) { - delete ::Units.Ptr(i); - i--; - } - } - for (i = 0; i < Infantry.Count(); i++) { - if (Infantry.Ptr(i)->House == this) { - delete Infantry.Ptr(i); - i--; - } - } - for (i = 0; i < Buildings.Count(); i++) { - if (Buildings.Ptr(i)->House == this) { - delete Buildings.Ptr(i); - i--; - } - } - for (i = 0; i < TeamTypes.Count(); i++) { - if (TeamTypes.Ptr(i)->House == Class->House) { - delete TeamTypes.Ptr(i); - i--; - } - } - for (i = 0; i < Triggers.Count(); i++) { - if (Triggers.Ptr(i)->House == Class->House) { - delete Triggers.Ptr(i); - i--; - } - } - - delete this; -} - - -#ifdef NEVER -/*********************************************************************************************** - * HouseClass::Init_Nuke_Bomb -- Adds (if necessary) the atom bomb to the sidebar. * - * * - * Use this routine whenever a piece of atom bomb has been discovered (also at scenario * - * start). It will add the nuclear bomb button to the sidebar if necessary. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - *=============================================================================================*/ -void HouseClass::Init_Nuke_Bomb(bool first_time, bool one_time_effect) -{ - Validate(); - if (!first_time || !NukePresent) { - - if (NukePresent && NukeOneTimeFlag) { - NukeOneTimeFlag = false; - if (this == PlayerPtr) Map.Recalc(); - return; - } - - if (first_time && this == PlayerPtr) { - Map.Add(RTTI_SPECIAL, SPC_NUCLEAR_BOMB); - } - - NukeControl.Set(NUKE_GONE_TIME); - NukePresent = true; - NukeReady = false; - NukeOldStage = -1; - NukeOneTimeFlag = one_time_effect; - - } else { - if (!one_time_effect && NukeOneTimeFlag) { - NukeOneTimeFlag = false; - } - } -} - - -/*********************************************************************************************** - * HouseClass::Remove_Nuke_Bomb -- Removes the nuclear bomb from the sidebar. * - * * - * This routine will remove the nuclear bomb from the sidebar. It should be called when * - * the nuclear strike has been launched. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - * 07/25/1995 JLB : Handles recharge reset logic. * - *=============================================================================================*/ -void HouseClass::Remove_Nuke_Bomb(void) -{ - Validate(); - if (NukePresent && !NukeOneTimeFlag) { - NukePresent = false; - NukeControl.Clear(); - NukeOldStage = -1; - NukeReady = false; - } -} - - -/*********************************************************************************************** - * HouseClass::Init_Air_Strike -- Add (or reset) the air strike sidebar button. * - * * - * This routine will activate (add if so indicated) the air strike button to the sidebar. * - * Call this routine when events indicate that a special air strike is available. * - * * - * INPUT: first_time -- If the air strike button is to be added, then this will be true. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - *=============================================================================================*/ -void HouseClass::Init_Air_Strike(bool first_time, bool one_time_effect) -{ - Validate(); - if (!(first_time && AirPresent)) { - - if (AirPresent && AirOneTimeFlag) { - AirOneTimeFlag = false; - AirPresent = false; - Map.Recalc(); - return; - } - - if (first_time) { - if (PlayerPtr == this) { - Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE); - } - AirControl.Set(0); - } else { - AirControl.Set(AIR_CANNON_GONE_TIME); - } - - AirReady = first_time; - AirPresent = true; - AirOldStage = -1; - AirOneTimeFlag = one_time_effect; - - if (AirReady && !IsHuman) { - Special_Weapon_AI(SPC_AIR_STRIKE); - } - } else { - if (first_time && AirPresent && !one_time_effect && AirOneTimeFlag) { - AirOneTimeFlag = false; - } - } -} - - -/*********************************************************************************************** - * HouseClass::Remove_Air_Strike -- Removes the air strike button from the sidebar. * - * * - * This routine will remove the air strike button from the sidebar. Call this routine when * - * the air strike has been launched. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - *=============================================================================================*/ -void HouseClass::Remove_Air_Strike(void) -{ - Validate(); - AirPresent = false; - AirReady = false; - AirControl.Clear(); - AirOldStage = -1; -} - - -/*********************************************************************************************** - * HouseClass::Make_Air_Strike_Available -- Make the airstrike available. * - * * - * This routine will make the airstrike available. Typically, this results in a new icon * - * added to the sidebar. * - * * - * INPUT: present -- The the airstrike being added? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Make_Air_Strike_Available(bool present, bool one_time_effect) -{ - Validate(); - Init_Air_Strike(true, one_time_effect); - AirPresent = present; -} -#endif - - -/*********************************************************************************************** - * HouseClass::Add_Nuke_Piece -- Add a nuclear piece to the collection. * - * * - * This routine will a the specified nuclear piece to the house collection of parts. When * - * all the pieces have been added, a nuclear strike ability is made available. * - * * - * INPUT: piece -- The nuclear piece to add. If equal to "-1", then the next possible piece * - * is added. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Add_Nuke_Piece(int piece) -{ - Validate(); - if (piece == -1) { - piece = 1; - if (!(NukePieces & 0x01)) { - piece = 1; - } - if (!(NukePieces & 0x02)) { - piece = 2; - } - if (!(NukePieces & 0x04)) { - piece = 3; - } - } - NukePieces |= 1 << (piece - 1); -// Init_Nuke_Bomb(false); -} - - -/*********************************************************************************************** - * HouseClass::Detach -- Removes specified object from house tracking systems. * - * * - * This routine is called when an object is to be removed from the game system. If the * - * specified object is part of the house tracking system, then it will be removed. * - * * - * INPUT: target -- The target value of the object that is to be removed from the game. * - * * - * all -- Is the target going away for good as opposed to just cloaking/hiding? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : commented * - *=============================================================================================*/ -void HouseClass::Detach(TARGET, bool ) -{ - Validate(); -// if (LaunchSite == target) { -// LaunchSite = TARGET_NONE; -// } -} - - -/*********************************************************************************************** - * HouseClass::Does_Enemy_Building_Exist -- Checks for enemy building of specified type. * - * * - * This routine will examine the enemy houses and if there is a building owned by one * - * of those house, true will be returned. * - * * - * INPUT: btype -- The building type to check for. * - * * - * OUTPUT: Does a building of the specified type exist for one of the enemy houses? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Does_Enemy_Building_Exist(StructType btype) const -{ - Validate(); - int bflag = 1L << btype; - for (HousesType index = HOUSE_FIRST; index < HOUSE_COUNT; index++) { - HouseClass * house = HouseClass::As_Pointer(index); - - if (house && !Is_Ally(house) && (house->BScan & bflag) != 0) { - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::Suggest_New_Object -- Determine what would the next buildable object be. * - * * - * This routine will examine the house status and return with a techno type pointer to * - * the object type that it thinks should be created. The type is restricted to match the * - * type specified. Typical use of this routine is by computer controlled factories. * - * * - * INPUT: objecttype -- The type of object to restrict the scan for. * - * * - * OUTPUT: Returns with a pointer to a techno type for the object type that should be * - * created. If no object should be created, then NULL is returned. * - * * - * WARNINGS: This is a time consuming routine. Only call when necessary. * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -TechnoTypeClass const * HouseClass::Suggest_New_Object(RTTIType objecttype) const -{ - Validate(); - TechnoTypeClass const * techno = NULL; - -#ifdef USE_RA_AI - // - // Copied from RA for AI. ST - 7/25/2019 3:58PM - // - if (!IsHuman && GameToPlay != GAME_NORMAL) { - switch (objecttype) { - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - if (BuildAircraft != AIRCRAFT_NONE) { - return(&AircraftTypeClass::As_Reference(BuildAircraft)); - } - return(NULL); - - /* - ** Unit construction is based on the rule that up to twice the number required - ** to fill all teams will be created. - */ - case RTTI_UNIT: - case RTTI_UNITTYPE: - if (BuildUnit != UNIT_NONE) { - return(&UnitTypeClass::As_Reference(BuildUnit)); - } - return(NULL); - - /* - ** Infantry construction is based on the rule that up to twice the number required - ** to fill all teams will be created. - */ - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - if (BuildInfantry != INFANTRY_NONE) { - return(&InfantryTypeClass::As_Reference(BuildInfantry)); - } - return(NULL); - - /* - ** Building construction is based upon the preconstruction list. - */ - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - if (BuildStructure != STRUCT_NONE) { - return(&BuildingTypeClass::As_Reference(BuildStructure)); - } - return(NULL); - } - - return NULL; - } - -#endif //USE_RA_AI - - - - switch (objecttype) { - - /* - ** Unit construction is based on the rule that up to twice the number required - ** to fill all teams will be created. - */ - case RTTI_UNIT: - case RTTI_UNITTYPE: - if (CurUnits < MaxUnit) { - - /* - ** A computer controlled house will try to build a replacement - ** harvester if possible. Never replace harvesters if the game - ** is in easy mode. - */ - if (!(GameToPlay == GAME_NORMAL && PlayerPtr->Difficulty == DIFF_EASY) && !IsHuman && (ActiveBScan & STRUCTF_REFINERY) && !(UScan & UNITF_HARVESTER)) { - techno = &UnitTypeClass::As_Reference(UNIT_HARVESTER); - if (techno->Scenario <= BuildLevel) break; - techno = 0; - } - - int counter[UNIT_COUNT]; - if (GameToPlay == GAME_NORMAL) { - memset(counter, 0x00, sizeof(counter)); - } else { - for (UnitType index = UNIT_FIRST; index < UNIT_COUNT; index++) { - if (Can_Build(index, Class->House) && UnitTypeClass::As_Reference(index).Level <= BuildLevel) { - counter[index] = 16; - } else { - counter[index] = 0; - } - } - } - - /* - ** Build a list of the maximum of each type we wish to produce. This will be - ** twice the number required to fill all teams. - */ - int index; - for (index = 0; index < Teams.Count(); index++) { - TeamClass * tptr = Teams.Ptr(index); - if (tptr) { - TeamTypeClass const * team = tptr->Class; - - if ((/*team->IsReinforcable || */!tptr->IsFullStrength) && team->House == Class->House) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Class[subindex]->What_Am_I() == RTTI_UNITTYPE) { - counter[((UnitTypeClass const *)(team->Class[subindex]))->Type] = 1; -// counter[((UnitTypeClass const *)(team->Class[subindex]))->Type] += team->DesiredNum[subindex]*2; - } - } - } - } - } - - /* - ** Team types that are flagged as prebuilt, will always try to produce enough - ** to fill one team of this type regardless of whether there is a team active - ** of that type. - */ - for (index = 0; index < TeamTypes.Count(); index++) { - TeamTypeClass const * team = TeamTypes.Ptr(index); - if (team) { - if (team->House == Class->House && team->IsPrebuilt && (!team->IsAutocreate || IsAlerted)) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Class[subindex]->What_Am_I() == RTTI_UNITTYPE) { - int subtype = ((UnitTypeClass const *)(team->Class[subindex]))->Type; - counter[subtype] = MAX(counter[subtype], (int)team->DesiredNum[subindex]); - } - } - } - } - } - - /* - ** Reduce the theoretical maximum by the actual number of objects currently - ** in play. - */ - for (int uindex = 0; uindex < Units.Count(); uindex++) { - UnitClass * unit = Units.Ptr(uindex); - if (unit && !unit->Team && unit->House == this && (unit->Mission != MISSION_GUARD_AREA && unit->Mission != MISSION_HUNT && unit->Mission != MISSION_STICKY && unit->Mission != MISSION_SLEEP)) { - counter[unit->Class->Type]--; - } - } - - /* - ** Pick to build the most needed object but don't consider those object that - ** can't be built because of scenario restrictions or insufficient cash. - */ - int bestval = -1; - int bestcount = 0; - UnitType bestlist[UNIT_COUNT]; - for (UnitType utype = UNIT_FIRST; utype < UNIT_COUNT; utype++) { - if (counter[utype] > 0 && Can_Build(utype, Class->House) && UnitTypeClass::As_Reference(utype).Cost_Of() <= Available_Money()) { - if (bestval == -1 || bestval < counter[utype]) { - bestval = counter[utype]; - bestcount = 0; - } - bestlist[bestcount++] = utype; - } - } - - /* - ** The unit type to build is now known. Fetch a pointer to the techno type class. - */ - if (bestcount) { - techno = &UnitTypeClass::As_Reference(bestlist[Random_Pick(0, bestcount-1)]); - } - } - break; - - /* - ** Infantry construction is based on the rule that up to twice the number required - ** to fill all teams will be created. - */ - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - if (CurUnits < MaxUnit) { - int counter[INFANTRY_COUNT]; - if (GameToPlay == GAME_NORMAL) { - memset(counter, 0x00, sizeof(counter)); - } else { - for (InfantryType index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - if (Can_Build(index, Class->House) && InfantryTypeClass::As_Reference(index).Level <= BuildLevel) { - counter[index] = 16; - } else { - counter[index] = 0; - } - } - } - - /* - ** Build a list of the maximum of each type we wish to produce. This will be - ** twice the number required to fill all teams. - */ - int index; - for (index = 0; index < Teams.Count(); index++) { - TeamClass * tptr = Teams.Ptr(index); - if (tptr) { - TeamTypeClass const * team = tptr->Class; - - if ((team->IsReinforcable || !tptr->IsFullStrength) && team->House == Class->House) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Class[subindex]->What_Am_I() == RTTI_INFANTRYTYPE) { - counter[((InfantryTypeClass const *)(team->Class[subindex]))->Type] += team->DesiredNum[subindex]+1; - } - } - } - } - } - - /* - ** Team types that are flagged as prebuilt, will always try to produce enough - ** to fill one team of this type regardless of whether there is a team active - ** of that type. - */ - for (index = 0; index < TeamTypes.Count(); index++) { - TeamTypeClass const * team = TeamTypes.Ptr(index); - if (team) { - if (team->House == Class->House && team->IsPrebuilt && (!team->IsAutocreate || IsAlerted)) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Class[subindex]->What_Am_I() == RTTI_INFANTRYTYPE) { - int subtype = ((InfantryTypeClass const *)(team->Class[subindex]))->Type; -// counter[subtype] = 1; - counter[subtype] = MAX(counter[subtype], (int)team->DesiredNum[subindex]); - counter[subtype] = MIN(counter[subtype], 5); - } - } - } - } - } - - /* - ** Reduce the theoretical maximum by the actual number of objects currently - ** in play. - */ - for (int uindex = 0; uindex < Infantry.Count(); uindex++) { - InfantryClass * infantry = Infantry.Ptr(uindex); - if (infantry && !infantry->Team && infantry->House == this && (infantry->Mission != MISSION_GUARD_AREA && infantry->Mission != MISSION_HUNT && infantry->Mission != MISSION_STICKY && infantry->Mission != MISSION_SLEEP)) { - counter[infantry->Class->Type]--; - } - } - - /* - ** Pick to build the most needed object but don't consider those object that - ** can't be built because of scenario restrictions or insufficient cash. - */ - int bestval = -1; - int bestcount = 0; - InfantryType bestlist[INFANTRY_COUNT]; - for (InfantryType utype = INFANTRY_FIRST; utype < INFANTRY_COUNT; utype++) { - if (counter[utype] > 0 && Can_Build(utype, Class->House) && InfantryTypeClass::As_Reference(utype).Cost_Of() <= Available_Money()) { - if (bestval == -1 || bestval < counter[utype]) { - bestval = counter[utype]; - bestcount = 0; - } - bestlist[bestcount++] = utype; - } - } - - /* - ** The infantry type to build is now known. Fetch a pointer to the techno type class. - */ - if (bestcount) { - techno = &InfantryTypeClass::As_Reference(bestlist[Random_Pick(0, bestcount-1)]); - } - } - break; - - /* - ** Building construction is based upon the preconstruction list. - */ - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - if (CurBuildings < MaxBuilding) { - BaseNodeClass * node = Base.Next_Buildable(); - if (node) { - techno = &BuildingTypeClass::As_Reference(node->Type); - } - } - break; - } - return(techno); -} - - -/*********************************************************************************************** - * HouseClass::Flag_Remove -- Removes the flag from the specified target. * - * * - * This routine will remove the flag attached to the specified target object or cell. * - * Call this routine before placing the object down. This is called inherently by the * - * the Flag_Attach() functions. * - * * - * INPUT: target -- The target that the flag was attached to but will be removed from. * - * * - * set_home -- if true, clears the flag's waypoint designation * - * * - * OUTPUT: Was the flag successfully removed from the specified target? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Flag_Remove(TARGET target, bool set_home) -{ - Validate(); - bool rc = false; - - if (Target_Legal(target)) { - - /* - ** Remove the flag from a unit - */ - UnitClass * object = As_Unit(target); - if (object) { - rc = object->Flag_Remove(); - if (rc && FlagLocation == target) { - FlagLocation = TARGET_NONE; - } - - } else { - - /* - ** Remove the flag from a cell - */ - CELL cell = As_Cell(target); - if (Map.In_Radar(cell)) { - rc = Map[cell].Flag_Remove(); - if (rc && FlagLocation == target) { - FlagLocation = TARGET_NONE; - } - } - } - - /* - ** Handle the flag home cell: - ** If 'set_home' is set, clear the home value & the cell's overlay - */ - if (set_home) { - if (FlagHome) { - Map[FlagHome].Overlay = OVERLAY_NONE; - Map.Flag_Cell(FlagHome); - FlagHome = 0; - } - } - } - return(rc); -} - - -/*********************************************************************************************** - * HouseClass::Flag_Attach -- Attach flag to specified cell (or thereabouts). * - * * - * This routine will attach the house flag to the location specified. If the location * - * cannot contain the flag, then a suitable nearby location will be selected. * - * * - * INPUT: cell -- The desired cell location to place the flag. * - * * - * set_home -- if true, resets the flag's waypoint designation * - * * - * OUTPUT: Was the flag successfully placed? * - * * - * WARNINGS: The cell picked for the flag might very likely not be the cell requested. * - * Check the FlagLocation value to determine the final cell resting spot. * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Flag_Attach(CELL cell, bool set_home) -{ - Validate(); - bool rc; - bool clockwise; - FacingType rot; - FacingType fcounter; - - /* - ** Randomly decide if we're going to search cells clockwise or counter- - ** clockwise - */ - clockwise = IRandom(0,1); - - /* - ** Only continue if this cell is a legal placement cell. - */ - if (Map.In_Radar(cell)) { - - /* - ** If the flag already exists, then it must be removed from the object - ** it is attached to. - */ - Flag_Remove(FlagLocation, set_home); - - /* - ** Attach the flag to the cell specified. If it can't be placed, then pick - ** a nearby cell where it can be placed. - */ - CELL newcell = cell; - rc = Map[newcell].Flag_Place(Class->House); - if (!rc) { - - /* - ** Loop for increasing distance from the desired cell. - ** For each distance, randomly pick a starting direction. Between - ** this and the clockwise/counterclockwise random value, the flag - ** should appear to be placed fairly randomly. - */ - for (int dist = 1; dist < 32; dist++) { - - /* - ** Clockwise search. - */ - if (clockwise) { - rot = (FacingType)IRandom(FACING_N, FACING_NW); - for (fcounter = FACING_N; fcounter <= FACING_NW; fcounter++) { - newcell = Coord_Cell(Coord_Move(Cell_Coord(cell), Facing_Dir(rot), dist*256)); - if (Map.In_Radar(newcell) && Map[newcell].Flag_Place(Class->House)) { - dist = 32; - rc = true; - break; - } - rot++; - if (rot > FACING_NW) rot = FACING_N; - } - } else { - - /* - ** Counter-clockwise search - */ - rot = (FacingType)IRandom (FACING_N, FACING_NW); - for (fcounter = FACING_NW; fcounter >= FACING_N; fcounter--) { - newcell = Coord_Cell(Coord_Move(Cell_Coord(cell), Facing_Dir(rot), dist*256)); - if (Map.In_Radar(newcell) && Map[newcell].Flag_Place(Class->House)) { - dist = 32; - rc = true; - break; - } - rot--; - if (rot < FACING_N) - rot = FACING_NW; - } - } - } - } - - /* - ** If we've found a spot for the flag, place the flag at the new cell. - ** if 'set_home' is set, OR this house has no current flag home cell, - ** mark that cell as this house's flag home cell. Otherwise fall back - ** on returning the flag to its home. - */ - if (rc) { - FlagLocation = As_Target(newcell); - - if (set_home || FlagHome == 0) { - Map[newcell].Overlay = OVERLAY_FLAG_SPOT; - FlagHome = newcell; - } - } - else if (FlagHome != 0) { - rc = Map[FlagHome].Flag_Place(Class->House); - } - - return(rc); - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::Flag_Attach -- Attaches the house flag the specified unit. * - * * - * This routine will attach the house flag to the specified unit. This routine is called * - * when a unit drives over a cell containing a flag. * - * * - * INPUT: object -- Pointer to the object that the house flag is to be attached to. * - * * - * set_home -- if true, clears the flag's waypoint designation * - * * - * OUTPUT: Was the flag attached successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Flag_Attach(UnitClass * object, bool set_home) -{ - Validate(); - if (object && !object->IsInLimbo) { - Flag_Remove(FlagLocation, set_home); - - /* - ** Attach the flag to the object. - */ - object->Flag_Attach(Class->House); - FlagLocation = object->As_Target(); - return(true); - } - return(false); -} - -extern void On_Defeated_Message(const char* message, float timeout_seconds); - -/*************************************************************************** - * HouseClass::MPlayer_Defeated -- multiplayer; house is defeated * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/25/1995 BRR : Created. * - *=========================================================================*/ -void HouseClass::MPlayer_Defeated(void) -{ - Validate(); - char txt[80]; - int i,j,k; - unsigned char id; - HousesType house; - HouseClass *hptr; - HouseClass *hptr2; - int num_alive; - int num_humans; - int all_allies; - int max_index; - int max_count; - int count; - int score_index[MAX_PLAYERS]; // array of each multi-player's index into - // the score array - - /*------------------------------------------------------------------------ - Set the defeat flag for this house - ------------------------------------------------------------------------*/ - IsDefeated = true; - -#ifdef USE_RA_AI - /* - ** Moved in from RA for AI. ST - 7/24/2019 4:02PM - */ - /* - ** If this is a computer controlled house, then all computer controlled - ** houses become paranoid. - */ - if (IQ == Rule.MaxIQ && !IsHuman && Rule.IsComputerParanoid) { - Computer_Paranoid(); - } -#endif // USE_RA_AI - - /*------------------------------------------------------------------------ - Remove this house's flag & flag home cell - ------------------------------------------------------------------------*/ - if (Special.IsCaptureTheFlag) { - if (FlagLocation) { - Flag_Remove(FlagLocation,true); - } else { - if (FlagHome) { - Flag_Remove(FlagHome,true); - } - } - } - - /*------------------------------------------------------------------------ - If this is me: - - Set MPlayerObiWan, so I can only send messages to all players, and - not just one (so I can't be obnoxiously omnipotent) - - Reveal the map - - Add my defeat message - ------------------------------------------------------------------------*/ - if (PlayerPtr == this) { - MPlayerObiWan = 1; - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - - /*..................................................................... - Pop up a message showing that I was defeated - .....................................................................*/ - sprintf(txt,Text_String(TXT_PLAYER_DEFEATED), MPlayerName); - //Messages.Add_Message(txt, MPlayerTColors[MPlayerColorIdx], TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - - int timeout = 600; - On_Defeated_Message(txt, timeout * 60.0f / TICKS_PER_MINUTE); - //Sound_Effect(VOC_INCOMING_MESSAGE); - - } else { - - /*------------------------------------------------------------------------ - If it wasn't me, find out who was defeated - ------------------------------------------------------------------------*/ - if (IsHuman) { - sprintf(txt, Text_String(TXT_PLAYER_DEFEATED), Text_String(TXT_UNKNOWN)); - id = 0; - for (i = 0; i < MPlayerCount; i++) { - house = MPlayerHouses[i]; - if (HouseClass::As_Pointer(house) == this) { - sprintf (txt,Text_String(TXT_PLAYER_DEFEATED), MPlayerNames[i]); - id = MPlayerID[i]; - } - } - - Messages.Add_Message(txt, MPlayerTColors[MPlayerID_To_ColorIndex(id)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - } - } - - /*------------------------------------------------------------------------ - Find out how many players are left alive. - ------------------------------------------------------------------------*/ - num_alive = 0; - num_humans = 0; - for (i = 0; i < MPlayerMax; i++) { - hptr = HouseClass::As_Pointer((HousesType)(HOUSE_MULTI1 + i)); - if (hptr && hptr->IsDefeated==0) { - if (hptr->IsHuman) - num_humans++; - num_alive++; - } - } - - /*------------------------------------------------------------------------ - If all the houses left alive are allied with each other, then in reality - there's only one player left: - ------------------------------------------------------------------------*/ - all_allies = 1; - for (i = 0; i < MPlayerMax; i++) { - /*..................................................................... - Get a pointer to this house - .....................................................................*/ - hptr = HouseClass::As_Pointer((HousesType)(HOUSE_MULTI1 + i)); - if (!hptr || hptr->IsDefeated) - continue; - - /*..................................................................... - Loop through all houses; if there's one left alive that this house - isn't allied with, then all_allies will be false - .....................................................................*/ - for (j = 0; j < MPlayerMax; j++) { - hptr2 = HouseClass::As_Pointer((HousesType)(HOUSE_MULTI1 + j)); - if (!hptr2) - continue; - if (!hptr2->IsDefeated && !hptr->Is_Ally(hptr2)) { - all_allies = 0; - break; - } - } - if (!all_allies) - break; - } - /*........................................................................ - If all houses left are allies, set 'num_alive' to 1; game over. - ........................................................................*/ - if (all_allies) - num_alive = 1; - - /*------------------------------------------------------------------------ - If there's only one human player left or no humans left, the game is over: - - Determine whether this player wins or loses, based on the state of the - MPlayerObiWan flag - - Find all players' indices in the MPlayerScore array - - Tally up scores for this game - ------------------------------------------------------------------------*/ - if (num_alive == 1 || num_humans == 0) { - if (PlayerPtr->IsDefeated) { - PlayerLoses = true; - } else { - PlayerWins = true; - } - - /*--------------------------------------------------------------------- - Find each player's score index - ---------------------------------------------------------------------*/ - for (i = 0; i < MPlayerCount; i++) { - score_index[i] = -1; - - /*.................................................................. - Search for this player's name in the MPlayerScore array - ..................................................................*/ - for (j = 0; j < MPlayerNumScores; j++) { - if (!stricmp(MPlayerNames[i],MPlayerScore[j].Name)) { - score_index[i] = j; - break; - } - } - - /*.................................................................. - If the index is still -1, the name wasn't found; add a new entry. - ..................................................................*/ - if (score_index[i] == -1) { - if (MPlayerNumScores < MAX_MULTI_NAMES) { - score_index[i] = MPlayerNumScores; - MPlayerNumScores++; - } else { - - /*............................................................... - For each player in the scores array, count the # of '-1' entries - from this game backwards; the one with the most is the one that - hasn't played the longest; replace him with this new guy. - ...............................................................*/ - max_index = 0; - max_count = 0; - for (j = 0; j < MPlayerNumScores; j++) { - count = 0; - for (k = MPlayerNumScores - 1; k >= 0; k--) { - if (MPlayerScore[j].Kills[k]==-1) { - count++; - } else { - break; - } - } - if (count > max_count) { - max_count = count; - max_index = j; - } - } - score_index[i] = max_index; - } - - /*............................................................... - Initialize this score entry - ...............................................................*/ - MPlayerScore[score_index[i]].Wins = 0; - strcpy (MPlayerScore[score_index[i]].Name,MPlayerNames[i]); - for (j = 0; j < MAX_MULTI_GAMES; j++) - MPlayerScore[score_index[i]].Kills[j] = -1; - } - - /*.................................................................. - Init this player's Kills to 0 (-1 means he didn't play this round; - 0 means he played but got no kills). - ..................................................................*/ - MPlayerScore[score_index[i]].Kills[MPlayerCurGame] = 0; - - /*.................................................................. - Init this player's color to his last-used color index - ..................................................................*/ - MPlayerScore[score_index[i]].Color = MPlayerID_To_ColorIndex(MPlayerID[i]); - } - -#if 0 // (This is the old method of tallying scores: - /*--------------------------------------------------------------------- - Tally up the scores for this game: - - For each house: - - If this house is human & wasn't defeated, its the winner - - If this house was defeated, find out who did it & increment their - Kills value. - ---------------------------------------------------------------------*/ - for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { - hptr = HouseClass::As_Pointer(house); - if (!hptr) continue; - - if (!hptr->IsDefeated) { - - /*............................................................... - If this is the winning house, find which player it was & increment - their 'Wins' value - ...............................................................*/ - if (hptr->IsHuman) { - for (i = 0; i < MPlayerCount; i++) { - if (house == MPlayerHouses[i]) { - MPlayerScore[score_index[i]].Wins++; - MPlayerWinner = score_index[i]; - } - } - } - } else { - - /*.................................................................. - This house was defeated; find which player who defeated him & increment - his 'Kills' value for this game - ..................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - if (hptr->WhoLastHurtMe == MPlayerHouses[i]) { - MPlayerScore[score_index[i]].Kills[MPlayerCurGame]++; - } - } - } - } - -#else // This is the new method: - - /*--------------------------------------------------------------------- - Tally up the scores for this game: - - For each player: - - If this player is undefeated this round, he's the winner - - Each player's Kills value is the sum of the unit's they killed - ---------------------------------------------------------------------*/ - for (i = 0; i < MPlayerCount; i++) { - hptr = HouseClass::As_Pointer(MPlayerHouses[i]); - - /*.................................................................. - If this house was undefeated, it must have been the winner. (If - no human houses are undefeated, the computer won.) - ..................................................................*/ - if (!hptr->IsDefeated) { - MPlayerScore[score_index[i]].Wins++; - MPlayerWinner = score_index[i]; - } - - /*.................................................................. - Tally up all kills for this player - ..................................................................*/ - for (house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - - MPlayerScore[score_index[i]].Kills[MPlayerCurGame] += - hptr->UnitsKilled[house]; - - MPlayerScore[score_index[i]].Kills[MPlayerCurGame] += - hptr->BuildingsKilled[house]; - } - } -#endif - - /*--------------------------------------------------------------------- - Destroy all the IPX connections, since we have to go through the rest - of the Main_Loop() before we detect that the game is over, and we'll - end up waiting for frame sync packets from the other machines. - ---------------------------------------------------------------------*/ - if (GameToPlay==GAME_IPX || GameToPlay == GAME_INTERNET) { - i = 0; - while (Ipx.Num_Connections() && (i++ < 1000) ) { - id = Ipx.Connection_ID(0); - Ipx.Delete_Connection(id); - } - MPlayerCount = 0; - } - } -} - - -/*************************************************************************** - * HouseClass::Blowup_All -- blows up everything * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/16/1995 BRR : Created. * - * 06/09/1995 JLB : Handles aircraft. * - *=========================================================================*/ -void HouseClass::Blowup_All(void) -{ - Validate(); - int i; - int damage; - UnitClass *uptr; - InfantryClass *iptr; - BuildingClass *bptr; - int count; - WarheadType warhead; - - /* - ** Find everything owned by this house & blast it with a huge amount of damage - ** at zero range. Do units before infantry, so the units' drivers are killed - ** too. Using Explosion_Damage is like dropping a big bomb right on the - ** object; it will also damage anything around it. - */ - for (i = 0; i < ::Units.Count(); i++) { - if (::Units.Ptr(i)->House == this && !::Units.Ptr(i)->IsInLimbo) { - uptr = ::Units.Ptr(i); - - /* - ** Some units can't be killed with one shot, so keep damaging them until - ** they're gone. The unit will destroy itself, and put an infantry in - ** its place. When the unit destroys itself, decrement 'i' since - ** its pointer will be removed from the active pointer list. - */ - count = 0; - while (::Units.Ptr(i)==uptr && uptr->Strength) { - damage = 0x7fff; - Explosion_Damage(uptr->Center_Coord(), damage, NULL, WARHEAD_HE); - count++; - if (count > 5) { - delete uptr; - break; - } - } - i--; - } - } - - /* - ** Destroy all aircraft owned by this house. - */ - for (i = 0; i < ::Aircraft.Count(); i++) { - if (::Aircraft.Ptr(i)->House == this && !::Aircraft.Ptr(i)->IsInLimbo) { - AircraftClass * aptr = ::Aircraft.Ptr(i); - - damage = 0x7fff; - aptr->Take_Damage(damage, 0, WARHEAD_HE, NULL); - if (!aptr->IsActive) { - i--; - } - } - } - - /* - ** Buildings don't delete themselves when they die; they shake the screen - ** and begin a countdown, so don't decrement 'i' when it's destroyed. - */ - for (i = 0; i < Buildings.Count(); i++) { - if (Buildings.Ptr(i)->House == this && !Buildings.Ptr(i)->IsInLimbo) { - bptr = Buildings.Ptr(i); - - count = 0; - bptr->IsSurvivorless = true; - while (Buildings.Ptr(i)==bptr && bptr->Strength) { - damage = 0x7fff; - Explosion_Damage(bptr->Center_Coord(), damage, NULL, WARHEAD_HE); - count++; - if (count > 5) { - delete bptr; - break; - } - } - } - } - - /* - ** Infantry don't delete themselves when they die; they go into a death- - ** animation sequence, so there's no need to decrement 'i' when they die. - ** Infantry should die by different types of warheads, so their death - ** anims aren't all synchronized. - */ - for (i = 0; i < Infantry.Count(); i++) { - if (Infantry.Ptr(i)->House == this && !Infantry.Ptr(i)->IsInLimbo) { - iptr = Infantry.Ptr(i); - - count = 0; - while (Infantry.Ptr(i)==iptr && iptr->Strength) { - damage = 0x7fff; - warhead = (WarheadType)IRandom (WARHEAD_SA, WARHEAD_FIRE); - Explosion_Damage(iptr->Center_Coord(), damage, NULL, warhead); - if (iptr->IsActive) { - damage = 0x7fff; - iptr->Take_Damage(damage, 0, warhead); - } - - count++; - if (count > 5) { - delete iptr; - break; - } - } - } - } - -#ifdef NEVER - /* - ** Just delete the teams & triggers for this house. - */ - for (i = 0; i < TeamTypes.Count(); i++) { - if (TeamTypes.Ptr(i)->House == Class->House) { - delete TeamTypes.Ptr(i); - i--; - } - } - for (i = 0; i < Triggers.Count(); i++) { - if (Triggers.Ptr(i)->House == Class->House) { - delete Triggers.Ptr(i); - i--; - } - } -#endif -} - - -/*********************************************************************************************** - * HouseClass::Flag_To_Die -- Flags the house to blow up soon. * - * * - * When this routine is called, the house will blow up after a period of time. Typically * - * this is called when the flag is captured or the HQ destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: Was the house flagged to blow up? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Flag_To_Die(void) -{ - Validate(); - if (!IsToWin && !IsToDie && !IsToLose) { - IsToDie = true; - if (IsV107) { - BorrowedTime = TICKS_PER_SECOND * 3; - } else { - BorrowedTime = TICKS_PER_SECOND * 1; - } - } - return(IsToDie); -} - - -/*********************************************************************************************** - * HouseClass::Flag_To_Win -- Flags the house to win soon. * - * * - * When this routine is called, the house will be declared the winner after a period of * - * time. * - * * - * INPUT: none * - * * - * OUTPUT: Was the house flagged to win? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Flag_To_Win(void) -{ - Validate(); - if (!IsToWin && !IsToDie && !IsToLose) { - IsToWin = true; - if (IsV107) { - BorrowedTime = TICKS_PER_SECOND * 3; - } else { - BorrowedTime = TICKS_PER_SECOND * 1; - } - } - return(IsToWin); -} - - -/*********************************************************************************************** - * HouseClass::Flag_To_Lose -- Flags the house to die soon. * - * * - * When this routine is called, it will spell the doom of this house. In a short while * - * all of the object owned by this house will explode. Typical use of this routine is when * - * the flag has been captured or the command vehicle has been destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: Has the doom been initiated? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/12/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Flag_To_Lose(void) -{ - Validate(); - IsToWin = false; - if (!IsToDie && !IsToLose) { - IsToLose = true; - if (IsV107) { - BorrowedTime = TICKS_PER_SECOND * 3; - } else { - BorrowedTime = TICKS_PER_SECOND * 1; - } - } - return(IsToLose); -} - - -/*********************************************************************************************** - * HouseClass::Init_Data -- Initializes the multiplayer color data. * - * * - * This routine is called when initializing the color and remap data for this house. The * - * primary user of this routine is the multiplayer version of the game. * - * * - * INPUT: color -- The color of this house. * - * * - * house -- The house that this should act like. * - * * - * credits -- The initial credits to assign to this house. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Init_Data(PlayerColorType color, HousesType house, int credits) -{ - Validate(); - Credits = InitialCredits = credits; - VisibleCredits.Current = Credits; - - ActLike = house; - RemapColor = color; - switch (color) { - case REMAP_GOLD: - RemapTable = RemapGold; - ((unsigned char &)Class->Color) = 157; - ((unsigned char &)Class->BrightColor) = 5; - break; - - case REMAP_RED: - RemapTable = RemapRed; - ((unsigned char &)Class->Color) = 123; - ((unsigned char &)Class->BrightColor) = 127; - break; - - case REMAP_LTBLUE: - RemapTable = RemapLtBlue; - ((unsigned char &)Class->Color) = 135; - ((unsigned char &)Class->BrightColor) = 2; - break; - - case REMAP_ORANGE: - RemapTable = RemapOrange; - ((unsigned char &)Class->Color) = 26; - ((unsigned char &)Class->BrightColor) = 24; - break; - - case REMAP_GREEN: - RemapTable = RemapGreen; - ((unsigned char &)Class->Color) = 167; - ((unsigned char &)Class->BrightColor) = 159; - break; - - case REMAP_BLUE: - RemapTable = RemapBlue; - ((unsigned char &)Class->Color) = 203; - ((unsigned char &)Class->BrightColor) = 201; - break; - } -} - - -/*********************************************************************************************** - * HouseClass::Power_Fraction -- Fetches the current power output rating. * - * * - * Use this routine to fetch the current power output as a fixed point fraction. The * - * value 0x0100 is 100% power. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with power rating as a fixed pointer number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/22/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::Power_Fraction(void) const -{ - Validate(); - if (Power) { - if (Drain) { - return(Cardinal_To_Fixed(Drain, Power)); - } else { - return(0x0100); - } - } - return(0); -} - - -/*********************************************************************************************** - * HouseClass::Has_Nuke_Device -- Deteremines if the house has a nuclear device. * - * * - * This routine checks to see if the house has a nuclear device to launch. A nuclear * - * device is available when the necessary parts have been retrieved in earlier scenarios * - * or if this is the multiplayer version. * - * * - * INPUT: none * - * * - * OUTPUT: Does the house have a nuclear device? * - * * - * WARNINGS: This does not check to see if there is a suitable launch facility (i.e., the * - * Temple of Nod), only that there is a nuclear device potential. * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Has_Nuke_Device(void) -{ - Validate(); - if (GameToPlay != GAME_NORMAL || !IsHuman) return(true); - return((NukePieces & 0x07) == 0x07); -} - - -/*********************************************************************************************** - * HouseClass::Sell_Wall -- Tries to sell the wall at the specified location. * - * * - * This routine will try to sell the wall at the specified location. If there is a wall * - * present and it is owned by this house, then it can be sold. * - * * - * INPUT: cell -- The cell that wall selling is desired. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/05/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Sell_Wall(CELL cell) -{ - Validate(); - if ((unsigned)cell > 0) { - OverlayType overlay = Map[cell].Overlay; - - if (overlay != OVERLAY_NONE && Map[cell].Owner == Class->House) { - OverlayTypeClass const & optr = OverlayTypeClass::As_Reference(overlay); - - if (optr.IsWall) { - BuildingTypeClass const * btype = NULL; - switch (overlay) { - case OVERLAY_SANDBAG_WALL: - btype = &BuildingTypeClass::As_Reference(STRUCT_SANDBAG_WALL); - break; - - case OVERLAY_CYCLONE_WALL: - btype = &BuildingTypeClass::As_Reference(STRUCT_CYCLONE_WALL); - break; - - case OVERLAY_BRICK_WALL: - btype = &BuildingTypeClass::As_Reference(STRUCT_BRICK_WALL); - break; - - case OVERLAY_BARBWIRE_WALL: - btype = &BuildingTypeClass::As_Reference(STRUCT_BARBWIRE_WALL); - break; - - case OVERLAY_WOOD_WALL: - btype = &BuildingTypeClass::As_Reference(STRUCT_WOOD_WALL); - break; - - default: - break; - } - if (btype != NULL && !btype->IsUnsellable) { - - if (PlayerPtr == this) { - Sound_Effect(VOC_CASHTURN); - } - - Refund_Money(btype->Cost_Of()/2); - Map[cell].Overlay = OVERLAY_NONE; - Map[cell].OverlayData = 0; - Map[cell].Owner = HOUSE_NONE; - Map[cell].Wall_Update(); - CellClass * ncell = Map[cell].Adjacent_Cell(FACING_N); - if (ncell) ncell->Wall_Update(); - CellClass * wcell = Map[cell].Adjacent_Cell(FACING_W); - if (wcell) wcell->Wall_Update(); - CellClass * scell = Map[cell].Adjacent_Cell(FACING_S); - if (scell) scell->Wall_Update(); - CellClass * ecell = Map[cell].Adjacent_Cell(FACING_E); - if (ecell) ecell->Wall_Update(); - Map[cell].Recalc_Attributes(); - Map[cell].Redraw_Objects(); - ObjectClass::Detach_This_From_All(::As_Target(cell), true); - } - } - } - } -} - - - -/*********************************************************************************************** - * HouseClass::Check_Pertinent_Structures -- See if any useful structures remain * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 1/31/2020 3:34PM ST : Created. * - *=============================================================================================*/ -void HouseClass::Check_Pertinent_Structures(void) -{ - /* - ** New default win mode to avoid griefing. ST - 1/31/2020 3:33PM - ** - ** Game is over when no pertinent structures remain - */ - - if (!Special.IsEarlyWin) { - return; - } - - if (IsToDie || IsToWin || IsToLose) { - return; - } - - bool any_good_buildings = false; - - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass *b = Buildings.Ptr(index); - - if (b && b->IsActive && b->House == this) { - if (!b->Class->IsWall) { - if (!b->IsInLimbo && b->Strength > 0) { - any_good_buildings = true; - break; - } - } - } - } - - if (!any_good_buildings) { - for (int index = 0; index < Units.Count(); index++) { - UnitClass * unit = Units.Ptr(index); - - if (unit && unit->IsActive && *unit == UNIT_MCV && unit->House == this) { - if (!unit->IsInLimbo && unit->Strength > 0) { - any_good_buildings = true; - break; - } - } - } - } - - if (!any_good_buildings) { - Flag_To_Die(); - } -} - - - - -/*********************************************************************************************** - * HouseClass::Init_Unit_Trackers -- Allocate the unit trackers for the house * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 4/23/2020 11:06PM ST : Created. * - *=============================================================================================*/ -void HouseClass::Init_Unit_Trackers(void) -{ - AircraftTotals = new UnitTrackerClass( (int) AIRCRAFT_COUNT); - InfantryTotals = new UnitTrackerClass( (int) INFANTRY_COUNT); - UnitTotals = new UnitTrackerClass ( (int) UNIT_COUNT); - BuildingTotals = new UnitTrackerClass ( (int) STRUCT_COUNT); - - DestroyedAircraft = new UnitTrackerClass ( (int) AIRCRAFT_COUNT); - DestroyedInfantry = new UnitTrackerClass( (int) INFANTRY_COUNT); - DestroyedUnits = new UnitTrackerClass ( (int) UNIT_COUNT); - DestroyedBuildings = new UnitTrackerClass ( (int) STRUCT_COUNT); - - CapturedBuildings = new UnitTrackerClass ( (int) STRUCT_COUNT); - TotalCrates = new UnitTrackerClass ( TOTAL_CRATE_TYPES ); //15 crate types -} - - - -/*********************************************************************************************** - * HouseClass::Free_Unit_Trackers -- Free the unit trackers for the house * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 4/23/2020 11:06PM ST : Created. * - *=============================================================================================*/ -void HouseClass::Free_Unit_Trackers(void) -{ - if (AircraftTotals) { - delete AircraftTotals; - AircraftTotals = NULL; - } - - if (InfantryTotals) { - delete InfantryTotals; - InfantryTotals = NULL; - } - - if (UnitTotals) { - delete UnitTotals; - UnitTotals = NULL; - } - - if (BuildingTotals) { - delete BuildingTotals; - BuildingTotals = NULL; - } - - if (DestroyedAircraft) { - delete DestroyedAircraft; - DestroyedAircraft = NULL; - } - - if (DestroyedInfantry) { - delete DestroyedInfantry; - DestroyedInfantry = NULL; - } - - if (DestroyedUnits) { - delete DestroyedUnits; - DestroyedUnits = NULL; - } - - if (DestroyedBuildings) { - delete DestroyedBuildings; - DestroyedBuildings = NULL; - } - - if (CapturedBuildings) { - delete CapturedBuildings; - CapturedBuildings = NULL; - } - - if (TotalCrates) { - delete TotalCrates; - TotalCrates = NULL; - } -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#ifdef USE_RA_AI - - - -/*********************************************************************************************** - - Below AI code imported from RA - -***********************************************************************************************/ - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - -/* -** In RA, Control is a container for other variables. In TD, they are defined in the class -*/ -#define Control (*this) - -/* -** Percent_Chance - implementation similar to Red Alert -*/ -inline bool Percent_Chance(int percent) -{ - return (Random_Pick(0, 99) < percent); -} - - -/* -** Engineer was renamed to RENOVATOR for RA -*/ -#define INFANTRY_RENOVATOR INFANTRY_E7 - - -TFixedIHeapClass HouseClass::BuildChoice; - -/* -** This is a replacement for the RA 'fixed' round up function. It takes the equivalent of a 'fixed' value, but returns just the integer part -** ST - 7/26/2019 11:13AM -*/ -unsigned short Round_Up(unsigned short val) -{ - if ((val & 0xff) == 0) { - return val; - } - val &= 0xff00; - val += 0x0100; - val >>= 8; - return val; -} - - -unsigned short fixed(int val) {return (unsigned short)val;} - - - -/*********************************************************************************************** - * HouseClass::Suggest_New_Building -- Examines the situation and suggests a building. * - * * - * This routine is called when a construction yard needs to know what to build next. It * - * will either examine the prebuilt base list or try to figure out what to build next * - * based on the current game situation. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the building type class to build. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1995 JLB : Created. * - *=============================================================================================*/ -BuildingTypeClass const * HouseClass::Suggest_New_Building(void) const -{ - //assert(Houses.ID(this) == ID); - - if (BuildStructure != STRUCT_NONE) { - return(&BuildingTypeClass::As_Reference(BuildStructure)); - } - return(NULL); -} - - -/*********************************************************************************************** - * HouseClass::Find_Building -- Finds a building of specified type. * - * * - * This routine is used to find a building of the specified type. This is particularly * - * useful for when some event requires a specific building instance. The nuclear missile * - * launch is a good example. * - * * - * INPUT: type -- The building type to scan for. * - * * - * zone -- The zone that the building must be located in. If no zone specific search * - * is desired, then pass ZONE_NONE. * - * * - * OUTPUT: Returns with a pointer to the building type requested. If there is no building * - * of the type requested, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1995 JLB : Created. * - * 10/02/1995 JLB : Allows for zone specifics. * - *=============================================================================================*/ -BuildingClass * HouseClass::Find_Building(StructType type, ZoneType zone) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** Only scan if we KNOW there is at least one building of the type - ** requested. - */ - if (BQuantity[type] > 0) { - - /* - ** Search for a suitable launch site for this missile. - */ - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * b = Buildings.Ptr(index); - if (b && !b->IsInLimbo && b->House == this && *b == type) { - if (zone == ZONE_NONE || Which_Zone(b) == zone) { - return(b); - } - } - } - } - return(NULL); -} - - -/*********************************************************************************************** - * HouseClass::Find_Build_Location -- Finds a suitable building location. * - * * - * This routine is used to find a suitable building location for the building specified. * - * The auto base building logic uses this when building the base for the computer. * - * * - * INPUT: building -- Pointer to the building that needs to be placed down. * - * * - * OUTPUT: Returns with the coordinate to place the building at. If there are no suitable * - * locations, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE HouseClass::Find_Build_Location(BuildingClass * building) const -{ - //assert(Houses.ID(this) == ID); - - int zonerating[ZONE_COUNT]; - struct { - int AntiAir; // Average air defense for the base. - int AntiArmor; // Average armor defense for the base. - int AntiInfantry; // Average infantry defense for the base. - } zoneinfo = {0,0,0}; - int antiair = building->Anti_Air(); - int antiarmor = building->Anti_Armor(); - int antiinfantry = building->Anti_Infantry(); - bool adj = true; - - /* - ** Never place combat buildings adjacent to each other. This is partly - ** because combat buildings don't have a bib and jamming will occur as well - ** as because spacing defensive buildings out will yield a better - ** defense. - */ - if (antiair || antiarmor || antiinfantry) { - adj = false; - } - - /* - ** Determine the average zone strengths for the base. This value is - ** used to determine what zones are considered under or over strength. - */ - ZoneType z; - for (z = ZONE_NORTH; z < ZONE_COUNT; z++) { - zoneinfo.AntiAir += ZoneInfo[z].AirDefense; - zoneinfo.AntiArmor += ZoneInfo[z].ArmorDefense; - zoneinfo.AntiInfantry += ZoneInfo[z].InfantryDefense; - } - zoneinfo.AntiAir /= ZONE_COUNT-ZONE_NORTH; - zoneinfo.AntiArmor /= ZONE_COUNT-ZONE_NORTH; - zoneinfo.AntiInfantry /= ZONE_COUNT-ZONE_NORTH; - - /* - ** Give each zone a rating for value. The higher the value the more desirable - ** to place the specified building in that zone. Factor the average value of - ** zone defense such that more weight is given to zones that are very under - ** defended. - */ - memset(&zonerating[0], '\0', sizeof(zonerating)); - for (z = ZONE_FIRST; z < ZONE_COUNT; z++) { - int diff; - - diff = zoneinfo.AntiAir-ZoneInfo[z].AirDefense; - if (z == ZONE_CORE) diff /= 2; - if (diff > 0) { - zonerating[z] += min(antiair, diff); - } - - diff = zoneinfo.AntiArmor-ZoneInfo[z].ArmorDefense; - if (z == ZONE_CORE) diff /= 2; - if (diff > 0) { - zonerating[z] += min(antiarmor, diff); - } - - diff = zoneinfo.AntiInfantry-ZoneInfo[z].InfantryDefense; - if (z == ZONE_CORE) diff /= 2; - if (diff > 0) { - zonerating[z] += min(antiinfantry, diff); - } - } - - /* - ** Now that each zone has been given a desirability rating, find the zone - ** with the greatest value and try to place the building in that zone. - */ - ZoneType zone = Random_Pick(ZONE_FIRST, ZONE_WEST); - int largest = 0; - for (z = ZONE_FIRST; z < ZONE_COUNT; z++) { - if (zonerating[z] > largest) { - zone = z; - largest = zonerating[z]; - } - } - - CELL zcell = Find_Cell_In_Zone(building, zone); - if (zcell) { - return(Cell_Coord(zcell)); - } - - /* - ** Could not build in preferred zone, so try building in any zone. - */ - static ZoneType _zones[] = {ZONE_CORE, ZONE_NORTH, ZONE_SOUTH, ZONE_EAST, ZONE_WEST}; - int start = Random_Pick(0U, ARRAY_SIZE(_zones)-1); - for (int zz = 0; zz < ARRAY_SIZE(_zones); zz++) { - ZoneType tryzone = _zones[(zz + start) % ARRAY_SIZE(_zones)]; - zcell = Find_Cell_In_Zone(building, tryzone); - if (zcell) return(zcell); - } - - return(NULL); -} - - -/*********************************************************************************************** - * HouseClass::Recalc_Center -- Recalculates the center point of the base. * - * * - * This routine will average the location of the base and record the center point. The * - * recorded center point is used to determine such things as how far the base is spread * - * out and where to protect the most. This routine should be called whenever a building * - * is created or destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/28/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Recalc_Center(void) -{ - //assert(Houses.ID(this) == ID); - - /* - ** First presume that there is no base. If there is a base, then these values will be - ** properly filled in below. - */ - Center = 0; - Radius = 0; - for (ZoneType zone = ZONE_FIRST; zone < ZONE_COUNT; zone++) { - ZoneInfo[zone].AirDefense = 0; - ZoneInfo[zone].ArmorDefense = 0; - ZoneInfo[zone].InfantryDefense = 0; - } - - /* - ** Only process the center base size/position calculation if there are buildings to - ** consider. When no buildings for this house are present, then no processing need - ** occur. - */ - if (CurBuildings > 0) { - int x = 0; - int y = 0; - int count = 0; - int index; - - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass const * b = Buildings.Ptr(index); - - if (b != NULL && !b->IsInLimbo && (HouseClass *)b->House == this && b->Strength > 0) { - - /* - ** Give more "weight" to buildings that cost more. The presumption is that cheap - ** buildings don't affect the base disposition as much as the more expensive - ** buildings do. - */ - int weight = (b->Class->Cost_Of() / 1000)+1; - for (int i = 0; i < weight; i++) { - x += Coord_X(b->Center_Coord()); - y += Coord_Y(b->Center_Coord()); - count++; - } - } - } - - /* - ** This second check for quantity of buildings is necessary because the first - ** check against CurBuildings doesn't take into account if the building is in - ** limbo, but for base calculation, the limbo state disqualifies a building - ** from being processed. Thus, CurBuildings may indicate a base, but count may - ** not match. - */ - if (count > 0) { - x /= count; - y /= count; - -#ifdef NEVER - /* - ** Bias the center of the base away from the edges of the map. - */ - LEPTON left = Cell_To_Lepton(Map.MapCellX + 10); - LEPTON top = Cell_To_Lepton(Map.MapCellY + 10); - LEPTON right = Cell_To_Lepton(Map.MapCellX + Map.MapCellWidth - 10); - LEPTON bottom = Cell_To_Lepton(Map.MapCellY + Map.MapCellHeight - 10); - if (x < left) x = left; - if (x > right) x = right; - if (y < top) y = top; - if (y > bottom) y = bottom; -#endif - - Center = XY_Coord(x, y); - } - - /* - ** If there were any buildings discovered as legal to consider as part of the base, - ** then figure out the general average radius of the building disposition as it - ** relates to the center of the base. - */ - if (count > 1) { - int radius = 0; - - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass const * b = Buildings.Ptr(index); - - if (b != NULL && !b->IsInLimbo && (HouseClass *)b->House == this && b->Strength > 0) { - radius += Distance(Center, b->Center_Coord()); - } - } - Radius = max(radius / count, 2 * CELL_LEPTON_W); - - /* - ** Determine the relative strength of each base defense zone. - */ - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass const * b = Buildings.Ptr(index); - - if (b != NULL && !b->IsInLimbo && (HouseClass *)b->House == this && b->Strength > 0) { - ZoneType z = Which_Zone(b); - - if (z != ZONE_NONE) { - ZoneInfo[z].ArmorDefense += b->Anti_Armor(); - ZoneInfo[z].AirDefense += b->Anti_Air(); - ZoneInfo[z].InfantryDefense += b->Anti_Infantry(); - } - } - } - - } else { - Radius = 0x0200; - } - } -} - - -/*********************************************************************************************** - * HouseClass::Expert_AI -- Handles expert AI processing. * - * * - * This routine is called when the computer should perform expert AI processing. This * - * method of AI is categorized as an "Expert System" process. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: This is relatively time consuming -- call periodically. * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::Expert_AI(void) -{ - //assert(Houses.ID(this) == ID); - - BuildingClass * b = 0; - bool stop = false; - int time = TICKS_PER_SECOND * 10; - - /* - ** If the current enemy no longer has a base or is defeated, then don't consider - ** that house a threat anymore. Clear out the enemy record and then try - ** to find a new enemy. - */ - if (Enemy != HOUSE_NONE) { - HouseClass * h = HouseClass::As_Pointer(Enemy); - - if (h == NULL || !h->IsActive || h->IsDefeated || Is_Ally(h) || h->BScan == 0) { - Enemy = HOUSE_NONE; - } - } - - /* - ** If there is no enemy assigned to this house, then assign one now. The - ** enemy that is closest is picked. However, don't pick an enemy if the - ** base has not been established yet. - */ - if (ActiveBScan && Center && Attack == 0) { - int close = 0; - HousesType enemy = HOUSE_NONE; - int maxunit = 0; - int maxinfantry = 0; - int maxvessel = 0; - int maxaircraft = 0; - int maxbuilding = 0; - int enemycount = 0; - - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - HouseClass * h = HouseClass::As_Pointer(house); - if (h != NULL && h->IsActive && !h->IsDefeated && !Is_Ally(h)) { - - /* - ** Perform a special restriction check to ensure that no enemy is chosen if - ** there is even one enemy that has not established a base yet. This will - ** ensure an accurate first pick for enemy since the distance to base - ** value can be determined. - */ - if (!h->IsStarted) { - enemy = HOUSE_NONE; - break; - } - - /* - ** Keep track of the number of buildings and units owned by the - ** enemy. This is used to bring up the maximum allowed to match. - */ - maxunit += h->CurUnits; - maxbuilding += h->CurBuildings; - maxinfantry += h->CurInfantry; - //maxvessel += h->CurVessels; - maxaircraft += h->CurAircraft; - enemycount++; - - /* - ** Determine a priority value based on distance to the center of the - ** candidate base. The higher the value, the better the candidate house - ** is to becoming the preferred enemy for this house. - */ - int value = ((MAP_CELL_W*2)-Distance(Center, h->Center)); - value *= 2; - - /* - ** In addition to distance, record the number of kills directed - ** against this house. The enemy that does more damage might be - ** considered a greater threat. - */ - value += h->BuildingsKilled[Class->House]*5; - value += h->UnitsKilled[Class->House]; - - /* - ** Factor in the relative sizes of the bases. An enemy that has a - ** larger base will be considered a bigger threat. Conversely, a - ** smaller base is considered a lesser threat. - */ - value += h->CurUnits - CurUnits; - value += h->CurBuildings - CurBuildings; - value += (h->CurInfantry - CurInfantry)/4; - - /* - ** Whoever last attacked is given a little more priority as - ** a potential designated enemy. - */ - if (house == LAEnemy) { - value += 100; - } - -#ifdef OBSOLETE - /* - ** Human players are a given preference as the target. - */ - if (h->IsHuman) { - value *= 2; - } -#endif - - /* - ** Compare the calculated value for this candidate house and if it is - ** greater than the previously recorded maximum, record this house as - ** the prime candidate for enemy. - */ - if (value > close) { - enemy = house; - close = value; - } - } - } - - /* - ** Record this closest enemy base as the first enemy to attack. - */ - Enemy = enemy; - - /* - ** Up the maximum allowed units and buildings to match a rough average - ** of what the enemies are allowed. - */ - if (enemycount) { - maxunit /= enemycount; - maxbuilding /= enemycount; - maxinfantry /= enemycount; - maxvessel /= enemycount; - maxaircraft /= enemycount; - } - - if (Control.MaxBuilding < (unsigned)maxbuilding + 10) { - Control.MaxBuilding = maxbuilding + 10; - } - if (Control.MaxUnit < (unsigned)maxunit + 10) { - Control.MaxUnit = maxunit + 10; - } - if (Control.MaxInfantry < (unsigned)maxinfantry + 10) { - Control.MaxInfantry = maxinfantry + 10; - } - //if (Control.MaxVessel < (unsigned)maxvessel + 10) { - // Control.MaxVessel = maxvessel + 10; - //} - if (Control.MaxAircraft < (unsigned)maxaircraft + 10) { - Control.MaxAircraft = maxaircraft + 10; - } - } - - /* - ** House state transition check occurs here. Transitions that occur here are ones - ** that relate to general base condition rather than specific combat events. - ** Typically, this is limited to transitions between normal buildup mode and - ** broke mode. - */ - if (State == STATE_ENDGAME) { - Fire_Sale(); - Do_All_To_Hunt(); - } else { - if (State == STATE_BUILDUP) { - if (Available_Money() < 25) { - State = STATE_BROKE; - } - } - if (State == STATE_BROKE) { - if (Available_Money() >= 25) { - State = STATE_BUILDUP; - } - } - if (State == STATE_ATTACKED && LATime + TICKS_PER_MINUTE < Frame) { - State = STATE_BUILDUP; - } - if (State != STATE_ATTACKED && LATime + TICKS_PER_MINUTE > Frame) { - State = STATE_ATTACKED; - } - } - - /* - ** Records the urgency of all actions possible. - */ - UrgencyType urgency[STRATEGY_COUNT]; - StrategyType strat; - for (strat = STRATEGY_FIRST; strat < STRATEGY_COUNT; strat++) { - urgency[strat] = URGENCY_NONE; - - switch (strat) { - case STRATEGY_BUILD_POWER: - urgency[strat] = Check_Build_Power(); - break; - - case STRATEGY_BUILD_DEFENSE: - urgency[strat] = Check_Build_Defense(); - break; - - case STRATEGY_BUILD_INCOME: - urgency[strat] = Check_Build_Income(); - break; - - case STRATEGY_FIRE_SALE: - urgency[strat] = Check_Fire_Sale(); - break; - - case STRATEGY_BUILD_ENGINEER: - urgency[strat] = Check_Build_Engineer(); - break; - - case STRATEGY_BUILD_OFFENSE: - urgency[strat] = Check_Build_Offense(); - break; - - case STRATEGY_RAISE_MONEY: - urgency[strat] = Check_Raise_Money(); - break; - - case STRATEGY_RAISE_POWER: - urgency[strat] = Check_Raise_Power(); - break; - - case STRATEGY_LOWER_POWER: - urgency[strat] = Check_Lower_Power(); - break; - - case STRATEGY_ATTACK: - urgency[strat] = Check_Attack(); - break; - - default: - urgency[strat] = URGENCY_NONE; - break; - } - } - - /* - ** Performs the action required for each of the strategies that share - ** the most urgent category. Stop processing if any strategy at the - ** highest urgency performed any action. This is because higher urgency - ** actions tend to greatly affect the lower urgency actions. - */ - for (UrgencyType u = URGENCY_CRITICAL; u >= URGENCY_LOW; u--) { - bool acted = false; - - for (strat = STRATEGY_FIRST; strat < STRATEGY_COUNT; strat++) { - if (urgency[strat] == u) { - switch (strat) { - case STRATEGY_BUILD_POWER: - acted |= AI_Build_Power(u); - break; - - case STRATEGY_BUILD_DEFENSE: - acted |= AI_Build_Defense(u); - break; - - case STRATEGY_BUILD_INCOME: - acted |= AI_Build_Income(u); - break; - - case STRATEGY_FIRE_SALE: - acted |= AI_Fire_Sale(u); - break; - - case STRATEGY_BUILD_ENGINEER: - acted |= AI_Build_Engineer(u); - break; - - case STRATEGY_BUILD_OFFENSE: - acted |= AI_Build_Offense(u); - break; - - case STRATEGY_RAISE_MONEY: - acted |= AI_Raise_Money(u); - break; - - case STRATEGY_RAISE_POWER: - acted |= AI_Raise_Power(u); - break; - - case STRATEGY_LOWER_POWER: - acted |= AI_Lower_Power(u); - break; - - case STRATEGY_ATTACK: - acted |= AI_Attack(u); - break; - - default: - break; - } - } - } - } - - return(TICKS_PER_SECOND*5 + Random_Pick(1, TICKS_PER_SECOND/2)); -} - - -UrgencyType HouseClass::Check_Build_Power(void) const -{ - //assert(Houses.ID(this) == ID); - - //fixed frac = Power_Fraction(); - int frac = Power_Fraction(); - - UrgencyType urgency = URGENCY_NONE; - - //if (frac < 1 && Can_Make_Money()) { - if (frac < 0x0100 && Can_Make_Money()) { - urgency = URGENCY_LOW; - - /* - ** Very low power condition is considered a higher priority. - */ - //if (frac < fixed::_3_4) urgency = URGENCY_MEDIUM; - if (frac < 0x00C0) urgency = URGENCY_MEDIUM; - - /* - ** When under attack and there is a need for power in defense, - ** then consider power building a higher priority. - */ - // No chronosphere in TD. ST - 7/19/2019 4:38PM - //if (State == STATE_THREATENED || State == STATE_ATTACKED) { - // if (BScan | (STRUCTF_CHRONOSPHERE)) { - // urgency = URGENCY_HIGH; - // } - //} - - } - return(urgency); -} - - -UrgencyType HouseClass::Check_Build_Defense(void) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** This routine determines what urgency level that base defense - ** should be given. The more vulnerable the base is, the higher - ** the urgency this routine should return. - */ - return(URGENCY_NONE); -} - - -UrgencyType HouseClass::Check_Build_Offense(void) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** This routine determines what urgency level that offensive - ** weaponry should be given. Surplus money or a very strong - ** defense will cause the offensive urgency to increase. - */ - return(URGENCY_NONE); -} - -/* -** Determines what the attack state of the base is. The higher the state, -** the greater the immediate threat to base defense is. -*/ -UrgencyType HouseClass::Check_Attack(void) const -{ - //assert(Houses.ID(this) == ID); - - if (Frame > TICKS_PER_MINUTE && Attack == 0) { - if (State == STATE_ATTACKED) { - return(URGENCY_LOW); - } - return(URGENCY_CRITICAL); - } - return(URGENCY_NONE); -} - - -UrgencyType HouseClass::Check_Build_Income(void) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** This routine should determine if income processing buildings - ** should be constructed and at what urgency. The lower the money, - ** the lower the refineries, or recent harvester losses should - ** cause a greater urgency to be returned. - */ - return(URGENCY_NONE); -} - - -UrgencyType HouseClass::Check_Fire_Sale(void) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** If there are no more factories at all, then sell everything off because the game - ** is basically over at this point. - */ - //if (State != STATE_ATTACKED && CurBuildings && !(ActiveBScan & (STRUCTF_TENT|STRUCTF_BARRACKS|STRUCTF_CONST|STRUCTF_AIRSTRIP|STRUCTF_WEAP|STRUCTF_HELIPAD))) { - if (State != STATE_ATTACKED && CurBuildings && !(ActiveBScan & (STRUCTF_BARRACKS|STRUCTF_CONST|STRUCTF_AIRSTRIP|STRUCTF_WEAP|STRUCTF_HELIPAD))) { - return(URGENCY_CRITICAL); - } - return(URGENCY_NONE); -} - - -UrgencyType HouseClass::Check_Build_Engineer(void) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** This routine should check to see what urgency that the production of - ** engineers should be. If a friendly building has been captured or the - ** enemy has weak defenses, then building an engineer would be a priority. - */ - return(URGENCY_NONE); -} - - -/* -** Checks to see if money is critically low and something must be done -** to immediately raise cash. -*/ -UrgencyType HouseClass::Check_Raise_Money(void) const -{ - //assert(Houses.ID(this) == ID); - - UrgencyType urgency = URGENCY_NONE; - if (Available_Money() < 100) { - urgency = URGENCY_LOW; - } - if (Available_Money() < 2000 && !Can_Make_Money()) { - urgency++; - } - - return(urgency); -} - -/* -** Checks to see if power is very low and if so, a greater urgency to -** build more power is returned. -*/ -UrgencyType HouseClass::Check_Lower_Power(void) const -{ - //assert(Houses.ID(this) == ID); - - if (Power > Drain+300) { - return(URGENCY_LOW); - } - return(URGENCY_NONE); -} - -/* -** This routine determines if there is a power emergency. Such an -** emergency might require selling of structures in order to free -** up power. This might occur if the base is being attacked and there -** are defenses that require power, but are just short of having -** enough. -*/ -UrgencyType HouseClass::Check_Raise_Power(void) const -{ - //assert(Houses.ID(this) == ID); - - UrgencyType urgency = URGENCY_NONE; - - if (Power_Fraction() < Rule.PowerEmergencyFraction && Power < Drain - 400) { -// if (Power_Fraction() < Rule.PowerEmergencyFraction && (BQuantity[STRUCT_CONST] == 0 || Available_Money() < 200 || Power < Drain-400)) { - urgency = URGENCY_MEDIUM; - if (State == STATE_ATTACKED) { - urgency++; - } - } - return(urgency); -} - - -bool HouseClass::AI_Attack(UrgencyType ) -{ - //assert(Houses.ID(this) == ID); - - bool shuffle = !((Frame > TICKS_PER_MINUTE && !CurBuildings) || Percent_Chance(33)); - bool forced = (CurBuildings == 0); - int index; - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass * a = Aircraft.Ptr(index); - - if (a != NULL && !a->IsInLimbo && a->House == this && a->Strength > 0) { - if (!shuffle && a->Is_Weapon_Equipped() && (forced || Percent_Chance(75))) { - a->Assign_Mission(MISSION_HUNT); - } - } - } - for (index = 0; index < Units.Count(); index++) { - UnitClass * u = Units.Ptr(index); - - if (u != NULL && !u->IsInLimbo && u->House == this && u->Strength > 0) { - if (!shuffle && u->Is_Weapon_Equipped() && (forced || Percent_Chance(75))) { - u->Assign_Mission(MISSION_HUNT); - } else { - - /* - ** If this unit is guarding the base, then cause it to shuffle - ** location instead. - */ - if (Percent_Chance(20) && u->Mission == MISSION_GUARD_AREA && Which_Zone(u) != ZONE_NONE) { - u->ArchiveTarget = ::As_Target(Where_To_Go(u)); - } - } - } - } - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * i = Infantry.Ptr(index); - - if (i != NULL && !i->IsInLimbo && i->House == this && i->Strength > 0) { - if (!shuffle && (i->Is_Weapon_Equipped() || *i == INFANTRY_RENOVATOR) && (forced || Percent_Chance(75))) { - i->Assign_Mission(MISSION_HUNT); - } else { - - /* - ** If this soldier is guarding the base, then cause it to shuffle - ** location instead. - */ - if (Percent_Chance(20) && i->Mission == MISSION_GUARD_AREA && Which_Zone(i) != ZONE_NONE) { - i->ArchiveTarget = ::As_Target(Where_To_Go(i)); - } - } - } - } - Attack = Rule.AttackInterval * Random_Pick(TICKS_PER_MINUTE/2, TICKS_PER_MINUTE*2); - return(true); -} - - -/* -** Given the specified urgency, build a power structure to meet -** this need. -*/ -bool HouseClass::AI_Build_Power(UrgencyType ) const -{ - //assert(Houses.ID(this) == ID); - - return(false); -} - - -/* -** Given the specified urgency, build base defensive structures -** according to need and according to existing base disposition. -*/ -bool HouseClass::AI_Build_Defense(UrgencyType ) const -{ - //assert(Houses.ID(this) == ID); - - return(false); -} - -/* -** Given the specified urgency, build offensive units according -** to need and according to the opponents base defenses. -*/ -bool HouseClass::AI_Build_Offense(UrgencyType ) const -{ - //assert(Houses.ID(this) == ID); - - return(false); -} - -/* -** Given the specified urgency, build income producing -** structures according to need. -*/ -bool HouseClass::AI_Build_Income(UrgencyType ) const -{ - //assert(Houses.ID(this) == ID); - - return(false); -} - - -bool HouseClass::AI_Fire_Sale(UrgencyType urgency) -{ - //assert(Houses.ID(this) == ID); - - if (CurBuildings && urgency == URGENCY_CRITICAL) { - Fire_Sale(); - Do_All_To_Hunt(); - return(true); - } - return(false); -} - -/* -** Given the specified urgency, build an engineer. -*/ -bool HouseClass::AI_Build_Engineer(UrgencyType ) const -{ - //assert(Houses.ID(this) == ID); - - return(false); -} - -/* -** Given the specified urgency, sell of some power since -** there appears to be excess. -*/ -bool HouseClass::AI_Lower_Power(UrgencyType ) const -{ - //assert(Houses.ID(this) == ID); - - BuildingClass * b = Find_Building(STRUCT_POWER); - if (b != NULL) { - b->Sell_Back(1); - return(true); - } - - b = Find_Building(STRUCT_ADVANCED_POWER); - if (b != NULL) { - b->Sell_Back(1); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::AI_Raise_Power -- Try to raise power levels by selling off buildings. * - * * - * This routine is called when the computer needs to raise power by selling off buildings. * - * Usually this occurs because of some catastrophe that has lowered power levels to * - * the danger zone. * - * * - * INPUT: urgency -- The urgency that the power needs to be raised. This controls what * - * buildings will be sold. * - * * - * OUTPUT: bool; Was a building sold to raise power? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/02/1996 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::AI_Raise_Power(UrgencyType urgency) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** Sell off structures in this order. - */ -#if (0) - static struct { - StructType Structure; - UrgencyType Urgency; - } _types[] = { - {STRUCT_CHRONOSPHERE, URGENCY_LOW}, - {STRUCT_SHIP_YARD, URGENCY_LOW}, - {STRUCT_SUB_PEN, URGENCY_LOW}, - {STRUCT_ADVANCED_TECH, URGENCY_LOW}, - {STRUCT_FORWARD_COM, URGENCY_LOW}, - {STRUCT_SOVIET_TECH, URGENCY_LOW}, - {STRUCT_IRON_CURTAIN, URGENCY_MEDIUM}, - {STRUCT_RADAR, URGENCY_MEDIUM}, - {STRUCT_REPAIR, URGENCY_MEDIUM}, - {STRUCT_TESLA, URGENCY_HIGH} - }; -#endif - static struct { - StructType Structure; - UrgencyType Urgency; - } _types[] = { - {STRUCT_BIO_LAB, URGENCY_LOW}, - {STRUCT_EYE, URGENCY_MEDIUM}, - {STRUCT_RADAR, URGENCY_MEDIUM}, - {STRUCT_REPAIR, URGENCY_MEDIUM}, - {STRUCT_OBELISK, URGENCY_HIGH}, - {STRUCT_TURRET, URGENCY_HIGH}, - {STRUCT_ATOWER, URGENCY_HIGH}, - {STRUCT_GTOWER, URGENCY_HIGH} - }; - - - /* - ** Find a structure to sell and then sell it. Bail from further scanning until - ** the next time. - */ - for (int i = 0; i < ARRAY_SIZE(_types); i++) { - if (urgency >= _types[i].Urgency) { - BuildingClass * b = Find_Building(_types[i].Structure); - if (b != NULL) { - b->Sell_Back(1); - return(true); - } - } - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::AI_Raise_Money -- Raise emergency cash by selling buildings. * - * * - * This routine handles the situation where the computer desperately needs cash but cannot * - * wait for normal harvesting to raise it. Buildings must be sold. * - * * - * INPUT: urgency -- The urgency level that cash must be raised. The greater the urgency, * - * the more important the buildings that can be sold become. * - * * - * OUTPUT: bool; Was a building sold to raise cash? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/02/1996 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::AI_Raise_Money(UrgencyType urgency) const -{ - //assert(Houses.ID(this) == ID); - - /* - ** Sell off structures in this order. - */ -#if (0) - static struct { - StructType Structure; - UrgencyType Urgency; - } _types[] = { - {STRUCT_CHRONOSPHERE, URGENCY_LOW}, - {STRUCT_SHIP_YARD, URGENCY_LOW}, - {STRUCT_SUB_PEN, URGENCY_LOW}, - {STRUCT_ADVANCED_TECH, URGENCY_LOW}, - {STRUCT_FORWARD_COM, URGENCY_LOW}, - {STRUCT_SOVIET_TECH, URGENCY_LOW}, - {STRUCT_STORAGE,URGENCY_LOW}, - {STRUCT_REPAIR,URGENCY_LOW}, - {STRUCT_TESLA,URGENCY_MEDIUM}, - {STRUCT_HELIPAD,URGENCY_MEDIUM}, - {STRUCT_POWER,URGENCY_HIGH}, - {STRUCT_AIRSTRIP,URGENCY_HIGH}, -// {STRUCT_WEAP,URGENCY_HIGH}, -// {STRUCT_BARRACKS,URGENCY_HIGH}, -// {STRUCT_TENT,URGENCY_HIGH}, - {STRUCT_CONST,URGENCY_CRITICAL} - }; -#endif - - static struct { - StructType Structure; - UrgencyType Urgency; - } _types[] = { - {STRUCT_BIO_LAB, URGENCY_LOW}, - {STRUCT_EYE, URGENCY_MEDIUM}, - {STRUCT_RADAR, URGENCY_MEDIUM}, - {STRUCT_STORAGE,URGENCY_LOW}, - {STRUCT_REPAIR, URGENCY_MEDIUM}, - {STRUCT_OBELISK, URGENCY_HIGH}, - {STRUCT_TURRET, URGENCY_HIGH}, - {STRUCT_ATOWER, URGENCY_HIGH}, - {STRUCT_GTOWER, URGENCY_HIGH}, - {STRUCT_HELIPAD,URGENCY_MEDIUM}, - {STRUCT_POWER,URGENCY_HIGH}, - {STRUCT_AIRSTRIP,URGENCY_HIGH}, - {STRUCT_CONST,URGENCY_CRITICAL} - }; - - - - BuildingClass * b = 0; - - /* - ** Find a structure to sell and then sell it. Bail from further scanning until - ** the next time. - */ - for (int i = 0; i < ARRAY_SIZE(_types); i++) { - if (urgency >= _types[i].Urgency) { - b = Find_Building(_types[i].Structure); - if (b != NULL) { - b->Sell_Back(1); - return(true); - } - } - } - return(false); -} - - -#ifdef NEVER - -/*********************************************************************************************** - * HouseClass::AI_Base_Defense -- Handles maintaining a strong base defense. * - * * - * This logic is used to maintain a base defense. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::AI_Base_Defense(void) -{ - //assert(Houses.ID(this) == ID); - - /* - ** Check to find if any zone of the base is over defended. Such zones should have - ** some of their defenses sold off to make better use of the money. - */ - - /* - ** Make sure that the core defense is only about 1/2 of the perimeter defense average. - */ - int average = 0; - for (ZoneType z = ZONE_NORTH; z < ZONE_COUNT; z++) { - average += ZoneInfo[z].AirDefense; - average += ZoneInfo[z].ArmorDefense; - average += ZoneInfo[z].InfantryDefense; - } - average /= (ZONE_COUNT-ZONE_NORTH); - - /* - ** If the core value is greater than the average, then sell off some of the - ** inner defensive structures. - */ - int core = ZoneInfo[ZONE_CORE].AirDefense + ZoneInfo[ZONE_CORE].ArmorDefense + ZoneInfo[ZONE_CORE].InfantryDefense; - if (core >= average) { - static StructType _stype[] = { - STRUCT_GTOWER, - STRUCT_TURRET, - STRUCT_ATOWER, - STRUCT_OBELISK, - STRUCT_TESLA, - STRUCT_SAM - }; - BuildingClass * b; - - for (int index = 0; index < sizeof(_stype)/sizeof(_stype[0]); index++) { - b = Find_Building(_stype[index], ZONE_CORE); - if (b) { - b->Sell_Back(1); - break; - } - } - } - - /* - ** If the enemy doesn't have any offensive air capability, then sell off any - ** SAM sites. Only do this when money is moderately low. - */ - if (Available_Money() < 1000 && (ActiveBScan & STRUCTF_SAM)) { - - /* - ** Scan to find if ANY human opponents have aircraft or a helipad. If one - ** is found then consider that opponent to have a valid air threat potential. - ** Don't sell off SAM sites in that case. - */ - bool nothreat = true; - for (HousesType h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { - HouseClass * house = HouseClass::As_Pointer(h); - - if (house && house->IsActive && house->IsHuman && !Is_Ally(house)) { - if ((house->ActiveAScan & (AIRCRAFTF_ORCA|AIRCRAFTF_TRANSPORT|AIRCRAFTF_HELICOPTER)) || (house->ActiveBScan & STRUCTF_HELIPAD)) { - nothreat = false; - break; - } - } - } - } - - return(TICKS_PER_SECOND*5); -} -#endif - - -/*********************************************************************************************** - * HouseClass::AI_Building -- Determines what building to build. * - * * - * This routine handles the general case of determining what building to build next. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - * 11/03/1996 JLB : Tries to match aircraft of enemy * - *=============================================================================================*/ -int HouseClass::AI_Building(void) -{ - //assert(Houses.ID(this) == ID); - - if (BuildStructure != STRUCT_NONE) return(TICKS_PER_SECOND); - -#if (0) // Not used for GAME_NORMAL in C&C. ST - 7/23/2019 3:04PM - if (Session.Type == GAME_NORMAL && Base.House == Class->House) { - BaseNodeClass * node = Base.Next_Buildable(); - if (node) { - BuildStructure = node->Type; - } - } -#endif - - if (IsBaseBuilding) { - /* - ** Don't suggest anything to build if the base is already big enough. - */ - unsigned int quant = 0; - for (HousesType h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { - HouseClass const * hptr = HouseClass::As_Pointer(h); - - if (hptr != NULL && hptr->IsActive && hptr->IsHuman && quant < hptr->CurBuildings) { - quant = hptr->CurBuildings; - } - } - quant += Rule.BaseSizeAdd; - -// TCTC -- Should multiply largest player base by some rational number. -// if (CurBuildings >= quant) return(TICKS_PER_SECOND); - - BuildChoice.Free_All(); - BuildChoiceClass * choiceptr; - StructType stype = STRUCT_NONE; - int money = Available_Money(); - //int level = Control.TechLevel; - bool hasincome = (BQuantity[STRUCT_REFINERY] > 0 && !IsTiberiumShort && UQuantity[UNIT_HARVESTER] > 0); - BuildingTypeClass const * b = NULL; - HouseClass const * enemy = NULL; - if (Enemy != HOUSE_NONE) { - enemy = HouseClass::As_Pointer(Enemy); - } - - //level = Control.TechLevel; - - /* - ** Try to build a power plant if there is insufficient power and there is enough - ** money available. - */ - b = &BuildingTypeClass::As_Reference(STRUCT_ADVANCED_POWER); - if (Can_Build(b, ActLike) && Power <= Drain+Rule.PowerSurplus && b->Cost_Of() < money) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(BQuantity[STRUCT_REFINERY] == 0 ? URGENCY_LOW : URGENCY_MEDIUM, b->Type); - } - } else { - b = &BuildingTypeClass::As_Reference(STRUCT_POWER); - if (Can_Build(b, ActLike) && Power <= Drain+Rule.PowerSurplus && b->Cost_Of() < money) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(BQuantity[STRUCT_REFINERY] == 0 ? URGENCY_LOW : URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** Build a refinery if there isn't one already available. - */ - unsigned int current = BQuantity[STRUCT_REFINERY]; - if (!IsTiberiumShort && current < Round_Up(Rule.RefineryRatio*fixed(CurBuildings)) && current < (unsigned)Rule.RefineryLimit) { - b = &BuildingTypeClass::As_Reference(STRUCT_REFINERY); - if (Can_Build(b, ActLike) && (money > b->Cost_Of() || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(BQuantity[STRUCT_REFINERY] == 0 ? URGENCY_HIGH : URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** Always make sure there is a barracks available, but only if there - ** will be sufficient money to train troopers. - */ - //current = BQuantity[STRUCT_BARRACKS] + BQuantity[STRUCT_TENT]; - current = BQuantity[STRUCT_BARRACKS] + BQuantity[STRUCT_HAND]; - if (current < Round_Up(Rule.BarracksRatio*fixed(CurBuildings)) && current < (unsigned)Rule.BarracksLimit && (money > 300 || hasincome)) { - b = &BuildingTypeClass::As_Reference(STRUCT_BARRACKS); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(current > 0 ? URGENCY_LOW : URGENCY_MEDIUM, b->Type); - } - } else { - //b = &BuildingTypeClass::As_Reference(STRUCT_TENT); - b = &BuildingTypeClass::As_Reference(STRUCT_HAND); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(current > 0 ? URGENCY_LOW : URGENCY_MEDIUM, b->Type); - } - } - } - } -#if (0) - /* - ** Try to build one dog house. - */ - current = BQuantity[STRUCT_KENNEL]; - if (current < 1 && (money > 300 || hasincome)) { - b = &BuildingTypeClass::As_Reference(STRUCT_KENNEL); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** Try to build one gap generator. - */ - current = BQuantity[STRUCT_GAP]; - if (current < 1 && Power_Fraction() >= 1 && hasincome) { - b = &BuildingTypeClass::As_Reference(STRUCT_GAP); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } - } -#endif - /* - ** A source of combat vehicles is always needed, but only if there will - ** be sufficient money to build vehicles. - */ - current = BQuantity[STRUCT_WEAP]; - if (current < Round_Up(Rule.WarRatio*fixed(CurBuildings)) && current < (unsigned)Rule.WarLimit && (money > 2000 || hasincome)) { - b = &BuildingTypeClass::As_Reference(STRUCT_WEAP); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(current > 0 ? URGENCY_LOW : URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** Always build up some base defense. - */ - //current = BQuantity[STRUCT_PILLBOX] + BQuantity[STRUCT_CAMOPILLBOX] + BQuantity[STRUCT_TURRET] + BQuantity[STRUCT_FLAME_TURRET]; - current = BQuantity[STRUCT_TURRET] + BQuantity[STRUCT_OBELISK]; - if (current < Round_Up(Rule.DefenseRatio*fixed(CurBuildings)) && current < (unsigned)Rule.DefenseLimit) { - //b = &BuildingTypeClass::As_Reference(STRUCT_FLAME_TURRET); - b = &BuildingTypeClass::As_Reference(STRUCT_OBELISK); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } else { - //if (Percent_Chance(50)) { - //b = &BuildingTypeClass::As_Reference(STRUCT_PILLBOX); - b = &BuildingTypeClass::As_Reference(STRUCT_TURRET); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } -#if (0) - } else { - b = &BuildingTypeClass::As_Reference(STRUCT_TURRET); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } - } -#endif - } - } - - /* - ** Build some air defense. - */ - //current = BQuantity[STRUCT_SAM] + BQuantity[STRUCT_AAGUN]; - current = BQuantity[STRUCT_SAM]; - if (current < Round_Up(Rule.AARatio*fixed(CurBuildings)) && current < (unsigned)Rule.AALimit) { - - /* - ** Building air defense only makes sense if the opponent has aircraft - ** of some kind. - */ - bool airthreat = false; - int threat_quantity = 0; - if (enemy != NULL && enemy->AScan != 0) { - airthreat = true; - threat_quantity = enemy->CurAircraft; - } - if (!airthreat) { - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - HouseClass * h = HouseClass::As_Pointer(house); - if (h != NULL && !Is_Ally(house) && h->AScan != 0) { - airthreat = true; - break; - } - } - } - - if (airthreat) { - - if (BQuantity[STRUCT_RADAR] == 0) { - b = &BuildingTypeClass::As_Reference(STRUCT_RADAR); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_HIGH, b->Type); - } - } - } - - b = &BuildingTypeClass::As_Reference(STRUCT_SAM); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass((current < (unsigned)threat_quantity) ? URGENCY_HIGH : URGENCY_MEDIUM, b->Type); - } - } else { -#if (0) - b = &BuildingTypeClass::As_Reference(STRUCT_AAGUN); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass((current < (unsigned)threat_quantity) ? URGENCY_HIGH : URGENCY_MEDIUM, b->Type); - } - } -#endif - } - } - } - - -#if (0) - /* - ** Advanced base defense would be good. - */ - current = BQuantity[STRUCT_TESLA]; - if (current < Round_Up(Rule.TeslaRatio*fixed(CurBuildings)) && current < (unsigned)Rule.TeslaLimit) { - b = &BuildingTypeClass::As_Reference(STRUCT_TESLA); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome) && Power_Fraction() >= 1) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** Build a tech center as soon as possible. - */ - current = BQuantity[STRUCT_ADVANCED_TECH] + BQuantity[STRUCT_SOVIET_TECH]; - if (current < 1) { - b = &BuildingTypeClass::As_Reference(STRUCT_ADVANCED_TECH); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome) && Power_Fraction() >= 1) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } else { - b = &BuildingTypeClass::As_Reference(STRUCT_SOVIET_TECH); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome) && Power_Fraction() >= 1) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - *choiceptr = BuildChoiceClass(URGENCY_MEDIUM, b->Type); - } - } - } - } -#endif - - /* - ** A helipad would be good. - */ - current = BQuantity[STRUCT_HELIPAD]; - if (current < Round_Up(Rule.HelipadRatio*fixed(CurBuildings)) && current < (unsigned)Rule.HelipadLimit) { - b = &BuildingTypeClass::As_Reference(STRUCT_HELIPAD); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - int threat_quantity = 0; - if (enemy != NULL) { - threat_quantity = enemy->CurAircraft; - } - - *choiceptr = BuildChoiceClass((CurAircraft < (unsigned)threat_quantity) ? URGENCY_HIGH : URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** An airstrip would be good. - */ - current = BQuantity[STRUCT_AIRSTRIP]; - if (current < Round_Up(Rule.AirstripRatio*fixed(CurBuildings)) && current < (unsigned)Rule.AirstripLimit) { - b = &BuildingTypeClass::As_Reference(STRUCT_AIRSTRIP); - if (Can_Build(b, ActLike) && (b->Cost_Of() < money || hasincome)) { - choiceptr = BuildChoice.Alloc(); - if (choiceptr != NULL) { - int threat_quantity = 0; - if (enemy != NULL) { - threat_quantity = enemy->CurAircraft; - } - - *choiceptr = BuildChoiceClass((CurAircraft < (unsigned)threat_quantity) ? URGENCY_HIGH : URGENCY_MEDIUM, b->Type); - } - } - } - - /* - ** Pick the choice that is the most urgent. - */ - UrgencyType best = URGENCY_NONE; - int bestindex; - for (int index = 0; index < BuildChoice.Count(); index++) { - if (BuildChoice.Ptr(index)->Urgency > best) { - bestindex = index; - best = BuildChoice.Ptr(index)->Urgency; - } - } - if (best != URGENCY_NONE) { - BuildStructure = BuildChoice.Ptr(bestindex)->Structure; - } - } - - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * HouseClass::AI_Unit -- Determines what unit to build next. * - * * - * This routine handles the general case of determining what units to build next. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of games frames to delay before calling this routine again.* - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::AI_Unit(void) -{ - //assert(Houses.ID(this) == ID); - - if (BuildUnit != UNIT_NONE) return(TICKS_PER_SECOND); - if (CurUnits >= Control.MaxUnit) return(TICKS_PER_SECOND); - - /* - ** A computer controlled house will try to build a replacement - ** harvester if possible. - */ - if (IQ >= Rule.IQHarvester && !IsTiberiumShort && !IsHuman && BQuantity[STRUCT_REFINERY] > UQuantity[UNIT_HARVESTER] && Difficulty != DIFF_HARD) { - //if (UnitTypeClass::As_Reference(UNIT_HARVESTER).Level <= (unsigned)Control.TechLevel) { - if (UnitTypeClass::As_Reference(UNIT_HARVESTER).Level <= (unsigned)BuildLevel) { - BuildUnit = UNIT_HARVESTER; - return(TICKS_PER_SECOND); - } - } - - //if (Session.Type == GAME_NORMAL) { // Why? ST - 7/24/2019 2:38PM - - int counter[UNIT_COUNT]; - memset(counter, 0x00, sizeof(counter)); - - /* - ** Build a list of the maximum of each type we wish to produce. This will be - ** twice the number required to fill all teams. - */ - int index; - for (index = 0; index < Teams.Count(); index++) { - TeamClass * tptr = Teams.Ptr(index); - if (tptr != NULL) { - TeamTypeClass const * team = tptr->Class; - //if (((team->IsReinforcable && !tptr->IsFullStrength) || (!tptr->IsForcedActive && !tptr->IsHasBeen && !tptr->JustAltered)) && team->House == Class->House) { - if (((team->IsReinforcable && !tptr->IsFullStrength) || (!tptr->IsForcedActive && !tptr->IsHasBeen && !tptr->IsAltered)) && team->House == Class->House) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - //TechnoTypeClass const * memtype = team->Members[subindex].Class; - TechnoTypeClass const * memtype = team->Class[subindex]; - if (memtype->What_Am_I() == RTTI_UNITTYPE) { - counter[((UnitTypeClass const *)memtype)->Type] = 1; - } - } - } - } - } - - /* - ** Team types that are flagged as prebuilt, will always try to produce enough - ** to fill one team of this type regardless of whether there is a team active - ** of that type. - */ - for (index = 0; index < TeamTypes.Count(); index++) { - TeamTypeClass const * team = TeamTypes.Ptr(index); - if (team != NULL && team->House == Class->House && team->IsPrebuilt && (!team->IsAutocreate || IsAlerted)) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - //TechnoTypeClass const * memtype = team->Members[subindex].Class; - TechnoTypeClass const * memtype = team->Class[subindex]; - - if (memtype->What_Am_I() == RTTI_UNITTYPE) { - int subtype = ((UnitTypeClass const *)memtype)->Type; - //counter[subtype] = max(counter[subtype], team->Members[subindex].Quantity); - counter[subtype] = max(counter[subtype], 1); - } - } - } - } - - /* - ** Reduce the theoretical maximum by the actual number of objects currently - ** in play. - */ - for (int uindex = 0; uindex < Units.Count(); uindex++) { - UnitClass * unit = Units.Ptr(uindex); - //if (unit != NULL && unit->Is_Recruitable(this) && counter[unit->Class->Type] > 0) { - if (unit != NULL && counter[unit->Class->Type] > 0) { - counter[unit->Class->Type]--; - } - } - - /* - ** Pick to build the most needed object but don't consider those objects that - ** can't be built because of scenario restrictions or insufficient cash. - */ - int bestval = -1; - int bestcount = 0; - UnitType bestlist[UNIT_COUNT]; - for (UnitType utype = UNIT_FIRST; utype < UNIT_COUNT; utype++) { - if (counter[utype] > 0 && Can_Build(&UnitTypeClass::As_Reference(utype), Class->House) && UnitTypeClass::As_Reference(utype).Cost_Of() <= Available_Money()) { - if (bestval == -1 || bestval < counter[utype]) { - bestval = counter[utype]; - bestcount = 0; - } - bestlist[bestcount++] = utype; - } - } - - /* - ** The unit type to build is now known. Fetch a pointer to the techno type class. - */ - if (bestcount) { - BuildUnit = bestlist[Random_Pick(0, bestcount-1)]; - } - //} - - if (IsBaseBuilding) { - - int counter[UNIT_COUNT]; - int total = 0; - UnitType index; - for (index = UNIT_FIRST; index < UNIT_COUNT; index++) { - UnitTypeClass const * utype = &UnitTypeClass::As_Reference(index); - if (Can_Build(utype, ActLike) && utype->Type != UNIT_HARVESTER) { - //if (utype->PrimaryWeapon != NULL) { - if (utype->Primary != WEAPON_NONE) { - counter[index] = 20; - } else { - counter[index] = 1; - } - } else { - counter[index] = 0; - } - total += counter[index]; - } - - if (total > 0) { - int choice = Random_Pick(0, total-1); - for (index = UNIT_FIRST; index < UNIT_COUNT; index++) { - if (choice < counter[index]) { - BuildUnit = index; - break; - } - choice -= counter[index]; - } - } - } - - return(TICKS_PER_SECOND); -} - - -int HouseClass::AI_Vessel(void) -{ -#if (0) - //assert(Houses.ID(this) == ID); - if (BuildVessel != VESSEL_NONE) return(TICKS_PER_SECOND); - - if (CurVessels >= Control.MaxVessel) { - return(TICKS_PER_SECOND); - } - - if (Session.Type == GAME_NORMAL) { - - int counter[VESSEL_COUNT]; - if (Session.Type == GAME_NORMAL) { - memset(counter, 0x00, sizeof(counter)); - } else { - for (VesselType index = VESSEL_FIRST; index < VESSEL_COUNT; index++) { - //if (Can_Build(&VesselTypeClass::As_Reference(index), Class->House) && VesselTypeClass::As_Reference(index).Level <= (unsigned)Control.TechLevel) { - if (Can_Build(&VesselTypeClass::As_Reference(index), Class->House) && VesselTypeClass::As_Reference(index).Level <= (unsigned)BuildLevel) { - counter[index] = 16; - } else { - counter[index] = 0; - } - } - } - - /* - ** Build a list of the maximum of each type we wish to produce. This will be - ** twice the number required to fill all teams. - */ - int index; - for (index = 0; index < Teams.Count(); index++) { - TeamClass * tptr = Teams.Ptr(index); - if (tptr) { - TeamTypeClass const * team = tptr->Class; - - //if (((team->IsReinforcable && !tptr->IsFullStrength) || (!tptr->IsForcedActive && !tptr->IsHasBeen && !tptr->JustAltered)) && team->House == Class->House) { - if (((team->IsReinforcable && !tptr->IsFullStrength) || (!tptr->IsForcedActive && !tptr->IsHasBeen && !tptr->IsAltered)) && team->House == Class->House) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Members[subindex].Class->What_Am_I() == RTTI_VESSELTYPE) { - counter[((VesselTypeClass const *)(team->Members[subindex].Class))->Type] = 1; - } - } - } - } - } - - /* - ** Team types that are flagged as prebuilt, will always try to produce enough - ** to fill one team of this type regardless of whether there is a team active - ** of that type. - */ - for (index = 0; index < TeamTypes.Count(); index++) { - TeamTypeClass const * team = TeamTypes.Ptr(index); - if (team) { - if (team->House == Class->House && team->IsPrebuilt && (!team->IsAutocreate || IsAlerted)) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Members[subindex].Class->What_Am_I() == RTTI_VESSELTYPE) { - int subtype = ((VesselTypeClass const *)(team->Members[subindex].Class))->Type; - //counter[subtype] = max(counter[subtype], team->Members[subindex].Quantity); - counter[subtype] = max(counter[subtype], 1); - } - } - } - } - } - - /* - ** Reduce the theoretical maximum by the actual number of objects currently - ** in play. - */ - for (int vindex = 0; vindex < Vessels.Count(); vindex++) { - VesselClass * unit = Vessels.Ptr(vindex); - //if (unit != NULL && unit->Is_Recruitable(this) && counter[unit->Class->Type] > 0) { - if (unit != NULL && counter[unit->Class->Type] > 0) { - counter[unit->Class->Type]--; - } - } - - /* - ** Pick to build the most needed object but don't consider those object that - ** can't be built because of scenario restrictions or insufficient cash. - */ - int bestval = -1; - int bestcount = 0; - VesselType bestlist[VESSEL_COUNT]; - for (VesselType utype = VESSEL_FIRST; utype < VESSEL_COUNT; utype++) { - if (counter[utype] > 0 && Can_Build(&VesselTypeClass::As_Reference(utype), Class->House) && VesselTypeClass::As_Reference(utype).Cost_Of() <= Available_Money()) { - if (bestval == -1 || bestval < counter[utype]) { - bestval = counter[utype]; - bestcount = 0; - } - bestlist[bestcount++] = utype; - } - } - - /* - ** The unit type to build is now known. Fetch a pointer to the techno type class. - */ - if (bestcount) { - BuildVessel = bestlist[Random_Pick(0, bestcount-1)]; - } - } - - if (IsBaseBuilding) { - BuildVessel = VESSEL_NONE; - } -#endif - return(TICKS_PER_SECOND); -} - - - -/*********************************************************************************************** - * HouseClass::AI_Infantry -- Determines the infantry unit to build. * - * * - * This routine handles the general case of determining what infantry unit to build * - * next. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before being called again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::AI_Infantry(void) -{ - //assert(Houses.ID(this) == ID); - - if (BuildInfantry != INFANTRY_NONE) return(TICKS_PER_SECOND); - if (CurInfantry >= Control.MaxInfantry) return(TICKS_PER_SECOND); - - //if (Session.Type == GAME_NORMAL) { - if (GameToPlay == GAME_NORMAL) { // Not used for skirmish? ST - 7/24/2019 2:59PM -#if (0) - TechnoTypeClass const * techno = 0; - int counter[INFANTRY_COUNT]; - memset(counter, 0x00, sizeof(counter)); - - /* - ** Build a list of the maximum of each type we wish to produce. This will be - ** twice the number required to fill all teams. - */ - int index; - for (index = 0; index < Teams.Count(); index++) { - TeamClass * tptr = Teams.Ptr(index); - if (tptr != NULL) { - TeamTypeClass const * team = tptr->Class; - - //if (((team->IsReinforcable && !tptr->IsFullStrength) || (!tptr->IsForcedActive && !tptr->IsHasBeen && !tptr->JustAltered)) && team->House == Class->House) { - if (((team->IsReinforcable && !tptr->IsFullStrength) || (!tptr->IsForcedActive && !tptr->IsHasBeen && !tptr->IsAltered)) && team->House == Class->House) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Members[subindex].Class->What_Am_I() == RTTI_INFANTRYTYPE) { - //counter[((InfantryTypeClass const *)(team->Members[subindex].Class))->Type] += team->Members[subindex].Quantity + (team->IsReinforcable ? 1 : 0); - counter[((InfantryTypeClass const *)(team->Members[subindex].Class))->Type] += 1 + (team->IsReinforcable ? 1 : 0); - } - } - } - } - } - - /* - ** Team types that are flagged as prebuilt, will always try to produce enough - ** to fill one team of this type regardless of whether there is a team active - ** of that type. - */ - for (index = 0; index < TeamTypes.Count(); index++) { - TeamTypeClass const * team = TeamTypes.Ptr(index); - if (team != NULL) { - if (team->House == Class->House && team->IsPrebuilt && (!team->IsAutocreate || IsAlerted)) { - for (int subindex = 0; subindex < team->ClassCount; subindex++) { - if (team->Members[subindex].Class->What_Am_I() == RTTI_INFANTRYTYPE) { - int subtype = ((InfantryTypeClass const *)(team->Members[subindex].Class))->Type; -// counter[subtype] = 1; - //counter[subtype] = max(counter[subtype], team->Members[subindex].Quantity); - counter[subtype] = max(counter[subtype], 1); - counter[subtype] = min(counter[subtype], 5); - } - } - } - } - } - - /* - ** Reduce the theoretical maximum by the actual number of objects currently - ** in play. - */ - for (int uindex = 0; uindex < Infantry.Count(); uindex++) { - InfantryClass * infantry = Infantry.Ptr(uindex); - //if (infantry != NULL && infantry->Is_Recruitable(this) && counter[infantry->Class->Type] > 0) { - if (infantry != NULL && counter[infantry->Class->Type] > 0) { - counter[infantry->Class->Type]--; - } - } - - /* - ** Pick to build the most needed object but don't consider those object that - ** can't be built because of scenario restrictions or insufficient cash. - */ - int bestval = -1; - int bestcount = 0; - InfantryType bestlist[INFANTRY_COUNT]; - for (InfantryType utype = INFANTRY_FIRST; utype < INFANTRY_COUNT; utype++) { - - if (utype != INFANTRY_DOG || !(IScan & INFANTRYF_DOG)) { - if (counter[utype] > 0 && Can_Build(&InfantryTypeClass::As_Reference(utype), Class->House) && InfantryTypeClass::As_Reference(utype).Cost_Of() <= Available_Money()) { - if (bestval == -1 || bestval < counter[utype]) { - bestval = counter[utype]; - bestcount = 0; - } - bestlist[bestcount++] = utype; - } - } - } - - /* - ** The infantry type to build is now known. Fetch a pointer to the techno type class. - */ - if (bestcount) { - int pick = Random_Pick(0, bestcount-1); - BuildInfantry = bestlist[pick]; - } -#endif - } - - if (IsBaseBuilding) { - HouseClass const * enemy = NULL; - if (Enemy != HOUSE_NONE) { - enemy = HouseClass::As_Pointer(Enemy); - } - - /* - ** This structure is used to keep track of the list of infantry types that should be - ** built. The infantry type and the value assigned to it is recorded. - */ - struct { - InfantryType Type; // Infantry type. - int Value; // Relative value assigned. - } typetrack[INFANTRY_COUNT]; - int count = 0; - int total = 0; - for (InfantryType index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - //if (Can_Build(&InfantryTypeClass::As_Reference(index), ActLike) && InfantryTypeClass::As_Reference(index).Level <= (unsigned)Control.TechLevel) { - if (Can_Build(&InfantryTypeClass::As_Reference(index), ActLike) && InfantryTypeClass::As_Reference(index).Level <= (unsigned)BuildLevel) { - typetrack[count].Value = 0; -#ifdef FIXIT_CSII // checked - ajw 9/28/98 This looks like a potential bug. It is prob. for save game format compatibility. - int clipindex = index; - if (clipindex >= INFANTRY_RA_COUNT) clipindex -= INFANTRY_RA_COUNT; - if ((enemy != NULL && enemy->IQuantity[clipindex] > IQuantity[clipindex]) || Available_Money() > Rule.InfantryReserve || CurInfantry < CurBuildings * Rule.InfantryBaseMult) { -#else - if ((enemy != NULL && enemy->IQuantity[index] > IQuantity[index]) || Available_Money() > Rule.InfantryReserve || CurInfantry < CurBuildings * Rule.InfantryBaseMult) { -#endif - - switch (index) { - case INFANTRY_E1: - typetrack[count].Value = 3; - break; - - case INFANTRY_E2: - typetrack[count].Value = 5; - break; - - case INFANTRY_E3: - typetrack[count].Value = 2; - break; - - case INFANTRY_E4: - typetrack[count].Value = 5; - break; - - //case INFANTRY_RENOVATOR: - case INFANTRY_E7: - if (CurInfantry > 5) { - typetrack[count].Value = 1 - max(IQuantity[index], 0); - } - break; - - //case INFANTRY_TANYA: - // typetrack[count].Value = 1 - max(IQuantity[index], 0); - // break; - - default: - typetrack[count].Value = 0; - break; - } - } - - if (typetrack[count].Value > 0) { - typetrack[count].Type = index; - total += typetrack[count].Value; - count++; - } - } - } - - /* - ** If there is at least one choice, then pick it. The object picked - ** is influenced by the weight (value) assigned to it. This is accomplished - ** by picking a number between 0 and the total weight value. The appropriate - ** infantry object that matches the number picked is then selected to be built. - */ - if (count > 0) { - int pick = Random_Pick(0, total-1); - for (int index = 0; index < count; index++) { - if (pick < typetrack[index].Value) { - BuildInfantry = typetrack[index].Type; - break; - } - pick -= typetrack[index].Value; - } - } - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * HouseClass::AI_Aircraft -- Determines what aircraft to build next. * - * * - * This routine is used to determine the general case of what aircraft to build next. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of frame to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -int HouseClass::AI_Aircraft(void) -{ - //assert(Houses.ID(this) == ID); - - if (!IsHuman && IQ >= Rule.IQAircraft) { - if (BuildAircraft != AIRCRAFT_NONE) return(TICKS_PER_SECOND); - if (CurAircraft >= Control.MaxAircraft) return(TICKS_PER_SECOND); - - if (Can_Build(&AircraftTypeClass::As_Reference(AIRCRAFT_HELICOPTER), ActLike) && - //AircraftTypeClass::As_Reference(AIRCRAFT_MIG).Level <= (unsigned)Control.TechLevel && - AircraftTypeClass::As_Reference(AIRCRAFT_HELICOPTER).Level <= (unsigned)BuildLevel && - BQuantity[STRUCT_AIRSTRIP] > AQuantity[AIRCRAFT_HELICOPTER] + AQuantity[AIRCRAFT_ORCA]) { - BuildAircraft = AIRCRAFT_HELICOPTER; - return(TICKS_PER_SECOND); - } - - if (Can_Build(&AircraftTypeClass::As_Reference(AIRCRAFT_ORCA), ActLike) && - //AircraftTypeClass::As_Reference(AIRCRAFT_YAK).Level <= (unsigned)Control.TechLevel && - AircraftTypeClass::As_Reference(AIRCRAFT_ORCA).Level <= (unsigned)BuildLevel && - BQuantity[STRUCT_AIRSTRIP] > AQuantity[AIRCRAFT_ORCA] + AQuantity[AIRCRAFT_HELICOPTER]) { - BuildAircraft = AIRCRAFT_ORCA; - return(TICKS_PER_SECOND); - } - -#if (0) - if (Can_Build(&AircraftTypeClass::As_Reference(AIRCRAFT_LONGBOW), ActLike) && - //AircraftTypeClass::As_Reference(AIRCRAFT_LONGBOW).Level <= (unsigned)Control.TechLevel && - AircraftTypeClass::As_Reference(AIRCRAFT_LONGBOW).Level <= (unsigned)BuildLevel && - BQuantity[STRUCT_HELIPAD] > AQuantity[AIRCRAFT_LONGBOW] + AQuantity[AIRCRAFT_HIND]) { - BuildAircraft = AIRCRAFT_LONGBOW; - return(TICKS_PER_SECOND); - } - - if (Can_Build(&AircraftTypeClass::As_Reference(AIRCRAFT_HIND), ActLike) && - //AircraftTypeClass::As_Reference(AIRCRAFT_HIND).Level <= (unsigned)Control.TechLevel && - AircraftTypeClass::As_Reference(AIRCRAFT_HIND).Level <= (unsigned)BuildLevel && - BQuantity[STRUCT_HELIPAD] > AQuantity[AIRCRAFT_LONGBOW] + AQuantity[AIRCRAFT_HIND]) { - BuildAircraft = AIRCRAFT_HIND; - return(TICKS_PER_SECOND); - } - - if (Can_Build(&AircraftTypeClass::As_Reference(AIRCRAFT_MIG), ActLike) && - //AircraftTypeClass::As_Reference(AIRCRAFT_MIG).Level <= (unsigned)Control.TechLevel && - AircraftTypeClass::As_Reference(AIRCRAFT_MIG).Level <= (unsigned)BuildLevel && - BQuantity[STRUCT_AIRSTRIP] > AQuantity[AIRCRAFT_MIG] + AQuantity[AIRCRAFT_YAK]) { - BuildAircraft = AIRCRAFT_MIG; - return(TICKS_PER_SECOND); - } - - if (Can_Build(&AircraftTypeClass::As_Reference(AIRCRAFT_YAK), ActLike) && - //AircraftTypeClass::As_Reference(AIRCRAFT_YAK).Level <= (unsigned)Control.TechLevel && - AircraftTypeClass::As_Reference(AIRCRAFT_YAK).Level <= (unsigned)BuildLevel && - BQuantity[STRUCT_AIRSTRIP] > AQuantity[AIRCRAFT_MIG] + AQuantity[AIRCRAFT_YAK]) { - BuildAircraft = AIRCRAFT_YAK; - return(TICKS_PER_SECOND); - } -#endif - } - - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * HouseClass::Production_Begun -- Records that production has begun. * - * * - * This routine is used to inform the Expert System that production of the specified object * - * has begun. This allows the AI to proceed with picking another object to begin production * - * on. * - * * - * INPUT: product -- Pointer to the object that production has just begun on. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Production_Begun(TechnoClass const * product) -{ - //assert(Houses.ID(this) == ID); - - if (product != NULL) { - switch (product->What_Am_I()) { - case RTTI_UNIT: - if (*((UnitClass*)product) == BuildUnit) { - BuildUnit = UNIT_NONE; - } - break; -#if (0) - case RTTI_VESSEL: - if (*((VesselClass*)product) == BuildVessel) { - BuildVessel = VESSEL_NONE; - } - break; -#endif - case RTTI_INFANTRY: - if (*((InfantryClass*)product) == BuildInfantry) { - BuildInfantry = INFANTRY_NONE; - } - break; - - case RTTI_BUILDING: - if (*((BuildingClass*)product) == BuildStructure) { - BuildStructure = STRUCT_NONE; - } - break; - - case RTTI_AIRCRAFT: - if (*((AircraftClass*)product) == BuildAircraft) { - BuildAircraft = AIRCRAFT_NONE; - } - break; - - default: - break; - } - } -} - - -/*********************************************************************************************** - * HouseClass::Tracking_Remove -- Remove object from house tracking system. * - * * - * This routine informs the Expert System that the specified object is no longer part of * - * this house's inventory. This occurs when the object is destroyed or captured. * - * * - * INPUT: techno -- Pointer to the object to remove from the tracking systems of this * - * house. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Tracking_Remove(TechnoClass const * techno) -{ - //assert(Houses.ID(this) == ID); - - int type; - - switch (techno->What_Am_I()) { - case RTTI_BUILDING: - CurBuildings--; - BQuantity[((BuildingTypeClass const &)techno->Class_Of()).Type]--; - break; - - case RTTI_AIRCRAFT: - CurAircraft--; - AQuantity[((AircraftTypeClass const &)techno->Class_Of()).Type]--; - break; - - case RTTI_INFANTRY: - CurInfantry--; - if (!((InfantryClass *)techno)->IsTechnician) { - type = ((InfantryTypeClass const &)techno->Class_Of()).Type; -#ifdef FIXIT_CSII // checked - ajw 9/28/98 - if (type >= INFANTRY_RA_COUNT) type -= INFANTRY_RA_COUNT; -#endif - IQuantity[type]--; - } - break; - - case RTTI_UNIT: - CurUnits--; - type = ((UnitTypeClass const &)techno->Class_Of()).Type; -#ifdef FIXIT_CSII // checked - ajw 9/28/98 - if (type >= UNIT_RA_COUNT) type -= UNIT_RA_COUNT; -#endif - UQuantity[type]--; - break; - -#if (0) - case RTTI_VESSEL: - CurVessels--; - type = ((VesselTypeClass const &)techno->Class_Of()).Type; -#ifdef FIXIT_CSII // checked - ajw 9/28/98 - if (type >= VESSEL_RA_COUNT) type -= VESSEL_RA_COUNT; -#endif - VQuantity[type]--; - break; -#endif - - default: - break; - } -} - - -/*********************************************************************************************** - * HouseClass::Tracking_Add -- Informs house of new inventory item. * - * * - * This function is called when the specified object is now available as part of the house's* - * inventory. This occurs when the object is newly produced and also when it is captured * - * by this house. * - * * - * INPUT: techno -- Pointer to the object that is now part of the house inventory. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/29/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Tracking_Add(TechnoClass const * techno) -{ - //assert(Houses.ID(this) == ID); - - StructType building; - AircraftType aircraft; - InfantryType infantry; - UnitType unit; - //VesselType vessel; - //int quant; - - switch (techno->What_Am_I()) { - case RTTI_BUILDING: - CurBuildings++; - building = ((BuildingTypeClass const &)techno->Class_Of()).Type; - BQuantity[building]++; - BScan |= (1L << building); -#if (0) // This is a stats thing. ST - 7/24/2019 3:08PM - if (Session.Type == GAME_INTERNET) { - BuildingTotals->Increment_Unit_Total(techno->Class_Of().ID); - } -#endif - break; - - case RTTI_AIRCRAFT: - CurAircraft++; - aircraft = ((AircraftTypeClass const &)techno->Class_Of()).Type; - AQuantity[aircraft]++; - AScan |= (1L << aircraft); -#if (0) // This is a stats thing. ST - 7/24/2019 3:08PM - if (Session.Type == GAME_INTERNET) { - AircraftTotals->Increment_Unit_Total(techno->Class_Of().ID); - } -#endif - break; - - case RTTI_INFANTRY: - CurInfantry++; - infantry = ((InfantryTypeClass const &)techno->Class_Of()).Type; - if (!((InfantryClass *)techno)->IsTechnician) { -#ifdef FIXIT_CSII // checked - ajw 9/28/98 - quant = infantry; - if (quant >= INFANTRY_RA_COUNT) quant -= INFANTRY_RA_COUNT; - IQuantity[quant]++; -#else - IQuantity[infantry]++; -#endif - -#if (0) // This is a stats thing. ST - 7/24/2019 3:08PM - if (!((InfantryTypeClass const &)techno->Class_Of()).IsCivilian && Session.Type == GAME_INTERNET) { - InfantryTotals->Increment_Unit_Total(techno->Class_Of().ID); - } -#endif - IScan |= (1L << infantry); - } - break; - - case RTTI_UNIT: - CurUnits++; - unit = ((UnitTypeClass const &)techno->Class_Of()).Type; -#ifdef FIXIT_CSII // checked - ajw 9/28/98 - quant = unit; - if (quant >= UNIT_RA_COUNT) quant -= UNIT_RA_COUNT; - UQuantity[quant]++; -#else - UQuantity[unit]++; -#endif - UScan |= (1L << unit); -#if (0) // This is a stats thing. ST - 7/24/2019 3:08PM - if (Session.Type == GAME_INTERNET) { - UnitTotals->Increment_Unit_Total(techno->Class_Of().ID); - } -#endif - break; - - -#if (0) - case RTTI_VESSEL: - CurVessels++; - vessel = ((VesselTypeClass const &)techno->Class_Of()).Type; -#ifdef FIXIT_CSII // checked - ajw 9/28/98 - quant = vessel; - if (quant >= VESSEL_RA_COUNT) quant -= VESSEL_RA_COUNT; - VQuantity[quant]++; -#else - VQuantity[vessel]++; -#endif - VScan |= (1L << vessel); - if (Session.Type == GAME_INTERNET) { - VesselTotals->Increment_Unit_Total(techno->Class_Of().ID); - } - break; -#endif - - default: - break; - } -} - - -/*********************************************************************************************** - * HouseClass::Factory_Counter -- Fetches a pointer to the factory counter value. * - * * - * Use this routine to fetch a pointer to the variable that holds the number of factories * - * that can produce the specified object type. This is a helper routine used when * - * examining the number of factories as well as adjusting their number. * - * * - * INPUT: rtti -- The RTTI of the object that could be produced. * - * * - * OUTPUT: Returns with the number of factories owned by this house that could produce the * - * object of the type specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/30/1996 JLB : Created. * - *=============================================================================================*/ -int * HouseClass::Factory_Counter(RTTIType rtti) -{ - switch (rtti) { - case RTTI_UNITTYPE: - case RTTI_UNIT: - return(&UnitFactories); -#if (0) - case RTTI_VESSELTYPE: - case RTTI_VESSEL: - return(&VesselFactories); -#endif - case RTTI_AIRCRAFTTYPE: - case RTTI_AIRCRAFT: - return(&AircraftFactories); - - case RTTI_INFANTRYTYPE: - case RTTI_INFANTRY: - return(&InfantryFactories); - - case RTTI_BUILDINGTYPE: - case RTTI_BUILDING: - return(&BuildingFactories); - - default: - break; - } - return(NULL); -} - - -/*********************************************************************************************** - * HouseClass::Active_Remove -- Remove this object from active duty for this house. * - * * - * This routine will recognize the specified object as having been removed from active * - * duty. * - * * - * INPUT: techno -- Pointer to the object to remove from active duty. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/16/1996 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Active_Remove(TechnoClass const * techno) -{ - if (techno == NULL) return; - - if (techno->What_Am_I() == RTTI_BUILDING) { - int * fptr = Factory_Counter(((BuildingClass *)techno)->Class->ToBuild); - if (fptr != NULL) { - *fptr = *fptr - 1; - } - } -} - - -/*********************************************************************************************** - * HouseClass::Active_Add -- Add an object to active duty for this house. * - * * - * This routine will recognize the specified object as having entered active duty. Any * - * abilities granted to the house by that object are now available. * - * * - * INPUT: techno -- Pointer to the object that is entering active duty. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/16/1996 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Active_Add(TechnoClass const * techno) -{ - if (techno == NULL) return; - - if (techno->What_Am_I() == RTTI_BUILDING) { - int * fptr = Factory_Counter(((BuildingClass *)techno)->Class->ToBuild); - if (fptr != NULL) { - *fptr = *fptr + 1; - } - } -} - - -/*********************************************************************************************** - * HouseClass::Which_Zone -- Determines what zone a coordinate lies in. * - * * - * This routine will determine what zone the specified coordinate lies in with respect to * - * this house's base. A location that is too distant from the base, even though it might * - * be a building, is not considered part of the base and returns ZONE_NONE. * - * * - * INPUT: coord -- The coordinate to examine. * - * * - * OUTPUT: Returns with the base zone that the specified coordinate lies in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -ZoneType HouseClass::Which_Zone(COORDINATE coord) const -{ - //assert(Houses.ID(this) == ID); - - if (coord == 0) return(ZONE_NONE); - - int distance = Distance(Center, coord); - if (distance <= Radius) return(ZONE_CORE); - if (distance > Radius*4) return(ZONE_NONE); - - DirType facing = Direction(Center, coord); - if (facing < DIR_NE || facing > DIR_NW) return(ZONE_NORTH); - if (facing >= DIR_NE && facing < DIR_SE) return(ZONE_EAST); - if (facing >= DIR_SE && facing < DIR_SW) return(ZONE_SOUTH); - return(ZONE_WEST); -} - - -/*********************************************************************************************** - * HouseClass::Which_Zone -- Determines which base zone the specified object lies in. * - * * - * Use this routine to determine what zone the specified object lies in. * - * * - * INPUT: object -- Pointer to the object that will be checked for zone occupation. * - * * - * OUTPUT: Returns with the base zone that the object lies in. For objects that are too * - * distant from the center of the base, ZONE_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -ZoneType HouseClass::Which_Zone(ObjectClass const * object) const -{ - //assert(Houses.ID(this) == ID); - - if (!object) return(ZONE_NONE); - return(Which_Zone(object->Center_Coord())); -} - - -/*********************************************************************************************** - * HouseClass::Which_Zone -- Determines which base zone the specified cell lies in. * - * * - * This routine is used to determine what base zone the specified cell is in. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: Returns the base zone that the cell lies in or ZONE_NONE if the cell is too far * - * away. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -ZoneType HouseClass::Which_Zone(CELL cell) const -{ - //assert(Houses.ID(this) == ID); - - return(Which_Zone(Cell_Coord(cell))); -} - - -/*********************************************************************************************** - * HouseClass::Recalc_Attributes -- Recalcs all houses existence bits. * - * * - * This routine will go through all game objects and reset the existence bits for the * - * owning house. This method ensures that if the object exists, then the corresponding * - * existence bit is also set. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Recalc_Attributes(void) -{ - /* - ** Clear out all tracking values that will be filled in by this - ** routine. This allows the filling in process to not worry about - ** old existing values. - */ - int index; - for (index = 0; index < Houses.Count(); index++) { - HouseClass * house = Houses.Ptr(index); - - if (house != NULL) { - house->BScan = 0; - house->ActiveBScan = 0; - house->IScan = 0; - house->ActiveIScan = 0; - house->UScan = 0; - house->ActiveUScan = 0; - house->AScan = 0; - house->ActiveAScan = 0; -#if (0) - house->VScan = 0; - house->ActiveVScan = 0; -#endif - } - } - - /* - ** A second pass through the sentient objects is required so that the appropriate scan - ** bits will be set for the owner house. - */ - for (index = 0; index < Units.Count(); index++) { - UnitClass const * unit = Units.Ptr(index); - unit->House->UScan |= (1L << unit->Class->Type); - //if (unit->IsLocked && (Session.Type != GAME_NORMAL || !unit->House->IsHuman || unit->IsDiscoveredByPlayer)) { - if (unit->IsLocked) { - if (!unit->IsInLimbo) { - unit->House->ActiveUScan |= (1L << unit->Class->Type); - } - } - } - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass const * infantry = Infantry.Ptr(index); - infantry->House->IScan |= (1L << infantry->Class->Type); - //if (infantry->IsLocked && (Session.Type != GAME_NORMAL || !infantry->House->IsHuman || infantry->IsDiscoveredByPlayer)) { - if (infantry->IsLocked) { - if (!infantry->IsInLimbo) { - infantry->House->ActiveIScan |= (1L << infantry->Class->Type); - //infantry->House->OldIScan |= (1L << infantry->Class->Type); - } - } - } - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass const * aircraft = Aircraft.Ptr(index); - aircraft->House->AScan |= (1L << aircraft->Class->Type); - //if (aircraft->IsLocked && (Session.Type != GAME_NORMAL || !aircraft->House->IsHuman || aircraft->IsDiscoveredByPlayer)) { - if (aircraft->IsLocked) { - if (!aircraft->IsInLimbo) { - aircraft->House->ActiveAScan |= (1L << aircraft->Class->Type); - //aircraft->House->OldAScan |= (1L << aircraft->Class->Type); - } - } - } - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass const * building = Buildings.Ptr(index); - if (building->Class->Type < 32) { - building->House->BScan |= (1L << building->Class->Type); - //if (building->IsLocked && (Session.Type != GAME_NORMAL || !building->House->IsHuman || building->IsDiscoveredByPlayer)) { - if (building->IsLocked) { - if (!building->IsInLimbo) { - building->House->ActiveBScan |= (1L << building->Class->Type); - building->House->OldBScan |= (1L << building->Class->Type); - } - } - } - } -#if (0) - for (index = 0; index < Vessels.Count(); index++) { - VesselClass const * vessel = Vessels.Ptr(index); - vessel->House->VScan |= (1L << vessel->Class->Type); - if (vessel->IsLocked && (Session.Type != GAME_NORMAL || !vessel->House->IsHuman || vessel->IsDiscoveredByPlayer)) { - if (!vessel->IsInLimbo) { - vessel->House->ActiveVScan |= (1L << vessel->Class->Type); - vessel->House->OldVScan |= (1L << vessel->Class->Type); - } - } - } -#endif -} - - -/*********************************************************************************************** - * HouseClass::Zone_Cell -- Finds the cell closest to the center of the zone. * - * * - * This routine is used to find the cell that is closest to the center point of the * - * zone specified. Typical use of this routine is for building and unit placement so that * - * they can "cover" the specified zone. * - * * - * INPUT: zone -- The zone that the center point is to be returned. * - * * - * OUTPUT: Returns with the cell that is closest to the center point of the zone specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -CELL HouseClass::Zone_Cell(ZoneType zone) const -{ - //assert(Houses.ID(this) == ID); - - switch (zone) { - case ZONE_CORE: - return(Coord_Cell(Center)); - - case ZONE_NORTH: - return(Coord_Cell(Coord_Move(Center, DIR_N, Radius*3))); - - case ZONE_EAST: - return(Coord_Cell(Coord_Move(Center, DIR_E, Radius*3))); - - case ZONE_WEST: - return(Coord_Cell(Coord_Move(Center, DIR_W, Radius*3))); - - case ZONE_SOUTH: - return(Coord_Cell(Coord_Move(Center, DIR_S, Radius*3))); - - default: - break; - } - return(0); -} - - -/*********************************************************************************************** - * HouseClass::Where_To_Go -- Determines where the object should go and wait. * - * * - * This function is called for every new unit produced or delivered in order to determine * - * where the unit should "hang out" to await further orders. The best area for the * - * unit to loiter is returned as a cell location. * - * * - * INPUT: object -- Pointer to the object that needs to know where to go. * - * * - * OUTPUT: Returns with the cell that the unit should move to. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - * 11/04/1996 JLB : Simplified to use helper functions * - *=============================================================================================*/ -CELL HouseClass::Where_To_Go(FootClass const * object) const -{ - //assert(Houses.ID(this) == ID); - //assert(object != NULL); - - ZoneType zone; // The zone that the object should go to. - if (object->Anti_Air() + object->Anti_Armor() + object->Anti_Infantry() == 0) { - zone = ZONE_CORE; - } else { - zone = Random_Pick(ZONE_NORTH, ZONE_WEST); - } - - CELL cell = Random_Cell_In_Zone(zone); - //assert(cell != 0); - - return(Map.Nearby_Location(cell)); //, SPEED_TRACK, Map[cell].Zones[MZONE_NORMAL], MZONE_NORMAL)); -} - - -/*********************************************************************************************** - * HouseClass::Find_Juicy_Target -- Finds a suitable field target. * - * * - * This routine is used to find targets out in the field and away from base defense. * - * Typical of this would be the attack helicopters and the roving attack bands of * - * hunter killers. * - * * - * INPUT: coord -- The coordinate of the attacker. Closer targets are given preference. * - * * - * OUTPUT: Returns with a suitable target to attack. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/12/1995 JLB : Created. * - *=============================================================================================*/ -TARGET HouseClass::Find_Juicy_Target(COORDINATE coord) const -{ - //assert(Houses.ID(this) == ID); - - UnitClass * best = 0; - int value = 0; - - for (int index = 0; index < Units.Count(); index++) { - UnitClass * unit = Units.Ptr(index); - - if (unit && !unit->IsInLimbo && !Is_Ally(unit) && unit->House->Which_Zone(unit) == ZONE_NONE) { - int val = Distance(coord, unit->Center_Coord()); - - if (unit->Anti_Air()) val *= 2; - - if (*unit == UNIT_HARVESTER) val /= 2; - - if (value == 0 || val < value) { - value = val; - best = unit; - } - } - } - if (best) { - return(best->As_Target()); - } - return(TARGET_NONE); -} - - -/*********************************************************************************************** - * HouseClass::Get_Quantity -- Fetches the total number of aircraft of the specified type. * - * * - * Call this routine to fetch the total quantity of aircraft of the type specified that is * - * owned by this house. * - * * - * INPUT: aircraft -- The aircraft type to check the quantity of. * - * * - * OUTPUT: Returns with the total quantity of all aircraft of that type that is owned by this * - * house. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/09/1996 JLB : Created. * - *=============================================================================================*/ -int HouseClass::Get_Quantity(AircraftType aircraft) -{ - return(AQuantity[aircraft]); -} - - -/*********************************************************************************************** - * HouseClass::Fetch_Factory -- Finds the factory associated with the object type specified. * - * * - * This is the counterpart to the Set_Factory function. It will return with a factory * - * pointer that is associated with the object type specified. * - * * - * INPUT: rtti -- The RTTI of the object type to find the factory for. * - * * - * OUTPUT: Returns with a pointer to the factory (if present) that can manufacture the * - * object type specified. * - * * - * WARNINGS: If this returns a non-NULL pointer, then the factory is probably already busy * - * producing another unit of that category. * - * * - * HISTORY: * - * 07/09/1996 JLB : Created. * - *=============================================================================================*/ -FactoryClass * HouseClass::Fetch_Factory(RTTIType rtti) const -{ - int factory_index = -1; - - switch (rtti) { - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - factory_index = InfantryFactory; - break; - - case RTTI_UNIT: - case RTTI_UNITTYPE: - factory_index = UnitFactory; - break; - - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - factory_index = BuildingFactory; - break; - - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - factory_index = AircraftFactory; - break; -#if (0) - case RTTI_VESSEL: - case RTTI_VESSELTYPE: - factory_index = VesselFactory; - break; -#endif - default: - factory_index = -1; - break; - } - - /* - ** Fetch the actual pointer to the factory object. If there is - ** no object factory that matches the specified rtti type, then - ** null is returned. - */ - if (factory_index != -1) { - return(Factories.Raw_Ptr(factory_index)); - } - return(NULL); -} - - -/*********************************************************************************************** - * HouseClass::Set_Factory -- Assign specified factory to house tracking. * - * * - * Call this routine when a factory has been created and it now must be passed on to the * - * house for tracking purposes. The house maintains several factory pointers and this * - * routine will ensure that the factory pointer gets stored correctly. * - * * - * INPUT: rtti -- The RTTI of the object the factory it to manufacture. * - * * - * factory -- The factory object pointer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/09/1996 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Set_Factory(RTTIType rtti, FactoryClass * factory) -{ - int * factory_index = 0; - - //assert(rtti != RTTI_NONE); - - switch (rtti) { - case RTTI_UNIT: - case RTTI_UNITTYPE: - factory_index = &UnitFactory; - break; - - case RTTI_INFANTRY: - case RTTI_INFANTRYTYPE: - factory_index = &InfantryFactory; - break; -#if (0) - case RTTI_VESSEL: - case RTTI_VESSELTYPE: - factory_index = &VesselFactory; - break; -#endif - case RTTI_BUILDING: - case RTTI_BUILDINGTYPE: - factory_index = &BuildingFactory; - break; - - case RTTI_AIRCRAFT: - case RTTI_AIRCRAFTTYPE: - factory_index = &AircraftFactory; - break; - } - - //assert(factory_index != NULL); - - /* - ** Assign the factory to the appropriate slot. For the case of clearing - ** the factory out, then -1 is assigned. - */ - if (factory != NULL) { - //*factory_index = factory->ID; - *factory_index = Factories.ID(factory); - } else { - *factory_index = -1; - } -} - - -/*********************************************************************************************** - * HouseClass::Factory_Count -- Fetches the number of factories for specified type. * - * * - * This routine will count the number of factories owned by this house that can build * - * objects of the specified type. * - * * - * INPUT: rtti -- The type of object (RTTI) that the factories are to be counted for. * - * * - * OUTPUT: Returns with the number of factories that can build the object type specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/30/1996 JLB : Created. * - *=============================================================================================*/ -int HouseClass::Factory_Count(RTTIType rtti) const -{ - int const * ptr = ((HouseClass *)this)->Factory_Counter(rtti); - if (ptr != NULL) { - return(*ptr); - } - return(0); -} - - -/*********************************************************************************************** - * HouseClass::Get_Quantity -- Gets the quantity of the building type specified. * - * * - * This will return the total number of buildings of that type owned by this house. * - * * - * INPUT: building -- The building type to check. * - * * - * OUTPUT: Returns with the number of buildings of that type owned by this house. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/09/1996 JLB : Created. * - *=============================================================================================*/ -int HouseClass::Get_Quantity(StructType building) -{ - return(BQuantity[building]); -} - - -/*********************************************************************************************** - * HouseClass::Read_INI -- Reads house specific data from INI. * - * * - * This routine reads the house specific data for a particular * - * scenario from the scenario INI file. Typical data includes starting * - * credits, maximum unit count, etc. * - * * - * INPUT: buffer -- Pointer to loaded scenario INI file. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - * 05/18/1995 JLB : Creates all houses. * - *=============================================================================================*/ -#if (0) // ST 7/17/2019 -void HouseClass::Read_INI(CCINIClass & ini) -{ - HouseClass * p; // Pointer to current player data. - char const * hname; // Pointer to house name. - - for (HousesType index = HOUSE_FIRST; index < HOUSE_COUNT; index++) { - hname = HouseTypeClass::As_Reference(index).IniName; - - p = new HouseClass(index); - p->Control.TechLevel = ini.Get_Int(hname, "TechLevel", Scen.Scenario); - p->Control.MaxBuilding = ini.Get_Int(hname, "MaxBuilding", p->Control.MaxBuilding); - p->Control.MaxUnit = ini.Get_Int(hname, "MaxUnit", p->Control.MaxUnit); - p->Control.MaxInfantry = ini.Get_Int(hname, "MaxInfantry", p->Control.MaxInfantry); - p->Control.MaxVessel = ini.Get_Int(hname, "MaxVessel", p->Control.MaxVessel); - if (p->Control.MaxVessel == 0) p->Control.MaxVessel = p->Control.MaxUnit; - p->Control.InitialCredits = ini.Get_Int(hname, "Credits", 0) * 100; - p->Credits = p->Control.InitialCredits; - - int iq = ini.Get_Int(hname, "IQ", 0); - if (iq > Rule.MaxIQ) iq = 1; - p->IQ = p->Control.IQ = iq; - - p->Control.Edge = ini.Get_SourceType(hname, "Edge", SOURCE_NORTH); - p->IsPlayerControl = ini.Get_Bool(hname, "PlayerControl", false); - - int owners = ini.Get_Owners(hname, "Allies", (1 << HOUSE_NEUTRAL)); - p->Make_Ally(index); - p->Make_Ally(HOUSE_NEUTRAL); - for (HousesType h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { - if ((owners & (1 << h)) != 0) { - p->Make_Ally(h); - } - } - } -} -#endif - -/*********************************************************************************************** - * HouseClass::Write_INI -- Writes the house data to the INI database. * - * * - * This routine will write out all data necessary to recreate it in anticipation of a * - * new scenario. All houses (that are active) will have their scenario type data written * - * out. * - * * - * INPUT: ini -- Reference to the INI database to write the data to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/09/1996 JLB : Created. * - *=============================================================================================*/ -#if (0) // ST 7/17/2019 -void HouseClass::Write_INI(CCINIClass & ini) -{ - /* - ** The identity house control object. Only if the house value differs from the - ** identity, will the data be written out. - */ - HouseStaticClass control; - - for (HousesType i = HOUSE_FIRST; i < HOUSE_COUNT; i++) { - HouseClass * p = As_Pointer(i); - - if (p != NULL) { - char const * name = p->Class->IniName; - - ini.Clear(name); - if (i >= HOUSE_MULTI1) continue; - - if (p->Control.InitialCredits != control.InitialCredits) { - ini.Put_Int(name, "Credits", (int)(p->Control.InitialCredits / 100)); - } - - if (p->Control.Edge != control.Edge) { - ini.Put_SourceType(name, "Edge", p->Control.Edge); - } - - if (p->Control.MaxUnit > 0 && p->Control.MaxUnit != control.MaxUnit) { - ini.Put_Int(name, "MaxUnit", p->Control.MaxUnit); - } - - if (p->Control.MaxInfantry > 0 && p->Control.MaxInfantry != control.MaxInfantry) { - ini.Put_Int(name, "MaxInfantry", p->Control.MaxInfantry); - } - - if (p->Control.MaxBuilding > 0 && p->Control.MaxBuilding != control.MaxBuilding) { - ini.Put_Int(name, "MaxBuilding", p->Control.MaxBuilding); - } - - if (p->Control.MaxVessel > 0 && p->Control.MaxVessel != control.MaxVessel) { - ini.Put_Int(name, "MaxVessel", p->Control.MaxVessel); - } - - if (p->Control.TechLevel != control.TechLevel) { - ini.Put_Int(name, "TechLevel", p->Control.TechLevel); - } - - if (p->Control.IQ != control.IQ) { - ini.Put_Int(name, "IQ", p->Control.IQ); - } - - if (p->IsPlayerControl != false && p != PlayerPtr) { - ini.Put_Bool(name, "PlayerControl", p->IsPlayerControl); - } - - ini.Put_Owners(name, "Allies", p->Control.Allies & ~((1 << p->Class->House) | (1 << HOUSE_NEUTRAL))); - } - } -} -#endif - - -#if (0) -/*********************************************************************************************** - * HouseClass::Is_No_YakMig -- Determines if no more yaks or migs should be allowed. * - * * - * This routine will examine the current yak and mig situation verses airfields. If there * - * are equal aircraft to airfields, then this routine will return TRUE. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Are all airfields full and thus no more yaks or migs are allowed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/23/1996 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Is_No_YakMig(void) const -{ - int quantity = AQuantity[AIRCRAFT_YAK] + AQuantity[AIRCRAFT_MIG]; - - /* - ** Adjust the quantity down one if there is an aircraft in production. This will - ** allow production to resume after being held. - */ - FactoryClass const * factory = Fetch_Factory(RTTI_AIRCRAFT); - if (factory != NULL && factory->Get_Object() != NULL) { - AircraftClass const * air = (AircraftClass const *)factory->Get_Object(); - if (*air == AIRCRAFT_MIG || *air == AIRCRAFT_YAK) { - quantity -= 1; - } - } - - if (quantity >= BQuantity[STRUCT_AIRSTRIP]) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::Is_Hack_Prevented -- Is production of the specified type and id prohibted? * - * * - * This is a special hack check routine to see if the object type and id specified is * - * prevented from being produced. The Yak and the Mig are so prevented if there would be * - * insufficient airfields for them to land upon. * - * * - * INPUT: rtti -- The RTTI type of the value specified. * - * * - * value -- The type number (according to the RTTI type specified). * - * * - * OUTPUT: bool; Is production of this object prohibited? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/23/1996 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Is_Hack_Prevented(RTTIType rtti, int value) const -{ - if (rtti == RTTI_AIRCRAFTTYPE && (value == AIRCRAFT_MIG || value == AIRCRAFT_YAK)) { - return(Is_No_YakMig()); - } - return(false); -} -#endif - -/*********************************************************************************************** - * HouseClass::Fire_Sale -- Cause all buildings to be sold. * - * * - * This routine will sell back all buildings owned by this house. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was a fire sale performed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/23/1996 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Fire_Sale(void) -{ - if (CurBuildings > 0) { - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * b = Buildings.Ptr(index); - - if (b != NULL && !b->IsInLimbo && b->House == this && b->Strength > 0) { - b->Sell_Back(1); - } - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * HouseClass::Do_All_To_Hunt -- Send all units to hunt. * - * * - * This routine will cause all combatants of this house to go into hunt mode. The effect of * - * this is to throw everything this house has to muster at the enemies of this house. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/23/1996 JLB : Created. * - * 10/02/1996 JLB : Handles aircraft too. * - *=============================================================================================*/ -void HouseClass::Do_All_To_Hunt(void) const -{ - int index; - - for (index = 0; index < Units.Count(); index++) { - UnitClass * unit = Units.Ptr(index); - - if (unit->House == this && unit->IsDown && !unit->IsInLimbo) { - if (unit->Team) unit->Team->Remove(unit); - unit->Assign_Mission(MISSION_HUNT); - } - } - - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * infantry = Infantry.Ptr(index); - - if (infantry->House == this && infantry->IsDown && !infantry->IsInLimbo) { - if (infantry->Team) infantry->Team->Remove(infantry); - infantry->Assign_Mission(MISSION_HUNT); - } - } - -#if (0) - for (index = 0; index < Vessels.Count(); index++) { - VesselClass * vessel = Vessels.Ptr(index); - - if (vessel->House == this && vessel->IsDown && !vessel->IsInLimbo) { - if (vessel->Team) vessel->Team->Remove(vessel); - vessel->Assign_Mission(MISSION_HUNT); - } - } -#endif - - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass * aircraft = Aircraft.Ptr(index); - - if (aircraft->House == this && aircraft->IsDown && !aircraft->IsInLimbo) { - if (aircraft->Team) aircraft->Team->Remove(aircraft); - aircraft->Assign_Mission(MISSION_HUNT); - } - } -} - - -/*********************************************************************************************** - * HouseClass::Is_Allowed_To_Ally -- Determines if this house is allied to make allies. * - * * - * Use this routine to determine if this house is legally allowed to ally with the * - * house specified. There are many reason why an alliance is not allowed. Typically, this * - * is when there would be no more opponents left to fight or if this house has been * - * defeated. * - * * - * INPUT: house -- The house that alliance with is desired. * - * * - * OUTPUT: bool; Is alliance with the house specified prohibited? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/23/1996 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Is_Allowed_To_Ally(HousesType house) const -{ - /* - ** Is not allowed to ally with a house that is patently invalid, such - ** as one that is illegally defined. - */ - if (house == HOUSE_NONE) { - return(false); - } - - /* - ** One cannot ally twice with the same house. - */ - if (Is_Ally(house)) { - return(false); - } - - /* - ** If the scenario is being set up, then alliances are always - ** allowed. No further checking is required. - */ - if (ScenarioInit) { - return(true); - } - - /* - ** Alliances (outside of scneario init time) are allowed only if - ** this is a multiplayer game. Otherwise, they are prohibited. - */ - //if (Session.Type == GAME_NORMAL) { - if (GameToPlay == GAME_NORMAL) { - return(false); - } - - /* - ** When the house is defeated, it can no longer make alliances. - */ - if (IsDefeated) { - return(false); - } - -#ifdef FIXIT_VERSION_3 - // Fix to prevent ally with computer. - if ( !HouseClass::As_Pointer(house)->IsHuman) { - return(false); - } -#else // FIXIT_VERSION_3 -#ifdef FIXIT_NO_COMP_ALLY - // Fix to prevent ally with computer. - if (PlayingAgainstVersion > VERSION_RED_ALERT_104 && !HouseClass::As_Pointer(house)->IsHuman) { - return(false); - } -#endif -#endif // FIXIT_VERSION_3 - - /* - ** Count the number of active houses in the game as well as the - ** number of existing allies with this house. - */ - int housecount = 0; - int allycount = 0; - for (HousesType house2 = HOUSE_MULTI1; house2 < HOUSE_COUNT; house2++) { - HouseClass * hptr = HouseClass::As_Pointer(house2); - if (hptr != NULL && hptr->IsActive && !hptr->IsDefeated) { - housecount++; - if (Is_Ally(hptr)) { - allycount++; - } - } - } - - /* - ** Alliance is not allowed if there wouldn't be any enemies left to - ** fight. - */ - if (housecount == allycount+1) { - return(false); - } - - return(true); -} - - -/*********************************************************************************************** - * HouseClass::Computer_Paranoid -- Cause the computer players to becom paranoid. * - * * - * This routine will cause the computer players to become suspicious of the human * - * players and thus the computer players will band together in order to defeat the * - * human players. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/23/1996 JLB : Created. * - *=============================================================================================*/ -void HouseClass::Computer_Paranoid(void) -{ - if (GameToPlay != GAME_GLYPHX_MULTIPLAYER) { // Re-enable this for multiplayer if we support classic team/ally mode. ST - 10/29/2019 - - /* - ** Loop through every computer controlled house and make allies with all other computer - ** controlled houses and then make enemies with all other human controlled houses. - */ - for (HousesType house = HOUSE_MULTI1; house < HOUSE_COUNT; house++) { - HouseClass * hptr = HouseClass::As_Pointer(house); - if (hptr != NULL && hptr->IsActive && !hptr->IsDefeated && !hptr->IsHuman) { - hptr->IsParanoid = true; - - /* - ** Break alliance with every human it is allied with and make friends with - ** any other computer players. - */ - for (HousesType house2 = HOUSE_MULTI1; house2 < HOUSE_COUNT; house2++) { - HouseClass * hptr2 = HouseClass::As_Pointer(house2); - if (hptr2 != NULL && hptr2->IsActive && !hptr2->IsDefeated) { - if (hptr2->IsHuman) { - hptr->Make_Enemy(house2); - } else { - hptr->Make_Ally(house2); - } - } - } - } - } - } -} - - -/*********************************************************************************************** - * HouseClass::Adjust_Power -- Adjust the power value of the house. * - * * - * This routine will update the power output value of the house. It will cause any buildgins* - * that need to be redrawn to do so. * - * * - * INPUT: adjust -- The amount to adjust the power output value. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/01/1996 BWG : Created. * - *=============================================================================================*/ -void HouseClass::Adjust_Power(int adjust) -{ - Power += adjust; -} - - -/*********************************************************************************************** - * HouseClass::Adjust_Drain -- Adjust the power drain value of the house. * - * * - * This routine will update the drain value of the house. It will cause any buildings that * - * need to be redraw to do so. * - * * - * INPUT: adjust -- The amount to adjust the drain (positive means more drain). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/01/1996 BWG : Created. * - *=============================================================================================*/ -void HouseClass::Adjust_Drain(int adjust) -{ - Drain += adjust; -} - - -/*********************************************************************************************** - * HouseClass::Find_Cell_In_Zone -- Finds a legal placement cell within the zone. * - * * - * Use this routine to determine where the specified object should go if it were to go * - * some random (but legal) location within the zone specified. * - * * - * INPUT: techno -- The object that is desirous of going into the zone specified. * - * * - * zone -- The zone to find a location within. * - * * - * OUTPUT: Returns with the cell that the specified object could be placed in the zone. If * - * no valid location could be found, then 0 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/01/1996 JLB : Created. * - * 11/04/1996 JLB : Not so strict on zone requirement. * - *=============================================================================================*/ -CELL HouseClass::Find_Cell_In_Zone(TechnoClass const * techno, ZoneType zone) const -{ - if (techno == NULL) return(0); - - int bestval = -1; - int bestcell = 0; - TechnoTypeClass const * ttype = techno->Techno_Type_Class(); - - /* - ** Pick a random location within the zone specified. - */ - CELL trycell = Random_Cell_In_Zone(zone); - - short const * list = NULL; - if (techno->What_Am_I() == RTTI_BUILDING) { - list = techno->Occupy_List(true); - } - - /* - ** Find a legal placement position as close as possible to the picked location while still - ** remaining within the zone. - */ - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { -// if (Map.In_Radar(cell)) { - if (Map.In_Radar(cell) && Which_Zone(cell) != ZONE_NONE) { - bool ok = ttype->Legal_Placement(cell); - - /* - ** Another (adjacency) check is required for buildings. - */ - if (ok && list != NULL && !Map.Passes_Proximity_Check(ttype, techno->House->Class->House, list, cell)) { - ok = false; - } - - if (ok) { - int dist = Distance(Cell_Coord(cell), Cell_Coord(trycell)); - if (bestval == -1 || dist < bestval) { - bestval = dist; - bestcell = cell; - } - } - } - } - - /* - ** Return the best location to move to. - */ - return(bestcell); -} - - -/*********************************************************************************************** - * HouseClass::Random_Cell_In_Zone -- Find a (technically) legal cell in the zone specified. * - * * - * This routine will pick a random cell within the zone specified. The pick will be * - * clipped to the map edge when necessary. * - * * - * INPUT: zone -- The zone to pick a cell from. * - * * - * OUTPUT: Returns with a picked cell within the zone. If the entire zone lies outside of the * - * map, then a cell in the core zone is returned instead. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/04/1996 JLB : Created. * - *=============================================================================================*/ -CELL HouseClass::Random_Cell_In_Zone(ZoneType zone) const -{ - COORDINATE coord = 0; - int maxdist = 0; - switch (zone) { - case ZONE_CORE: - coord = Coord_Scatter(Center, Random_Pick(0, Radius), true); - break; - - case ZONE_NORTH: - maxdist = min(Radius*3, (Coord_Y(Center) - Cell_To_Lepton(Map.MapCellY)) - CELL_LEPTON_H); - if (maxdist < 0) break; - coord = Coord_Move(Center, (DirType)(Random_Pick(DIR_N, DIR_E)-((DirType)32)), Random_Pick(min(Radius*2, maxdist), min(Radius*3, maxdist))); - break; - - case ZONE_EAST: - maxdist = min(Radius*3, (Cell_To_Lepton(Map.MapCellX + Map.MapCellWidth) - Coord_X(Center)) - CELL_LEPTON_W); - if (maxdist < 0) break; - coord = Coord_Move(Center, Random_Pick(DIR_NE, DIR_SE), Random_Pick(min(Radius*2, maxdist), min(Radius*3, maxdist))); - break; - - case ZONE_SOUTH: - maxdist = min(Radius*3, (Cell_To_Lepton(Map.MapCellY + Map.MapCellHeight) - Coord_Y(Center)) - CELL_LEPTON_H); - if (maxdist < 0) break; - coord = Coord_Move(Center, Random_Pick(DIR_SE, DIR_SW), Random_Pick(min(Radius*2, maxdist), min(Radius*3, maxdist))); - break; - - case ZONE_WEST: - maxdist = min(Radius*3, (Coord_X(Center) - Cell_To_Lepton(Map.MapCellX)) - CELL_LEPTON_W); - if (maxdist < 0) break; - coord = Coord_Move(Center, Random_Pick(DIR_SW, DIR_NW), Random_Pick(min(Radius*2, maxdist), min(Radius*3, maxdist))); - break; - } - - /* - ** Double check that the location is valid and if so, convert it into a cell - ** number. - */ - CELL cell; - if (coord == 0 || !Map.In_Radar(Coord_Cell(coord))) { - if (zone == ZONE_CORE) { - - /* - ** Finding a cell within the core failed, so just pick the center - ** cell. This cell is guaranteed to be valid. - */ - cell = Coord_Cell(Center); - } else { - - /* - ** If the edge fails, then try to find a cell within the core. - */ - cell = Random_Cell_In_Zone(ZONE_CORE); - } - } else { - cell = Coord_Cell(coord); - } - - /* - ** If the randomly picked location is not in the legal map area, then clip it to - ** the legal map area. - */ - if (!Map.In_Radar(cell)) { - int x = Cell_X(cell); - int y = Cell_Y(cell); - - if (x < Map.MapCellX) x = Map.MapCellX; - if (y < Map.MapCellY) y = Map.MapCellY; - if (x >= Map.MapCellX + Map.MapCellWidth) x = Map.MapCellX + Map.MapCellWidth -1; - if (y >= Map.MapCellY + Map.MapCellHeight) y = Map.MapCellY + Map.MapCellHeight -1; - cell = XY_Cell(x, y); - } - return(cell); -} - -/*********************************************************************************************** - * HouseClass::Get_Ally_Flags -- Get the bit flags denoting the allies this house has. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the bit field storing which houses this house is allied with. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/12/2019 JAS : Created. * - *=============================================================================================*/ -unsigned HouseClass::Get_Ally_Flags() -{ - return Allies; -} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/HOUSE.H b/code/TIBERIANDAWN/HOUSE.H deleted file mode 100644 index 0d77d1c..0000000 --- a/code/TIBERIANDAWN/HOUSE.H +++ /dev/null @@ -1,899 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\house.h_v 2.21 16 Oct 1995 16:46:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : HOUSE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 21, 1994 * - * * - * Last Update : May 21, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef HOUSE_H -#define HOUSE_H - -#include "type.h" -#include "region.h" -#include "vector.h" -#include "COORDA.h" -#include "Credits.h" - -//extern "C" { -//unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal); -//} -class TriggerClass; -#ifdef USE_RA_AI -class FootClass; // ST - 7/17/2019 11:54AM -class FactoryClass; // ST - 7/17/2019 11:54AM -#endif // USE_RA_AI -/**************************************************************************** -** Player control structure. Each player (computer or human) has one of -** these structures associated. These are located in a global array. -*/ -//#define REBUILD_MAX 5 // Maximum number of structures to rebuild. -class HouseClass { - public: - /* - ** Pointer to the HouseTypeClass that this house is "owned" by. - ** All constant data for a house type is stored in that class. - */ - HouseTypeClass const * const Class; - - /* - ** Override handicap control values. - */ - float FirepowerBias; - float GroundspeedBias; - float AirspeedBias; - float ArmorBias; - float ROFBias; - float CostBias; - float BuildSpeedBias; - float RepairDelay; - float BuildDelay; - - /* - ** This is the house type that this house object should act like. This - ** value controls production choices and radar cover plate imagery. - */ - HousesType ActLike; - - /* - ** Is this player active? Usually that answer is true, but for civilians, it - ** might possibly be false. - */ - unsigned IsActive:1; - - /* - ** If this house is controlled by the player, then this flag will be true. The - ** computer controls all other active houses. - */ - unsigned IsHuman:1; - unsigned WasHuman:1; - - /* - ** When the computer becomes alerted to the presence of the player's forces, it - ** begins production and attack logic. This flag is set to true if the human - ** player has been discovered by the computer. - */ - unsigned IsStarted:1; - - /* - ** When alerted, the house will create teams of the special "auto" type and - ** will generate appropriate units to fill those team types. - */ - unsigned IsAlerted:1; - - /* - ** If the house has been discovered, then this flag will be set - ** to true. However, the trigger even associated with discovery - ** will only be executed during the next house AI process. - */ - unsigned IsDiscovered:1; - - /* - ** If Tiberium storage is maxed out, then this flag will be set. At some point - ** the player is told of this fact and then this flag is cleared. This allows the - ** player to be told, but only occationally rather than continuously. - */ - unsigned IsMaxedOut:1; - - /* - ** If this house is played by a human in a multiplayer game, this flag - ** keeps track of whether this house has been defeated or not. - */ - unsigned IsDefeated:1; - - /* - ** These flags are used in conjunction with the BorrowedTime timer. When - ** that timer expires and one of these flags are set, then that event is - ** applied to the house. This allows a dramatic pause between the event - ** trigger and the result. - */ - unsigned IsToDie:1; - unsigned IsToWin:1; - unsigned IsToLose:1; - - /* - ** This flag is set when a transport carrying a civilian has been - ** successfully evacuated. It is presumed that a possible trigger - ** event will be sprung by this event. - */ - unsigned IsCivEvacuated:1; - - /* - ** If potentially something changed that might affect the sidebar list of - ** buildable objects, then this flag indicates that at the first LEGAL opportunity, - ** the sidebar will be recalculated. - */ - unsigned IsRecalcNeeded:1; - - /* - ** If the map has been completely revealed to the player, then this flag - ** will be set to true. By examining this flag, a second "reveal all map" - ** crate won't be given to the player. - */ - unsigned IsVisionary:1; - - /* - ** If a trigger has indicated that the airstrike option should appear, this flag - ** will be set to true. It is up to the normal house AI processing to actually - ** add the airstrike to the sidebar. - */ - unsigned IsAirstrikePending:1; - - /* - ** This records the existance of the three nuke weapon pieces. - */ - unsigned NukePieces:3; - - /* - ** This flag indicates that a free harvester is pending and will be - ** created when the FreeHarvester timer expires. - */ - unsigned IsFreeHarvester:1; - - TCountDownTimerClass FreeHarvester; - - /* - ** These super weapon control objects are used to control the recharge - ** and availability of these special weapons to this house. - */ - SuperClass IonCannon; - SuperClass AirStrike; - SuperClass NukeStrike; - - /* - ** This is a record of the last building that was built. For buildings that - ** were built as a part of scenario creation, it will be the last one - ** discovered. - */ - StructType JustBuilt; - - /* - ** This records the number of triggers associated with this house that are - ** blocking a win condition. A win will only occur if all the blocking - ** triggers have been deleted. - */ - int Blockage; - - /* - ** This timer controls the computer auto-attack logic. When this timer expires - ** and the house has been alerted, then it will create a set of attack - ** teams. - */ - TCountDownTimerClass AlertTime; - - /* - ** This timer is used to handle the delay between some catastrophic - ** event trigger and when it is actually carried out. - */ - TCountDownTimerClass BorrowedTime; - - /* - ** This is the last working scan bits for buildings. If a building is - ** active and owned by this house, it will have a bit set in this element - ** that corresponds to the building type number. Since this value is - ** accumulated over time, the "New" element contains the under-construction - ** version. - */ - unsigned long BScan; - unsigned long ActiveBScan; - unsigned long NewBScan; - unsigned long NewActiveBScan; -#ifdef USE_RA_AI - unsigned long OldBScan; -#endif - - /* - ** This is the last working scan bits for units. For every existing unit - ** type owned by this house, a corresponding bit is set in this element. As - ** the scan bits are being constructed, they are built into the "New" element - ** and then duplicated into the regular element at the end of every logic cycle. - */ - unsigned long UScan; - unsigned long ActiveUScan; - unsigned long NewUScan; - unsigned long NewActiveUScan; - - /* - ** Infantry type existence bits. Similar to unit and building bits. - */ - unsigned long IScan; - unsigned long ActiveIScan; - unsigned long NewIScan; - unsigned long NewActiveIScan; - - /* - ** Aircraft type existence bits. Similar to unit and building buts. - */ - unsigned long AScan; - unsigned long ActiveAScan; - unsigned long NewAScan; - unsigned long NewActiveAScan; - - /* - ** Record of gains and losses for this house during the course of the - ** scenario. - */ - unsigned CreditsSpent; - unsigned HarvestedCredits; - - /* - ** This is the running count of the number of units owned by this house. This - ** value is used to keep track of ownership limits. - */ - unsigned CurUnits; - unsigned CurBuildings; -#ifdef USE_RA_AI - unsigned CurInfantry; // Added from RA for AI. ST - 7/17/2019 12:03PM - unsigned CurAircraft; // Added from RA for AI. ST - 7/17/2019 12:03PM -#endif //USE_RA_AI - - /* - ** This is the maximum number allowed to be built by this house. The - ** value depends on the scenario being played. - */ - unsigned MaxUnit; - unsigned MaxBuilding; -#ifdef USE_RA_AI - unsigned MaxInfantry; // Added from RA for AI. ST - 7/19/2019 4:31PM - unsigned MaxAircraft; // Added from RA for AI. ST - 7/19/2019 4:31PM -#endif //USE_RA_AI - - /* - ** This is the running total of the number of credits this house has accumulated. - */ - long Tiberium; - long Credits; - long InitialCredits; - long Capacity; - - /* - ** Did this house lose via resignation? - */ - unsigned Resigned:1; - - /* - ** Did this house lose because the player quit? - */ - unsigned IGaveUp:1; - - /* - ** Stuff to keep track of the total number of units built by this house. - */ - UnitTrackerClass *AircraftTotals; - UnitTrackerClass *InfantryTotals; - UnitTrackerClass *UnitTotals; - UnitTrackerClass *BuildingTotals; - - /* - ** Total number of units destroyed by this house - */ - UnitTrackerClass *DestroyedAircraft; - UnitTrackerClass *DestroyedInfantry; - UnitTrackerClass *DestroyedUnits; - UnitTrackerClass *DestroyedBuildings; - - /* - ** Total number of enemy buildings captured by this house - */ - UnitTrackerClass *CapturedBuildings; - - /* - ** Total number of crates found by this house - */ - UnitTrackerClass *TotalCrates; - - /* - ** Records the number of infantry and vehicle factories active. This value is - ** used to regulate the speed of production. - */ - int AircraftFactories; - int InfantryFactories; - int UnitFactories; - int BuildingFactories; - int SpecialFactories; - - /* - ** This is the accumulation of the total power and drain factors. From these - ** values a ratio can be derived. This ratio is used to control the rate - ** of building decay. - */ - int Power; // Current power output. - int Drain; // Power consumption. - - /* - ** For generic (unspecified) reinforcements, they arrive by a common method. This - ** specifies which method is to be used. - */ - SourceType Edge; - - /* - ** For human controlled houses, only one type of unit can be produced - ** at any one instant. These factory objects control this production. - */ - int AircraftFactory; - int InfantryFactory; - int UnitFactory; - int BuildingFactory; - int SpecialFactory; - - /* - ** For human controlled houses, the current state of the radar map - */ - RadarEnum Radar; - - /* - ** This target value specifies where the flag is located. It might be a cell - ** or it might be an object. - */ - TARGET FlagLocation; - - /* - ** This is the flag-home-cell for this house. This is where we must bring - ** another house's flag back to, to defeat that house. - */ - CELL FlagHome; - - /* - ** For multiplayer games, each house instance has a remap table; the table - ** in the HousesTypeClass isn't used. This variable is set to the remap - ** table for the color the player wants to play. - */ - unsigned char const * RemapTable; - PlayerColorType RemapColor; - char Name[MPLAYER_NAME_MAX]; - - /* - ** For multiplayer games, each house needs to keep track of how many - ** objects of each other house they've killed. - */ - unsigned UnitsKilled[HOUSE_COUNT]; - unsigned UnitsLost; - unsigned BuildingsKilled[HOUSE_COUNT]; - unsigned BuildingsLost; - - /* - ** For multiplayer games, this keeps track of the last house to destroy - ** one of my units. - */ - HousesType WhoLastHurtMe; - - /* - ** Start location (waypoint index) passed in from GlyphX - */ - int StartLocationOverride; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - HouseClass(void) : Class(0) {}; - HouseClass(HousesType house); - ~HouseClass(void); - operator HousesType(void) const; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - ProdFailType Begin_Production(RTTIType type, int id); - ProdFailType Suspend_Production(RTTIType type); - ProdFailType Abandon_Production(RTTIType type); - bool Place_Object(RTTIType type, CELL cell); - bool Manual_Place(BuildingClass * builder, BuildingClass * object); - void Special_Weapon_AI(SpecialWeaponType id); - bool Place_Special_Blast(SpecialWeaponType id, CELL cell); - bool Flag_Attach(CELL cell, bool set_home = false); - bool Flag_Attach(UnitClass * object, bool set_home = false); - bool Flag_Remove(TARGET target, bool set_home = false); - void Init_Data(PlayerColorType color, HousesType house, int credits); - - void Sell_Wall(CELL cell); - bool Flag_To_Die(void); - bool Flag_To_Win(void); - bool Flag_To_Lose(void); - void Make_Ally(HousesType house); - void Make_Ally(ObjectClass * object) {if (object) Make_Ally(object->Owner());}; - void Make_Enemy(HousesType house); - void Make_Enemy(ObjectClass * object) {if (object) Make_Enemy(object->Owner());}; - bool Is_Ally(HousesType house) const; - bool Is_Ally(HouseClass const * house) const; - bool Is_Ally(ObjectClass const * object) const; - #ifdef CHEAT_KEYS - void Debug_Dump(MonoClass *mono) const; - #endif - void AI(void); - bool Can_Build(StructType structure, HousesType house) const; - bool Can_Build(InfantryType infantry, HousesType house) const; - bool Can_Build(UnitType unit, HousesType) const; - bool Can_Build(AircraftType aircraft, HousesType house) const; - bool Can_Build(TechnoTypeClass const * type, HousesType house) const; - unsigned char const * Remap_Table(bool blushing=false, bool unit=false) const; - - TechnoTypeClass const * Suggest_New_Object(RTTIType objectype) const; - bool Does_Enemy_Building_Exist(StructType) const; - void Harvested(unsigned tiberium); - long Available_Money(void) const; - void Spend_Money(unsigned money); - void Refund_Money(unsigned money); - void Attacked(BuildingClass* source); -#ifndef USE_RA_AI - void Adjust_Power(int adjust) {Power += adjust;}; // Replaced by function from RA. ST - 7/17/2019 11:51AM - void Adjust_Drain(int adjust) {Drain += adjust;}; // Replaced by function from RA. ST - 7/17/2019 11:51AM -#endif - int Adjust_Capacity(int adjust, bool inanger=false); - int Power_Fraction(void) const; - int Tiberium_Fraction(void) {return (!Tiberium) ? 0 : Cardinal_To_Fixed(Capacity, Tiberium);}; - void Begin_Production(void) {IsStarted = true;}; - TeamTypeClass const * Suggested_New_Team(bool alertcheck = false); - void Adjust_Threat(int region, int threat); - - static void Init(void); - static void One_Time(void); - static HouseClass * As_Pointer(HousesType house); - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static void Read_Flag_INI(char *buffer); - static void Write_Flag_INI(char *buffer); - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** Special house actions. - */ -// void Init_Ion_Cannon(bool first_time, bool one_time_effect = false); -// void Init_Air_Strike(bool first_time, bool one_time_effect = false); -// void Init_Nuke_Bomb(bool first_time, bool one_time_effect = false); -// void Remove_Ion_Cannon(void); -// void Remove_Air_Strike(void); -// void Remove_Nuke_Bomb(void); - void Detach(TARGET target, bool all); - void Add_Nuke_Piece(int piece=-1); -// void Make_Air_Strike_Available(bool present, bool one_time_effect = false); - bool Has_Nuke_Device(void); - - - /* - ** New default win mode to avoid griefing. ST - 1/31/2020 3:33PM - */ - void Check_Pertinent_Structures(void); - - void Init_Unit_Trackers(void); - void Free_Unit_Trackers(void); - -#ifdef USE_RA_AI - /* - ** AI Functions imported from RA - */ - //TechnoTypeClass const * Suggest_New_Object(RTTIType objectype, bool kennel=false) const; - BuildingTypeClass const * Suggest_New_Building(void) const; - void Recalc_Center(void); - //void Harvested(unsigned tiberium); - void Stole(unsigned worth); - //long Available_Money(void) const; - //void Spend_Money(unsigned money); - //void Refund_Money(unsigned money); - //void Attacked(void); - void Adjust_Power(int adjust); - void Adjust_Drain(int adjust); - //int Adjust_Capacity(int adjust, bool inanger=false); - //fixed Power_Fraction(void) const; - //fixed Tiberium_Fraction(void) const; - //void Begin_Production(void) {IsStarted = true;}; - //TeamTypeClass const * Suggested_New_Team(bool alertcheck = false); - //void Adjust_Threat(int region, int threat); - void Tracking_Remove(TechnoClass const * techno); - void Tracking_Add(TechnoClass const * techno); - void Active_Remove(TechnoClass const * techno); - void Active_Add(TechnoClass const * techno); - - UrgencyType Check_Attack(void) const; - UrgencyType Check_Build_Power(void) const; - UrgencyType Check_Build_Defense(void) const; - UrgencyType Check_Build_Offense(void) const; - UrgencyType Check_Build_Income(void) const; - UrgencyType Check_Fire_Sale(void) const; - UrgencyType Check_Build_Engineer(void) const; - UrgencyType Check_Raise_Money(void) const; - UrgencyType Check_Raise_Power(void) const; - UrgencyType Check_Lower_Power(void) const; - - bool AI_Attack(UrgencyType urgency); - bool AI_Build_Power(UrgencyType urgency) const; - bool AI_Build_Defense(UrgencyType urgency) const; - bool AI_Build_Offense(UrgencyType urgency) const; - bool AI_Build_Income(UrgencyType urgency) const; - bool AI_Fire_Sale(UrgencyType urgency); - bool AI_Build_Engineer(UrgencyType urgency) const; - bool AI_Raise_Money(UrgencyType urgency) const; - bool AI_Raise_Power(UrgencyType urgency) const; - bool AI_Lower_Power(UrgencyType urgency) const; - - bool Can_Make_Money(void) const { - return(Available_Money() > 300 || (BScan & STRUCTF_REFINERY)); - }; - - int Expert_AI(void); - COORDINATE Find_Build_Location(BuildingClass * building) const; - BuildingClass * Find_Building(StructType type, ZoneType zone=ZONE_NONE) const; - int AI_Building(void); - int AI_Unit(void); - int AI_Vessel(void); - int AI_Infantry(void); - int AI_Aircraft(void); - void Production_Begun(TechnoClass const * rtti); - int * Factory_Counter(RTTIType rtti); - int Factory_Count(RTTIType rtti) const; - CELL Where_To_Go(FootClass const * object) const; - CELL Zone_Cell(ZoneType zone) const; - ZoneType Which_Zone(COORDINATE coord) const; - ZoneType Which_Zone(ObjectClass const * object) const; - ZoneType Which_Zone(CELL cell) const; - DiffType Assign_Handicap(DiffType handicap); - TARGET Find_Juicy_Target(COORDINATE coord) const; - int Get_Quantity(AircraftType aircraft); - int Get_Quantity(StructType building); - FactoryClass * Fetch_Factory(RTTIType rtti) const; - void Set_Factory(RTTIType rtti, FactoryClass * factory); - bool Fire_Sale(void); - bool Is_Hack_Prevented(RTTIType rtti, int value) const; - bool Is_No_YakMig(void) const; - CELL Random_Cell_In_Zone(ZoneType zone) const; - static void Computer_Paranoid(void); - bool Is_Allowed_To_Ally(HousesType house) const; - void Do_All_To_Hunt(void) const; - void Super_Weapon_Handler(void); - CELL Find_Cell_In_Zone(TechnoClass const * techno, ZoneType zone) const; - - // Added so the ally flags could be sent to client machines - 09 / 12 / 2019 JAS - unsigned Get_Ally_Flags(); - - static void Recalc_Attributes(void); -#endif //USE_RA_AI - - - /* - ** This vector holds the recorded status of the map regions. It is through - ** this region information that team paths are calculated. - */ - RegionClass Regions[MAP_TOTAL_REGIONS]; - -#ifdef OBSOLETE - /* - ** This count down timer class handles decrements and then changes - ** the ion cannon state. If the Ion cannon was out of range it is - ** now in range. If the Ion cannon was in range it will toggle out - ** of range. - */ - TCountDownTimerClass IonControl; - int IonOldStage; - - TCountDownTimerClass AirControl; - int AirOldStage; - - TCountDownTimerClass NukeControl; - int NukeOldStage; -#endif - - - /* - ** This timer is for multiplayer mode; for a computer-controlled house, - ** it determines how long until this player "blitzes" the hapless humans. - */ - TCountDownTimerClass BlitzTime; - - /* - ** This count down timer class decrements and then changes - ** the Atomic Bomb state. - */ - CELL NukeDest; - - /* - ** Per-house credits class to track the visible credits state for each house. Redundant in the original game, but needed - ** to preserve the exact credits count behavior in the GlyphX client. ST - 10/16/2019 2:31PM - */ - CreditClass VisibleCredits; - - bool DebugUnlockBuildables; - - /* - ** This routine completely removes this house & all its objects from the game. - */ - void Clobber_All(void); - - /* - ** This routine blows up everything in this house. Fun! - */ - void Blowup_All(void); - - /* - ** This routine gets called in multiplayer games when every unit, building, - ** and infantry for a house is destroyed. - */ - void MPlayer_Defeated(void); - - /* - ** Screen shake timer. - */ - TCountDownTimerClass ScreenShakeTime; - - private: - void Silo_Redraw_Check(long oldtib, long oldcap); - - /* - ** This is a bit field record of all the other houses that are allies with - ** this house. It is presumed that any house that isn't an ally, is therefore - ** an enemy. A house is always considered allied with itself. - */ - unsigned Allies; - - /* - ** This is the standard delay time between announcements concerning the - ** state of the base or other intermittent house related events. - */ - enum SpeakDelayEnum { - SPEAK_DELAY=TICKS_PER_MINUTE*2, - TEAM_DELAY=TICKS_PER_MINUTE/10, - DAMAGE_DELAY=TICKS_PER_MINUTE - }; - - /* - ** General low-power related damaged is doled out whenever this timer - ** expires. - */ - TCountDownTimerClass DamageTime; - - /* - ** Team creation is done whenever this timer expires. - */ - TCountDownTimerClass TeamTime; - - /* - ** This controls the rate that the trigger time logic is processed. - */ - TCountDownTimerClass TriggerTime; - - /* - ** At various times, the computer may announce the player's condition. The following - ** variables are used as countdown timers so that these announcements are paced - ** far enough appart to reduce annoyance. - */ - TCountDownTimerClass SpeakAttackDelay; - TCountDownTimerClass SpeakPowerDelay; - TCountDownTimerClass SpeakMoneyDelay; - TCountDownTimerClass SpeakMaxedDelay; - - -#ifdef USE_RA_AI - - /*************************************************************************************** - ** - ** AI data imported from RA. ST - 7/17/2019 11:35AM - ** - ** - */ - - public: - /* - ** This records information about the location and size of - ** the base. - */ - COORDINATE Center; // Center of the base. - int Radius; // Average building distance from center (leptons). - struct { - int AirDefense; - int ArmorDefense; - int InfantryDefense; - } ZoneInfo[ZONE_COUNT]; - - /* - ** This records information about the last time a building of this - ** side was attacked. This information is used to determine proper - ** response. - */ - int LATime; // Time of attack. - RTTIType LAType; // Type of attacker. - ZoneType LAZone; // Last zone that was attacked. - HousesType LAEnemy; // Owner of attacker. - - /* - ** This target value is the building that must be captured as soon as possible. - ** Typically, this will be one of the buildings of this house that has been - ** captured and needs to be recaptured. - */ - TARGET ToCapture; - - /* - ** This value shows who is spying on this house's radar facilities. - ** This is used for the other side to be able to update their radar - ** map based on the cells that this house's units reveal. - */ - int RadarSpied; - - /* - ** Running score, based on units destroyed and units lost. - */ - int PointTotal; - - /* - ** This is the targeting directions for when this house gets a - ** special weapon. - */ - //QuarryType PreferredTarget; - - private: - /* - ** Tracks number of each building type owned by this house. Even if the - ** building is in construction, it will be reflected in this total. - */ - int BQuantity[STRUCT_COUNT]; - int UQuantity[UNIT_COUNT]; - int IQuantity[INFANTRY_COUNT]; - int AQuantity[AIRCRAFT_COUNT]; - - /* - ** This timer keeps track of when an all out attack should be performed. - ** When this timer expires, send most of this house's units in an - ** attack. - */ - /////CDTimerClass Attack; - TCountDownTimerClass Attack; - - public: - /* - ** This records the overriding enemy that the computer will try to - ** destroy. Typically, this is the last house to attack, but can be - ** influenced by nearness. - */ - HousesType Enemy; - - /* - ** The house expert system is regulated by this timer. Each computer controlled - ** house will process the Expert System AI at intermittent intervals. Not only will - ** this distribute the overhead more evenly, but will add variety to play. - */ - /////CDTimerClass AITimer; - TCountDownTimerClass AITimer; - - /* - ** For the moebius effect, this is a pointer to the unit that we - ** selected to teleport. Only one teleporter should be active per house. - */ - //TARGET UnitToTeleport; - - /* - ** This elaborates the suggested objects to construct. When the specified object - ** is constructed, then this corresponding value will be reset to nill state. The - ** expert system decides what should be produced, and then records the - ** recommendation in these variables. - */ - StructType BuildStructure; - UnitType BuildUnit; - InfantryType BuildInfantry; - AircraftType BuildAircraft; - //VesselType BuildVessel; - - /* - ** This records the current state of the base. This state is used to control - ** what action the base will perform and directly affects production and - ** unit disposition. The state will change according to time and combat - ** events. - */ - StateType State; - - /* - ** If automatic base building is on, then this flag will be set to true. - */ - unsigned IsBaseBuilding:1; - - /* - ** This flag is set to true when the house has determined that - ** there is insufficient Tiberium to keep the harvesters busy. - ** In such a case, the further refinery/harvester production - ** should cease. This is one of the first signs that the endgame - ** has begun. - */ - unsigned IsTiberiumShort:1; - - /* - ** If this computer controlled house has reason to be mad at humans, - ** then this flag will be true. Such a condition prevents alliances with - ** a human and encourages the computers players to ally amongst themselves. - */ - unsigned IsParanoid:1; - - /* - ** This value indicates the degree of smartness to assign to this house. - ** A value is zero is presumed for human controlled houses. - */ - int IQ; - - /* - ** This is the handicap (difficulty level) assigned to this house. - */ - DiffType Difficulty; - - /* - ** This structure is used to record a build request as determined by - ** the house AI processing. Higher priority build requests take precidence. - */ - struct BuildChoiceClass { - static void * operator new(size_t, void * ptr) {return(ptr);}; - UrgencyType Urgency; // The urgency of the build request. - StructType Structure; // The type of building to produce. - - BuildChoiceClass(UrgencyType u, StructType s) : Urgency(u), Structure(s) {}; - int Save(FileClass &) const {return(true);}; - int Load(FileClass &) {return(true);}; - void Code_Pointers(void) {}; - void Decode_Pointers(void) {}; - - }; - - static TFixedIHeapClass BuildChoice; - -#endif // USE_RA_AI - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[256]; - -}; -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/IDATA.CPP b/code/TIBERIANDAWN/IDATA.CPP deleted file mode 100644 index 7410c6b..0000000 --- a/code/TIBERIANDAWN/IDATA.CPP +++ /dev/null @@ -1,2153 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\idata.cpv 2.12 02 Aug 1995 17:00:30 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IDATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 15, 1994 * - * * - * Last Update : June 29, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * InfantryTypeClass::Create_And_Place -- Creates and places infantry object onto the map. * - * InfantryTypeClass::Create_One_Of -- Creates an infantry object. * - * InfantryTypeClass::Display -- Displays a generic infantry object. * - * InfantryTypeClass::From_Name -- Converts an ASCII name into an infantry type number. * - * InfantryTypeClass::Full_Name -- Fetches the full name text number. * - * InfantryTypeClass::Get_Cameo_Data -- Fetches the small cameo shape for sidebar strip. * - * InfantryTypeClass::InfantryTypeClass -- Constructor for infantry type class objects. * - * InfantryTypeClass::Occupy_List -- Returns with default infantry occupation list. * - * InfantryTypeClass::One_Time -- Performs any one time processing for infantry system. * - * InfantryTypeClass::Prep_For_Add -- Prepares the scenario editor for adding of infantry object.* - * InfantryTypeClass::Who_Can_Build_Me -- Determines what can build the infantry object. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "type.h" - - - -/* - * There were too many parameters for the InfantryTypeClass constructor so I have - * created a table of Do Controls for each unit type and I am passing a pointer - * to the table to the constructor instead of passing each value as it was before. - * - * If this offends anyones C++ sensibilities then please feel free to implement a - * more elegant oop solution. - * - * Steve T. 10/3/95 10:13AM - * - */ - -// Minigunners - -int MiniGunnerDos [DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 192, 1, 8, // DO_PRONE - 16, 6, 6, // DO_WALK - 64, 8, 8, // DO_FIRE_WEAPON - 128, 2, 2, // DO_LIE_DOWN - 144, 4, 4, // DO_CRAWL - 176, 2, 2, // DO_GET_UP - 192, 6, 8, // DO_FIRE_PRONE - 256, 16,0, // DO_IDLE1 - 272, 16,0, // DO_IDLE2 - 288, 13,0, // DO_ON_GUARD - 292, 10,0, // DO_FIGHT_READY - 301, 2, 0, // DO_PUNCH - 303, 6, 0, // DO_KICK - 309, 2, 0, // DO_PUNCH_HIT1 - 311, 4, 0, // DO_PUNCH_HIT2 - 315, 5, 0, // DO_PUNCH_DEATH - 319, 2, 0, // DO_KICK_HIT1 - 321, 4, 0, // DO_KICK_HIT2 - 325, 5, 0, // DO_KICK_DEATH - 330, 5, 0, // DO_READY_WEAPON - 382, 8, 0, // DO_GUN_DEATH - 398, 8, 0, // DO_EXPLOSION_DEATH - 398, 8, 0, // DO_EXPLOSION2_DEATH - 406, 12,0, // DO_GRENADE_DEATH - 418, 18,0, // DO_FIRE_DEATH - 436, 3, 3, // DO_GESTURE1 - 460, 3, 3, // DO_SALUTE1 - 484, 3, 3, // DO_GESTURE2 - 508, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A -}; - - -static InfantryTypeClass const E1( - INFANTRY_E1, // Infantry type number. - TXT_E1, // Translate name number for infantry type. - "E1", // INI name for infantry. - 1, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - true, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &MiniGunnerDos[0][0], // Ptr to minigunner 'DO' table above - 2, // Frame of projectile launch. - 2, // Frame of projectile launch while prone. - 50, // Strength of infantry (in damage points). - 1, // Sight range. - 100, // Cost of infantry (in credits). - 1, // Scenario when they first appear. - 80,10, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // Who can own this infantry unit. - WEAPON_M16,WEAPON_NONE, - MPH_SLOW // Maximum speed of infantry. -); - - -// Grenadiers - - -int GrenadierDos [DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 288, 1, 12, // DO_PRONE - 16, 6, 6, // DO_WALK - 64, 20,20, // DO_FIRE_WEAPON - 224, 2, 2, // DO_LIE_DOWN - 240, 4, 4, // DO_CRAWL - 272, 2, 2, // DO_GET_UP - 288, 8, 12, // DO_FIRE_PRONE - 384, 16,0, // DO_IDLE1 - 400, 16,0, // DO_IDLE2 - 416, 13,0, // DO_ON_GUARD - 420, 10,0, // DO_FIGHT_READY - 429, 2, 0, // DO_PUNCH - 431, 6, 0, // DO_KICK - 437, 2, 0, // DO_PUNCH_HIT1 - 439, 4, 0, // DO_PUNCH_HIT2 - 443, 4, 0, // DO_PUNCH_DEATH - 447, 2, 0, // DO_KICK_HIT1 - 449, 4, 0, // DO_KICK_HIT2 - 453, 5, 0, // DO_KICK_DEATH - 458, 5, 0, // DO_READY_WEAPON - 510, 8, 0, // DO_GUN_DEATH - 526, 8, 0, // DO_EXPLOSION_DEATH - 526, 8, 0, // DO_EXPLOSION2_DEATH - 534, 12,0, // DO_GRENADE_DEATH - 546, 18,0, // DO_FIRE_DEATH - 564, 3, 3, // DO_GESTURE1 - 588, 3, 3, // DO_SALUTE1 - 612, 3, 3, // DO_GESTURE2 - 636, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A -}; - -static InfantryTypeClass const E2( - INFANTRY_E2, // Infantry type number. - TXT_E2, // Translate name number for infantry type. - "E2", // INI name for infantry. - 1, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - true, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &GrenadierDos[0][0], // Ptr to grenadier DO table (above) - 14, // Frame of projectile launch. - 6, // Frame of projectile launch while prone. - 50, // Strength of infantry (in damage points). - 1, // Sight range. - 160, // Cost of infantry (in credits). - 3, // Scenario when they first appear. - 80,10, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD, // Who can own this infantry unit. - WEAPON_GRENADE,WEAPON_NONE, - MPH_SLOW_ISH // Maximum speed of infantry. -); - - - - -// Bazooka - -int BazookaDos [DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 192, 1,10, // DO_PRONE - 16, 6, 6, // DO_WALK - 64, 8, 8, // DO_FIRE_WEAPON - 128, 2, 2, // DO_LIE_DOWN - 144, 4, 4, // DO_CRAWL - 176, 2, 2, // DO_GET_UP - 192, 10,10, // DO_FIRE_PRONE - 272, 16,0, // DO_IDLE1 - 288, 16,0, // DO_IDLE2 - 304, 13,0, // DO_ON_GUARD - 308, 10,0, // DO_FIGHT_READY - 307, 2, 0, // DO_PUNCH - 319, 6, 0, // DO_KICK - 325, 2, 0, // DO_PUNCH_HIT1 - 327, 4, 0, // DO_PUNCH_HIT2 - 331, 4, 0, // DO_PUNCH_DEATH - 335, 2, 0, // DO_KICK_HIT1 - 337, 4, 0, // DO_KICK_HIT2 - 341, 5, 0, // DO_KICK_DEATH - 346, 5, 0, // DO_READY_WEAPON - 398, 8, 0, // DO_GUN_DEATH - 414, 8, 0, // DO_EXPLOSION_DEATH - 414, 8, 0, // DO_EXPLOSION2_DEATH - 422, 12,0, // DO_GRENADE_DEATH - 434, 18,0, // DO_FIRE_DEATH - 452, 3, 3, // DO_GESTURE1 - 476, 3, 3, // DO_SALUTE1 - 500, 3, 3, // DO_GESTURE2 - 524, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A -}; - - - -static InfantryTypeClass const E3( - INFANTRY_E3, // Infantry type number. - TXT_E3, // Translate name number for infantry type. - "E3", // INI name for infantry. - 2, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - true, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &BazookaDos[0][0], // Ptr to DO table (above) - 3, // Frame of projectile launch. - 3, // Frame of projectile launch while prone. - 25, // Strength of infantry (in damage points). - 2, // Sight range. - 300, // Cost of infantry (in credits). - 3, // Scenario when they first appear. - 80,10, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // Who can own this infantry unit. - WEAPON_DRAGON,WEAPON_NONE, - MPH_KINDA_SLOW // Maximum speed of infantry. -); - -// Flamethrower - -int FlamethrowerDos [DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 256, 1,16, // DO_PRONE - 16, 6, 6, // DO_WALK - 64, 16,16, // DO_FIRE_WEAPON - 192, 2, 2, // DO_LIE_DOWN - 208, 4, 4, // DO_CRAWL - 240, 2, 2, // DO_GET_UP - 256, 16,16, // DO_FIRE_PRONE - 384, 16,0, // DO_IDLE1 - 400, 16,0, // DO_IDLE2 - 416, 13,0, // DO_ON_GUARD - 420, 10,0, // DO_FIGHT_READY - 429, 2, 0, // DO_PUNCH - 431, 6, 0, // DO_KICK - 437, 2, 0, // DO_PUNCH_HIT1 - 439, 4, 0, // DO_PUNCH_HIT2 - 443, 4, 0, // DO_PUNCH_DEATH - 447, 2, 0, // DO_KICK_HIT1 - 449, 4, 0, // DO_KICK_HIT2 - 453, 5, 0, // DO_KICK_DEATH - 458, 5, 0, // DO_READY_WEAPON - 510, 8, 0, // DO_GUN_DEATH - 526, 8, 0, // DO_EXPLOSION_DEATH - 526, 8, 0, // DO_EXPLOSION2_DEATH - 534, 12,0, // DO_GRENADE_DEATH - 546, 18,0, // DO_FIRE_DEATH - 564, 3, 3, // DO_GESTURE1 - 588, 3, 3, // DO_SALUTE1 - 612, 3, 3, // DO_GESTURE2 - 636, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A -}; - - - -static InfantryTypeClass const E4( - INFANTRY_E4, // Infantry type number. - TXT_E4, // Translate name number for infantry type. - "E4", // INI name for infantry. - 1, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - true, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &FlamethrowerDos[0][0], // ptr to DO table (above) - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 70, // Strength of infantry (in damage points). - 1, // Sight range. - 200, // Cost of infantry (in credits). - 5, // Scenario when they first appear. - 80,10, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD, // Who can own this infantry unit. - WEAPON_FLAMETHROWER,WEAPON_NONE, - MPH_SLOW_ISH -); - - -// Chemwarrior - -int ChemwarriorDos [DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 256, 1,16, // DO_PRONE - 16, 6, 6, // DO_WALK - 64, 16,16, // DO_FIRE_WEAPON - 192, 2, 2, // DO_LIE_DOWN - 208, 4, 4, // DO_CRAWL - 240, 2, 2, // DO_GET_UP - 256, 16,16, // DO_FIRE_PRONE - 384, 16,0, // DO_IDLE1 - 400, 16,0, // DO_IDLE2 - 416, 13,0, // DO_ON_GUARD - 420, 10,0, // DO_FIGHT_READY - 429, 2, 0, // DO_PUNCH - 431, 6, 0, // DO_KICK - 437, 2, 0, // DO_PUNCH_HIT1 - 439, 4, 0, // DO_PUNCH_HIT2 - 443, 4, 0, // DO_PUNCH_DEATH - 447, 2, 0, // DO_KICK_HIT1 - 449, 4, 0, // DO_KICK_HIT2 - 453, 5, 0, // DO_KICK_DEATH - 458, 5, 0, // DO_READY_WEAPON - 510, 8, 0, // DO_GUN_DEATH - 526, 8, 0, // DO_EXPLOSION_DEATH - 526, 8, 0, // DO_EXPLOSION2_DEATH - 534, 12,0, // DO_GRENADE_DEATH - 546, 18,0, // DO_FIRE_DEATH - 564, 3, 3, // DO_GESTURE1 - 588, 3, 3, // DO_SALUTE1 - 612, 3, 3, // DO_GESTURE2 - 636, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A -}; - - -static InfantryTypeClass const E5( - INFANTRY_E5, // Infantry type number. - TXT_E5, // Translate name number for infantry type. - "E5", // INI name for infantry. - 7, // Build level. - STRUCTF_EYE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - true, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &ChemwarriorDos[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 70, // Strength of infantry (in damage points). - 1, // Sight range. - 300, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 80,10, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| -// HOUSEF_GOOD| - HOUSEF_BAD, // Who can own this infantry unit. - WEAPON_CHEMSPRAY,WEAPON_NONE, - MPH_SLOW -); - - -// Engineer - -int EngineerDos[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 82, 1, 4, // DO_PRONE - 16, 6, 6, // DO_WALK - 0, 0, 0, // DO_FIRE_WEAPON - 67, 2, 2, // DO_LIE_DOWN - 82, 4, 4, // DO_CRAWL - 114, 2, 2, // DO_GET_UP - 0, 0, 0, // DO_FIRE_PRONE - 130, 16,0, // DO_IDLE1 - 0, 0, 0, // DO_IDLE2 - 0, 0, 0, // DO_ON_GUARD - 0, 0, 0, // DO_FIGHT_READY - 0, 0, 0, // DO_PUNCH - 0, 0, 0, // DO_KICK - 0, 0, 0, // DO_PUNCH_HIT1 - 0, 0, 0, // DO_PUNCH_HIT2 - 0, 0, 0, // DO_PUNCH_DEATH - 0, 0, 0, // DO_KICK_HIT1 - 0, 0, 0, // DO_KICK_HIT2 - 0, 0, 0, // DO_KICK_DEATH - 0, 0, 0, // DO_READY_WEAPON - 146, 8, 0, // DO_GUN_DEATH - 154, 8, 0, // DO_EXPLOSION_DEATH - 162, 8, 0, // DO_EXPLOSION2_DEATH - 170, 12,0, // DO_GRENADE_DEATH - 182, 18,0, // DO_FIRE_DEATH - 200, 3, 3, // DO_GESTURE1 - 224, 3, 3, // DO_SALUTE1 - 200, 3, 3, // DO_GESTURE2 - 224, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A -}; - -static InfantryTypeClass const E7( - INFANTRY_E7, // Infantry type number. - TXT_E7, // Translate name number for infantry type. - "E6", // INI name for infantry. - 3, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - true, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &EngineerDos[0][0], // ptr to DO table - 3, // Frame of projectile launch. - 3, // Frame of projectile launch while prone. - 25, // Strength of infantry (in damage points). - 2, // Sight range. - 500, // Cost of infantry (in credits). - 2, // Scenario when they first appear. - 80,75, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_BAD| - HOUSEF_GOOD, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW // Maximum speed of infantry. -); - -// Commandos - -int CommandoDos[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 8, 1, 1, // DO_STAND_GUARD - 160, 1, 4, // DO_PRONE - 16, 6, 6, // DO_WALK - 64, 4, 4, // DO_FIRE_WEAPON - 96, 2, 2, // DO_LIE_DOWN - 112, 4, 4, // DO_CRAWL - 144, 2, 2, // DO_GET_UP - 160, 4, 4, // DO_FIRE_PRONE - 192, 16,0, // DO_IDLE1 - 208, 16,0, // DO_IDLE2 - 224, 13,0, // DO_ON_GUARD - 228, 9, 0, // DO_FIGHT_READY - 237, 2, 0, // DO_PUNCH - 239, 6, 0, // DO_KICK - 245, 2, 0, // DO_PUNCH_HIT1 - 247, 4, 0, // DO_PUNCH_HIT2 - 251, 4, 0, // DO_PUNCH_DEATH - 255, 2, 0, // DO_KICK_HIT1 - 257, 4, 0, // DO_KICK_HIT2 - 261, 5, 0, // DO_KICK_DEATH - 266, 5, 0, // DO_READY_WEAPON - 318, 8, 0, // DO_GUN_DEATH - 334, 8, 0, // DO_EXPLOSION_DEATH - 334, 8, 0, // DO_EXPLOSION2_DEATH - 342, 12,0, // DO_GRENADE_DEATH - 354, 18,0, // DO_FIRE_DEATH - 372, 3, 3, // DO_GESTURE1 - 396, 3, 3, // DO_SALUTE1 - 420, 3, 3, // DO_GESTURE2 - 444, 3, 3, // DO_SALUTE2 - 0, 1, 1, // DO_PULL_GUN // N/A - 0, 1, 1, // DO_PLEAD // N/A - 0, 1, 1 // DO_PLEAD_DEATH // N/A - -}; -static InfantryTypeClass const Commando( - INFANTRY_RAMBO, // Infantry type number. - TXT_RAMBO, // Translate name number for infantry type. - "RMBO", // INI name for infantry. - 7, // Build level. - STRUCTF_EYE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - true, // Has crawling animation frames? - false, // Is this a civlian? - false, // Always use the given name for the infantry? - false, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - -1, // Number of shots it has (default). - &CommandoDos[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 2, // Frame of projectile launch while prone. - 80, // Strength of infantry (in damage points). - 5, // Sight range. - 1000, // Cost of infantry (in credits). - 98, // Scenario when they first appear. - 80,75, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD, // Who can own this infantry unit. - WEAPON_RIFLE,WEAPON_NONE, - MPH_SLOW_ISH // Maximum speed of infantry. -); - -// Civilians - -int CivilianDos1[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C1( - INFANTRY_C1, // Infantry type number. - TXT_C1, // Translate name number for infantry type. - "C1", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 10, // Number of shots it has (default). - &CivilianDos1[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 25, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_PISTOL,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos2[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C2( - INFANTRY_C2, // Infantry type number. - TXT_C2, // Translate name number for infantry type. - "C2", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos2[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos3[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH - -}; - -static InfantryTypeClass const C3( - INFANTRY_C3, // Infantry type number. - TXT_C3, // Translate name number for infantry type. - "C3", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - true, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos3[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos4[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0, // DO_PLEAD_DEATH -}; - - -static InfantryTypeClass const C4( - INFANTRY_C4, // Infantry type number. - TXT_C4, // Translate name number for infantry type. - "C4", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - true, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos4[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos5[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C5( - INFANTRY_C5, // Infantry type number. - TXT_C5, // Translate name number for infantry type. - "C5", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos5[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos6[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C6( - INFANTRY_C6, // Infantry type number. - TXT_C6, // Translate name number for infantry type. - "C6", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos6[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos7[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C7( - INFANTRY_C7, // Infantry type number. - TXT_C7, // Translate name number for infantry type. - "C7", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - true, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 10, // Number of shots it has (default). - &CivilianDos7[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_PISTOL,WEAPON_NONE, - MPH_SLOW_ISH -); - -int CivilianDos8[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C8( - INFANTRY_C8, // Infantry type number. - TXT_C8, // Translate name number for infantry type. - "C8", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos8[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int CivilianDos9[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const C9( - INFANTRY_C9, // Infantry type number. - TXT_C9, // Translate name number for infantry type. - "C9", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &CivilianDos9[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 5, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int NikoombaDos[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0, // DO_PLEAD_DEATH - -}; - -// Nikoomba -static InfantryTypeClass const C10( - INFANTRY_C10, // Infantry type number. - TXT_C10, // Translate name number for infantry type. - "C10", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &NikoombaDos[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 50, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - -int MoebiusDos[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 0, 0, 0, // DO_FIRE_PRONE - 104, 16,0, // DO_IDLE1 - 120, 20,0, // DO_IDLE2 - 0, 0, 0, // DO_ON_GUARD - 0, 0, 0, // DO_FIGHT_READY - 0, 0, 0, // DO_PUNCH - 0, 0, 0, // DO_KICK - 0, 0, 0, // DO_PUNCH_HIT1 - 0, 0, 0, // DO_PUNCH_HIT2 - 0, 0, 0, // DO_PUNCH_DEATH - 0, 0, 0, // DO_KICK_HIT1 - 0, 0, 0, // DO_KICK_HIT2 - 0, 0, 0, // DO_KICK_DEATH - 0, 0, 0, // DO_READY_WEAPON - 212, 8, 0, // DO_GUN_DEATH - 220, 8, 0, // DO_EXPLOSION_DEATH - 228, 12,0, // DO_EXPLOSION2_DEATH - 228, 12,0, // DO_GRENADE_DEATH - 240, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 0, 0, 0, // DO_PULL_GUN - 120, 31,0, // DO_PLEAD - 151, 14,0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const Moebius( - INFANTRY_MOEBIUS, // Infantry type number. - TXT_MOEBIUS, // Translate name number for infantry type. - "MOEBIUS", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 0, // Number of shots it has (default). - &MoebiusDos[0][0], // ptr to DO table - 0, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 50, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,10, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_BAD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - -int DelphiDos[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 205, 4, 4, // DO_FIRE_PRONE - 189, 10,0, // DO_IDLE1 - 199, 6, 0, // DO_IDLE2 - 104, 3, 0, // DO_ON_GUARD - 107, 7, 0, // DO_FIGHT_READY - 114, 2, 0, // DO_PUNCH - 116, 6, 0, // DO_KICK - 122, 2, 0, // DO_PUNCH_HIT1 - 124, 4, 0, // DO_PUNCH_HIT2 - 128, 4, 0, // DO_PUNCH_DEATH - 133, 2, 0, // DO_KICK_HIT1 - 135, 4, 0, // DO_KICK_HIT2 - 139, 5, 0, // DO_KICK_DEATH - 144, 3, 0, // DO_READY_WEAPON - 329, 8, 0, // DO_GUN_DEATH - 337, 8, 0, // DO_EXPLOSION_DEATH - 337, 8, 0, // DO_EXPLOSION2_DEATH - 345, 12,0, // DO_GRENADE_DEATH - 357, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 199, 6, 0, // DO_PULL_GUN - 237, 40,0, // DO_PLEAD - 277, 6, 0, // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const Delphi( - INFANTRY_DELPHI, // Infantry type number. - TXT_DELPHI, // Translate name number for infantry type. - "DELPHI", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 10, // Number of shots it has (default). - &DelphiDos[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 25, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,0, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_PISTOL,WEAPON_NONE, - MPH_SLOW_ISH -); - - -int DrChanDos[DO_COUNT][3]={ - 0, 1, 1, // DO_STAND_READY - 0, 1, 1, // DO_STAND_GUARD - 0, 1, 1, // DO_PRONE // N/A - 56, 6, 6, // DO_WALK - 205, 4, 4, // DO_FIRE_WEAPON - 0, 1, 1, // DO_LIE_DOWN // N/A - 8, 6, 6, // DO_CRAWL - 0, 1, 1, // DO_GET_UP // N/A - 0, 0, 0, // DO_FIRE_PRONE - 104, 16,0, // DO_IDLE1 - 120, 20,0, // DO_IDLE2 - 0, 0, 0, // DO_ON_GUARD - 0, 0, 0, // DO_FIGHT_READY - 0, 0, 0, // DO_PUNCH - 0, 0, 0, // DO_KICK - 0, 0, 0, // DO_PUNCH_HIT1 - 0, 0, 0, // DO_PUNCH_HIT2 - 0, 0, 0, // DO_PUNCH_DEATH - 0, 0, 0, // DO_KICK_HIT1 - 0, 0, 0, // DO_KICK_HIT2 - 0, 0, 0, // DO_KICK_DEATH - 0, 0, 0, // DO_READY_WEAPON - 212, 8, 0, // DO_GUN_DEATH - 220, 8, 0, // DO_EXPLOSION_DEATH - 228, 12,0, // DO_EXPLOSION2_DEATH - 228, 12,0, // DO_GRENADE_DEATH - 240, 18,0, // DO_FIRE_DEATH - 0, 0, 0, // DO_GESTURE1 // N/A - 0, 0, 0, // DO_SALUTE1 // N/A - 0, 0, 0, // DO_GESTURE2 // N/A - 0, 0, 0, // DO_SALUTE2 // N/A - 0, 0, 0, // DO_PULL_GUN - 120, 31,0, // DO_PLEAD - 151, 14,0 // DO_PLEAD_DEATH -}; - -static InfantryTypeClass const DrChan( - INFANTRY_CHAN, // Infantry type number. - TXT_CHAN, // Translate name number for infantry type. - "CHAN", // INI name for infantry. - 99, // Build level. - STRUCTF_NONE, // Building prerequisite. - false, // Is this a female type? - false, // Is a leader type? - false, // Has crawling animation frames? - true, // Is this a civlian? - true, // Always use the given name for the infantry? - true, // Is this a "fraidycat" run-away type infantry? - false, // Can this infantry type capture a building? - false, // Theater specific graphic image? - 10, // Number of shots it has (default). - &DrChanDos[0][0], // ptr to DO table - 2, // Frame of projectile launch. - 0, // Frame of projectile launch while prone. - 25, // Strength of infantry (in damage points). - 0, // Sight range. - 10, // Cost of infantry (in credits). - 99, // Scenario when they first appear. - 0,1, // Risk/Reward of this infantry unit. - HOUSEF_MULTI1| - HOUSEF_MULTI2| - HOUSEF_MULTI3| - HOUSEF_MULTI4| - HOUSEF_MULTI5| - HOUSEF_MULTI6| - HOUSEF_JP| - HOUSEF_GOOD| - HOUSEF_NEUTRAL, // Who can own this infantry unit. - WEAPON_NONE,WEAPON_NONE, - MPH_SLOW_ISH -); - - - -/* -** This is the array of pointers to the static data associated with each -** infantry type. -*/ -InfantryTypeClass const * const InfantryTypeClass::Pointers[INFANTRY_COUNT] = { - &E1, - &E2, - &E3, - &E4, - &E5, -// &E6, - &E7, - &Commando, - &C1, - &C2, - &C3, - &C4, - &C5, - &C6, - &C7, - &C8, - &C9, - &C10, - &Moebius, - &Delphi, - &DrChan -}; - - -/*********************************************************************************************** - * InfantryTypeClass::InfantryTypeClass -- Constructor for infantry type class objects. * - * * - * This routine will construct the infantry type objects. It is use to create the static * - * infantry types that are used to give each of the infantry objects their characteristics. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -InfantryTypeClass::InfantryTypeClass ( - InfantryType type, int name, char const *ininame, - unsigned char level, long pre, - bool is_female, - bool is_leader, - bool is_crawling, - bool is_civilian, - bool is_nominal, - bool is_fraidycat, - bool is_capture, - bool is_theater, - int ammo, - int *do_table, - int firelaunch, int pronelaunch, - unsigned short strength, int sightrange, - int cost, int scenario, int risk, int reward, int ownable, - WeaponType primary, WeaponType secondary, - MPHType maxspeed) - : TechnoTypeClass(name, ininame, level, pre, - is_leader, true, is_nominal, false, false, true, true, true, true, false, false, - is_theater, false, false, false, true, false, - ammo, strength, maxspeed, sightrange, cost, - scenario, risk, reward, ownable, - primary, secondary, - ARMOR_NONE) -{ - IsFemale = is_female; - IsCrawling = is_crawling; - IsCapture = is_capture; - IsFraidyCat = is_fraidycat; - IsCivilian = is_civilian; - IsAvoidingTiberium = false; - Type = type; - FireLaunch = firelaunch; - ProneLaunch = pronelaunch; - - /* - ** Set the animation sequence custom values. - */ - - for ( int i=0 ; iClass->House)); -} - - -/*********************************************************************************************** - * InfantryTypeClass::Create_And_Place -- Creates and places infantry object onto the map. * - * * - * This routine is used by the scenario editor to create and place an infantry object onto * - * the map at the location specified. * - * * - * INPUT: cell -- The cell location to place the infantry object at. * - * * - * house -- The owner of the infantry object. * - * * - * OUTPUT: bool; Was the infantry object successfully created and placed at the location * - * specified? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryTypeClass::Create_And_Place(CELL cell, HousesType house) const -{ - InfantryClass * i = new InfantryClass(Type, house); - if (i) { - COORDINATE coord = Map[cell].Closest_Free_Spot(Cell_Coord(cell)); - if (coord) { - return(i->Unlimbo(coord, DIR_E)); - } else { - delete i; - } - } - return(false); -} - - -/*********************************************************************************************** - * InfantryTypeClass::Occupy_List -- Returns with default infantry occupation list. * - * * - * This routine will return with a cell offset occupation list for a generic infantry * - * object. This is typically just a single cell since infantry are never bigger than one * - * cell and this routine presumes the infantry is located in the center of the cell. * - * * - * INPUT: placement -- Is this for placement legality checking only? The normal condition * - * is for marking occupation flags. * - * * - * OUTPUT: Returns with a cell offset list for the infantry object as if it were located * - * in the center of a cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -short const * InfantryTypeClass::Occupy_List(bool) const -{ - static short const _list[] = {0, REFRESH_EOL}; - - return(&_list[0]); -} - - -#ifdef SCENARIO_EDITOR -/*********************************************************************************************** - * InfantryTypeClass::Display -- Displays a generic infantry object. * - * * - * This routine is used by the scenario editor to display a generic representation of the * - * infantry object for the scenario editor. It simply draws a single (nice profile) view * - * of the infantry type. * - * * - * INPUT: x,y -- The display coordinates to render the infantry object at. * - * * - * window -- The window that the display coordinates are relative to. * - * * - * house -- The house colors to use when rendering this infantry object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryTypeClass::Display(int x, int y, WindowNumberType window, HousesType house) const -{ - if (house != HOUSE_NONE) { - - int shape = 0; - void const * ptr = Get_Cameo_Data(); - if (!ptr) { - ptr = Get_Image_Data(); - shape = 2; - } - - CC_Draw_Shape(ptr, shape, x, y, window, SHAPE_NORMAL|SHAPE_CENTER|SHAPE_WIN_REL); - } -} - - -/*********************************************************************************************** - * InfantryTypeClass::Prep_For_Add -- Prepares the scenario editor for adding of infantry object.* - * * - * This routine will prepare the scenario editor so that the infantry objects appear on * - * the object list. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryTypeClass::Prep_For_Add(void) -{ - for (InfantryType index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - Map.Add_To_List(&As_Reference(index)); - } -} -#endif - - -/*********************************************************************************************** - * InfantryTypeClass::From_Name -- Converts an ASCII name into an infantry type number. * - * * - * This routine is used to convert the infantry ASCII name as specified into an infantry * - * type number. This is called from the INI reader routine in the process if creating the * - * infantry objects needed for the scenario. * - * * - * INPUT: name -- The ASCII name to convert into an infantry type number. * - * * - * OUTPUT: Returns with the infantry type number that corresponds to the infantry ASCII name * - * specified. If no match could be found, then INFANTRY_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -InfantryType InfantryTypeClass::From_Name(char const *name) -{ - if (name) { - for (InfantryType classid = INFANTRY_FIRST; classid < INFANTRY_COUNT; classid++) { - if (stricmp(Pointers[classid]->IniName, name) == 0) { - return(classid); - } - } - } - return(INFANTRY_NONE); -} - - -/*********************************************************************************************** - * InfantryTypeClass::One_Time -- Performs any one time processing for infantry system. * - * * - * This routine will perform one time processing for the infantry type system. This is * - * generally restricted to loading of the infantry shape data. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryTypeClass::One_Time(void) -{ - InfantryType index; - - for (index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - char fullname[_MAX_FNAME+_MAX_EXT]; - InfantryTypeClass const *uclass; - CCFileClass file; - - uclass = &As_Reference(index); - - /* - ** Generic shape for all houses load method. - */ - _makepath(fullname, NULL, NULL, uclass->IniName, ".SHP"); - ((void const *&)uclass->ImageData) = MixFileClass::Retrieve(fullname); - - /* - ** The small build image icon sized shapes are always generic. - */ - char buffer[_MAX_FNAME]; - if ( Get_Resolution_Factor() ) { - sprintf(buffer, "%.4sICNH", uclass->IniName); - } else { - sprintf(buffer, "%.4sICON", uclass->IniName); - } - _makepath(fullname, NULL, NULL, buffer, ".SHP"); - ((void const *&)uclass->CameoData) = MixFileClass::Retrieve(fullname); - } -} - - - - - - -/*********************************************************************************************** - * ITC::Init -- load up terrain set dependant sidebar icons * - * * - * * - * * - * INPUT: theater type * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 4/25/96 0:33AM ST : Created * - *=============================================================================================*/ - -void InfantryTypeClass::Init(TheaterType theater) -{ - if ( Get_Resolution_Factor() ) { - - if (theater != LastTheater){ - InfantryType index; - char buffer[_MAX_FNAME]; - char fullname[_MAX_FNAME+_MAX_EXT]; - void const * cameo_ptr; - - for (index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - InfantryTypeClass const *uclass; - CCFileClass file; - - uclass = &As_Reference(index); - - ((void const *&)uclass->CameoData) = NULL; - - sprintf(buffer, "%.4sICNH", uclass->IniName); - _makepath (fullname, NULL, NULL, buffer, Theaters[theater].Suffix); - cameo_ptr = MixFileClass::Retrieve(fullname); - if (cameo_ptr){ - ((void const *&)uclass->CameoData) = cameo_ptr; - } - } - } - } -} - - - - - - - - - -/*********************************************************************************************** - * InfantryTypeClass::Who_Can_Build_Me -- Determines what can build the infantry object. * - * * - * Use this routine to determine what building can produce the infantry object. This is * - * typically used to maintain the construction list sidebar. * - * * - * INPUT: intheory -- If no regard is to be given to whether the construction building is * - * currently busy, then this flag should be true. In such a case, only * - * the existance of the building is sufficient to achieve success. * - * * - * legal -- Should building prerequisite legality checks be performed as well? * - * For building placements, this is usually false. For sidebar button * - * adding, this is usually true. * - * * - * house -- The house of the infantry to be produced. Only construction buildings * - * of the same house are considered. * - * * - * OUTPUT: Returns with a pointer to the object (building) that can produce the infantry * - * type. If there are no available buildings then the return value is NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/29/1994 JLB : Created. * - *=============================================================================================*/ -BuildingClass * InfantryTypeClass::Who_Can_Build_Me(bool intheory, bool legal, HousesType house) const -{ - BuildingClass * anybuilding = NULL; - - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && - !building->IsInLimbo && - building->House->Class->House == house && - building->Mission != MISSION_DECONSTRUCTION && - building->Class->ToBuild == RTTI_INFANTRYTYPE && - ((1L << building->ActLike) & Ownable) && - (!legal || building->House->Can_Build(Type, building->ActLike)) && - (intheory || !building->In_Radio_Contact())) { - - anybuilding = building; - if (building->IsLeader) return(building); - } - } - return(anybuilding); -} - - -/*********************************************************************************************** - * InfantryTypeClass::Full_Name -- Fetches the full name text number. * - * * - * This routine will fetch the full name text number for this infantry type. It examines * - * the special custom name flag to determine whether the custom name or the generic name * - * is to be used. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with text number for the name to give this infantry type object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/29/1995 JLB : Created. * - *=============================================================================================*/ -int InfantryTypeClass::Full_Name(void) const -{ - if (Debug_Map || !IsNominal || Special.IsNamed || Type == INFANTRY_C10 || Type == INFANTRY_DELPHI || Type == INFANTRY_MOEBIUS) { - return(TechnoTypeClass::Full_Name()); - } - return(TXT_CIVILIAN); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/INFANTRY.CPP b/code/TIBERIANDAWN/INFANTRY.CPP deleted file mode 100644 index 585fce8..0000000 --- a/code/TIBERIANDAWN/INFANTRY.CPP +++ /dev/null @@ -1,3329 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\infantry.cpv 2.19 16 Oct 1995 16:50:30 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INFANTRY.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 15, 1994 * - * * - * Last Update : August 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * InfantryClass::AI -- Handles the infantry non-graphic related AI processing. * - * InfantryClass::Active_Click_With -- Handles action when clicking with infantry soldier. * - * InfantryClass::As_Target -- Converts the infantry unit into a target value. * - * InfantryClass::Assign_Destination -- Gives the infantry a movement destination. * - * InfantryClass::Assign_Mission -- Make sure he's out of boxing mode first * - * InfantryClass::Assign_Target -- Gives the infantry a combat target. * - * InfantryClass::Can_Enter_Cell -- Determines if the infantry can enter the cell specified. * - * InfantryClass::Can_Fire -- Can the infantry fire its weapon? * - * InfantryClass::Clear_Occupy_Bit -- Clears occupy bit and given cell * - * InfantryClass::Debug_Dump -- Displays debug information about infantry unit. * - * InfantryClass::Detach -- Removes the specified target from targeting computer. * - * InfantryClass::Do_Action -- Launches the infantry into an animation sequence. * - * InfantryClass::Draw_It -- Draws a unit object. * - * InfantryClass::Enter_Idle_Mode -- The infantry unit enters idle mode by this routine. * - * InfantryClass::Fire_At -- Fires projectile from infantry unit. * - * InfantryClass::Fire_Coord -- Calculates the origin point for projectiles fired. * - * InfantryClass::Greatest_Threat -- Determines greatest threat (target) for infantry unit. * - * InfantryClass::InfantryClass -- The constructor for infantry objects. * - * InfantryClass::Init -- Initialize the infantry object system. * - * InfantryClass::Limbo -- Performs cleanup operations needed when limboing. * - * InfantryClass::Look -- The infantry performs a look operation. * - * InfantryClass::Made_A_Kill -- Marks a kill caused by this infantry soldier. * - * InfantryClass::Overlap_List -- The list of cells that the infantry overlaps, but doesn't occ* - * InfantryClass::Per_Cell_Process -- Handles special operations that occur once per cell. * - * InfantryClass::Random_Animate -- Randomly animate the infantry (maybe) * - * InfantryClass::Read_INI -- Reads units from scenario INI file. * - * InfantryClass::Rearm_Delay -- Return Arming delay for infantry if boxing * - * InfantryClass::Receive_Message -- Process radio messages * - * InfantryClass::Response_Attack -- Plays infantry audio response to attack order. * - * InfantryClass::Response_Move -- Plays infantry response to movement order. * - * InfantryClass::Response_Select -- Plays infantry audio response due to being selected. * - * InfantryClass::Scatter -- Causes the infantry to scatter to nearby cell. * - * InfantryClass::Set_Occupy_Bit -- Sets the occupy bit cell and bit pos * - * InfantryClass::Set_Primary_Facing -- Change infantry primary facing -- always and instantl* - * InfantryClass::Start_Driver -- Handles giving immediate destination and move orders. * - * InfantryClass::Stop_Driver -- Stops the infantry from moving any further. * - * InfantryClass::Take_Damage -- Applies damage to the infantry unit. * - * InfantryClass::Unlimbo -- Unlimbo infantry unit in legal sub-location. * - * InfantryClass::What_Action -- Infantry units might be able to capture -- check. * - * InfantryClass::Write_INI -- Writes all the infantry out to an INI file. * - * InfantryClass::operator delete -- Returns the infantry object back to the free pool * - * InfantryClass::operator new -- Allocates an infantry object from the free pool. * - * InfantryClass::~InfantryClass -- Default destructor for infantry units. * - * InfantryClass::Full_Name -- Fetches the full name of the infantry unit. * - * InfantryClass::Mission_Attack -- Intercept attack mission for special handling. * - * InfantryClass::Validate -- validates infantry pointer. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -int const InfantryClass::HumanShape[32] = {0,0,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,4,3,3,3,3,2,2,2,2,1,1,1,1,1,0}; - -int Infantry_Kick_Damage[] = {10,15}; -int Infantry_Punch_Damage[] = { 4, 7}; - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * InfantryClass::VTable; - - -/*************************************************************************** -** This is the array of constant data associated with infantry maneuvers. It -** specifies the frame rate as well as if the animation can be aborted. -*/ -// interruptable, mobile, randomstart, rate -DoStruct const InfantryClass::MasterDoControls[DO_COUNT] = { - {true, false, false, 0}, // DO_STAND_READY - {true, false, false, 0}, // DO_STAND_GUARD - {true, false, false, 0}, // DO_PRONE - {true, true, true, 2}, // DO_WALK - {true, false, false, 1}, // DO_FIRE_WEAPON - {false, true, false, 2}, // DO_LIE_DOWN - {true, true, true, 2}, // DO_CRAWL - {false, false, false, 3}, // DO_GET_UP - {true, false, false, 1}, // DO_FIRE_PRONE - {true, false, false, 2}, // DO_IDLE1 - {true, false, false, 2}, // DO_IDLE2 - {false, false, false, 2}, // DO_ON_GUARD - {true, false, false, 2}, // DO_FIGHT_READY - {false, false, false, 2}, // DO_PUNCH - {false, false, false, 2}, // DO_KICK - {false, false, false, 2}, // DO_PUNCH_HIT1 - {false, false, false, 2}, // DO_PUNCH_HIT2 - {false, false, false, 1}, // DO_PUNCH_DEATH - {false, false, false, 2}, // DO_KICK_HIT1 - {false, false, false, 2}, // DO_KICK_HIT2 - {false, false, false, 1}, // DO_KICK_DEATH - {false, false, false, 2}, // DO_READY_WEAPON - {false, false, false, 2}, // DO_GUN_DEATH - {false, false, false, 2}, // DO_EXPLOSION_DEATH - {false, false, false, 2}, // DO_EXPLOSION2_DEATH - {false, false, false, 2}, // DO_GRENADE_DEATH - {false, false, false, 2}, // DO_FIRE_DEATH - {false, false, false, 2}, // DO_GESTURE1 - {false, false, false, 2}, // DO_SALUTE1 - {false, false, false, 2}, // DO_GESTURE2 - {false, false, false, 2}, // DO_SALUTE2 - {true, false, false, 2}, // DO_PULL_GUN - {true, false, false, 2}, // DO_PLEAD - {true, false, false, 2}, // DO_PLEAD_DEATH -}; - - -/*********************************************************************************************** - * InfantryClass::Validate -- validates infantry pointer. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int InfantryClass::Validate(void) const -{ - int num; - - num = Infantry.ID(this); - if (num < 0 || num >= INFANTRY_MAX) { - Validate_Error("INFANTRY"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * InfantryClass::Debug_Dump -- Displays debug information about infantry unit. * - * * - * This routine is used by the debug version to display pertinent information about the * - * infantry unit. * - * * - * INPUT: mono -- The monochrome screen to display the debug information to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Debug_Dump(MonoClass *mono) const -{ - Validate(); - mono->Set_Cursor(0, 0);mono->Print( - "ÚName:ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂMission:ÄÄÄÂTarCom:ÂNavCom:ÂRadio:ÂCoord:ÄÄÂHeadTo:ÄÂSt:Ä¿\n" - "³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂNÂYÂHealth:ÄÂBody:ÂTurret:ÂSpeed:ÂPath:ÁÄÄÄÄÄÄÂCargo:ÄÄÄÄÁÄÄÄÄ´\n" - "³Active........³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Limbo.........³ ³ ÃÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n" - "³Owned.........³ ³ ³Last Message: ³\n" - "³Discovered....³ ³ ÃTimer:ÂArm:ÂTrack:ÂTiberium:ÂFlash:ÂStage:ÂTeam:ÄÄÄÄÂArch:´\n" - "³Selected......³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Teathered.....³ ³ ÃÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ\n" - "³Locked on Map.³ ³ ³ \n" - "³Is Prone......³ ³ ³ \n" - "³Is A Loner....³ ³ ³ \n" - "³Deploying.....³ ³ ³ \n" - "³Rotating......³ ³ ³ \n" - "³Firing........³ ³ ³ \n" - "³Driving.......³ ³ ³ \n" - "³To Look.......³ ³ ³ \n" - "³Recoiling.....³ ³ ³ \n" - "³To Display....³ ³ ³ \n" - "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÙ \n"); - mono->Set_Cursor(1, 1);mono->Printf("%s:%s", House->Class->IniName, Class->IniName); - mono->Text_Print("X", 16 + (IsProne?2:0), 10); - mono->Set_Cursor(33, 7);mono->Printf("%2d", Fear); - mono->Set_Cursor(41, 7);mono->Printf("%2d", Doing); - FootClass::Debug_Dump(mono); -} -#endif - -InfantryClass::InfantryClass(void) : Class(0) {}; // Default constructor does nothing. - - -/*********************************************************************************************** - * InfantryClass::InfantryClass -- The constructor for infantry objects. * - * * - * This is the constructor used when creating an infantry unit. All values are required * - * except for facing and position. If these are absent, then the infantry is created in * - * a state of limbo -- not placed upon the map. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -InfantryClass::InfantryClass(InfantryType classid, HousesType house) : - Class(&InfantryTypeClass::As_Reference(classid)), - FootClass(house) -{ - - /* - ** For two shooters, clear out the second shot flag -- it will be set the first time - ** the object fires. For non two shooters, set the flag since it will never be cleared - ** and the second shot flag tells the system that normal rearm times apply -- this is - ** what is desired for non two shooters. - */ - if (Class->IsTwoShooter) { - IsSecondShot = false; - } else { - IsSecondShot = true; - } - Doing = DO_NOTHING; - Fear = 0; // Starts completely brave. - IsProne = false; - IsStoked = false; - IsBoxing = false; - IsTechnician = false; - Strength = Class->MaxStrength; - - /* - ** Civilians carry much less ammo than soldiers do. - */ - Ammo = Class->MaxAmmo; - - /* - ** Keep count of the number of units created. Dont track civilians. - */ - if (!Class->IsCivilian && GameToPlay == GAME_INTERNET){ - House->InfantryTotals->Increment_Unit_Total((int)classid); - } - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Add(this); -#endif // USE_RA_AI - - StopDriverFrame = -1; -} - - -/*********************************************************************************************** - * InfantryClass::~InfantryClass -- Default destructor for infantry units. * - * * - * This is the default destructor for infantry type units. It will put the infantry into * - * a limbo state if it isn't already in that state and the game is still active. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/10/1995 JLB : Created. * - *=============================================================================================*/ -InfantryClass::~InfantryClass(void) -{ - if (GameActive && Class) { -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Remove(this); -#endif //USE_RA_AI - Limbo(); - } - if (GameActive && Team) Team->Remove(this); -} - - -/*********************************************************************************************** - * InfantryClass::operator new -- Allocates an infantry object from the free pool. * - * * - * This will allocate an infantry object from the infantry object free pool. If there is * - * no available slot, then NULL is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the allocated infantry object or NULL if none could be * - * allocated. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void * InfantryClass::operator new(size_t) -{ - void * ptr = Infantry.Allocate(); - if (ptr) { - ((InfantryClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * InfantryClass::operator delete -- Returns the infantry object back to the free pool * - * * - * This routine is used return an infantry object back to the system. * - * * - * INPUT: ptr -- Pointer to the infantry object to delete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::operator delete(void *ptr) -{ - if (ptr) { - ((InfantryClass *)ptr)->IsActive = false; - } - Infantry.Free((InfantryClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * InfantryClass::Take_Damage -- Applies damage to the infantry unit. * - * * - * This routine applies the damage specified to the infantry object. It is possible that * - * this routine will DESTROY the infantry unit in the process. * - * * - * INPUT: damage -- The damage points to inflict. * - * * - * distance -- The distance from the damage center point to the object's center point.* - * * - * warhead -- The warhead type that is inflicting the damage. * - * * - * source -- Who is responsible for inflicting the damage. * - * * - * OUTPUT: bool; Was the infantry unit destroyed by this damage? * - * * - * WARNINGS: Since the infantry unit could be destroyed by this routine, be sure to check * - * for this in the code that follows the call to Take_Damage(). * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - * 11/22/1994 JLB : Shares base damage handler for techno objects. * - * 03/31/1995 JLB : Revenge factor. * - *=============================================================================================*/ -ResultType InfantryClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - Validate(); - ResultType res = RESULT_NONE; - - IsFiring = false; - - /* - ** Prone infantry take only half damage, but never below one damage point. - */ - if (IsProne && damage) { - damage >>= 1; -// damage = MAX(damage, 1); - } - - -//Mono_Printf("Infantry Take_Damage(%d, %d, %d, %p)\r", damage, distance, warhead, source); -//Get_Key(); - - res = FootClass::Take_Damage(damage, distance, warhead, source); - - /* - ** Flame thrower guys take more damage because of the exposed pilot light - ** on their flame gun. - */ - if (damage && res != RESULT_DESTROYED && *this == INFANTRY_E4) { - damage = 5; - ResultType newres = FootClass::Take_Damage(damage, distance, warhead, source); - res = MAX(res, newres); - } - - if (res == RESULT_NONE) return(res); - - if (res == RESULT_DESTROYED) { - Death_Announcement(source); - Stop_Driver(); - Stun(); - Mission = MISSION_NONE; - Assign_Mission(MISSION_GUARD); - Commence(); - - /* - ** Flame thrower infantry always go out with a bang. - */ - if (*this == INFANTRY_E4) { - new AnimClass(ANIM_NAPALM1, Coord); - Explosion_Damage(Coord, 80, 0, WARHEAD_FIRE); - } - - if (*this == INFANTRY_E2) { - new AnimClass(ANIM_ART_EXP1, Coord); - Explosion_Damage(Coord, 30, 0, WARHEAD_HE); - } - - if (*this == INFANTRY_E5) { - new AnimClass(ANIM_CHEM_BALL, Coord); - Explosion_Damage(Coord, 80, 0, WARHEAD_HE); - } - - VocType sound; - VocType altsound; - if (*this == INFANTRY_RAMBO) { -// if (Sim_Random_Pick(0, 3) != 1) { - sound = VOC_RAMBO_YELL; -// } else { -// sound = VOC_RAMBO_OHSH; -// } - altsound = sound; - } else { - sound = Sim_Random_Pick(VOC_SCREAM1, VOC_SCREAM5); - altsound = VOC_YELL1; - } - - /* - ** The type of warhead determines the animation the infantry - ** will perform when killed. - */ - switch (warhead) { - case WARHEAD_FEEDME: - if (source) { - source->Strength += 30; - if (source->Strength > source->Class_Of().MaxStrength) { - source->Strength = source->Class_Of().MaxStrength; - } - } - // Fall thru to WARHEAD_SA: - - case WARHEAD_HEADBUTT: - case WARHEAD_SPORE: - case WARHEAD_HOLLOW_POINT: - case WARHEAD_SA: - Sound_Effect(sound, Coord); - Do_Action(DO_GUN_DEATH, true); - break; - - case WARHEAD_HE: - Sound_Effect(sound, Coord); - Do_Action(DO_EXPLOSION_DEATH, true); - break; - - case WARHEAD_AP: - Sound_Effect(sound, Coord); - Do_Action(DO_GRENADE_DEATH, true); - break; - - case WARHEAD_PB: - case WARHEAD_LASER: - case WARHEAD_FIRE: - Sound_Effect(altsound, Coord); - Do_Action(DO_FIRE_DEATH, true); - break; - - case WARHEAD_FIST: - Sound_Effect(sound, Coord); - Do_Action(DO_PUNCH_DEATH,true); - break; - - case WARHEAD_FOOT: - Sound_Effect(sound, Coord); - Do_Action(DO_KICK_DEATH,true); - break; - } - - return(res); - } - - /* - ** When infantry gets hit, it gets scared. - */ - if (res != RESULT_DESTROYED) { - COORDINATE c4 = (source) ? source->Coord : NULL; - if (source) { - Scatter(c4); - } - -#ifdef BOXING - if (IsBoxing) { - int addval = 0; - - switch (warhead) { - case WARHEAD_FIST: - if (damage == Infantry_Punch_Damage[1]) addval++; - Do_Action( (DoType) ( (int)DO_PUNCH_HIT1 + addval),true); - break; - - case WARHEAD_FOOT: - if (damage == Infantry_Kick_Damage[1]) addval++; - Do_Action( (DoType) ( (int)DO_KICK_HIT1 + addval),true); - break; - } - } else { -#endif - if (source && Fear < FEAR_SCARED) { - if (Class->IsFraidyCat) { - Fear = FEAR_PANIC; - } else { - Fear = FEAR_SCARED; - } - } else { - int morefear = FEAR_ANXIOUS; - if (Health_Ratio() > 0x0080) morefear /= 4; - Fear = MIN((int)Fear + morefear, FEAR_MAXIMUM); - } -#ifdef BOXING - } -#endif - } - return(res); -} - - -/*********************************************************************************************** - * InfantryClass::Draw_It -- Draws a unit object. * - * * - * This routine is the one that actually draws a unit object. It displays the unit * - * according to its current state flags and centered at the location specified. * - * * - * INPUT: x,y -- The X and Y coordinate of where to draw the unit. * - * * - * window -- The clipping window to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1994 JLB : Created. * - * 06/27/1994 JLB : Takes a window parameter. * - * 08/15/1994 JLB : Converted to infantry support. * - *=============================================================================================*/ -void InfantryClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - void const * shapefile; // Working shape file pointer. - int facing = Facing_To_32(PrimaryFacing.Current()); - - /* - ** Verify the legality of the unit class. - */ - shapefile = Class->Get_Image_Data(); - if (!shapefile) return; - - y += 4; - x -= 2; - - /* - ** Fetch the basic body shape pointer. This requires taking into account - ** the current animation stage. - */ - int shapenum; - int facenum; - - shapenum = 0; - facenum = HumanShape[facing]; - - /* - ** Fetch the shape pointer to use for the infantry. This is controlled by what - ** choreograph sequence the infantry is performing, it's facing, and whether it - ** is prone. - */ - DoType doit = Doing; - if (doit == DO_NOTHING) doit = DO_STAND_READY; - - /* - ** Hold the walk pose for a couple of frames after we come to a stop to try and avoid the problem where a moving infantry - ** goes into the stand pose for a single frame when pausing in the assigned cell destination. ST - 9/4/2019 1:39PM - */ - if (doit == DO_STAND_READY) { - if (window == WINDOW_VIRTUAL) { - if (StopDriverFrame != -1) { - if (Frame - StopDriverFrame <= 2) { - if (Path[0] != FACING_NONE) { - doit = DO_WALK; - } - } - } - } - } - - shapenum = Class->DoControls[doit].Count; - shapenum = Fetch_Stage() % MAX(shapenum, 1); - if (Class->DoControls[doit].Jump) { - shapenum += facenum * Class->DoControls[doit].Jump; - } - shapenum += Class->DoControls[doit].Frame; - -#ifdef BOXING -// BG hack to get him to face right when he's supposed to. - if (IsBoxing && BodyFacing<128) shapenum += 47; -#endif - - /* - ** Actually draw the root body of the unit. - */ - Techno_Draw_Object(shapefile, shapenum, x, y, window); -// CC_Draw_Shape(shapefile, shapenum, x, y, window, SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST, House->Remap_Table(IsBlushing, true), Map.UnitShadow); - - FootClass::Draw_It(x, y, window); -} - - -/*********************************************************************************************** - * InfantryClass::Per_Cell_Process -- Handles special operations that occur once per cell. * - * * - * This routine will handle any special operations that need to be performed once each * - * cell travelled. This includes radioing a transport that is is now clear and the * - * transport is free to leave. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - * 03/01/1995 JLB : Capture building options. * - * 05/31/1995 JLB : Capture is always successful now. * - *=============================================================================================*/ -void InfantryClass::Per_Cell_Process(bool center) -{ - Validate(); - CellClass *cellptr = &Map[Coord_Cell(Coord)]; - - /* - ** If the infantry unit is entering a cell that contains the building it is trying to - ** capture, then capture it. - */ - if (center && Mission == MISSION_CAPTURE) { - TechnoClass * tech = cellptr->Cell_Techno(); - if (tech && tech->As_Target() == NavCom) { - tech->Captured(House); - Delete_This(); - return; - } else { -//#ifdef NEVER - if (!Target_Legal(NavCom)) { - Enter_Idle_Mode(); - if (Map[Coord_Cell(Coord)].Cell_Building()) { - Scatter(0, true); - } - } -//#endif - } - } - - /* - ** Infantry entering a transport vehicle will break radio contact - ** at attach itself to the transporter. - */ - TechnoClass * techno = Contact_With_Whom(); - if (center && Mission == MISSION_ENTER && techno && Coord_Cell(Coord) == Coord_Cell(techno->Coord) && techno == As_Techno(NavCom)) { - if (Transmit_Message(RADIO_IM_IN) == RADIO_ATTACH) { - Limbo(); - techno->Attach(this); - } - return; - } - - /* - ** If the infantry unit is entering a cell that contains the building it is trying to - ** sabotage, then sabotage it. - */ - if (center && Mission == MISSION_SABOTAGE) { - BuildingClass *building = cellptr->Cell_Building(); - if (building && building->As_Target() == NavCom) { - int temp = Special.IsScatter; - - building->IsGoingToBlow = true; - building->Clicked_As_Target(PlayerPtr->Class->House, 20); // 2019/09/20 JAS - Added record of who clicked on the object - building->Clicked_As_Target(building->Owner(), 20); - building->CountDown.Set(20); - building->WhomToRepay = As_Target(); - Special.IsScatter = true; - NavCom = TARGET_NONE; - Do_Uncloak(); - Arm = Rearm_Delay(true); - Scatter(building->Center_Coord(), true); // RUN AWAY! - Special.IsScatter = temp; - return; - } - } - - /* - ** If this unit is on a teather, then cut it at this time so that - ** the "parent" unit is free to proceed. Note that the parent - ** unit might actually be a building. - */ - if (center && IsTethered) { - Transmit_Message(RADIO_UNLOADED); - if (House->Class->House == HOUSE_GOOD) { - Do_Action(DO_GESTURE1); - } else { - Do_Action(DO_GESTURE2); - } - - /* - ** Rambo types give a gung-ho comment when unloaded. - */ - if (*this == INFANTRY_RAMBO) { - Sound_Effect(VOC_RAMBO_ROCK, Coord); - } - - /* - ** If the cell is now full of infantry, tell them all to scatter - ** in order to make room for more. - */ - if ((cellptr->Flag.Composite & 0x01F) == 0x01F) { - cellptr->Incoming(0, true); - } - } - - /* - ** When the infantry reaches the center of the cell, it may begin a new mission. - */ - if (center) { - Commence(); - } - - Look(true); - FootClass::Per_Cell_Process(center); - - /* - ** If over Tiberium, then this infantry unit will take damage. - */ - if (IsActive && !IsInLimbo && center && cellptr->Land_Type() == LAND_TIBERIUM && *this != INFANTRY_E5) { - int damage = 2; - Take_Damage(damage, 0, WARHEAD_FIRE); - } -} - - -/*********************************************************************************************** - * InfantryClass::Detach -- Removes the specified target from targeting computer. * - * * - * This is a support routine that removes the target specified from any targeting or * - * navigation computers. When a target is destroyed or removed from the game system, * - * the target must be removed from any tracking systems of the other units. This routine * - * handles removal for infantry units. * - * * - * INPUT: target -- The target to remove from the infantry unit's tracking systems. * - * * - * all -- Is the target going away for good as opposed to just cloaking/hiding? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Detach(TARGET target, bool all) -{ - Validate(); - if (TarCom == target) { - IsFiring = false; - } - FootClass::Detach(target, all); -} - - -/*********************************************************************************************** - * InfantryClass::As_Target -- Converts the infantry unit into a target value. * - * * - * This support routine is used to convert the infantry object (as a pointer) into a target * - * value (which is a number). * - * * - * INPUT: none * - * * - * OUTPUT: Returns the infantry unit as a target value. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -TARGET InfantryClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_INFANTRY, Infantry.ID(this))); -} - - -/*********************************************************************************************** - * InfantryClass::Init -- Initialize the infantry object system. * - * * - * This routine will force the infantry object system into its empty initial state. It * - * is called when the scenario needs to be cleared in preparation for a scenario load. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Init(void) -{ - InfantryClass *ptr; - - Infantry.Free_All(); - - ptr = new InfantryClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * InfantryClass::Look -- The infantry performs a look operation. * - * * - * This routine will cause the infantry unit to "look". For player owned infantry, this * - * causes the dark shroud to be pushed back. * - * * - * INPUT: incremental -- If it is known that the infantry performed a look in the last cell * - * it was in AND it has only moved one cell, then setting this * - * parameter to true will perform a faster "incremental" look * - * operation. * - * * - * OUTPUT: none * - * * - * WARNINGS: This is a relatively slow routine. Call ONLY when necessary. * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Look(bool incremental) -{ - Validate(); - int sight; // Number of cells to sight. - - if (!IsInLimbo) { - //if (IsOwnedByPlayer) { // Changed for multiple player mapping. ST - 3/6/2019 1:27PM - if (House->IsHuman) { - sight = Class->SightRange; - - if (sight) { - Map.Sight_From(House, Coord_Cell(Coord), sight, incremental); // Passed our house into Map.Sight_From since it now needs to know who it is performing the action on behalf of. ST - 3/28/2019 2:55PM - } - } - } -} - - -/*********************************************************************************************** - * InfantryClass::Assign_Destination -- Gives the infantry a movement destination. * - * * - * This routine updates the infantry's navigation computer so that the infantry will * - * travel to the destination target specified. * - * * - * INPUT: target -- The target to have the infantry unit move to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Assign_Destination(TARGET target) -{ - Validate(); - /* - ** Special flag so that infantry will start heading in the right direction immediately. - */ - if (Target_Legal(target)) { - Stop_Driver(); - } - - /* - ** When telling an infantry soldier to move to a location twice, then this - ** means that movement is more important than safety. Get up and run! - */ - if (House->IsHuman && Target_Legal(target) && NavCom == target && IsProne && !Class->IsFraidyCat) { - Do_Action(DO_GET_UP); - } - - /* - ** Handle entry logic here. - */ - if (Mission == MISSION_ENTER || MissionQueue == MISSION_ENTER) { - - /* - ** If not already in radio contact (presumed with the transport), then - ** either try to establish contact if allowed, or just move close and - ** wait until radio contact can be established. - */ - if (!In_Radio_Contact()) { - TechnoClass * techno = As_Techno(target); - - if (techno) { - - /* - ** Determine if the transport is already in radio contact. If so, then just move - ** toward the transport and try to establish contact at a later time. - */ - if (techno->In_Radio_Contact()) { - -// TCTCTC -- call for an update from the transport to get a good rondezvous position. - - ArchiveTarget = target; - } else { - if (Transmit_Message(RADIO_HELLO, techno) == RADIO_ROGER) { - if (Transmit_Message(RADIO_DOCKING) != RADIO_ROGER) { - Transmit_Message(RADIO_OVER_OUT); - Assign_Mission(MISSION_MOVE); - } - } else { - Assign_Mission(MISSION_MOVE); - } - } - } - } else { - Path[0] = FACING_NONE; - } - } else { - Path[0] = FACING_NONE; - } - FootClass::Assign_Destination(target); -} - - -/*********************************************************************************************** - * InfantryClass::Assign_Target -- Gives the infantry a combat target. * - * * - * This routine will update the infantry's targeting computer so that it will try to * - * attack the target specified. This might result in it moving to be within range and thus * - * also cause adjustment of the navigation computer. * - * * - * INPUT: target -- The target that this infantry should attack. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - * 06/30/1995 JLB : Tries to capture target if possible. * - *=============================================================================================*/ -void InfantryClass::Assign_Target(TARGET target) -{ - Validate(); - Path[0] = FACING_NONE; - FootClass::Assign_Target(target); - - /* - ** If this is an infantry that can only capture, then also assign its destination to the - ** target specified. - */ - if (!Target_Legal(NavCom) && Class->IsCapture && Class->Primary == WEAPON_NONE) { - BuildingClass const * building = As_Building(target); - if (building && building->Can_Capture()) { - Assign_Destination(target); - } - } -} - - -/*********************************************************************************************** - * InfantryClass::AI -- Handles the infantry non-graphic related AI processing. * - * * - * This routine is used to handle the non-graphic AI processing the infantry requires. * - * Call this routine ONCE per game frame. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::AI(void) -{ - Validate(); - FootClass::AI(); - - if (IsUnloading) Mark(MARK_CHANGE); - - /* - ** Special hack to make sure that if this infantry is in firing animation, but the - ** stage class isn't set, then abort the firing flag. - */ - if (IsFiring && !Fetch_Rate()) { - IsFiring = false; - } - - /* - ** Delete this unit if it finds itself off the edge of the map and it is in - ** guard or other static mission mode. - */ - if (!Team && Mission == MISSION_GUARD && !Map.In_Radar(Coord_Cell(Coord))) { - Stun(); - Delete_This(); - return; - } - - /* - ** Act on new orders if the unit is at a good position to do so. - */ - if (!IsDriving && (Doing == DO_NOTHING || MasterDoControls[Doing].Interrupt)) { - Commence(); - } - - /* - ** After a time, the infantry will gain courage. - */ - if (Fear) { - - /* - ** Nikumba is really a coward at heart. He never becomes un-afraid. - */ - if (*this != INFANTRY_C10) { - Fear--; - - /* - ** When an armed civilian becomes unafraid, he will then reload - ** another clip into his pistol. - */ - if (Fear == 0 && Ammo == 0 && Class->Primary != WEAPON_NONE) { - Ammo = Class->MaxAmmo; - } - } - - /* - ** Stand up if brave and lie down if afraid. - */ - if (IsProne) { - if (Fear < FEAR_ANXIOUS) { - Do_Action(DO_GET_UP); - } - } else { - - /* - ** Drop to the ground if anxious. Don't drop to the ground while moving - ** and the special elite flag is active. - */ - if (Fear >= FEAR_ANXIOUS && ((!Target_Legal(NavCom) && !IsDriving) || !Special.IsDefenderAdvantage)) { - Do_Action(DO_LIE_DOWN); - } - } - } - - /* - ** When is darkness or in doubt, - ** run in circles, scream, and shout. - */ - if (Class->IsFraidyCat && Fear > FEAR_ANXIOUS && !IsDriving && !Target_Legal(NavCom)) { - Scatter(true); - } - - /* - ** Special victory dance action. - */ - if (!Target_Legal(NavCom) && !IsProne && IsStoked && Comment.Expired()) { - IsStoked = false; - Do_Action((Random_Pick(0, 1) == 0) ? DO_GESTURE1 : DO_GESTURE2); - if (*this == INFANTRY_RAMBO) { - VocType _response[] = { - VOC_RAMBO_LEFTY, - VOC_RAMBO_LAUGH, - VOC_RAMBO_COMIN, - VOC_RAMBO_TUFF - }; - Sound_Effect(_response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)], Coord); - } - } - - /* - ** Determine if this infantry unit should fire off an - ** attack or not. - */ - switch (Can_Fire(TarCom, 0)) { - case FIRE_CLOAKED: - Do_Uncloak(); - break; - - case FIRE_OK: -#ifdef BOXING - ObjectClass *object = As_Object(TarCom); - - if (object) { - /* If we're engaged in hand-to-hand combat, keep boxing */ - if (IsBoxing) { - IsFiring = true; - if (((InfantryClass *)object)->Doing == DO_FIGHT_READY) { - Do_Action((DoType) ((int)DO_PUNCH + (DoType)(Random_Pick(0, 1) == 1)),true); - } - } else { - - if (Is_Target_Infantry(TarCom) && (Distance(TarCom)<=0x80) && (Coord_Y(Coord) == Coord_Y(object->Coord))) { - - // Too close to shoot, so start hand-to-hand combat - if (Establish_Contact((TechnoClass *)object)) { - if (Transmit_Message(RADIO_PREPARE_TO_BOX) == RADIO_ROGER) { - IsBoxing = true; - Do_Action(DO_ON_GUARD,true); - } - } - } else { -#endif - - /* - ** Start firing animation. - */ - if (IsProne) { - Do_Action(DO_FIRE_PRONE); - IsFiring = true; - } else { - Do_Action(DO_FIRE_WEAPON); - IsFiring = true; - } -#ifdef BOXING - } -#endif - - PrimaryFacing.Set(Direction8(Center_Coord(), As_Coord(TarCom))); - - /* - ** If the target is in range, and the NavCom is the same, then just - ** stop and keep firing. - */ - if (TarCom == NavCom) { - NavCom = TARGET_NONE; - Path[0] = FACING_NONE; - } -#ifdef BOXING - } - } -#endif - break; - } - - /* - ** If in the middle of firing animation, then only - ** process that. Infantry cannot fire and move simultaneously. - ** At some point in the firing animation process, a projectile - ** will be launched. When the required animation frames have - ** been completed, the firing animation stops. - */ - int firestage = Class->FireLaunch; - if (IsProne) firestage = Class->ProneLaunch; - -#ifdef BOXING - if (IsBoxing) { - firestage = 1; - if (Doing == DO_KICK) firestage = 2; - } -#endif - - if (IsFiring && Fetch_Stage() == firestage) { - Fire_At(TarCom, 0); - - if (Class->Primary == WEAPON_GRENADE) { - Map[::As_Cell(TarCom)].Incoming(Coord, true); - } - } - - /* - ** Handle the completion of the animation sequence. - */ - - if (Doing == DO_NOTHING || Fetch_Stage() >= Class->DoControls[Doing].Count) { - switch (Doing) { - default: - if (IsDriving) { - if (IsProne) { - Do_Action(DO_CRAWL, true); - } else { - Do_Action(DO_WALK, true); - } - } else { - if (IsProne) { - Do_Action(DO_PRONE, true); - } else { - Do_Action(DO_STAND_READY, true); - } - } - break; - -#ifdef BOXING - case DO_FIGHT_READY: - case DO_ON_GUARD: - case DO_PUNCH: - case DO_KICK: - case DO_PUNCH_HIT1: - case DO_PUNCH_HIT2: - case DO_KICK_HIT1: - case DO_KICK_HIT2: - if (In_Radio_Contact()) { - Do_Action(DO_FIGHT_READY, true); - } else { - IsBoxing = false; - Do_Action(DO_READY_WEAPON); - } - break; -#endif - - /* - ** When death is due to hand-to-hand combat, use the gunfire death - ** decay animation since there is no custom animation available - yet. - */ - case DO_PUNCH_DEATH: - case DO_KICK_DEATH: - // Fall into next case. - - case DO_GUN_DEATH: - case DO_EXPLOSION_DEATH: - case DO_EXPLOSION2_DEATH: - case DO_GRENADE_DEATH: - case DO_FIRE_DEATH: - Delete_This(); - return; - } - } - - /* - ** Perform movement operations at this time. - */ - if (!IsFiring /*&& !IsBoxing*/) { - if (!IsDriving) { - - /* - ** When in guard mode, never allow a valid navcom. - */ - if (Mission == MISSION_GUARD && MissionQueue == MISSION_NONE && Target_Legal(NavCom)) { - Assign_Destination(TARGET_NONE); -// if (IsTethered) Scatter(0, true); - } - - /* - ** A head to coordinate is needed. If there is no path - ** available, then create one. - */ - if (Target_Legal(NavCom) && Strength && Mission != MISSION_GUARD) { - - /* - ** Determine if the next cell in the list is available - ** to be entered. If not, then abort the path and try - ** again. - */ - if (Path[0] != FACING_NONE && Can_Enter_Cell(Adjacent_Cell(Coord_Cell(Center_Coord()), Path[0])) != MOVE_OK) { - Path[0] = FACING_NONE; - } - - /* - ** Check to see if the target is closer than expected. This occurs - ** when heading toward a moving object and that object is heading - ** toward the unit. Shorten the precalculated path to be no longer - ** than the distance to the target. - */ - int d = Lepton_To_Cell(Distance(NavCom)); - if (d < CONQUER_PATH_MAX) { - Path[d] = FACING_NONE; - } - - /* - ** Find a path to follow if one isn't already calculated. - */ - if (Path[0] == FACING_NONE) { - - /* - ** Calculate the path from the current location to the - ** destination indicated by the navigation computer. If there - ** was a fundamental error with finding a path, then this - ** indicates that basic path & movement logic needs to be - ** aborted. - */ - if (!PathDelay.Expired()) { - return; - } - if (!Basic_Path()) { -//Mono_Printf("Infantry Basic_Path is failing.\n");Get_Key(); - if (Distance(NavCom) < 0x0280 && !IsTethered) { - Assign_Destination(TARGET_NONE); - } else { - if (TryTryAgain) { - TryTryAgain--; - } else { - if (IsNewNavCom) Sound_Effect(VOC_SCOLD); - IsNewNavCom = false; - - //If we're trying to enter a transport we need to fail so others can try to enter. - LLL 4/17/2020 - if (Mission == MISSION_ENTER) { - Mission = MISSION_NONE; - Assign_Mission(MISSION_GUARD); - Commence(); - - Transmit_Message(RADIO_OVER_OUT); - } - } - } - Stop_Driver(); - return; - } - TryTryAgain = PATH_RETRY; - } - - /* - ** Determine the coordinate to head to based on the infantry's - ** current location and the next location in the path. - */ - COORDINATE acoord = Adjacent_Cell(Coord, Path[0]); - CELL acell = Coord_Cell(acoord); - - if (Can_Enter_Cell(acell) != MOVE_OK) { - - if ((Mission == MISSION_MOVE || Mission == MISSION_ENTER) && !IsTethered && House->IsHuman && Distance(NavCom) < 0x0200) { - Assign_Destination(TARGET_NONE); - } - - /* - ** If blocked by a moving block then just exit start of move and - ** try again next tick. - */ - if (Can_Enter_Cell(acell) == MOVE_DESTROYABLE) { - if (Map[acell].Cell_Object()) { - if (!House->Is_Ally(Map[acell].Cell_Object())) { - Override_Mission(MISSION_ATTACK, Map[acell].Cell_Object()->As_Target(), TARGET_NONE); - } - } else { - if (Map[acell].Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(Map[acell].Overlay).IsWall) { - Override_Mission(MISSION_ATTACK, ::As_Target(acell), TARGET_NONE); - } - } - } - - Path[0] = FACING_NONE; - Stop_Driver(); - if (IsNewNavCom) Sound_Effect(VOC_SCOLD); - IsNewNavCom = false; - - } else { - if (Start_Driver(acoord)) { - PrimaryFacing.Set(Direction8(Center_Coord(), Head_To_Coord())); - Set_Speed(0xFF); - if (IsProne) { - Do_Action(DO_CRAWL); - } else { - Do_Action(DO_WALK); - } - } - } - } - - } else { - - /* - ** The infantry knows where it should be headed, so head there. Check - ** to see if the infantry is "close enough" to the desired location that - ** it should just consider itself to have arrived. In this case, force - ** the infantry to the destination location and mark this path step - ** as complete. - */ - Mark(MARK_UP); - if (Distance(Head_To_Coord()) < 0x0010) { - - memcpy(&Path[0], &Path[1], sizeof(Path)-sizeof(Path[0])); - Path[(sizeof(Path)/sizeof(Path[0]))-1] = FACING_NONE; - Coord = Head_To_Coord(); - Stop_Driver(); - Per_Cell_Process(true); - - if (!IsActive || IsInLimbo) return; - - if (Coord_Cell(Coord) == As_Cell(NavCom)) { - NavCom = TARGET_NONE; - if (Mission == MISSION_MOVE) { - Enter_Idle_Mode(); - } - //Stop_Driver(); - Path[0] = FACING_NONE; - } - } else { - int movespeed = Speed; - - /* - ** When prone, the infantry moves at half speed or double - ** speed. This depends on whether the infantry actually has - ** prone animation stages. Civilians don't, and so they - ** run instead. - */ - if (IsProne) { - if (Class->IsFraidyCat && !Class->IsCrawling) { - movespeed = Speed*2; - } else { - movespeed = Speed/2; - } - } - - if (IsTethered) { - Transmit_Message(RADIO_REDRAW); - } - - /* - ** Advance the infantry as far as it should go. - */ - MPHType maxspeed = MPHType(min((unsigned)(Class->MaxSpeed * House->GroundspeedBias), MPH_LIGHT_SPEED)); - Coord = Coord_Move(Coord, Direction(Head_To_Coord()), Fixed_To_Cardinal(maxspeed, movespeed)); - } - Mark(MARK_DOWN); - } - IsNewNavCom = false; - } -} - - -#ifdef NEVER -/*************************************************************************** - * InfantryClass::Blocking_Object -- Determines how a object blocks an inf * - * * - * INPUT: TechnoClass * pointer to object that is blocking unit * - * CELL the cell the unit is being blocked in * - * * - * OUTPUT: MoveBitType the way that the object is blocking the unit * - * * - * HISTORY: * - * 06/08/1995 PWG : Created. * - *=========================================================================*/ -MoveBitType InfantryClass::Blocking_Object(TechnoClass const *techno, CELL cell) const -{ - Validate(); - bool inf = (techno->What_Am_I() == RTTI_INFANTRY); - bool unit = (techno->What_Am_I() == RTTI_UNIT) || inf; - - CellClass const * cellptr = &Map[cell]; - - if (House->Is_Ally(techno)) { - - /* - ** Logic to handle a trasport type object. - */ - if (NavCom == techno->As_Target() && Contact_With_Whom() == techno) { - return(MOVEF_OK); - } - - /* - ** If the object is of type infantry, then the square is blocked only - ** if the cell is completely full of infantry. - */ - if (inf && ((cellptr->Flag.Composite & 0x1f) != 0x1f)) { - return(MOVEF_OK); - } - - if (unit) { - - /* - ** If the unit in question has a destination than we should - ** be prepared to wait for the unit to get out of our way. - */ - if (((FootClass *)techno)->NavCom != TARGET_NONE) { - return(MOVEF_MOVING_BLOCK); - } - return(MOVEF_TEMP); - } - } else { - - /* - ** If its an enemy unit, things are dealt with a little differently - */ - if (unit) { - - - /* - ** If the object is cloaked, then consider it passable for findpath purposes, - ** but not so for all other cases. - */ - if (techno->Cloak == CLOAKED) { - if (IsFindPath) return(MOVEF_OK); - return(MOVEF_CLOAK); - } - - /* - ** If our vehicle is weapon equipped, then report that the cell occupier - ** needs only to be destroyed in order to make the cell passable. - */ - if (Class->Primary != WEAPON_NONE) { - return(MOVEF_DESTROYABLE); - } - } - } - return(MOVEF_NO); -} -#endif - - - -/*********************************************************************************************** - * InfantryClass::Can_Enter_Cell -- Determines if the infantry can enter the cell specified. * - * * - * This routine is used to examine the cell specified and determine if the infantry is * - * allowed to enter it. It is used by the path finding algorithm. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: Returns the type of blockage in the cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -MoveType InfantryClass::Can_Enter_Cell(CELL cell, FacingType ) const -{ - Validate(); - /* - ** If we are moving into an illegal cell, then we can't do that. - */ - if ((unsigned)cell >= MAP_CELL_TOTAL) return(MOVE_NO); - - /* - ** If moving off the edge of the map, then consider that an illegal move. - */ - if (IsLocked && !IsALoaner && !ScenarioInit && !Map.In_Radar(cell)) { - return(MOVE_NO); - } - CellClass * cellptr = &Map[cell]; - - /* - ** Walls are considered impassable for infantry UNLESS the wall has a hole - ** in it. - */ - if (cellptr->Overlay != OVERLAY_NONE) { - OverlayTypeClass const & otype = OverlayTypeClass::As_Reference(cellptr->Overlay); - - if (otype.IsCrate && !House->IsHuman) { - return(MOVE_NO); - } - - if (otype.IsWall) { - if ((cellptr->OverlayData / 16) != otype.DamageLevels) { - return(MOVE_NO); - } - } - } - - /* - ** Loop through all of the objects in the square setting a bit - ** for how they affect movement. - */ - MoveType retval = MOVE_OK; - ObjectClass *obj = cellptr->Cell_Occupier(); - while (obj) { - - if (obj != this) { - - /* - ** Special case check so that a landed aircraft that is in radio contact, will not block - ** a capture attempt. It is presumed that this case happens when a helicopter is landed - ** at a helipad. - */ - if ((Mission != MISSION_CAPTURE && Mission != MISSION_SABOTAGE) || obj->What_Am_I() != RTTI_AIRCRAFT || !((AircraftClass *)obj)->In_Radio_Contact()) { - - /* - ** Special check to always allow entry into the building that this infantry - ** is trying to capture. - */ - if (obj->What_Am_I() == RTTI_BUILDING || obj->What_Am_I() == RTTI_AIRCRAFT) { - if ((Mission == MISSION_CAPTURE || Mission == MISSION_SABOTAGE) && (obj->As_Target() == NavCom || obj->As_Target() == TarCom)) { - return(MOVE_OK); - } - } - - /* - ** Special check to always allow entry into the building that this infantry - ** is trying to capture. - */ - if (Mission == MISSION_ENTER && obj->As_Target() == NavCom && IsTethered) { - return(MOVE_OK); - } - - /* - ** Allied objects block movement using different rules than for enemy - ** objects. - */ - if (House->Is_Ally(obj)) { - switch (obj->What_Am_I()) { - - /* - ** A unit blocks as either a moving blockage or a stationary temp blockage. - ** This depends on whether the unit is currently moving or not. - */ - case RTTI_UNIT: - if (((UnitClass *)obj)->IsDriving || Target_Legal(((UnitClass *)obj)->NavCom)) { - if (retval < MOVE_MOVING_BLOCK) retval = MOVE_MOVING_BLOCK; - } else { - if (retval < MOVE_TEMP) retval = MOVE_TEMP; - } - break; - - /* - ** Aircraft and buildings always block movement. If for some reason there is an - ** allied terrain object, that blocks movement as well. - */ - case RTTI_TERRAIN: - case RTTI_AIRCRAFT: - case RTTI_BUILDING: - return(MOVE_NO); - - default: - break; - } - - } else { - - /* - ** Cloaked enemy objects are not considered if this is a Find_Path() - ** call. - */ - if (!obj->Is_Techno() || ((TechnoClass *)obj)->Cloak != CLOAKED) { - - /* - ** Any non-allied blockage is considered impassible if the infantry - ** is not equipped with a weapon. - */ - if (Class->Primary == WEAPON_NONE) return(MOVE_NO); - - /* - ** Some kinds of terrain are considered destroyable if the infantry is equipped - ** with the weapon that can destroy it. Otherwise, the terrain is considered - ** impassable. - */ - switch (obj->What_Am_I()) { - case RTTI_TERRAIN: - if (((TerrainClass *)obj)->Class->IsFlammable && - BulletTypeClass::As_Reference(Weapons[Class->Primary].Fires).Warhead == WARHEAD_FIRE) { - - if (retval < MOVE_DESTROYABLE) retval = MOVE_DESTROYABLE; - } else { - return(MOVE_NO); - } - break; - - default: - if (retval < MOVE_DESTROYABLE) retval = MOVE_DESTROYABLE; - break; - } - } else { - if (retval < MOVE_CLOAK) retval = MOVE_CLOAK; - } - } - } - } - - /* - ** Move to next object in chain. - */ - obj = obj->Next; - } - - /* - ** If foot soldiers cannot travel on the cell -- consider it impassible. - */ - if (retval == MOVE_OK && !IsTethered && !Ground[cellptr->Land_Type()].Cost[SPEED_FOOT]) { - return(MOVE_NO); - } - - /* - ** if a unit has the cell reserved then we just can't go in there. - */ - if (retval == MOVE_OK && cellptr->Flag.Occupy.Vehicle) { - return(MOVE_NO); - } - - /* - ** if a block of infantry has the cell reserved then there are two - ** possibilities... - */ - if (cellptr->InfType != HOUSE_NONE) { - if (House->Is_Ally(cellptr->InfType)) { - if ((cellptr->Flag.Composite & 0x1F) == 0x1f) { - if (retval < MOVE_MOVING_BLOCK) retval = MOVE_MOVING_BLOCK; - } - } else { - if (Class->Primary != WEAPON_NONE) { - if (retval < MOVE_DESTROYABLE) retval = MOVE_DESTROYABLE; - } else { - return(MOVE_NO); - } - } - } - - /* - ** If it is still ok to move the infantry, then perform the last check - ** to see if the cell is already full of infantry. - */ - if (retval == MOVE_OK && (cellptr->Flag.Composite & 0x1F) == 0x1F) { - return(MOVE_NO); - } - - /* - ** Return with the most severe reason why this cell would be impassable. - */ - return(retval); -} - - -/*********************************************************************************************** - * InfantryClass::Overlap_List -- The list of cells that the infantry overlaps, but doesn't occ* - * * - * This is a rendering support routine that will return a pointer to a list of cell offsets * - * that specify the cells the infantry unit is currently overlapping (graphic wise) but * - * is not considered to occupy. This list is used to update the map display. * - * * - * INPUT: none * - * * - * OUTPUT: Returns a pointer to an offset list for cells that the unit overlaps but doesn't * - * occupy. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -short const * InfantryClass::Overlap_List(void) const -{ - Validate(); - //return(Coord_Spillage_List(Coord, 24 + ((IsSelected || Doing > DO_WALK)?12:0))); - return(Coord_Spillage_List(Coord, 24 + ((Doing > DO_WALK || Is_Selected_By_Player())?12:0))); -// return(Coord_Spillage_List(Coord, (IsSelected ? 24 : 14))+1); -} - - -/*********************************************************************************************** - * InfantryClass::Can_Fire -- Can the infantry fire its weapon? * - * * - * Determines if the infantry unit can fire on the target. If it can't fire, then the * - * reason why is returned. * - * * - * INPUT: target -- The target to determine if the infantry can fire upon. * - * * - * OUTPUT: Returns the fire error type that indicates if the infantry can fire and if it * - * can't, why not. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - * 06/27/1995 JLB : Flame thrower can fire while prone now. * - *=============================================================================================*/ -FireErrorType InfantryClass::Can_Fire(TARGET target, int which) const -{ - Validate(); - WeaponTypeClass const * weapon = (which == 0) ? &Weapons[Class->Primary] : &Weapons[Class->Secondary]; - -#ifdef BOXING - /* - ** If in hand-to-hand, and we're currently playing a got-hit animation, - ** then we can't punch back yet. - */ - if (IsBoxing) { - if ( (Doing>=DO_PUNCH_HIT1 && Doing<=DO_KICK_DEATH) || (Doing == DO_ON_GUARD) ) return FIRE_BUSY; - if (Arm) return(FIRE_BUSY); // don't let fire if still re-arming - } -#endif - - /* - ** Don't allow firing if the turret is not ready. - */ - if (IsFiring) return(FIRE_REARM); - -#ifdef OBSOLETE - if (weapon->Fires == BULLET_FLAME && IsProne) return(FIRE_ILLEGAL); -#endif - - /* - ** The target must still be legal. - */ - if (!Target_Legal(target)) { - return(FIRE_ILLEGAL); - } - - /* - ** If this unit cannot fire while moving, then bail. - */ - if ((IsDriving && Special.IsDefenderAdvantage) || (Doing != DO_NOTHING && !MasterDoControls[Doing].Interrupt)) { - return(FIRE_MOVING); - } - - /* - ** If we're moving, but not facing the right direction, then exit. - */ - if (!Special.IsDefenderAdvantage && IsDriving) { - int diff = PrimaryFacing.Difference(Direction(TarCom)); - if (ABS(diff) >= 32) { - return(FIRE_MOVING); - } - } - - return(FootClass::Can_Fire(target, which)); -} - - -/*********************************************************************************************** - * InfantryClass::Enter_Idle_Mode -- The infantry unit enters idle mode by this routine. * - * * - * Use this routine when the infantry unit as accomplished its task and needs to find * - * something to do. The default behavior is to enter some idle state such as guarding. * - * * - * INPUT: initial -- Is this called when the unit just leaves a factory or is initially * - * or is initially placed on the map? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Enter_Idle_Mode(bool ) -{ - Validate(); - MissionType order; - - if (Target_Legal(TarCom)) { - order = MISSION_ATTACK; - } else { - if (Target_Legal(NavCom)) { - order = MISSION_MOVE; - } else { - if (GameToPlay == GAME_NORMAL || House->IsHuman) { - order = MISSION_GUARD; - } else { -#ifndef USE_RA_AI - order = MISSION_HUNT; - -#else - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - // This applies only to non-human houses in a non-normal game type - // - - order = MISSION_GUARD; - - if (Mission == MISSION_GUARD || Mission == MISSION_GUARD_AREA) { - return; - } - - if (!Team) { - if (House->IQ >= Rule.IQGuardArea) { - if (Is_Weapon_Equipped()) { - order = MISSION_GUARD_AREA; - } - } - } -#endif - - } - } - } - Assign_Mission(order); -} - - -/*********************************************************************************************** - * InfantryClass::Random_Animate -- Randomly animate the infantry (maybe) * - * * - * This routine is the random animator initiator for infantry units. This routine should * - * be called regularly. On occasion, it will cause the infantry to go into an idle * - * animation. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - * 12/13/1994 JLB : Does random facing change. * - * 07/02/1995 JLB : Nikoomba special effects. * - *=============================================================================================*/ -void InfantryClass::Random_Animate(void) -{ - Validate(); - if (!IsDriving && !IsProne && (Doing == DO_STAND_GUARD || Doing == DO_STAND_READY) && !IsFiring) { - - /* - ** Scared infantry will always follow the golden rule of civilians; - ** "When in darkness or in doubt, run in circles, scream, and shout!" - */ - if (Class->IsFraidyCat && !House->IsHuman && Fear > FEAR_ANXIOUS) { - Scatter(NULL, true); - return; - } - - /* - ** If Nikoomba is not scared, then he will be doing his thing with random animations. - */ - if (*this == INFANTRY_C10) { - switch (Random_Pick(0, 3)) { - case 0: - Do_Action(DO_IDLE2); - break; - - default: - break; - } - } - - switch (Random_Picky((int)0, (int)55, (char*)NULL, (int)0)) { - case 10: - Do_Action(DO_SALUTE1); - break; - - case 11: - Do_Action(DO_SALUTE2); - break; - - case 12: - Do_Action(DO_GESTURE1); - break; - - case 13: - Do_Action(DO_GESTURE2); - break; - - case 4: - case 3: - case 0: - PrimaryFacing.Set(Facing_Dir(Random_Pick(FACING_N, FACING_NW))); - Mark(MARK_CHANGE); - break; - - case 1: - Do_Action(DO_IDLE1); - PrimaryFacing.Set(Facing_Dir(Random_Pick(FACING_N, FACING_NW))); - if (Sim_Random_Pick(1,20) == 1 && !Is_Selected_By_Player() && *this == INFANTRY_MOEBIUS && IsDiscoveredByPlayer) { - static VocType _response[] = { -// VOC_EXCELLENT1, -// VOC_EXCELLENT2, - VOC_EXCELLENT3, -// VOC_EXCELLENT4, -// VOC_EXCELLENT5, - VOC_QUIP1, -// VOC_QUIP2 - }; - Sound_Effect(_response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)], Coord); - } - break; - - case 2: - Do_Action(DO_IDLE2); - PrimaryFacing.Set(Facing_Dir(Random_Pick(FACING_N, FACING_NW))); - if (!Is_Selected_By_Player() && IsOwnedByPlayer && *this == INFANTRY_RAMBO && Sim_Random_Pick(0, 2) == 0) { - Sound_Effect(VOC_RAMBO_CMON, Coord); - } - break; - - /* - ** On occasion, civilian types will wander about. - */ - case 5: - case 6: - case 7: - case 8: - case 9: - if (!House->IsHuman && Class->IsFraidyCat) { - Scatter(NULL, true); - } - break; - } - } -} - - -/*********************************************************************************************** - * InfantryClass::Scatter -- Causes the infantry to scatter to nearby cell. * - * * - * This routine is used when the infantry should scatter to a nearby cell. Scattering * - * occurs as an occasional consequence of being fired upon. It is one of the features * - * that makes infantry so "charming". * - * * - * INPUT: threat -- The coordinate source of the threat that is causing the infantry to * - * scatter. If the threat isn't from a particular direction, then this * - * parameter will be NULL. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - * 12/12/1994 JLB : Flame thrower infantry always scatter. * - *=============================================================================================*/ -void InfantryClass::Scatter(COORDINATE threat, bool forced, bool nokidding) -{ - Validate(); - - /* - ** A unit that is in the process of going somewhere will never scatter. - */ - if (IsDriving || Target_Legal(NavCom)) forced = false; - - /* - ** If the infantry is currently engaged in legitimate combat, then don't - ** scatter unless forced to. - */ - if (!Class->IsFraidyCat && Target_Legal(TarCom) && !forced) return; - - /* - ** Don't scatter if performing an action that can't be interrupted. - */ - if (Doing != DO_NOTHING && !MasterDoControls[Doing].Interrupt) return; - - /* - ** For human players, don't scatter the infantry, if the special - ** flag has not been enabled that allows infantry scatter. - */ - if (!Special.IsScatter && !nokidding && House->IsHuman && !forced && !Team) return; - - if (forced || Class->IsFraidyCat /*|| !(Random_Pick(1, 4) == 1)*/) { - FacingType toface; - FacingType newface; - CELL newcell; - - if (threat) { - toface = Dir_Facing(Direction8(threat, Coord)); - toface = toface + (Random_Pick(0, 4)-2); - } else { - COORDINATE coord = Coord & 0x00FF00FFL; - - if (coord != 0x00800080L) { - toface = Dir_Facing((DirType)Desired_Facing8(0x0080, 0x0080, Coord_X(coord), Coord_Y(coord))); - } else { - toface = Dir_Facing(PrimaryFacing.Current()); - } - toface = toface + (Random_Pick(0, 4)-2); - } - - for (FacingType face = FACING_N; face < FACING_COUNT; face++) { - newface = toface + face; - newcell = Adjacent_Cell(Coord_Cell(Coord), newface); - - if (Map.In_Radar(newcell) && Can_Enter_Cell(newcell) == MOVE_OK) { - if (!Class->IsAvoidingTiberium || - Map[newcell].Overlay == OVERLAY_NONE || - OverlayTypeClass::As_Reference(Map[newcell].Overlay).Land != LAND_TIBERIUM) { - Assign_Mission(MISSION_MOVE); - Assign_Destination(::As_Target(newcell)); - } - } - } - } -} - - -/*********************************************************************************************** - * InfantryClass::Do_Action -- Launches the infantry into an animation sequence. * - * * - * This starts the infantry into a choreographed animation sequence. These sequences can * - * be as simple as standing up or lying down, but can also be complex, such as dying or * - * performing some idle animation. * - * * - * INPUT: todo -- The choreographed sequence to start. * - * * - * force -- Force starting this animation even if the current animation is flagged * - * as uninterruptible. This is necessary for death animations. * - * * - * OUTPUT: bool; Was the animation started? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryClass::Do_Action(DoType todo, bool force) -{ - Validate(); - if (todo != Doing && (Doing == DO_NOTHING || force || MasterDoControls[Doing].Interrupt)) { - Mark(MARK_CHANGE); - //Mark(MARK_OVERLAP_UP); - Doing = todo; - //Mark(MARK_OVERLAP_DOWN); - if (todo == DO_IDLE1 || todo == DO_IDLE2) { - Set_Rate(Options.Normalize_Delay(MasterDoControls[Doing].Rate)); - } else { - Set_Rate(MasterDoControls[Doing].Rate); - } - Set_Stage(0); - - /* - ** Kludge to make sure that if infantry is in the dying animation, it isn't still - ** moving as well. - */ - if (!Strength) { - Stop_Driver(); - } - - /* - ** Since the animation sequence might be interrupted. Set any flags - ** necessary so that if interrupted, the affect on the infantry is - ** still accomplished. - */ - switch (todo) { - case DO_LIE_DOWN: - IsProne = true; - break; - - case DO_GET_UP: - IsProne = false; - break; - - case DO_READY_WEAPON: - IsBoxing = false; - break; - - case DO_ON_GUARD: - IsBoxing = true; - PrimaryFacing.Set(Direction8(Center_Coord(), As_Coord(TarCom))); - Path[0] = FACING_NONE; - break; - - default: - break; - } - - return(true); - } - - return(false); -} - - -/*********************************************************************************************** - * InfantryClass::Stop_Driver -- Stops the infantry from moving any further. * - * * - * This is used to stop the infantry from animating in movement. This function will stop * - * the infantry moving and revert it to either a prone or standing. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the driving stopped? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryClass::Stop_Driver(void) -{ - Validate(); - if (Head_To_Coord()) { - - /* - ** Remove the "reservation" bit in the destination location. - */ - Clear_Occupy_Bit(Head_To_Coord()); - } - - /* - ** Set the occupation bit at the current location. - */ - Set_Occupy_Bit(Coord); - - if (Doing != DO_STAND_READY) { - StopDriverFrame = Frame; - } - - if (IsProne) { - Do_Action(DO_PRONE); - } else { - Do_Action(DO_STAND_READY); - } - - return(FootClass::Stop_Driver()); -} - - -/*********************************************************************************************** - * InfantryClass::Start_Driver -- Handles giving immediate destination and move orders. * - * * - * Use this routine to being the infantry moving toward the destination specified. The * - * destination is first checked to see if there is a free spot available. Then the infantry * - * reserves that spot and begins movement toward it. * - * * - * INPUT: headto -- The coordinate location desired for the infantry to head to. * - * * - * OUTPUT: bool; Was the infantry successfully started on its journey? Failure may be because * - * the specified destination could not contain the infantry unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/21/1994 JLB : Created. * - * 05/14/1995 JLB : Tries to move to closest spot possible. * - * 05/15/1995 JLB : Uses closest spot if moving onto transport. * - *=============================================================================================*/ -bool InfantryClass::Start_Driver(COORDINATE & headto) -{ - Validate(); - COORDINATE old = headto; - - /* - ** Convert the head to coordinate to a legal sub-position location. - */ - headto = Map[Coord_Cell(headto)].Closest_Free_Spot(Coord_Move(headto, Direction(headto)+DIR_S, 0x007C)); - if (!headto && Can_Enter_Cell(Coord_Cell(old)) == MOVE_OK) { - headto = Map[Coord_Cell(old)].Closest_Free_Spot(Coord_Move(old, Direction(headto)+DIR_S, 0x0080), true); - } - - /* - ** If the infantry started moving, then fixup the occupation bits. - */ - if (headto && FootClass::Start_Driver(headto)) { - /* - ** Remove the occupation bit from the infantry's current location. - */ - Clear_Occupy_Bit(Coord); - - /* - ** Set the occupation bit for the new headto location. - */ - Set_Occupy_Bit(headto); - return(true); - } - - return(false); -} - - -#ifdef NEVER -/*********************************************************************************************** - * InfantryClass::Set_Primary_Facing -- Change infantry primary facing -- always and instantly * - * * - * This routine ensures that when the infantry primary facing is changes, it is changed * - * instantly and always. There is no provision for infantry facing changing slowly over * - * time as the other vehicles usually do. * - * * - * INPUT: facing -- The desired facing for the infantry unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/11/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Set_Primary_Facing(DirType facing, bool ) -{ - Validate(); - FootClass::Set_Primary_Facing(facing, true); -} -#endif - - -/*********************************************************************************************** - * InfantryClass::Limbo -- Performs cleanup operations needed when limboing. * - * * - * This routine will clean up the infantry occupation bits (as necessary) as well as stop * - * the infantry movement process when it gets limboed. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the infantry unit limboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryClass::Limbo(void) -{ - Validate(); - if (!IsInLimbo) { - Stop_Driver(); - - Clear_Occupy_Bit(Coord); - } - return(FootClass::Limbo()); -} - - -/*********************************************************************************************** - * InfantryClass::Fire_At -- Fires projectile from infantry unit. * - * * - * Use this routine when the infantry unit wishes to fire a projectile. This routine * - * will launch the projectile and perform any other necessary infantry specific operations. * - * * - * INPUT: target -- The target of the attack. * - * * - * which -- Which weapon to use for firing. 0=primary, 1=secondary. * - * * - * OUTPUT: Returns with pointer to the projectile launched. If none could be launched, then * - * NULL is returned. If there is already the maximum bullet objects in play, then * - * this could happen. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -BulletClass * InfantryClass::Fire_At(TARGET target, int which) -{ - Validate(); - BulletClass * bullet = NULL; - WeaponTypeClass const * weapon = (which == 0) ? &Weapons[Class->Primary] : &Weapons[Class->Secondary]; - - IsFiring = false; - -#ifdef BOXING - if (IsBoxing) { - RadioMessageType hitaction = (Doing == DO_KICK) ? RADIO_KICK : RADIO_PUNCH; - - /* - ** When fighting, verify that the target is legal to proceed. If there is some - ** error, then abort fightning mode. Otherwise, tell the target that it has - ** just been hit. - */ - if (In_Radio_Contact() && Target_Legal(target) && Transmit_Message(hitaction) == RADIO_ROGER) { - Arm = Rearm_Delay(true); - } else { - - /* - ** Fighting done for some reason, so pick up gun - */ - IsBoxing = false; - Do_Action(DO_READY_WEAPON,true); - } - } else { -#endif - - bullet = FootClass::Fire_At(target, which); - if (bullet) { - - /* - ** For fraidycat infantry that run out of ammo, always go into - ** a maximum fear state at that time. - */ - if (Class->IsFraidyCat && !Ammo) { - Fear = FEAR_MAXIMUM; - if (Mission == MISSION_ATTACK || Mission == MISSION_HUNT) { - Assign_Mission(MISSION_GUARD); - } - } - - /* - ** Create the projectile. Then process any special operations that - ** need to be performed according to the style of projectile - ** created. - */ - Sound_Effect(weapon->Sound, Coord); - } - -#ifdef BOXING - } -#endif - return(bullet); -} - - -/*********************************************************************************************** - * InfantryClass::Unlimbo -- Unlimbo infantry unit in legal sub-location. * - * * - * This will attempt to unlimbo the infantry unit at the designated coordinate, but will * - * ensure that the coordinate is a legal subposition. * - * * - * INPUT: coord -- The coordinate to unimbo the infantry at. * - * * - * facing -- The desired initial facing for the infantry unit. * - * * - * strength -- The desired initial strength for the infantry unit. * - * * - * mission -- The desired initial mission for the infantry unit. * - * * - * OUTPUT: bool; Was the infantry unlimboed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryClass::Unlimbo(COORDINATE coord, DirType facing) -{ - Validate(); - /* - ** Make sure that the infantry start in a legal position on the map. - */ - coord = Map[Coord_Cell(coord)].Closest_Free_Spot(coord, ScenarioInit); - if (coord == NULL) { - return(false); - } - - if (FootClass::Unlimbo(coord, facing)) { - - /* - ** Ensure that the owning house knows about the - ** new object. - */ - House->IScan |= (1L << Class->Type); - House->ActiveIScan |= (1L << Class->Type); - - /* - ** If there is no sight range, then this object isn't discovered by the player unless - ** it actually appears in a cell mapped by the player. - */ - if (Class->SightRange == 0) { - IsDiscoveredByPlayer = false; - } - - Set_Occupy_Bit(coord); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * InfantryClass::Greatest_Threat -- Determines greatest threat (target) for infantry unit. * - * * - * This routine intercepts the Greatest_Threat request and adds the appropriate target * - * types to search for. For regular infantry, this consists of all the ground types. For * - * rocket launching infantry, this also includes aircraft. * - * * - * INPUT: threat -- The basic threat control value. * - * * - * OUTPUT: Returns with the best target for this infantry unit to attack. If no suitable * - * target could be found, then TARGET_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - *=============================================================================================*/ -TARGET InfantryClass::Greatest_Threat(ThreatType threat) const -{ - Validate(); - /* - ** Engineers consider only buildings that can be captures as being a threat. All others - ** are ignored. - */ - if (Class->IsCapture && Class->Primary == WEAPON_NONE) { - threat = threat | THREAT_CAPTURE; - } - - switch (Class->Primary) { - case WEAPON_NONE: - if (*this != INFANTRY_E7) { - return(TARGET_NONE); - } - // fall into next case. - - // - // ^ - // | Original comment above. - // - // Crash here because INFANTRY_E7 has no primary weapon and WEAPON_NONE == -1, so we will reference a -ve index into the Weapons array. - // Assume original intent was to fall out of the switch and call the base class Greatest_Threat, so adding a break here. - // ST - 4/24/2019 11:01AM - // - break; // Added. ST - 4/24/2019 11:02AM - - /* - ** Dragon missile equiped soldiers are also assumed to carry a Stinger missile. As such, - ** they will consider aircraft a legal target. - */ - default: - if (BulletTypeClass::As_Reference(Weapons[Class->Primary].Fires).IsAntiAircraft) { - threat = threat | THREAT_AIR; - } - break; - - /* - ** The sniper rifle equipped soldier doesn't go hunting for targets - ** unless specifically in hunt mode. - */ - case WEAPON_RIFLE: - if (House->IsHuman && (Mission == MISSION_GUARD || Mission == MISSION_GUARD_AREA)) { - return(TARGET_NONE); - } - return(TechnoClass::Greatest_Threat(threat | THREAT_INFANTRY|THREAT_BUILDINGS)); - } - return(FootClass::Greatest_Threat(threat)); -} - - -/*********************************************************************************************** - * InfantryClass::Response_Select -- Plays infantry audio response due to being selected. * - * * - * This routine handles playing an audio response as a result of the player selecting the * - * infantry unit. This occurs prior to giving it an order and may not be followed by any * - * order at all. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - * 05/05/1995 JLB : Rambo response types added. * - *=============================================================================================*/ -void InfantryClass::Response_Select(void) -{ - Validate(); - VocType response; - if (*this == INFANTRY_RAMBO) { - static VocType _response[] = { - VOC_RAMBO_YEA, - VOC_RAMBO_YES, - VOC_RAMBO_YO - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } else { - if (Class->IsCivilian) { - if (*this == INFANTRY_MOEBIUS) { - static VocType _response[] = { - VOC_YES, - VOC_COMMANDER, - VOC_HELLO, - VOC_HMMM - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } else { - if (Class->IsFemale) { - response = VOC_GIRL_YEAH; - } else { - response = VOC_GUY_YEAH; - } - } - } else { - static VocType _response[] = { - VOC_ACKNOWL, - VOC_REPORT, - VOC_REPORT, - VOC_YESSIR, - VOC_YESSIR, - VOC_READY, - VOC_AWAIT - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } - } - if (AllowVoice) { - Sound_Effect(response, 0, Infantry.ID(this)+1); - } -} - - -/*********************************************************************************************** - * InfantryClass::Response_Move -- Plays infantry response to movement order. * - * * - * When the infantry is given the order to move, this routine handles the audio repsonse * - * generated by the infantry unit. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - * 05/05/1995 JLB : Rambo response types added. * - *=============================================================================================*/ -void InfantryClass::Response_Move(void) -{ - Validate(); - VocType response; - if (*this == INFANTRY_RAMBO) { - static VocType _response[] = { - VOC_RAMBO_UGOTIT, - VOC_RAMBO_ONIT, - VOC_RAMBO_NOPROB - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } else { - if (Class->IsCivilian) { - if (*this == INFANTRY_MOEBIUS) { - static VocType _response[] = { - VOC_OF_COURSE, - VOC_YESYES - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } else { - if (Class->IsFemale) { - response = VOC_GIRL_OKAY; - } else { - response = VOC_GUY_OKAY; - } - } - } else { - static VocType _response[] = { - VOC_MOVEOUT, - VOC_MOVEOUT, - VOC_MOVEOUT, - VOC_ROGER, - VOC_RIGHT_AWAY, - VOC_UGOTIT, - VOC_AFFIRM, - VOC_AFFIRM - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } - } - if (AllowVoice) { - Sound_Effect(response, 0, Infantry.ID(this)+1); - } -} - - -/*********************************************************************************************** - * InfantryClass::Response_Attack -- Plays infantry audio response to attack order. * - * * - * When the player gives an infantry unit the order to attack, this routine handles * - * the audio response by that unit. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - * 05/05/1995 JLB : Rambo response types added. * - *=============================================================================================*/ -void InfantryClass::Response_Attack(void) -{ - Validate(); - VocType response; - if (*this == INFANTRY_RAMBO) { - static VocType _response[] = { - VOC_RAMBO_NOPROB, - VOC_RAMBO_UGOTIT, - VOC_RAMBO_NOPROB, - VOC_RAMBO_ONIT - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } else { - if (Class->IsCivilian) { - if (Class->IsFemale) { - response = VOC_GIRL_OKAY; - } else { - response = VOC_GUY_OKAY; - } - } else { - static VocType _response[] = { - VOC_RIGHT_AWAY, - VOC_AFFIRM, - VOC_AFFIRM, - VOC_UGOTIT, - VOC_NO_PROB, - VOC_YESSIR, - VOC_YESSIR, - VOC_YESSIR - }; - response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - } - } - - if (AllowVoice) { - Sound_Effect(response, 0, Infantry.ID(this)+1); - } -} - - -/*********************************************************************************************** - * InfantryClass::Fire_Coord -- Calculates the origin point for projectiles fired. * - * * - * This routine will return with the point of origin for any firing projectiles. Typically, * - * this only includes the rocket launcher and the grenade thrower. The other infantry * - * have either invisible projectiles or special animations. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate where the projectile will appear as it is fired. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/04/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE InfantryClass::Fire_Coord(int) const -{ - Validate(); - if (Class->Type == INFANTRY_E4) { - return(Coord); // special case for flame thrower guy - } else { - return(Coord_Add(Coord, XYP_COORD(0, -5))); - } -} - - -/*************************************************************************** - * InfantryClass::Receive_Message -- Process radio messages * - * * - * If the infantry's boxing, it needs to return to a normal state when * - * his opponent moves away. Otherwise fall thru to FootClass processing* - * * - * INPUT: from - Pointer to the originator of this message. * - * * - * message - the message to process * - * * - * param -- Reference to an optional parameter that can be * - * used to transfer more information than is * - * possible with the simple radio message values. * - * * - * OUTPUT: an appropriate response message * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/19/1995 BWG : Created. * - * 05/14/1995 JLB : Handles loading maneuver messages. * - *=========================================================================*/ -RadioMessageType InfantryClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - Validate(); - int damage; - - switch (message) { - - case RADIO_OVER_OUT: -#ifdef BOXING - if (IsBoxing) Do_Action(DO_READY_WEAPON); -#endif - break; - - /* - ** Request a fisticuff fight. If this infantry is already involved in a fight, - ** then refuse the offer. - */ - case RADIO_PREPARE_TO_BOX: -#ifdef BOXING - if (IsBoxing) break; -#endif - if (Contact_With_Whom() == from) { - Do_Action(DO_ON_GUARD, true); - Assign_Target(Contact_With_Whom()->As_Target()); - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - - /* - ** Just received a kick! Take some damage. - */ - case RADIO_KICK: - damage = Infantry_Kick_Damage[Random_Pick(0, (int)(sizeof(Infantry_Kick_Damage) / sizeof(Infantry_Kick_Damage[0])))]; - if (Take_Damage(damage, 0, WARHEAD_FOOT, this) == RESULT_DESTROYED) return(RADIO_STATIC); - return(RADIO_ROGER); - - /* - ** Just recieved a punch! Take some damage. - */ - case RADIO_PUNCH: - damage = Infantry_Punch_Damage[Random_Pick(0, (int)(sizeof(Infantry_Punch_Damage) / sizeof(Infantry_Punch_Damage[0])))]; - if (Take_Damage(damage, 0, WARHEAD_FIST, this) == RESULT_DESTROYED) return(RADIO_STATIC); - return(RADIO_ROGER); - - } - return(FootClass::Receive_Message(from, message, param)); -} - - -/*************************************************************************** - * InfantryClass::Rearm_Delay -- Return Arming delay for infantry if boxing* - * * - * If the infantry's in a boxing mode, return an appropriate re-arming * - * delay. Otherwise return the default return val. * - * * - * INPUT: second -- bool; see TechnoClass... * - * * - * OUTPUT: Returns with the # of game frames to delay before shooting * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 BWG : Created. * - *=========================================================================*/ -int InfantryClass::Rearm_Delay(bool second) const -{ - Validate(); -#ifdef BOXING - if (IsBoxing) { - return(Random_Pick(5, 50)); - } -#endif - return(FootClass::Rearm_Delay(second)); -} - - -/*********************************************************************************************** - * InfantryClass::Assign_Mission -- Assign mission to infantry object. * - * * - * When a new mission is assigned, make sure he gets out of boxing mode. * - * * - * INPUT: order -- The new mission to assign to the unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Assign_Mission(MissionType order) -{ - Validate(); - if (order == MISSION_SABOTAGE) { - Sound_Effect(VOC_RAMBO_PRESENT, Coord); - } - - IsBoxing = false; - FootClass::Assign_Mission(order); -} - - -/*********************************************************************************************** - * InfantryClass::What_Action -- Infantry units might be able to capture -- check. * - * * - * This routine checks to see if the infantry unit can capture the specified object rather * - * than merely attacking it. If this is the case, then ACTION_CAPTURE will be returned. * - * * - * INPUT: object -- The object that the mouse is currently over. * - * * - * OUTPUT: Returns the action that will be performed if the mouse were clicked over the * - * object specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/01/1995 JLB : Created. * - *=============================================================================================*/ -ActionType InfantryClass::What_Action(ObjectClass * object) const -{ - Validate(); - ActionType action = FootClass::What_Action(object); - - /* - ** First see if it's a commando, and if he's attacking a building, have him return ACTION_SABOTAGE instead - */ - if (*this == INFANTRY_RAMBO && action == ACTION_ATTACK && object->What_Am_I() == RTTI_BUILDING) { - return(ACTION_SABOTAGE); - } - - /* - ** There is no self-select action available for infantry types. - */ - if (action == ACTION_SELF) { - action = ACTION_NONE; - } - - /* - ** Check to see if it can enter a transporter. - */ - if ( - House->Is_Ally(object) && - Is_Owned_By_Player() && // Changed for multiplayer. ST - 3/13/2019 5:37PM - //IsOwnedByPlayer && - object->Is_Techno() && - //IsOwnedByPlayer && - ((InfantryClass *)this)->Transmit_Message(RADIO_CAN_LOAD, (TechnoClass*)object) == RADIO_ROGER) { -// if (object->Owner() == Owner() && object->What_Am_I() == RTTI_UNIT && ((UnitClass *)object)->Class->IsTransporter && ((UnitClass *)object)->How_Many() < 5) { - action = ACTION_ENTER; - } - - if (Class->IsCapture && action == ACTION_ATTACK) { - if (object->Owner() != Owner() && - ((object->What_Am_I() == RTTI_AIRCRAFT && ((AircraftClass *)object)->Pip_Count() == 0 && *((AircraftClass *)object) == AIRCRAFT_TRANSPORT) || - (object->What_Am_I() == RTTI_BUILDING && - ((BuildingClass *)object)->Can_Capture())) - ) { - - action = ACTION_CAPTURE; - } else { - if (Class->Primary == WEAPON_NONE) { - action = ACTION_NONE; - } - } - } - return(action); -} - - -/*********************************************************************************************** - * InfantryClass::Read_INI -- Reads units from scenario INI file. * - * * - * This routine is used to read all the starting units from the * - * scenario control INI file. The units are created and placed on the * - * map by this routine. * - * * - * INI entry format: * - * Housename, Typename, Strength, Cellnum, CellSublocation, Missionname, * - * Facingnum, Triggername * - * * - * INPUT: buffer -- Pointer to the loaded scenario INI file. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Read_INI(char *buffer) -{ - InfantryClass *infantry; // Working infantry pointer. - char *tbuffer; // Accumulation buffer of infantry IDs. - HousesType inhouse; // Infantry house. - InfantryType classid; // Infantry class. - int len; // Length of data in buffer. - char buf[128]; - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - /*------------------------------------------------------------------------ - Read the entire INFANTRY INI section into HIDBUF - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - - while (*tbuffer != '\0') { - - /* - ** Get an infantry entry - */ - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - - /* - ** 1st token: house name. - */ - inhouse = HouseTypeClass::From_Name(strtok(buf, ",\n\r")); - if (inhouse != HOUSE_NONE) { - - /* - ** 2nd token: infantry type name. - */ - classid = InfantryTypeClass::From_Name(strtok(NULL, ",\n\r")); - - /* - ** Special case: replace C7 with C5 on scg08eb - */ - if (GameToPlay == GAME_NORMAL && PlayerPtr->ActLike == HOUSE_GOOD && Scenario == 8 && ScenVar == SCEN_VAR_B && classid == INFANTRY_C7) { - classid = INFANTRY_C5; - } - - if (classid != INFANTRY_NONE) { - - if (HouseClass::As_Pointer(inhouse) != NULL) { - infantry = new InfantryClass(classid, inhouse); - if (infantry) { - - /* - ** 3rd token: strength. - */ - int strength = atoi(strtok(NULL, ",\n\r")); - - /* - ** 4th token: cell #. - */ - COORDINATE coord = Cell_Coord((CELL)atoi(strtok(NULL, ",\n\r"))); - - /* - ** 5th token: cell sub-location. - */ - coord = Coord_Add(coord & 0xFF00FF00L, StoppingCoordAbs[atoi(strtok(NULL, ","))]); - - /* - ** Fetch the mission and facing. - */ - MissionType mission = MissionClass::Mission_From_Name(strtok(NULL, ",\n\r")); - DirType dir = (DirType)atoi(strtok(NULL,",\n\r")); - infantry->Trigger = TriggerClass::As_Pointer(strtok(NULL,",\n\r")); - if (infantry->Trigger) { - infantry->Trigger->AttachCount++; - } - - /* - ** Special case: delete pre-placed Chan on scb10ea; he will spawn from the Tech Center. - */ - bool is_scb10ea_chan = GameToPlay == GAME_NORMAL && PlayerPtr->ActLike == HOUSE_BAD && Scenario == 10 && ScenVar == SCEN_VAR_A && *infantry == INFANTRY_CHAN; - - if (!is_scb10ea_chan && infantry->Unlimbo(coord, dir)) { - infantry->Strength = Fixed_To_Cardinal(infantry->Class_Of().MaxStrength, strength); - if (GameToPlay == GAME_NORMAL || infantry->House->IsHuman) { - infantry->Assign_Mission(mission); - infantry->Commence(); - } else { - infantry->Enter_Idle_Mode(); - } - } else { - - /* - ** If the infantry could not be unlimboed, then this is a big error. - ** Delete the infantry. - */ - delete infantry; - } - } - } - } - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * InfantryClass::Write_INI -- Writes all the infantry out to an INI file. * - * * - * This routine writes all of the infantry in the game out to an INI file. This is used * - * in the scenario editor when the game needs to be saved. * - * * - * INI entry format: * - * Housename, Typename, Strength, Cellnum, CellSublocation, Missionname, * - * Facingnum, Triggername * - * * - * INPUT: buffer -- A pointer to the loaded INI file staging area. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Write_INI(char *buffer) -{ - int index; - char uname[10]; - char buf[128]; - char *tbuffer; // Accumulation buffer of infantry IDs. - - /* - ** First, clear out all existing infantry data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Write the infantry data out. - */ - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * infantry; - - infantry = Infantry.Ptr(index); - if (!infantry->IsInLimbo) { - - sprintf(uname, "%03d", index); - sprintf(buf, "%s,%s,%d,%u,%d,%s,%d,%s", - infantry->House->Class->IniName, - infantry->Class->IniName, - infantry->Health_Ratio(), - Coord_Cell(infantry->Coord), - CellClass::Spot_Index(infantry->Coord), - MissionClass::Mission_Name((infantry->Mission == MISSION_NONE) ? - infantry->MissionQueue : infantry->Mission), - infantry->PrimaryFacing.Current(), - infantry->Trigger ? infantry->Trigger->Get_Name() : "None" - ); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} - - -/*********************************************************************************************** - * InfantryClass::Active_Click_With -- Handles action when clicking with infantry soldier. * - * * - * This routine is called when the player clicks over an object while this infantry soldier * - * is selected. Capture attempts are prohibited if the infantry cannot capture. The * - * command might respond if told to sabotage something. * - * * - * INPUT: action -- The action that is nominally to be performed. * - * * - * object -- The object over which the mouse was clicked. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void InfantryClass::Active_Click_With(ActionType action, ObjectClass * object) -{ - Validate(); - if (What_Action(object) != action) { - switch (action) { - case ACTION_SABOTAGE: - case ACTION_CAPTURE: - action = ACTION_ATTACK; - break; - - case ACTION_ENTER: - action = ACTION_MOVE; - break; - - default: - action = ACTION_NONE; - break; - } - } - - FootClass::Active_Click_With(action, object); -} - - -/*********************************************************************************************** - * InfantryClass::Made_A_Kill -- Marks a kill caused by this infantry soldier. * - * * - * When the infantry soldier is responsible for a kill, this routine is called. It checks * - * to see if the soldier should make some comment or perform some action. The commando * - * infantry is most likely to respond. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of kills this infantry soldier has made. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -int InfantryClass::Made_A_Kill(void) -{ - Validate(); - if (*this == INFANTRY_RAMBO || Random_Pick(0, 5) < Kills) { - IsStoked = true; - Comment = TICKS_PER_SECOND*2; - } - return(FootClass::Made_A_Kill()); -} - - -/*********************************************************************************************** - * InfantryClass::Set_Occupy_Bit -- Sets the occupy bit cell and bit pos * - * * - * INPUT: CELL - the cell we are setting the bit in * - * * - * int - the spot index we are setting the bit for * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 06/08/1995 PWG : Created. * - *=============================================================================================*/ -void InfantryClass::Set_Occupy_Bit(CELL cell, int spot_index) -{ - Validate(); - - if ((unsigned)cell >= MAP_CELL_TOTAL) { - return; - } - - /* - ** Set the occupy postion for the spot that we passed in - */ - Map[cell].Flag.Composite |= (1 << spot_index); - - /* - ** Record the type of infantry that now owns the cell - */ - Map[cell].InfType = Owner(); -} - - -/*************************************************************************** - * InfantryClass::Clear_Occupy_Bit -- Clears occupy bit and given cell * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/08/1995 PWG : Created. * - *=========================================================================*/ -void InfantryClass::Clear_Occupy_Bit(CELL cell, int spot_index) -{ - Validate(); - - if ((unsigned)cell >= MAP_CELL_TOTAL) { - return; - } - - /* - ** Clear the occupy bit for the infantry in that cell - */ - Map[cell].Flag.Composite &= ~(1 << spot_index); - - /* - ** If he was the last infantry recorded in the cell then - ** remove the infantry ownership flag. - */ - if (!(Map[cell].Flag.Composite & 0x1F)) { - Map[cell].InfType = HOUSE_NONE; - } -} - - -/*********************************************************************************************** - * InfantryClass::Full_Name -- Fetches the full name of the infantry unit. * - * * - * This routine will return with the full name (as a text number) for this infantry * - * unit. Typically, this is the normal name, but in cases of civilian type survivors from * - * a building explosion, it might be a technician instead. In such a case, the special * - * technician name number is returned instead. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the full name to use for this infantry unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/30/1995 JLB : Created. * - *=============================================================================================*/ -int InfantryClass::Full_Name(void) const -{ - Validate(); - if (IsTechnician) { - return(TXT_TECHNICIAN); - } - return(Class->Full_Name()); -} - - -/*********************************************************************************************** - * InfantryClass::Mission_Attack -- Intercept attack mission for special handling. * - * * - * This routine intercepts the normal attack mission and if an engineer is detected and the * - * target is a building, then the engineer will be automatically assigned the capture * - * mission. In other cases, the normal attack logic will proceed. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of game frames to delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/07/1995 JLB : Created. * - *=============================================================================================*/ -int InfantryClass::Mission_Attack(void) -{ - Validate(); - if (*this == INFANTRY_E7 && As_Building(TarCom)) { - Assign_Destination(TarCom); - Assign_Mission(MISSION_CAPTURE); - return(1); - } - return(FootClass::Mission_Attack()); -} - - -RTTIType InfantryClass::What_Am_I(void) const -{ - Validate(); - return(RTTI_INFANTRY); -} - -ActionType InfantryClass::What_Action(CELL cell) const -{ - Validate(); - return FootClass::What_Action(cell); -} - -ObjectTypeClass const & InfantryClass::Class_Of(void) const -{ - Validate(); - return(*Class); -} - -bool InfantryClass::Is_Infantry(void) const -{ - Validate(); - return(true); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/INFANTRY.H b/code/TIBERIANDAWN/INFANTRY.H deleted file mode 100644 index 225d9a7..0000000 --- a/code/TIBERIANDAWN/INFANTRY.H +++ /dev/null @@ -1,251 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\infantry.h_v 2.18 16 Oct 1995 16:48:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INFANTRY.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 15, 1994 * - * * - * Last Update : August 15, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef INFANTRY_H -#define INFANTRY_H - -/********************************************************************** -** Infantry can be afraid. These defines are for the various infantry -** fear levels. When infantry be come scared enough they take cover and -** even run away in panic. -*/ -#define FEAR_ANXIOUS 10 // Something makes them scared. -#define FEAR_SCARED 100 // Scared enough to take cover. -#define FEAR_PANIC 200 // Run away! Run away! -#define FEAR_MAXIMUM 255 // Scared to death. - - -class InfantryClass : public FootClass -{ - public: - InfantryTypeClass const * const Class; - operator InfantryType(void) const {return Class->Type;}; - - /* - ** If the infantry is undergoing some choreographed animation sequence, then - ** this holds the particular sequence number. The frame of animation is kept - ** track of by the regular frame tracking system. When performing an animation - ** sequence, the infantry cannot perform anything else (even move). - */ - DoType Doing; - - /* - ** Certain infantry will either perform some comment or say something after an - ** amount of time has expired subsiquent to an significant event. This is the - ** timer the counts down. - */ - TCountDownTimerClass Comment; - - /* - ** If this civilian is actually a technician, then this flag will be true. - ** It should only be set for the civilian type infantry. Typically, the - ** technician appears after a building is destroyed. - */ - unsigned IsTechnician:1; - - /* - ** If the infantry just performed some feat, then it may respond with an action. - ** This flag will be true if an action is to be performed when the Comment timer - ** has expired. - */ - unsigned IsStoked:1; - - /* - ** This flag indicates if the infantry unit is prone. Prone infantry become that way - ** when they are fired upon. Infantry in the prone position are less vulnerable to - ** combat. - */ - unsigned IsProne:1; - - /* - ** This flag is set when the infantryman is engaged in hand-to-hand - ** combat. By setting this flag, it'll play the put-down-the-gun - ** sequence only once, and it'll know to pick up the gun when the - ** fight is over. - */ - unsigned IsBoxing:1; - - /* - ** Track when movement last stopped. - */ - long StopDriverFrame; - - /* - ** The fear rating of this infantry unit. The more afraid the infantry, the more - ** likely it is to panic and seek cover. - */ - unsigned char Fear; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - InfantryClass(void); - InfantryClass(InfantryType classid, HousesType house); - virtual ~InfantryClass(void); - virtual RTTIType What_Am_I(void) const; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - static void Init(void); - - virtual void Assign_Destination(TARGET); - - /* - ** Query functions. - */ - virtual bool Is_Infantry(void) const; - virtual ObjectTypeClass const & Class_Of(void) const; - virtual int Full_Name(void) const; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Fire_Coord(int which) const; - - /* - ** Object entry and exit from the game system. - */ - virtual bool Unlimbo(COORDINATE coord, DirType facing); - virtual bool Limbo(void); - virtual void Detach(TARGET target, bool all); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual short const * Overlap_List(void) const; - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual void Look(bool incremental=false); - - /* - ** User I/O. - */ - virtual void Response_Select(void); - virtual void Response_Move(void); - virtual void Response_Attack(void); - virtual void Active_Click_With(ActionType action, ObjectClass * object); - - /* - ** Combat related. - */ - virtual int Made_A_Kill(void); - virtual ActionType What_Action(ObjectClass * object) const; - virtual ActionType What_Action(CELL cell) const; - virtual void Assign_Mission(MissionType order); - virtual BulletClass * Fire_At(TARGET target, int which); - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source=0); - virtual TARGET As_Target(void) const; - virtual FireErrorType Can_Fire(TARGET target, int which) const; - virtual void Assign_Target(TARGET); - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual int Rearm_Delay(bool second) const; - void Set_Occupy_Bit(COORDINATE coord) {Set_Occupy_Bit(Coord_Cell(coord), CellClass::Spot_Index(coord));}; - void Set_Occupy_Bit(CELL cell, int spot_index); - void Clear_Occupy_Bit(COORDINATE coord) {Clear_Occupy_Bit(Coord_Cell(coord), CellClass::Spot_Index(coord));}; - void Clear_Occupy_Bit(CELL cell, int spot_index); - - /* - ** Driver control support functions. These are used to control cell - ** occupation flags and driver instructions. - */ - virtual bool Stop_Driver(void); - virtual bool Start_Driver(COORDINATE & coord); - - /* - ** AI. - */ - virtual void AI(void); - virtual TARGET Greatest_Threat(ThreatType threat) const; - virtual int Mission_Attack(void); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static char *INI_Name(void) {return "INFANTRY";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Movement and animation. - */ - virtual bool Do_Action(DoType todo, bool force=false); - virtual void Random_Animate(void); - virtual MoveType Can_Enter_Cell(CELL , FacingType =FACING_NONE) const; - virtual void Per_Cell_Process(bool center); - virtual void Enter_Idle_Mode(bool initial=false); - virtual void Scatter(COORDINATE threat, bool forced =false, bool nokidding =false); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** Translation table to convert facing into infantry shape number. This special - ** table is needed since several facing stages are reused and flipped about the Y - ** axis. - */ - static int const HumanShape[32]; - - private: - - static DoStruct const MasterDoControls[DO_COUNT]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/INI.CPP b/code/TIBERIANDAWN/INI.CPP deleted file mode 100644 index 1bfcad7..0000000 --- a/code/TIBERIANDAWN/INI.CPP +++ /dev/null @@ -1,2331 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ini.cpv 2.18 16 Oct 1995 16:48:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INI.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : July 30, 1995 [BRR] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Assign_Houses -- Assigns multiplayer houses to various players * - * Clear_Flag_Spots -- Clears flag overlays off the map * - * Clip_Move -- moves in given direction from given cell; clips to map * - * Clip_Scatter -- randomly scatters from given cell; won't fall off map * - * Create_Units -- Creates infantry & units, for non-base multiplayer * - * Furthest_Cell -- Finds cell furthest from a group of cells * - * Place_Flags -- Places flags for multiplayer games * - * Read_Scenario_Ini -- Read specified scenario INI file. * - * Remove_AI_Players -- Removes the computer AI houses & their units * - * Scan_Place_Object -- places an object >near< the given cell * - * Set_Scenario_Name -- Creates the INI scenario name string. * - * Sort_Cells -- sorts an array of cells by distance * - * Write_Scenario_Ini -- Write the scenario INI file. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/************************************* Prototypes *********************************************/ -static void Assign_Houses(void); -static void Remove_AI_Players(void); -static void Create_Units(void); -static void Sort_Cells(CELL *cells, int numcells, CELL *outcells); -static int Furthest_Cell(CELL *cells, int numcells, CELL *tcells, int numtcells); -static CELL Clip_Scatter(CELL cell, int maxdist); -static CELL Clip_Move(CELL cell, FacingType facing, int dist); - - -/*********************************************************************************************** - * Set_Scenario_Name -- Creates the INI scenario name string. * - * * - * This routine is used by the scenario loading and saving code. It generates the scenario * - * INI root file name for the specified scenario parameters. * - * * - * INPUT: * - * buf buffer to store filename in; must be long enough for root.ext * - * scenario scenario number * - * player player type for this game (GDI, NOD, multi-player, ...) * - * dir directional parameter for this game (East/West) * - * var variation of this game (Lose, A/B/C/D, etc) * - * * - * OUTPUT: none. * - * * - * WARNINGS: none. * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - * 05/01/1995 BRR : 2-player scenarios use same names as multiplayer * - *=============================================================================================*/ -void Set_Scenario_Name(char *buf, int scenario, ScenarioPlayerType player, ScenarioDirType dir, ScenarioVarType var) -{ - char c_player; // character representing player type - char c_dir; // character representing direction type - char c_var; // character representing variation type - ScenarioVarType i; - char fname[_MAX_FNAME+_MAX_EXT]; - - /* - ** Set the player-type value. - */ - switch (player) { - case SCEN_PLAYER_GDI: - c_player = HouseTypeClass::As_Reference(HOUSE_GOOD).Prefix; -// c_player = 'G'; - break; - - case SCEN_PLAYER_NOD: - c_player = HouseTypeClass::As_Reference(HOUSE_BAD).Prefix; -// c_player = 'B'; - break; - - case SCEN_PLAYER_JP: - c_player = HouseTypeClass::As_Reference(HOUSE_JP).Prefix; -// c_player = 'J'; - break; - - /* - ** Multi player scenario. - */ - default: - c_player = HouseTypeClass::As_Reference(HOUSE_MULTI1).Prefix; -// c_player = 'M'; - break; - } - - /* - ** Set the directional character value. - ** If SCEN_DIR_NONE is specified, randomly pick a direction; otherwise, use 'E' or 'W' - */ - switch (dir) { - case SCEN_DIR_EAST: - c_dir = 'E'; - break; - - case SCEN_DIR_WEST: - c_dir = 'W'; - break; - - default: - case SCEN_DIR_NONE: - c_dir = (Random_Pick(0, 1) == 0) ? 'W' : 'E'; - break; - } - - /* - ** Set the variation value. - */ - if (var == SCEN_VAR_NONE) { - - /* - ** Find which variations are available for this scenario - */ - for (i = SCEN_VAR_FIRST; i < SCEN_VAR_COUNT; i++) { - sprintf(fname, "SC%c%02d%c%c.INI", c_player, scenario, c_dir, 'A' + i); - if (!CCFileClass(fname).Is_Available()) { - break; - } - } - - if (i==SCEN_VAR_FIRST) { - c_var = 'X'; // indicates an error - } else { - c_var = 'A' + Random_Pick(0, i-1); - } - } else { - switch (var) { - case SCEN_VAR_A: - c_var = 'A'; - break; - - case SCEN_VAR_B: - c_var = 'B'; - break; - - case SCEN_VAR_C: - c_var = 'C'; - break; - - case SCEN_VAR_D: - c_var = 'D'; - break; - - default: - c_var = 'L'; - break; - - } - } - - /* - ** generate the filename - */ - sprintf(buf, "SC%c%02d%c%c", c_player, scenario, c_dir, c_var); -} - - -extern void GlyphX_Assign_Houses(void); //ST - 6/25/2019 11:08AM - - -/*********************************************************************************************** - * Read_Scenario_Ini -- Read specified scenario INI file. * - * * - * Read in the scenario INI file. This routine only sets the game * - * globals with that data that is explicitly defined in the INI file. * - * The remaining necessary interpolated data is generated elsewhere. * - * * - * INPUT: * - * root root filename for scenario file to read * - * * - * fresh true = should the current scenario be cleared? * - * * - * OUTPUT: bool; Was the scenario read successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -bool Read_Scenario_Ini(char *root, bool fresh) -{ - char *buffer; // Scenario.ini staging buffer pointer. - char fname[_MAX_FNAME+_MAX_EXT]; // full INI filename - char buf[128]; // Working string staging buffer. -#ifndef USE_RA_AI - int rndmax; - int rndmin; -#endif //USE_RA_AI - int len; - unsigned char val; - - ScenarioInit++; - - /* - ** Fetch working pointer to the INI staging buffer. Make sure that the buffer - ** is cleared out before proceeding. (Don't use the HidPage for this, since - ** the HidPage may be needed for various uncompressions during the INI - ** parsing.) - */ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - if (fresh) { - Clear_Scenario(); - } - - /* - ** If we are not dealing with scenario 1, or a multi player scenario - ** then make sure the correct disk is in the drive. - */ - if (RequiredCD != -2) { - if (Scenario >= 20 && Scenario <60 && GameToPlay == GAME_NORMAL) { - RequiredCD = 2; - } else { - if (Scenario != 1) { - if (Scenario >=60){ - RequiredCD = -1; - }else{ - switch (ScenPlayer) { - case SCEN_PLAYER_GDI: - RequiredCD = 0; - break; - case SCEN_PLAYER_NOD: - RequiredCD = 1; - break; - default: - RequiredCD = -1; - break; - } - } - } else { - RequiredCD = -1; - } - } - } - if (!Force_CD_Available(RequiredCD)) { - Prog_End("Read_Scenario_Ini - CD not found", true); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } - } - - /* - ** Create scenario filename and read the file. - */ - - sprintf(fname,"%s.INI",root); - CCFileClass file(fname); - if (!file.Is_Available()) { - GlyphX_Debug_Print("Failed to find scenario file"); - GlyphX_Debug_Print(fname); - return(false); - } else { - - GlyphX_Debug_Print("Opened scenario file"); - GlyphX_Debug_Print(fname); - - file.Read(buffer, _ShapeBufferSize-1); - } - - /* - ** Init the Scenario CRC value - */ - ScenarioCRC = 0; - len = strlen(buffer); - for (int i = 0; i < len; i++) { - val = (unsigned char)buffer[i]; -#ifndef DEMO - Add_CRC(&ScenarioCRC, (unsigned long)val); -#endif - } - - /* - ** Fetch the appropriate movie names from the INI file. - */ - WWGetPrivateProfileString("Basic", "Intro", "x", IntroMovie, sizeof(IntroMovie), buffer); - WWGetPrivateProfileString("Basic", "Brief", "x", BriefMovie, sizeof(BriefMovie), buffer); - WWGetPrivateProfileString("Basic", "Win", "x", WinMovie, sizeof(WinMovie), buffer); - WWGetPrivateProfileString("Basic", "Win2", "x", WinMovie2, sizeof(WinMovie2), buffer); - WWGetPrivateProfileString("Basic", "Win3", "x", WinMovie3, sizeof(WinMovie3), buffer); - WWGetPrivateProfileString("Basic", "Win4", "x", WinMovie4, sizeof(WinMovie4), buffer); - WWGetPrivateProfileString("Basic", "Lose", "x", LoseMovie, sizeof(LoseMovie), buffer); - WWGetPrivateProfileString("Basic", "Action", "x", ActionMovie, sizeof(ActionMovie), buffer); - - /* - ** For single-player scenarios, 'BuildLevel' is the scenario number. - ** This must be set before any buildings are created (if a factory is created, - ** it needs to know the BuildLevel for the sidebar.) - */ - if (GameToPlay == GAME_NORMAL) { -#ifdef NEWMENU - if (Scenario <= 15) { - BuildLevel = Scenario; - } else { - BuildLevel = WWGetPrivateProfileInt("Basic", "BuildLevel", Scenario, buffer); - } -#else - BuildLevel = Scenario; -#endif - } - - /* - ** Jurassic scenarios are allowed to build the full multiplayer set - ** of objects. - */ - if (Special.IsJurassic && AreThingiesEnabled) { - BuildLevel = 98; - } - - /* - ** Fetch the transition theme for this scenario. - */ - TransitTheme = THEME_NONE; - WWGetPrivateProfileString("Basic", "Theme", "No Theme", buf, sizeof(buf), buffer); - TransitTheme = Theme.From_Name(buf); - - /* - ** Read in the team-type data. The team types must be created before any - ** triggers can be created. - */ - TeamTypeClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the specific information for each of the house types. This creates - ** the houses of different types. - */ - HouseClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the trigger data. The triggers must be created before any other - ** objects can be initialized. - */ - TriggerClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the map control values. This includes dimensions - ** as well as theater information. - */ - Map.Read_INI(buffer); - Call_Back(); - - /* - ** Assign PlayerPtr by reading the player's house from the INI; - ** Must be done before any TechnoClass objects are created. - */ -// if (GameToPlay == GAME_NORMAL && (ScenPlayer == SCEN_PLAYER_GDI || ScenPlayer == SCEN_PLAYER_NOD)) { - if (GameToPlay == GAME_NORMAL) { - WWGetPrivateProfileString("Basic", "Player", "GoodGuy", buf, 127, buffer); - CarryOverPercent = WWGetPrivateProfileInt("Basic", "CarryOverMoney", 100, buffer); - CarryOverPercent = Cardinal_To_Fixed(100, CarryOverPercent); - CarryOverCap = WWGetPrivateProfileInt("Basic", "CarryOverCap", -1, buffer); - - PlayerPtr = HouseClass::As_Pointer(HouseTypeClass::From_Name(buf)); - PlayerPtr->IsHuman = true; - int carryover; - if (CarryOverCap != -1) { - carryover = MIN((int)Fixed_To_Cardinal(CarryOverMoney, CarryOverPercent), CarryOverCap); - } else { - carryover = Fixed_To_Cardinal(CarryOverMoney, CarryOverPercent); - } - PlayerPtr->Credits += carryover; - PlayerPtr->InitialCredits += carryover; - - if (Special.IsJurassic) { - PlayerPtr->ActLike = Whom; - } - - if (Special.IsEasy) { - PlayerPtr->Assign_Handicap(DIFF_EASY); - } else if (Special.IsDifficult) { - PlayerPtr->Assign_Handicap(DIFF_HARD); - } - } else { - -#ifdef OBSOLETE - if (GameToPlay==GAME_NORMAL && ScenPlayer==SCEN_PLAYER_JP) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4); - PlayerPtr->IsHuman = true; - PlayerPtr->Credits += CarryOverMoney; - PlayerPtr->InitialCredits += CarryOverMoney; - PlayerPtr->ActLike = Whom; - } else { - Assign_Houses(); - } -#endif - //Call new Assign_Houses function. ST - 6/25/2019 11:07AM - //Assign_Houses(); - GlyphX_Assign_Houses(); - } - - /* - ** Attempt to read the map's binary image file; if fails, read the - ** template data from the INI, for backward compatibility - */ - if (fresh) { - if (!Map.Read_Binary(root, &ScenarioCRC)) { - TemplateClass::Read_INI(buffer); - } - } - Call_Back(); - - /* - ** Read in and place the 3D terrain objects. - */ - TerrainClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in and place the units (all sides). - */ - UnitClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in and place the infantry units (all sides). - */ - InfantryClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in and place all the buildings on the map. - */ - BuildingClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the AI's base information. - */ - Base.Read_INI(buffer); - Call_Back(); - - /* - ** Read in any normal overlay objects. - */ - OverlayClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in any smudge overlays. - */ - SmudgeClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in any briefing text. - */ - char * stage = &BriefingText[0]; - *stage = '\0'; - int index = 1; - - /* - ** Build the full text of the mission objective. - */ - for (;;) { - char buff[16]; - - sprintf(buff, "%d", index++); - *stage = '\0'; - WWGetPrivateProfileString("Briefing", buff, "", stage, (sizeof(BriefingText)-strlen(BriefingText))-1, buffer); - if (strlen(stage) == 0) break; - strcat(stage, " "); - stage += strlen(stage); - } - - /* - ** If the briefing text could not be found in the INI file, then search - ** the mission.ini file. - */ - if (BriefingText[0] == '\0') { - memset(_ShapeBuffer, '\0', _ShapeBufferSize); - CCFileClass("MISSION.INI").Read(_ShapeBuffer, _ShapeBufferSize); - - char * buffer = (char *)Add_Long_To_Pointer(_ShapeBuffer, strlen(_ShapeBuffer)); - char * work = &BriefingText[0]; - int index = 1; - - /* - ** Build the full text of the mission objective. - */ - for (;;) { - char buff[16]; - - sprintf(buff, "%d", index++); - *work = '\0'; - WWGetPrivateProfileString(root, buff, "", work, (sizeof(BriefingText)-strlen(BriefingText))-1, _ShapeBuffer); - if (strlen(work) == 0) break; - strcat(work, " "); - work += strlen(work); - } - } - - /* - ** Perform a final overpass of the map. This handles smoothing of certain - ** types of terrain (tiberium). - */ - Map.Overpass(); - Call_Back(); - - /* - ** Special cases: - ** NOD7A cell 2795 - LAND_ROCK - ** NOD09A - delete airstrike trigger when radar destroyed - ** NOD10B cell 2015 - LAND_ROCK - */ - if (_stricmp(ScenarioName, "scb07ea") == 0) { - Map[(CELL)2795].Override_Land_Type(LAND_ROCK); - } - if (_stricmp(ScenarioName, "scb09ea") == 0) { - for (int index = 0; index < Buildings.Count(); ++index) { - BuildingClass* building = Buildings.Ptr(index); - if (building != NULL && building->Owner() == HOUSE_GOOD && *building == STRUCT_RADAR) { - building->Trigger = TriggerClass::As_Pointer("dely"); - if (building->Trigger) { - building->Trigger->AttachCount++; - } - break; - } - } - } - if (_stricmp(ScenarioName, "scb10eb") == 0) { - Map[(CELL)2015].Override_Land_Type(LAND_ROCK); - } - - /* - ** Scenario fix-up (applied on loaded games as well) - */ - Fixup_Scenario(); - - /* - ** Multi-player last-minute fixups: - ** - If computer players are disabled, remove all computer-owned houses - ** - Otherwise, set MPlayerBlitz to 0 or 1, randomly - ** - If bases are disabled, create the scenario dynamically - ** - Remove any flag spot overlays lying around - ** - If capture-the-flag is enabled, assign flags to cells. - */ - if (GameToPlay != GAME_NORMAL || ScenPlayer == SCEN_PLAYER_2PLAYER || - ScenPlayer == SCEN_PLAYER_MPLAYER) { - - /* - ** If Ghosts are disabled and we're not editing, remove computer players - ** (Must be done after all objects are read in from the INI) - */ - if (!MPlayerGhosts && !Debug_Map) { - //Remove_AI_Players(); // Done elsewhere now. ST - 6/25/2019 12:33PM - } else { - - /* - ** If Ghosts are on, set up their houses for blitzing the humans - */ -#ifndef USE_RA_AI - MPlayerBlitz = IRandom (0,1); // 1 = computer will blitz - - if (MPlayerBlitz) { - if (MPlayerBases) { - rndmax = 14000; - rndmin = 10000; - } else { - rndmax = 8000; - rndmin = 4000; - } - - for (int i = 0; i < MPlayerMax; i++) { - HousesType house = (HousesType)(i + (int)HOUSE_MULTI1); - HouseClass *housep = HouseClass::As_Pointer (house); - if (housep) { //Added. ST - 6/25/2019 11:37AM - housep->BlitzTime = IRandom (rndmin,rndmax); - } - } - - } -#else // USE_RA_AI - MPlayerBlitz = 0; -#endif // USE_RA_AI - } - - /* - ** Units must be created for each house. If bases are ON, this routine - ** will create an MCV along with the units; otherwise, it will just create - ** a whole bunch of units. MPlayerUnitCount is the total # of units - ** to create. - */ - if (!Debug_Map) { - int save_init = ScenarioInit; // turn ScenarioInit off - ScenarioInit = 0; - Create_Units(); - ScenarioInit = save_init; // turn ScenarioInit back on - } - - /* - ** Place crates if MPlayerGoodies is on. - */ - if (MPlayerGoodies) { - for (int index = 0; index < MPlayerCount; index++) { - //for (int index = 0; index < 200; index++) { // Lots of crates for test - Map.Place_Random_Crate(); - } - } - } - - Call_Back(); - - /* - ** Return with flag saying that the scenario file was read. - */ - ScenarioInit--; - return(true); -} - - -/*********************************************************************************************** - * Read_Scenario_Ini_File -- Read specified scenario INI file. * - * * - * Read in the scenario INI file. This routine only sets the game * - * globals with that data that is explicitly defined in the INI file. * - * The remaining necessary interpolated data is generated elsewhere. * - * * - * INPUT: * - * scenario_file_name path to the ini for the scenario * - * * - * bin_file_name path to the bin for the scenario * - * * - * root root filename for scenario file to read * - * * - * fresh true = should the current scenario be cleared? * - * * - * OUTPUT: bool; Was the scenario read successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/28/2019 JAS : Created. * - *=============================================================================================*/ -bool Read_Scenario_Ini_File(char *scenario_file_name, char* bin_file_name, const char* root, bool fresh) -{ - ScenarioInit++; - - char *buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - char buf[128]; - int len; - unsigned char val; - - CCFileClass file(scenario_file_name); - if (!file.Is_Available()) { - GlyphX_Debug_Print("Failed to find scenario file"); - GlyphX_Debug_Print(scenario_file_name); - return(false); - } - else { - - GlyphX_Debug_Print("Opened scenario file"); - GlyphX_Debug_Print(scenario_file_name); - - file.Read(buffer, _ShapeBufferSize - 1); - } - - /* - ** Init the Scenario CRC value - */ - ScenarioCRC = 0; - len = strlen(buffer); - for (int i = 0; i < len; i++) { - val = (unsigned char)buffer[i]; -#ifndef DEMO - Add_CRC(&ScenarioCRC, (unsigned long)val); -#endif - } - - /* - ** Fetch the appropriate movie names from the INI file. - */ - WWGetPrivateProfileString("Basic", "Intro", "x", IntroMovie, sizeof(IntroMovie), buffer); - WWGetPrivateProfileString("Basic", "Brief", "x", BriefMovie, sizeof(BriefMovie), buffer); - WWGetPrivateProfileString("Basic", "Win", "x", WinMovie, sizeof(WinMovie), buffer); - WWGetPrivateProfileString("Basic", "Win2", "x", WinMovie2, sizeof(WinMovie2), buffer); - WWGetPrivateProfileString("Basic", "Win3", "x", WinMovie3, sizeof(WinMovie3), buffer); - WWGetPrivateProfileString("Basic", "Win4", "x", WinMovie4, sizeof(WinMovie4), buffer); - WWGetPrivateProfileString("Basic", "Lose", "x", LoseMovie, sizeof(LoseMovie), buffer); - WWGetPrivateProfileString("Basic", "Action", "x", ActionMovie, sizeof(ActionMovie), buffer); - - /* - ** For single-player scenarios, 'BuildLevel' is the scenario number. - ** This must be set before any buildings are created (if a factory is created, - ** it needs to know the BuildLevel for the sidebar.) - */ - if (GameToPlay == GAME_NORMAL) { - /* - ** In this function we are only dealing with custom maps, so set based on the BuildLevel from the map, or 98 if none. - ** ST - 4/22/2020 5:14PM - */ - BuildLevel = WWGetPrivateProfileInt("Basic", "BuildLevel", 98, buffer); - } - - /* - ** Jurassic scenarios are allowed to build the full multiplayer set - ** of objects. - */ - if (Special.IsJurassic && AreThingiesEnabled) { - BuildLevel = 98; - } - - /* - ** Fetch the transition theme for this scenario. - */ - TransitTheme = THEME_NONE; - WWGetPrivateProfileString("Basic", "Theme", "No Theme", buf, sizeof(buf), buffer); - TransitTheme = Theme.From_Name(buf); - - /* - ** Read in the team-type data. The team types must be created before any - ** triggers can be created. - */ - TeamTypeClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the specific information for each of the house types. This creates - ** the houses of different types. - */ - HouseClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the trigger data. The triggers must be created before any other - ** objects can be initialized. - */ - TriggerClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the map control values. This includes dimensions - ** as well as theater information. - */ - Map.Read_INI(buffer); - Call_Back(); - - /* - ** Assign PlayerPtr by reading the player's house from the INI; - ** Must be done before any TechnoClass objects are created. - */ - // if (GameToPlay == GAME_NORMAL && (ScenPlayer == SCEN_PLAYER_GDI || ScenPlayer == SCEN_PLAYER_NOD)) { - if (GameToPlay == GAME_NORMAL) { - WWGetPrivateProfileString("Basic", "Player", "GoodGuy", buf, 127, buffer); - CarryOverPercent = WWGetPrivateProfileInt("Basic", "CarryOverMoney", 100, buffer); - CarryOverPercent = Cardinal_To_Fixed(100, CarryOverPercent); - CarryOverCap = WWGetPrivateProfileInt("Basic", "CarryOverCap", -1, buffer); - - PlayerPtr = HouseClass::As_Pointer(HouseTypeClass::From_Name(buf)); - PlayerPtr->IsHuman = true; - int carryover; - if (CarryOverCap != -1) { - carryover = MIN((int)Fixed_To_Cardinal(CarryOverMoney, CarryOverPercent), CarryOverCap); - } - else { - carryover = Fixed_To_Cardinal(CarryOverMoney, CarryOverPercent); - } - PlayerPtr->Credits += carryover; - PlayerPtr->InitialCredits += carryover; - - if (Special.IsJurassic) { - PlayerPtr->ActLike = Whom; - } - - if (Special.IsEasy) { - PlayerPtr->Assign_Handicap(DIFF_EASY); - } - else if (Special.IsDifficult) { - PlayerPtr->Assign_Handicap(DIFF_HARD); - } - } - else { - -#ifdef OBSOLETE - if (GameToPlay == GAME_NORMAL && ScenPlayer == SCEN_PLAYER_JP) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4); - PlayerPtr->IsHuman = true; - PlayerPtr->Credits += CarryOverMoney; - PlayerPtr->InitialCredits += CarryOverMoney; - PlayerPtr->ActLike = Whom; - } - else { - Assign_Houses(); - } -#endif - //Call new Assign_Houses function. ST - 6/25/2019 11:07AM - //Assign_Houses(); - GlyphX_Assign_Houses(); - } - - /* - ** Attempt to read the map's binary image file; if fails, read the - ** template data from the INI, for backward compatibility - */ - if (fresh) { - if (!Map.Read_Binary_File(bin_file_name, &ScenarioCRC)) { - TemplateClass::Read_INI(buffer); - } - } - Call_Back(); - - /* - ** Read in and place the 3D terrain objects. - */ - TerrainClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in and place the units (all sides). - */ - UnitClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in and place the infantry units (all sides). - */ - InfantryClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in and place all the buildings on the map. - */ - BuildingClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in the AI's base information. - */ - Base.Read_INI(buffer); - Call_Back(); - - /* - ** Read in any normal overlay objects. - */ - OverlayClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in any smudge overlays. - */ - SmudgeClass::Read_INI(buffer); - Call_Back(); - - /* - ** Read in any briefing text. - */ - char * stage = &BriefingText[0]; - *stage = '\0'; - int index = 1; - - /* - ** Build the full text of the mission objective. - */ - for (;;) { - char buff[16]; - - sprintf(buff, "%d", index++); - *stage = '\0'; - WWGetPrivateProfileString("Briefing", buff, "", stage, (sizeof(BriefingText) - strlen(BriefingText)) - 1, buffer); - if (strlen(stage) == 0) break; - strcat(stage, " "); - stage += strlen(stage); - } - - /* - ** If the briefing text could not be found in the INI file, then search - ** the mission.ini file. - */ - if (BriefingText[0] == '\0') { - memset(_ShapeBuffer, '\0', _ShapeBufferSize); - CCFileClass("MISSION.INI").Read(_ShapeBuffer, _ShapeBufferSize); - - char * buffer = (char *)Add_Long_To_Pointer(_ShapeBuffer, strlen(_ShapeBuffer)); - char * work = &BriefingText[0]; - int index = 1; - - /* - ** Build the full text of the mission objective. - */ - for (;;) { - char buff[16]; - - sprintf(buff, "%d", index++); - *work = '\0'; - WWGetPrivateProfileString(root, buff, "", work, (sizeof(BriefingText) - strlen(BriefingText)) - 1, _ShapeBuffer); - if (strlen(work) == 0) break; - strcat(work, " "); - work += strlen(work); - } - } - - /* - ** Perform a final overpass of the map. This handles smoothing of certain - ** types of terrain (tiberium). - */ - Map.Overpass(); - Call_Back(); - - /* - ** Multi-player last-minute fixups: - ** - If computer players are disabled, remove all computer-owned houses - ** - Otherwise, set MPlayerBlitz to 0 or 1, randomly - ** - If bases are disabled, create the scenario dynamically - ** - Remove any flag spot overlays lying around - ** - If capture-the-flag is enabled, assign flags to cells. - */ - if (GameToPlay != GAME_NORMAL || ScenPlayer == SCEN_PLAYER_2PLAYER || - ScenPlayer == SCEN_PLAYER_MPLAYER) { - - /* - ** If Ghosts are disabled and we're not editing, remove computer players - ** (Must be done after all objects are read in from the INI) - */ - if (!MPlayerGhosts && !Debug_Map) { - //Remove_AI_Players(); // Done elsewhere now. ST - 6/25/2019 12:33PM - } - else { - - /* - ** If Ghosts are on, set up their houses for blitzing the humans - */ -#ifndef USE_RA_AI - MPlayerBlitz = IRandom(0, 1); // 1 = computer will blitz - - if (MPlayerBlitz) { - if (MPlayerBases) { - rndmax = 14000; - rndmin = 10000; - } - else { - rndmax = 8000; - rndmin = 4000; - } - - for (int i = 0; i < MPlayerMax; i++) { - HousesType house = (HousesType)(i + (int)HOUSE_MULTI1); - HouseClass *housep = HouseClass::As_Pointer(house); - if (housep) { //Added. ST - 6/25/2019 11:37AM - housep->BlitzTime = IRandom(rndmin, rndmax); - } - } - - } -#else // USE_RA_AI - MPlayerBlitz = 0; -#endif // USE_RA_AI - } - - /* - ** Units must be created for each house. If bases are ON, this routine - ** will create an MCV along with the units; otherwise, it will just create - ** a whole bunch of units. MPlayerUnitCount is the total # of units - ** to create. - */ - if (!Debug_Map) { - int save_init = ScenarioInit; // turn ScenarioInit off - ScenarioInit = 0; - Create_Units(); - ScenarioInit = save_init; // turn ScenarioInit back on - } - - /* - ** Place crates if MPlayerGoodies is on. - */ - if (MPlayerGoodies) { - for (int index = 0; index < MPlayerCount; index++) { - //for (int index = 0; index < 200; index++) { // Lots of crates for test - Map.Place_Random_Crate(); - } - } - } - - Call_Back(); - - /* - ** Return with flag saying that the scenario file was read. - */ - ScenarioInit--; - return(true); -} - - - -/*********************************************************************************************** - * Read_Movies_From_Scenario_Ini -- Reads just the movie files from the scenario. * - * * - * * - * INPUT: * - * root root filename for scenario file to read * - * * - * fresh true = should the current scenario be cleared? * - * * - * OUTPUT: bool; Was the scenario read successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/14/2019 JAS : Created. * - *=============================================================================================*/ -bool Read_Movies_From_Scenario_Ini(char *root, bool fresh) -{ - char *buffer; // Scenario.ini staging buffer pointer. - char fname[_MAX_FNAME + _MAX_EXT]; // full INI filename -// char buf[128]; // Working string staging buffer. -#ifndef USE_RA_AI - int rndmax; - int rndmin; -#endif //USE_RA_AI - int len; - unsigned char val; - - ScenarioInit++; - - /* - ** Fetch working pointer to the INI staging buffer. Make sure that the buffer - ** is cleared out before proceeding. (Don't use the HidPage for this, since - ** the HidPage may be needed for various uncompressions during the INI - ** parsing.) - */ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - if (fresh) { - Clear_Scenario(); - } - - /* - ** If we are not dealing with scenario 1, or a multi player scenario - ** then make sure the correct disk is in the drive. - */ - if (RequiredCD != -2) { - if (Scenario >= 20 && Scenario < 60 && GameToPlay == GAME_NORMAL) { - RequiredCD = 2; - } - else { - if (Scenario != 1) { - if (Scenario >= 60) { - RequiredCD = -1; - } - else { - switch (ScenPlayer) { - case SCEN_PLAYER_GDI: - RequiredCD = 0; - break; - case SCEN_PLAYER_NOD: - RequiredCD = 1; - break; - default: - RequiredCD = -1; - break; - } - } - } - else { - RequiredCD = -1; - } - } - } - if (!Force_CD_Available(RequiredCD)) { - Prog_End("Read_Scenario_Ini - CD not found", true); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } - } - - /* - ** Create scenario filename and read the file. - */ - - sprintf(fname, "%s.INI", root); - CCFileClass file(fname); - if (!file.Is_Available()) { - GlyphX_Debug_Print("Failed to find scenario file"); - GlyphX_Debug_Print(fname); - return(false); - } - else { - - GlyphX_Debug_Print("Opened scenario file"); - GlyphX_Debug_Print(fname); - - file.Read(buffer, _ShapeBufferSize - 1); - } - - /* - ** Init the Scenario CRC value - */ - ScenarioCRC = 0; - len = strlen(buffer); - for (int i = 0; i < len; i++) { - val = (unsigned char)buffer[i]; -#ifndef DEMO - Add_CRC(&ScenarioCRC, (unsigned long)val); -#endif - } - - /* - ** Fetch the appropriate movie names from the INI file. - */ - WWGetPrivateProfileString("Basic", "Intro", "x", IntroMovie, sizeof(IntroMovie), buffer); - WWGetPrivateProfileString("Basic", "Brief", "x", BriefMovie, sizeof(BriefMovie), buffer); - WWGetPrivateProfileString("Basic", "Win", "x", WinMovie, sizeof(WinMovie), buffer); - WWGetPrivateProfileString("Basic", "Win2", "x", WinMovie2, sizeof(WinMovie2), buffer); - WWGetPrivateProfileString("Basic", "Win3", "x", WinMovie3, sizeof(WinMovie3), buffer); - WWGetPrivateProfileString("Basic", "Win4", "x", WinMovie4, sizeof(WinMovie4), buffer); - WWGetPrivateProfileString("Basic", "Lose", "x", LoseMovie, sizeof(LoseMovie), buffer); - WWGetPrivateProfileString("Basic", "Action", "x", ActionMovie, sizeof(ActionMovie), buffer); - - /* - ** Fetch the transition theme for this scenario. - */ - TransitTheme = THEME_NONE; - WWGetPrivateProfileString("Basic", "Theme", "No Theme", MovieThemeName, sizeof(MovieThemeName), buffer); - //TransitTheme = Theme.From_Name(buf); - - /* - ** Return with flag saying that the scenario file was read. - */ - ScenarioInit--; - return(true); -} - - - -/*********************************************************************************************** - * Write_Scenario_Ini -- Write the scenario INI file. * - * * - * INPUT: * - * root root filename for the scenario * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 05/11/1995 JLB : Updates movie data. * - *=============================================================================================*/ -void Write_Scenario_Ini(char *root) -{ -#ifndef CHEAT_KEYS - root = root; -#else - char * buffer; // Scenario.ini staging buffer pointer. - char fname[_MAX_FNAME+_MAX_EXT]; // full scenario name - HousesType house; - CCFileClass file; - - /* - ** Get a working pointer to the INI staging buffer. Make sure that the buffer - ** starts cleared out of any data. - */ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - switch (ScenPlayer) { - case SCEN_PLAYER_GDI: - house = HOUSE_GOOD; - break; - - case SCEN_PLAYER_NOD: - house = HOUSE_BAD; - break; - - case SCEN_PLAYER_JP: - house = HOUSE_JP; - break; - - default: - house = HOUSE_MULTI1; - break; - } - - /* - ** Create scenario filename and clear the buffer to empty. - */ - sprintf(fname,"%s.INI",root); - file.Set_Name(fname); - if (file.Is_Available()) { -// file.Open(READ); - file.Read(buffer, _ShapeBufferSize-1); -// file.Close(); - } else { - sprintf(buffer, "; Scenario %d control for house %s.\r\n", Scenario, HouseTypeClass::As_Reference(house).IniName); - } - - WWWritePrivateProfileString("Basic", "Intro", IntroMovie, buffer); - WWWritePrivateProfileString("Basic", "Brief", BriefMovie, buffer); - WWWritePrivateProfileString("Basic", "Win", WinMovie, buffer); - WWWritePrivateProfileString("Basic", "Win2", WinMovie, buffer); - WWWritePrivateProfileString("Basic", "Win3", WinMovie, buffer); - WWWritePrivateProfileString("Basic", "Win4", WinMovie, buffer); - WWWritePrivateProfileString("Basic", "Lose", LoseMovie, buffer); - WWWritePrivateProfileString("Basic", "Action", ActionMovie, buffer); - WWWritePrivateProfileString("Basic", "Player", PlayerPtr->Class->IniName, buffer); - WWWritePrivateProfileString("Basic", "Theme", Theme.Base_Name(TransitTheme), buffer); - WWWritePrivateProfileInt("Basic", "BuildLevel", BuildLevel, buffer); - WWWritePrivateProfileInt("Basic", "CarryOverMoney", Fixed_To_Cardinal(100, CarryOverPercent), buffer); - WWWritePrivateProfileInt("Basic", "CarryOverCap", CarryOverCap, buffer); - - TeamTypeClass::Write_INI(buffer, true); - TriggerClass::Write_INI(buffer, true); - Map.Write_INI(buffer); - Map.Write_Binary(root); - HouseClass::Write_INI(buffer); - UnitClass::Write_INI(buffer); - InfantryClass::Write_INI(buffer); - BuildingClass::Write_INI(buffer); - TerrainClass::Write_INI(buffer); - OverlayClass::Write_INI(buffer); - SmudgeClass::Write_INI(buffer); - - Base.Write_INI(buffer); - - /* - ** Write the scenario data out to a file. - */ -// file.Open(WRITE); - file.Write(buffer, strlen(buffer)); -// file.Close(); - - /* - ** Now update the Master INI file, containing the master list of triggers & teams - */ - memset(buffer, '\0', _ShapeBufferSize); - - file.Set_Name("MASTER.INI"); - if (file.Is_Available()) { -// file.Open(READ); - file.Read(buffer, _ShapeBufferSize-1); -// file.Close(); - } else { - sprintf(buffer, "; Master Trigger & Team List.\r\n"); - } - - TeamTypeClass::Write_INI(buffer, false); - TriggerClass::Write_INI(buffer, false); - -// file.Open(WRITE); - file.Write(buffer,strlen(buffer)); -// file.Close(); -#endif -} - - -/*********************************************************************************************** - * Assign_Houses -- Assigns multiplayer houses to various players * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/09/1995 BRR : Created. * - * 07/14/1995 JLB : Records name of player in house structure. * - *=============================================================================================*/ -static void Assign_Houses(void) -{ - HousesType house; - HousesType pref_house; - HouseClass *housep; - bool house_used[MAX_PLAYERS]; // true = this house is in use - bool color_used[16]; // true = this color is in use. We have more than 6 color options now, so bumped this to 16. ST - 6/19/2019 5:18PM - int i,j; - PlayerColorType color; - HousesType house2; - HouseClass *housep2; - - /* - ** Init the 'used' flag for all houses & colors to 0 - */ - for (i = 0; i < MAX_PLAYERS; i++) { - house_used[i] = false; - } - for (i = 0; i < 16; i++) { - color_used[i] = false; - } - - /* - ** For each player, randomly pick a house - */ - for (i = 0; i < MPlayerCount; i++) { - j = Random_Pick(0, MPlayerMax-1); - - /* - ** If this house was already selected, decrement 'i' & keep looping. - */ - if (house_used[j]) { - i--; - continue; - } - - /* - ** Set the house, preferred house (GDI/NOD), color, and actual house; - ** get a pointer to the house instance - */ - house = (HousesType)(j + (int)HOUSE_MULTI1); - pref_house = MPlayerID_To_HousesType(MPlayerID[i]); - color = MPlayerID_To_ColorIndex(MPlayerID[i]); - housep = HouseClass::As_Pointer(house); - MPlayerHouses[i] = house; - - /* - ** Mark this house & color as used - */ - house_used[j] = true; - color_used[color] = true; - - /* - ** Set the house's IsHuman, Credits, ActLike, & RemapTable - */ - memset((char *)housep->Name, 0, MPLAYER_NAME_MAX); - strncpy((char *)housep->Name, MPlayerNames[i], MPLAYER_NAME_MAX-1); - housep->IsHuman = true; - housep->Init_Data(color, pref_house, MPlayerCredits); - - /* - ** If this ID is for myself, set up PlayerPtr - */ - if (MPlayerID[i] == MPlayerLocalID) { - PlayerPtr = housep; - } - } - - /* - ** For all houses not assigned to a player, set them up for computer use - */ - for (i = 0; i < MPlayerMax; i++) { - if (house_used[i] == false) { - - /* - ** Set the house, preferred house (GDI/NOD), and color; get a pointer - ** to the house instance - */ - house = (HousesType)(i + (int)HOUSE_MULTI1); - pref_house = (HousesType)(IRandom(0, 1) + (int)HOUSE_GOOD); - for (;;) { - color = Random_Pick(REMAP_FIRST, REMAP_LAST); - if (color_used[color] == false) { - break; - } - } - housep = HouseClass::As_Pointer (house); - - /* - ** Mark this house & color as used - */ - house_used[i] = true; - color_used[color] = true; - - /* - ** Set the house's IsHuman, Credits, ActLike, & RemapTable - */ - housep->IsHuman = false; - housep->Init_Data(color, pref_house, MPlayerCredits); - } - } - - /* - ** Now make all computer-owned houses allies of each other. - */ - for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { - housep = HouseClass::As_Pointer(house); - if (housep->IsHuman) - continue; - - for (house2 = HOUSE_MULTI1; house2 < (HOUSE_MULTI1 + MPlayerMax); house2++) { - housep2 = HouseClass::As_Pointer (house2); - if (housep2->IsHuman) - continue; - housep->Make_Ally(house2); - } - } -} - - -/*********************************************************************************************** - * Remove_AI_Players -- Removes the computer AI houses & their units * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/09/1995 BRR : Created. * - *=============================================================================================*/ -static void Remove_AI_Players(void) -{ - int i; - HousesType house; - HouseClass *housep; - - for (i = 0; i < MAX_PLAYERS; i++) { - house = (HousesType)(i + (int)HOUSE_MULTI1); - housep = HouseClass::As_Pointer (house); - if (housep->IsHuman == false) { - housep->Clobber_All(); - } - } -} - -#define USE_GLYPHX_START_LOCATIONS 1 - -/*********************************************************************************************** - * Create_Units -- Creates infantry & units, for non-base multiplayer * - * * - * This routine uses data tables to determine which units to create for either * - * a GDI or NOD house, and how many of each. * - * * - * It also sets each house's FlagHome & FlagLocation to the Waypoint selected * - * as that house's "home" cell. * - * * - * ------------------ Unit Summary: ------------------------------- * - * UNIT_MTANK Medium tank (M1). GDI 7 * - * UNIT_JEEP 4x4 jeep replacement. GDI 5 * - * UNIT_MLRS MLRS rocket launcher. GDI 99 * - * UNIT_APC APC. GDI 10 * - * UNIT_HTANK Heavy tank (Mammoth). GDI 13 * - * * - * UNIT_LTANK Light tank ('Bradly'). NOD 5 * - * UNIT_BUGGY Rat patrol dune buggy type NOD 5 * - * UNIT_ARTY Artillery unit. NOD 10 * - * UNIT_FTANK Flame thrower tank. NOD 11 * - * UNIT_STANK Stealth tank (Romulan). NOD 13 * - * UNIT_BIKE Nod recon motor-bike. NOD 99 * - * * - * ~1/3 chance of getting: {UNIT_MHQ, Mobile Head Quarters. * - * * - * ------------------ Infantry Summary: ------------------------------- * - * INFANTRY_E1, Mini-gun armed. GDI/NOD * - * INFANTRY_E2, Grenade thrower. GDI * - * INFANTRY_E3, Rocket launcher. NOD * - * INFANTRY_E6, Rocket launcher GDI * - * INFANTRY_E4, Flame thrower equipped. NOD * - * INFANTRY_RAMBO, Commando. GDI/NOD * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/09/1995 BRR : Created. * - *=============================================================================================*/ -static int ReserveInfantryIndex = 0; -static void Reserve_Infantry() -{ - if (Infantry.Count() == Infantry.Length()) { - delete Infantry.Ptr(ReserveInfantryIndex); - ReserveInfantryIndex = (ReserveInfantryIndex + 1) % Infantry.Length(); - } -} - -static int ReserveUnitIndex = 0; -static void Reserve_Unit() -{ - if (Units.Count() == Units.Length()) { - delete Units.Ptr(ReserveUnitIndex); - ReserveUnitIndex = (ReserveUnitIndex + 1) % Units.Length(); - } -} - -static void Create_Units(void) -{ - enum { - NUM_UNIT_CATEGORIES = 8, - NUM_INFANTRY_CATEGORIES = 5, - }; - - static struct { - int MinLevel; - int GDICount; - UnitType GDIType; - int NODCount; - UnitType NODType; - } utable[] = { - {0, 1,UNIT_MTANK, 2,UNIT_LTANK}, - {2, 1,UNIT_JEEP, 1,UNIT_BUGGY}, - {3, 1,UNIT_MLRS, 1,UNIT_ARTY}, - {4, 1,UNIT_APC, 2,UNIT_BUGGY}, - {5, 1,UNIT_JEEP, 1,UNIT_BIKE}, - {5, 2,UNIT_JEEP, 1,UNIT_FTANK}, - {6, 1,UNIT_MSAM, 1,UNIT_MSAM}, - {7, 1,UNIT_HTANK, 2,UNIT_STANK}, - }; - static int num_units[NUM_UNIT_CATEGORIES]; // # of each type of unit to create - int tot_units; // total # units to create - - static struct { - int MinLevel; - int GDICount; - InfantryType GDIType; - int NODCount; - InfantryType NODType; - } itable[] = { - {0, 1,INFANTRY_E1, 1,INFANTRY_E1}, - {1, 1,INFANTRY_E2, 1,INFANTRY_E3}, - {3, 1,INFANTRY_E3, 1,INFANTRY_E3}, - {5, 1,INFANTRY_E3, 1,INFANTRY_E4}, - {7, 1,INFANTRY_RAMBO, 1,INFANTRY_RAMBO}, - }; - static int num_infantry[NUM_INFANTRY_CATEGORIES];// # of each type of infantry to create - int tot_infantry; // total # infantry to create - - CELL waypts[26]; -// CELL sorted_waypts[26]; - int num_waypts; - - HousesType h; // house loop counter - HouseClass *hptr; // ptr to house being processed - - CELL centroid; // centroid of this house's stuff -// int try_count; // # times we've tried to select a centroid - CELL centerpt; // centroid for a category of objects, as a CELL - - int u_limit; // last allowable index of units for this BuildLevel - int i_limit; // last allowable index of infantry for this BuildLevel - TechnoClass *obj; // newly-created object - int i,j,k; // loop counters - int scaleval; // value to scale # units or infantry - - ReserveInfantryIndex = ReserveUnitIndex = 0; - - /*------------------------------------------------------------------------ - For the current BuildLevel, find the max allowable index into the tables - ------------------------------------------------------------------------*/ - for (i = 0; i < NUM_UNIT_CATEGORIES; i++) { - if (BuildLevel >= (unsigned)utable[i].MinLevel) - u_limit = i; - } - for (i = 0; i < NUM_INFANTRY_CATEGORIES; i++) { - if (BuildLevel >= (unsigned)utable[i].MinLevel) - i_limit = i; - } - - /*------------------------------------------------------------------------ - Compute how many of each buildable category to create - ------------------------------------------------------------------------*/ - /*........................................................................ - Compute allowed # units - ........................................................................*/ - tot_units = (MPlayerUnitCount * 2) / 3; -// tot_units = MAX(tot_units, 1); - - /*........................................................................ - Init # of each category to 0 - ........................................................................*/ - for (i = 0; i <= u_limit; i++) - num_units[i] = 0; - - /*........................................................................ - Increment # of each category, until we've used up all units - ........................................................................*/ - j = 0; - for (i = 0; i < tot_units; i++) { - num_units[j]++; - j++; - if (j > u_limit) - j = 0; - } - - /*........................................................................ - Compute allowed # infantry - ........................................................................*/ - tot_infantry = MPlayerUnitCount - tot_units; - - /*........................................................................ - Init # of each category to 0 - ........................................................................*/ - for (i = 0; i <= i_limit; i++) - num_infantry[i] = 0; - - /*........................................................................ - Increment # of each category, until we've used up all infantry - ........................................................................*/ - j = 0; - for (i = 0; i < tot_infantry; i++) { - num_infantry[j]++; - j++; - if (j > i_limit) - j = 0; - } - - /*------------------------------------------------------------------------ - Now sort all the Waypoints on the map by distance. - ------------------------------------------------------------------------*/ - num_waypts = 0; // counts # waypoints - - /*........................................................................ - First, copy all valid waytpoints into my 'waypts' array - ........................................................................*/ - for (i = 0; i < 26; i++) { - if (Waypoint[i] != -1) { - waypts[num_waypts] = Waypoint[i]; - num_waypts++; - } - } - - /*........................................................................ - Now sort the 'waypts' array - ........................................................................*/ -#ifndef USE_GLYPHX_START_LOCATIONS - //Sort_Cells (waypts, num_waypts, sorted_waypts); -#endif - - /*------------------------------------------------------------------------ - Loop through all houses. Computer-controlled houses, with MPlayerBases - ON, are treated as though bases are OFF (since we have no base-building - AI logic.) - ------------------------------------------------------------------------*/ - for (h = HOUSE_MULTI1; h < (HOUSE_MULTI1 + MPlayerMax); h++) { - - /*..................................................................... - Get a pointer to this house; if there is none, go to the next house - .....................................................................*/ - hptr = HouseClass::As_Pointer(h); - if (!hptr) - continue; - -#ifdef USE_GLYPHX_START_LOCATIONS - /* - ** New code that respects the start locations passed in from GlyphX. - ** - ** ST - 1/8/2020 3:39PM - */ - centroid = waypts[hptr->StartLocationOverride]; - -#else // USE_GLYPHX_START_LOCATIONS - /* - ** Original start position logic. - */ - - /*..................................................................... - Pick a random waypoint; if the chosen waypoint isn't valid, try again. - 'centroid' will be the centroid of all this house's stuff. - .....................................................................*/ - try_count = 0; - while (1) { - j = IRandom(0,MPlayerMax - 1); - if (sorted_waypts[j] != -1) { - centroid = sorted_waypts[j]; - sorted_waypts[j] = -1; - break; - } - try_count++; - - /*.................................................................. - OK, we've tried enough; just pick any old cell at random, as long - as it's mappable. - ..................................................................*/ - if (try_count > 200) { - while (1) { - centroid = IRandom(0,MAP_CELL_TOTAL - 1); - if (Map.In_Radar(centroid)) - break; - } - break; - } - } -#endif // USE_GLYPHX_START_LOCATIONS - - /*--------------------------------------------------------------------- - If Bases are ON, human & computer houses are treated differently - ---------------------------------------------------------------------*/ - if (MPlayerBases) { - /*.................................................................. - - For a human-controlled house: - - Set 'scaleval' to 1 - - Create an MCV - - Attach a flag to it for capture-the-flag mode - ..................................................................*/ - if (hptr->IsHuman) { - scaleval = 1; - -#ifndef USE_RA_AI // Moved to below. ST - 7/25/2019 11:21AM - obj = new UnitClass (UNIT_MCV, h); - if (!obj->Unlimbo(Cell_Coord(centroid),DIR_N)) { - if (!Scan_Place_Object(obj, centroid)) { - delete obj; - obj = NULL; - } - } - if (obj) { - hptr->FlagHome = 0; - hptr->FlagLocation = 0; - if (Special.IsCaptureTheFlag) { - hptr->Flag_Attach((UnitClass *)obj,true); - } - } -#endif //USE_RA_AI - } else { - - /*.................................................................. - - For computer-controlled house: - - Set 'scaleval' to 3 - - Create a Mobile HQ for capture-the-flag mode - ..................................................................*/ - // Added fix for divide by zero. ST - 6/26/2019 10:40AM - int ai_player_count = MPlayerMax - MPlayerCount; - //scaleval = 3 / (MPlayerMax - MPlayerCount); - //scaleval = max(ai_player_count, 1); - scaleval = 1; //Set to 1 since EA QA can't beat skirmish with scaleval set higher. - - //if (scaleval==0) { - // scaleval = 1; - //} - -#ifndef USE_RA_AI // Give the AI an MCV below. ST - 7/25/2019 11:22AM - if (Special.IsCaptureTheFlag) { - obj = new UnitClass (UNIT_MHQ, h); - if (!obj->Unlimbo(Cell_Coord(centroid),DIR_N)) { - if (!Scan_Place_Object(obj, centroid)) { - delete obj; - obj = NULL; - } - } - hptr->FlagHome = 0; // turn house's flag off - hptr->FlagLocation = 0; - } -#endif //USE_RA_AI - } - -#ifdef USE_RA_AI - /* - ** Moved HQ code down here, so the AI player gets one too. ST - 7/25/2019 11:21AM - */ - Reserve_Unit(); - obj = new UnitClass (UNIT_MCV, h); - if (!obj->Unlimbo(Cell_Coord(centroid),DIR_N)) { - if (!Scan_Place_Object(obj, centroid)) { - delete obj; - obj = NULL; - } - } - if (obj) { - hptr->FlagHome = 0; - hptr->FlagLocation = 0; - if (Special.IsCaptureTheFlag) { - hptr->Flag_Attach((UnitClass *)obj,true); - } - } -#endif //USE_RA_AI - - - } else { - - /*--------------------------------------------------------------------- - If bases are OFF, set 'scaleval' to 1 & create a Mobile HQ for - capture-the-flag mode. - ---------------------------------------------------------------------*/ - scaleval = 1; - if (Special.IsCaptureTheFlag) { - Reserve_Unit(); - obj = new UnitClass (UNIT_MHQ, h); - obj->Unlimbo(Cell_Coord(centroid),DIR_N); - hptr->FlagHome = 0; // turn house's flag off - hptr->FlagLocation = 0; - } - } - - /*--------------------------------------------------------------------- - Set the house's max # units (this is used in the Mission_Timed_Hunt()) - ---------------------------------------------------------------------*/ - hptr->MaxUnit = MPlayerUnitCount * scaleval; - - /*--------------------------------------------------------------------- - Create units for this house - ---------------------------------------------------------------------*/ - for (i = 0; i <= u_limit; i++) { - /*.................................................................. - Find the center point for this category. - ..................................................................*/ - centerpt = Clip_Scatter(centroid,4); - - /*.................................................................. - Place objects; loop through all unit in this category - ..................................................................*/ - for (j = 0; j < num_units[i] * scaleval; j++) { - /*............................................................... - Create a GDI unit - ...............................................................*/ - if (hptr->ActLike == HOUSE_GOOD) { - for (k = 0; k < utable[i].GDICount; k++) { - Reserve_Unit(); - obj = new UnitClass (utable[i].GDIType, h); - if (!Scan_Place_Object(obj, centerpt)) { - delete obj; - } else { - - /* - ** Don't use MISSION_TIMED_HUNT since it can trigger blitz behavior. ST - 2/28/2020 10:51AM - */ - //if (!hptr->IsHuman) { - // obj->Set_Mission(MISSION_TIMED_HUNT); - //} - if (!hptr->IsHuman) { - obj->Set_Mission(MISSION_GUARD_AREA); - } - } - } - } else { - - /*............................................................... - Create a NOD unit - ...............................................................*/ - for (k = 0; k < utable[i].NODCount; k++) { - Reserve_Unit(); - obj = new UnitClass (utable[i].NODType, h); - if (!Scan_Place_Object(obj, centerpt)) { - delete obj; - } else { - /* - ** Don't use MISSION_TIMED_HUNT since it can trigger blitz behavior. ST - 2/28/2020 10:51AM - */ - //if (!hptr->IsHuman) { - // obj->Set_Mission(MISSION_TIMED_HUNT); - //} - if (!hptr->IsHuman) { - obj->Set_Mission(MISSION_GUARD_AREA); - } - } - } - } - } - } - - /*--------------------------------------------------------------------- - Create infantry - ---------------------------------------------------------------------*/ - for (i = 0; i <= i_limit; i++) { - /*.................................................................. - Find the center point for this category. - ..................................................................*/ - centerpt = Clip_Scatter(centroid,4); - - /*.................................................................. - Place objects; loop through all unit in this category - ..................................................................*/ - for (j = 0; j < num_infantry[i] * scaleval; j++) { - /*............................................................... - Create GDI infantry (Note: Unlimbo calls Enter_Idle_Mode(), which - assigns the infantry to HUNT; we must use Set_Mission() to override - this state.) - ...............................................................*/ - if (hptr->ActLike == HOUSE_GOOD) { - for (k = 0; k < itable[i].GDICount; k++) { - Reserve_Infantry(); - obj = new InfantryClass (itable[i].GDIType, h); - if (!Scan_Place_Object(obj, centerpt)) { - delete obj; - } else { - /* - ** Don't use MISSION_TIMED_HUNT since it can trigger blitz behavior. ST - 2/28/2020 10:51AM - */ - //if (!hptr->IsHuman) { - // obj->Set_Mission(MISSION_TIMED_HUNT); - //} - if (!hptr->IsHuman) { - obj->Set_Mission(MISSION_GUARD_AREA); - } - } - } - } else { - - /*............................................................... - Create NOD infantry - ...............................................................*/ - for (k = 0; k < itable[i].NODCount; k++) { - Reserve_Infantry(); - obj = new InfantryClass (itable[i].NODType, h); - if (!Scan_Place_Object(obj, centerpt)) { - delete obj; - } else { - /* - ** Don't use MISSION_TIMED_HUNT since it can trigger blitz behavior. ST - 2/28/2020 10:51AM - */ - //if (!hptr->IsHuman) { - // obj->Set_Mission(MISSION_TIMED_HUNT); - //} - if (!hptr->IsHuman) { - obj->Set_Mission(MISSION_GUARD_AREA); - } - } - } - } - } - } - } -} - - -/*********************************************************************************************** - * Scan_Place_Object -- places an object >near< the given cell * - * * - * INPUT: * - * obj ptr to object to Unlimbo * - * cell center of search area * - * * - * OUTPUT: * - * true = object was placed; false = it wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/09/1995 BRR : Created. * - *=============================================================================================*/ -int Scan_Place_Object(ObjectClass *obj, CELL cell) -{ - int dist; // for object placement - FacingType rot; // for object placement - FacingType fcounter; // for object placement - int tryval; - CELL newcell; - TechnoClass *techno; - int skipit; - - /*------------------------------------------------------------------------ - First try to unlimbo the object in the given cell. - ------------------------------------------------------------------------*/ - if (Map.In_Radar(cell)) { - techno = Map[cell].Cell_Techno(); - if (!techno || (techno->What_Am_I()==RTTI_INFANTRY && - obj->What_Am_I()==RTTI_INFANTRY)) { - if (obj->Unlimbo(Cell_Coord(cell),DIR_N)) { - return(true); - } - } - } - - /*------------------------------------------------------------------------ - Loop through distances from the given center cell; skip the center cell. - For each distance, try placing the object along each rotational direction; - if none are available, try each direction with a random scatter value. - If that fails, go to the next distance. - This ensures that the closest coordinates are filled first. - ------------------------------------------------------------------------*/ - for (dist = 1; dist < 32; dist++) { - /*..................................................................... - Pick a random starting direction - .....................................................................*/ - rot = (FacingType)IRandom (FACING_N, FACING_NW); - /*..................................................................... - Try all directions twice - .....................................................................*/ - for (tryval = 0 ; tryval < 2; tryval++) { - /*.................................................................. - Loop through all directions, at this distance. - ..................................................................*/ - for (fcounter = FACING_N; fcounter <= FACING_NW; fcounter++) { - - skipit = false; - - /*............................................................... - Pick a coordinate along this directional axis - ...............................................................*/ - newcell = Clip_Move(cell, rot, dist); - - /*............................................................... - If this is our second try at this distance, add a random scatter - to the desired cell, so our units aren't all aligned along spokes. - ...............................................................*/ - if (tryval > 0) - newcell = Clip_Scatter (newcell, 1); - - /*............................................................... - If, by randomly scattering, we've chosen the exact center, skip - it & try another direction. - ...............................................................*/ - if (newcell==cell) - skipit = true; - - if (!skipit) { - /*............................................................ - Only attempt to Unlimbo the object if: - - there is no techno in the cell - - the techno in the cell & the object are both infantry - ............................................................*/ - techno = Map[newcell].Cell_Techno(); - if (!techno || (techno->What_Am_I()==RTTI_INFANTRY && - obj->What_Am_I()==RTTI_INFANTRY)) { - if (obj->Unlimbo(Cell_Coord(newcell),DIR_N)) { - return(true); - } - } - } - - rot++; - if (rot > FACING_NW) - rot = FACING_N; - } - } - } - - return(false); -} - - -/*********************************************************************************************** - * Sort_Cells -- sorts an array of cells by distance * - * * - * INPUT: * - * cells array to sort * - * numcells # entries in 'cells' * - * outcells array to store sorted values in * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/19/1995 BRR : Created. * - *=============================================================================================*/ -static void Sort_Cells(CELL *cells, int numcells, CELL *outcells) -{ - int i,j,k; - int num_sorted = 0; - int num_unsorted = numcells; - - /*------------------------------------------------------------------------ - Pick the first cell at random - ------------------------------------------------------------------------*/ - j = Random_Pick(0,numcells - 1); - outcells[0] = cells[j]; - num_sorted++; - - for (k = j; k < num_unsorted - 1; k++) { - cells[k] = cells[k + 1]; - } - num_unsorted--; - - /*------------------------------------------------------------------------ - After the first cell, assign the other cells based on who's furthest away - from the chosen ones. - ------------------------------------------------------------------------*/ - for (i = 0; i < numcells; i++) { - j = Furthest_Cell (outcells, num_sorted, cells, num_unsorted); - outcells[num_sorted] = cells[j]; - num_sorted++; - - for (k = j; k < num_unsorted - 1; k++) { - cells[k] = cells[k + 1]; - } - num_unsorted--; - } -} - - -/*********************************************************************************************** - * Furthest_Cell -- Finds cell furthest from a group of cells * - * * - * INPUT: * - * cells array of cells to find furthest-cell-away-from * - * numcells # entries in 'cells' * - * tcells array of cells to test; one of these will be selected as being * - * "furthest" from all the cells in 'cells' * - * numtcells # entries in 'tcells' * - * * - * OUTPUT: * - * index of 'tcell' that's furthest away from 'cells' * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/19/1995 BRR : Created. * - *=============================================================================================*/ -static int Furthest_Cell(CELL *cells, int numcells, CELL *tcells, int numtcells) -{ - int i; - int j; - int mindist; // minimum distance a 'tcell' is from a 'cell' - int maxmindist; // the highest mindist value of all tcells - int maxmin_idx; // index of the tcell with largest mindist - int dist; // working distance measure - - /*------------------------------------------------------------------------ - Initialize - ------------------------------------------------------------------------*/ - maxmindist = 0; - maxmin_idx = 0; - - /*------------------------------------------------------------------------ - Loop through all test cells, finding the furthest one from all entries in - the 'cells' array - ------------------------------------------------------------------------*/ - for (i = 0; i < numtcells; i++) { - - /*..................................................................... - Find the 'cell' closest to this 'tcell' - .....................................................................*/ - mindist = 0xffff; - for (j = 0; j < numcells; j++) { - dist = Distance (tcells[i],cells[j]); - if (dist <= mindist) { - mindist = dist; - } - } - - /*..................................................................... - If this tcell is further away than the others, save its distance & - index value - .....................................................................*/ - if (mindist >= maxmindist) { - maxmindist = mindist; - maxmin_idx = i; - } - } - - return (maxmin_idx); -} - - -/*********************************************************************************************** - * Clip_Scatter -- randomly scatters from given cell; won't fall off map * - * * - * INPUT: * - * cell cell to scatter from * - * maxdist max distance to scatter * - * * - * OUTPUT: * - * new cell number * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/30/1995 BRR : Created. * - *=============================================================================================*/ -static CELL Clip_Scatter(CELL cell, int maxdist) -{ - int x,y; - int xdist; - int ydist; - int xmin,xmax; - int ymin,ymax; - - /*------------------------------------------------------------------------ - Get X & Y coords of given starting cell - ------------------------------------------------------------------------*/ - x = Cell_X(cell); - y = Cell_Y(cell); - - /*------------------------------------------------------------------------ - Compute our x & y limits - ------------------------------------------------------------------------*/ - xmin = Map.MapCellX; - xmax = xmin + Map.MapCellWidth - 1; - ymin = Map.MapCellY; - ymax = ymin + Map.MapCellHeight - 1; - - /*------------------------------------------------------------------------ - Adjust the x-coordinate - ------------------------------------------------------------------------*/ - xdist = IRandom(0,maxdist); - if (IRandom(0,1)==0) { - x += xdist; - if (x > xmax) { - x = xmax; - } - } else { - x -= xdist; - if (x < xmin) { - x = xmin; - } - } - - /*------------------------------------------------------------------------ - Adjust the y-coordinate - ------------------------------------------------------------------------*/ - ydist = IRandom(0,maxdist); - if (IRandom(0,1)==0) { - y += ydist; - if (y > ymax) { - y = ymax; - } - } else { - y -= ydist; - if (y < ymin) { - y = ymin; - } - } - - return (XY_Cell(x,y)); -} - - -/*********************************************************************************************** - * Clip_Move -- moves in given direction from given cell; clips to map * - * * - * INPUT: * - * cell cell to start from * - * facing direction to move * - * dist distance to move * - * * - * OUTPUT: * - * new cell number * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/30/1995 BRR : Created. * - *=============================================================================================*/ -static CELL Clip_Move(CELL cell, FacingType facing, int dist) -{ - int x,y; - int xmin,xmax; - int ymin,ymax; - - /*------------------------------------------------------------------------ - Get X & Y coords of given starting cell - ------------------------------------------------------------------------*/ - x = Cell_X(cell); - y = Cell_Y(cell); - - /*------------------------------------------------------------------------ - Compute our x & y limits - ------------------------------------------------------------------------*/ - xmin = Map.MapCellX; - xmax = xmin + Map.MapCellWidth - 1; - ymin = Map.MapCellY; - ymax = ymin + Map.MapCellHeight - 1; - - /*------------------------------------------------------------------------ - Adjust the x-coordinate - ------------------------------------------------------------------------*/ - switch (facing) { - case FACING_N: - y -= dist; - break; - - case FACING_NE: - x += dist; - y -= dist; - break; - - case FACING_E: - x += dist; - break; - - case FACING_SE: - x += dist; - y += dist; - break; - - case FACING_S: - y += dist; - break; - - case FACING_SW: - x -= dist; - y += dist; - break; - - case FACING_W: - x -= dist; - break; - - case FACING_NW: - x -= dist; - y -= dist; - break; - } - - /*------------------------------------------------------------------------ - Clip to the map - ------------------------------------------------------------------------*/ - if (x > xmax) - x = xmax; - if (x < xmin) - x = xmin; - - if (y > ymax) - y = ymax; - if (y < ymin) - y = ymin; - - return (XY_Cell(x,y)); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/INIT.CPP b/code/TIBERIANDAWN/INIT.CPP deleted file mode 100644 index 4f6ee3f..0000000 --- a/code/TIBERIANDAWN/INIT.CPP +++ /dev/null @@ -1,3054 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\init.cpv 2.18 16 Oct 1995 16:50:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INIT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : January 20, 1992 * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Anim_Init -- Initialize the VQ animation control structure. * - * Init_Game -- Main game initialization routine. * - * Load_Recording_Values -- Loads recording values from recording file * - * Obfuscate -- Sufficiently transform parameter to thwart casual hackers. * - * Parse_Command_Line -- Parses the command line parameters. * - * Parse_INI_File -- Parses CONQUER.INI for special options * - * Play_Intro -- plays the introduction & logo movies * - * Save_Recording_Values -- Saves recording values to a recording file * - * Select_Game -- The game's main menu * - * Version_Number -- Determines the version number. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "loaddlg.h" -#include "tcpip.h" -#include -#include -#include "ccdde.h" - -static HANDLE hCCLibrary; - -/**************************************** -** Function prototypes for this module ** -*****************************************/ -static void Play_Intro(bool for_real = false); - -extern "C" { -extern long RandNumb; -} - -extern int SimRandIndex; - -#define ATTRACT_MODE_TIMEOUT 3600 // timeout for attract mode -#if(0) - -long FAR PASCAL _export Start_Game_Proc(HWND hwnd, UINT message, UINT wParam, LONG lParam) -{ - switch (message) { - case WM_CREATE: - break; - - case WM_COMMAND: - EndDialog(hwnd, TRUE); - AllDone = TRUE; - break; - - case WM_DESTROY: - EndDialog(hwnd, TRUE); - break; - } - return(DefWindowProc(hwnd, message, wParam, lParam)); -} -#endif - - -extern bool Server_Remote_Connect(void); -extern bool Client_Remote_Connect(void); -extern bool SpawnedFromWChat; - - -/*********************************************************************************************** - * Init_Game -- Main game initialization routine. * - * * - * Perform all one-time game initializations here. This includes all * - * allocations and table setups. The intro and other one-time startup * - * tasks are also performed here. * - * * - * INPUT: argc,argv -- Command line arguments. * - * * - * OUTPUT: none * - * * - * WARNINGS: Only call this ONCE! * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -bool Init_Game(int , char *[]) -{ - void const *temp_mouse_shapes; - - CCDebugString ("C&C95 - About to load reslib.dll\n"); - hCCLibrary = LoadLibrary("reslib.dll"); - - /* - ** Initialize the game object heaps. - */ - CCDebugString ("C&C95 - About to enter Units.Set_Heap\n"); - Units.Set_Heap(UNIT_MAX); - CCDebugString ("C&C95 - About to enter Factories.Set_Heap\n"); - Factories.Set_Heap(FACTORY_MAX); - CCDebugString ("C&C95 - About to enter Terrains.Set_Heap\n"); - Terrains.Set_Heap(TERRAIN_MAX); - CCDebugString ("C&C95 - About to enter Templates.Set_Heap\n"); - Templates.Set_Heap(TEMPLATE_MAX); - CCDebugString ("C&C95 - About to enter Smudges.Set_Heap\n"); - Smudges.Set_Heap(SMUDGE_MAX); - CCDebugString ("C&C95 - About to enter Overlays.Set_Heap\n"); - Overlays.Set_Heap(OVERLAY_MAX); - CCDebugString ("C&C95 - About to enter Infantry.Set_Heap\n"); - Infantry.Set_Heap(INFANTRY_MAX); - CCDebugString ("C&C95 - About to enter Bullets.Set_Heap\n"); - Bullets.Set_Heap(BULLET_MAX); - CCDebugString ("C&C95 - About to enter Buildings.Set_Heap\n"); - Buildings.Set_Heap(BUILDING_MAX); - CCDebugString ("C&C95 - About to enter Anims.Set_Heap\n"); - Anims.Set_Heap(ANIM_MAX); - CCDebugString ("C&C95 - About to enter Aircraft.Set_Heap\n"); - Aircraft.Set_Heap(AIRCRAFT_MAX); - CCDebugString ("C&C95 - About to enter Triggers.Set_Heap\n"); - Triggers.Set_Heap(TRIGGER_MAX); - CCDebugString ("C&C95 - About to enter TeamTypes.Set_Heap\n"); - TeamTypes.Set_Heap(TEAMTYPE_MAX); - CCDebugString ("C&C95 - About to enter Teams.Set_Heap\n"); - Teams.Set_Heap(TEAM_MAX); - CCDebugString ("C&C95 - About to enter Houses.Set_Heap\n"); - Houses.Set_Heap(HOUSE_MAX); - - /* - ** Initialize all the waypoints to invalid values. - */ - CCDebugString ("C&C95 - About to clear waypoints\n"); - memset(Waypoint, 0xFF, sizeof(Waypoint)); - - /* - ** Setup the keyboard processor in preparation for the game. - */ - CCDebugString ("C&C95 - About to do various keyboard inits\n"); -#ifdef FIX_ME_LATER - Keyboard_Attributes_Off(TRACKEXT | PAUSEON | BREAKON | SCROLLLOCKON | CTRLSON | CTRLCON | PASSBREAKS | FILTERONLY | TASKSWITCHABLE); -#endif //FIX_ME_LATER - Keyboard::Clear(); - Kbd.Clear(); - - /* - ** This is the shape staging buffer. It must always be available, so it is - ** allocated here and never freed. The library sets the globals ShapeBuffer - ** and ShapeBufferSize to these values, so it can be accessed for other - ** purposes. - */ - CCDebugString ("C&C95 - About to call Set_Shape_Buffer\n"); - Set_Shape_Buffer(new unsigned char[SHAPE_BUFFER_SIZE], SHAPE_BUFFER_SIZE); - - /* - ** Bootstrap enough of the system so that the error dialog box can sucessfully - ** be displayed. - */ - CCDebugString ("C&C95 - About to register CCLOCAL.MIX\n"); -#ifdef DEMO - new MixFileClass("DEMOL.MIX"); - MixFileClass::Cache("DEMOL.MIX"); -#else - int temp = RequiredCD; - RequiredCD = -2; - new MixFileClass("CCLOCAL.MIX"); // Cached. - MixFileClass::Cache("CCLOCAL.MIX"); - CCDebugString ("C&C95 - About to register UPDATE.MIX\n"); - new MixFileClass("UPDATE.MIX"); // Cached. - new MixFileClass("UPDATA.MIX"); // Cached. - CCDebugString ("C&C95 - About to register UPDATEC.MIX\n"); - new MixFileClass("UPDATEC.MIX"); // Cached. - MixFileClass::Cache("UPDATEC.MIX"); -#ifdef JAPANESE - CCDebugString ("C&C95 - About to register LANGUAGE.MIX\n"); - new MixFileClass("LANGUAGE.MIX"); -#endif //JAPANESE - - RequiredCD = temp; - -#endif - CCDebugString ("C&C95 - About to load fonts\n"); - Green12FontPtr = Load_Alloc_Data(CCFileClass("12GREEN.FNT")); - Green12GradFontPtr = Load_Alloc_Data(CCFileClass("12GRNGRD.FNT")); - MapFontPtr = Load_Alloc_Data(CCFileClass("8FAT.FNT")); - Font8Ptr = MixFileClass::Retrieve(FONT8); - FontPtr = (char *)Font8Ptr; - Set_Font(FontPtr); - Font3Ptr = MixFileClass::Retrieve(FONT3); -// Font6Ptr = MixFileClass::Retrieve(FONT6); - Font6Ptr = Load_Alloc_Data(CCFileClass("6POINT.FNT")); - //ScoreFontPtr = MixFileClass::Retrieve("12GRNGRD.FNT"); //GRAD12FN"); //("SCOREFNT.FNT"); - ScoreFontPtr = Load_Alloc_Data(CCFileClass("12GRNGRD.FNT")); - FontLEDPtr = MixFileClass::Retrieve("LED.FNT"); - VCRFontPtr = MixFileClass::Retrieve("VCR.FNT"); -// GradFont6Ptr = MixFileClass::Retrieve("GRAD6FNT.FNT"); - GradFont6Ptr = Load_Alloc_Data(CCFileClass("GRAD6FNT.FNT")); - BlackPalette = new(MEM_CLEAR|MEM_REAL) unsigned char[768]; - GamePalette = new(MEM_CLEAR|MEM_REAL) unsigned char[768]; - OriginalPalette = new(MEM_CLEAR|MEM_REAL) unsigned char[768]; - WhitePalette = new(MEM_CLEAR|MEM_REAL) unsigned char[768]; - memset(WhitePalette, 63, 768); - - CCDebugString ("C&C95 - About to set palette\n"); - memset(BlackPalette, 0x01, 768); - if (!Special.IsFromInstall) Set_Palette(BlackPalette); - memset(BlackPalette, 0, 768); - if (!Special.IsFromInstall) { - Set_Palette(BlackPalette); - CCDebugString ("C&C95 - About to clear visible page\n"); - VisiblePage.Clear(); - } - - Set_Palette(GamePalette); - - CCDebugString ("C&C95 - About to set the mouse shape\n"); - /* - ** Since there is no mouse shape currently available we need' - ** to set one of our own. - */ - ShowCursor (FALSE); - if (MouseInstalled) { - temp_mouse_shapes = MixFileClass::Retrieve("MOUSE.SHP"); - if (temp_mouse_shapes) { - Set_Mouse_Cursor(0, 0, 0); - while (Get_Mouse_State() > 1) { - Show_Mouse(); - } - } - } - - CCDebugString ("C&C95 - About to enter wait for focus loop\n"); - /* - ** Process the message loop until we are in focus. - */ - do { - CCDebugString ("C&C95 - About to call Keyboard::Check\n"); - Keyboard::Check(); - }while (!GameInFocus); - AllSurfaces.SurfacesRestored=FALSE; - - CCDebugString ("C&C95 - About to load the language file\n"); - /* - ** Fetch the language text from the hard drive first. If it cannot be - ** found on the hard drive, then look for it in the mixfile. - */ - if (RawFileClass(Language_Name("CONQUER")).Is_Available()) { - SystemStrings = (char const *)Load_Alloc_Data(RawFileClass(Language_Name("CONQUER"))); - } else { - SystemStrings = (char const *)MixFileClass::Retrieve(Language_Name("CONQUER")); - } - - /* - ** Default palette initialization. Uses the desert palette for convenience, - ** but only the non terrain specific colors matter. - */ - //Mem_Copy((void *)MixFileClass::Retrieve("TEMPERAT.PAL"), GamePalette, 768L); - CCFileClass palfile ("TEMPERAT.PAL"); - palfile.Read (GamePalette, 768L); - - if (!MouseInstalled) { - char buffer[255]; - Set_Palette(GamePalette); -#ifdef GERMAN - sprintf(buffer, "Command & Conquer kann Ihren Maustreiber nicht finden.."); -#else -#ifdef FRENCH - sprintf(buffer, "Command & Conquer ne peut pas d‚tecter votre gestionnaire de souris."); -#else - sprintf(buffer, "Command & Conquer is unable to detect your mouse driver."); -#endif -#endif - CCMessageBox().Process(buffer, TXT_OK); - Prog_End(); - exit(1); - } - -#ifdef DEMO - /* - ** Add in any override path specified in the conquer.ini file. - */ - if (strlen(OverridePath)) { - CCFileClass::Set_Search_Drives(OverridePath); - } -#endif - -#if (0) //ST - 1/2/2019 5:49PM - CCDebugString ("C&C95 - About to search for CD drives\n"); - /* - ** Always try to look at the CD-ROM for data files. - */ - if (!CCFileClass::Is_There_Search_Drives()) { - - /* - ** If there are no search drives specified then we must be playing - ** off cd, so read files from there. - */ - int error; - - do { - if (!CDList.Get_Number_Of_Drives()){ - Set_Palette(GamePalette); - Show_Mouse(); - CCMessageBox().Process(TXT_CD_ERROR1, TXT_OK); - Prog_End(); - exit(EXIT_FAILURE); - } - CCFileClass::Set_CD_Drive( CDList.Get_First_CD_Drive() ); - - error = CCFileClass::Set_Search_Drives("?:\\"); - switch(error) { - case 1: - Set_Palette(GamePalette); - Show_Mouse(); - CCMessageBox().Process(TXT_CD_ERROR1, TXT_OK); - Prog_End(); - exit(EXIT_FAILURE); - - case 2: - Set_Palette(GamePalette); - Show_Mouse(); - if (CCMessageBox().Process(TXT_CD_DIALOG_1, TXT_OK, TXT_CANCEL) == 1) { - Prog_End(); - exit(EXIT_FAILURE); - } - Hide_Mouse(); - break; - - default: - Show_Mouse(); - if (!Force_CD_Available(RequiredCD)) { - Prog_End(); - exit(EXIT_FAILURE); - } - Hide_Mouse(); - break; - } - } while (error); - -#ifdef DEMO - RequiredCD = -2; -#else - RequiredCD = -1; -#endif - } else { - - /* - ** If there are search drives specified then all files are to be - ** considered local. - */ - RequiredCD = -2; - } -#endif - - -#ifndef DEMO - CCDebugString ("C&C95 - About to register addon mixfiles\n"); - /* - ** Before all else, cache any additional mixfiles. - */ - - /* - ** Need to search the search paths. ST - 3/15/2019 2:18PM - */ - const char *path = ".\\"; - char search_path[_MAX_PATH]; - char scan_path[_MAX_PATH]; - - for (int p=0 ; p<100 ; p++) { - - strcpy(search_path, path); - if (search_path[strlen(search_path) - 1] != '\\') { - strcat(search_path, "\\"); - } - - strcpy(scan_path, search_path); - strcat(scan_path, "SC*.MIX"); - - WIN32_FIND_DATA find_data; - memset(&find_data, 0, sizeof(find_data)); - HANDLE file_handle = FindFirstFile(scan_path, &find_data); - if (file_handle != INVALID_HANDLE_VALUE) - { - do - { - char *ptr = strdup(find_data.cFileName); - new MixFileClass(ptr); - MixFileClass::Cache(ptr); - } while (FindNextFile(file_handle, &find_data)); - FindClose(file_handle); - } - - memset(&find_data, 0, sizeof(find_data)); - strcpy(scan_path, search_path); - strcat(scan_path, "Ss*.MIX"); - file_handle = FindFirstFile(scan_path, &find_data); - if (file_handle != INVALID_HANDLE_VALUE) - { - do - { - char *ptr = strdup(find_data.cFileName); - new MixFileClass(ptr); - MixFileClass::Cache(ptr); - } while (FindNextFile(file_handle, &find_data)); - FindClose(file_handle); - } - - path = CDFileClass::Get_Search_Path(p); - - if (path == NULL) { - break; - } - } - -#if (0) - struct find_t ff; // for _dos_findfirst - if (!_dos_findfirst("SC*.MIX", _A_NORMAL, &ff)) { - char * ptr; - do { - ptr = strdup(ff.name); - new MixFileClass(ptr); - MixFileClass::Cache(ptr); -// free(ptr); - } while(!_dos_findnext(&ff)); - } - if (!_dos_findfirst("SS*.MIX", _A_NORMAL, &ff)) { - char * ptr; - do { - ptr = strdup(ff.name); - new MixFileClass(ptr); -// free(ptr); - } while(!_dos_findnext(&ff)); - } -#endif -#endif //DEMO - - CCDebugString ("C&C95 - About to register GENERAL.MIX\n"); - // - // This is a problem because registering the mix file can call Force_CD_Available which will try to load General.Mix - // Might as well just cut to the chase and call it directly. - // ST - 1/3/2019 5:19PM - // - //if (GeneralMix) delete GeneralMix; - //GeneralMix = new MixFileClass("GENERAL.MIX"); - Force_CD_Available(RequiredCD); - -// if (!_dos_findfirst("SC*.MIX", _A_NORMAL, &ff)) { -// do { -// new MixFileClass(ff.name); -// MixFileClass::Cache(ff.name); -// } while(!_dos_findnext(&ff)); -// } - - /* - ** Inform the file system of the various MIX files. - */ -#ifdef DEMO - new MixFileClass("DEMO.MIX"); - if (CCFileClass("DEMOM.MIX").Is_Available()) { - if (!MoviesMix) MoviesMix = new MixFileClass("DEMOM.MIX"); - ScoresPresent = true; - ThemeClass::Scan(); - } - -#else - CCDebugString ("C&C95 - About to register CONQUER.MIX\n"); - new MixFileClass("CONQUER.MIX"); // Cached. - CCDebugString ("C&C95 - About to register TRANSIT.MIX\n"); - new MixFileClass("TRANSIT.MIX"); - - CCDebugString ("C&C95 - About to register GENERAL.MIX\n"); - if (!GeneralMix) GeneralMix = new MixFileClass("GENERAL.MIX"); // Never cached. - -// if (CCFileClass("MOVIES.MIX").Is_Available()) { - CCDebugString ("C&C95 - About to register MOVIES.MIX\n"); - if (!MoviesMix) MoviesMix = new MixFileClass("MOVIES.MIX"); // Never cached. -// } - - - -#if (0) - - /* - ** Extract a movie from a mixfile. - */ - char *file_ptr = (char*)Alloc (32 * 1024 * 1024, MEM_NORMAL); - CCFileClass whatever ("PINTLE.VQA"); - - int len = whatever.Size(); - - whatever.Open(); - - DWORD actual; - HANDLE sfile = CreateFile("c:\\temp\\PINTLE.VQA", GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (sfile != INVALID_HANDLE_VALUE){ - SetFilePointer (sfile, 0, NULL, FILE_END); - - do{ - whatever.Read (file_ptr, MIN (len, 1024*64)); - WriteFile(sfile, file_ptr, MIN (len, 1024*64), &actual, NULL); - len -= MIN (len, 1024*64); - }while ( len >0 ); - - CloseHandle (sfile); - } - - whatever.Close(); - - Free (file_ptr); - -#endif //(0) - - - - /* - ** Register the score mixfile. - */ - CCDebugString ("C&C95 - About to register SCORES.MIX\n"); - ScoresPresent = false; -// if (CCFileClass("SCORES.MIX").Is_Available()) { - ScoresPresent = true; - if (!ScoreMix) { - ScoreMix = new MixFileClass("SCORES.MIX"); - ThemeClass::Scan(); - } -// } -#endif - - /* - ** These are sound card specific, but the install program would have - ** copied the coorect versions to the hard drive. - */ - CCDebugString ("C&C95 - About to register SPEECH.MIX\n"); - if (CCFileClass("SPEECH.MIX").Is_Available()) { - new MixFileClass("SPEECH.MIX"); // Never cached. - } - CCDebugString ("C&C95 - About to register SOUNDS.MIX\n"); - new MixFileClass("SOUNDS.MIX"); // Cached. - - /* - ** Initialize the animation system. - */ - CCDebugString ("C&C95 - About to initialise the animation system\n"); - Anim_Init(); - - if (SpawnedFromWChat){ - Special.IsFromWChat = true; - } - - /* - ** Play the introduction movies. - */ - CCDebugString ("C&C95 - About to play the intro movie\n"); - if (!Special.IsFromInstall && !Special.IsFromWChat) Play_Intro(true); - - /* - ** Wait for a VSync; during the vertical blank, set the game palette & blit - ** the title screen. We must ensure no RGB values in the game palette match - ** those in the WWLIB's 'CurrentPalette', or the WWLIB palette-set routine - ** will skip that color; the VQ player will have changed that color (behind - ** WWLIB's back), so it will be incorrect. - */ - memset(CurrentPalette, 0x01, 768); - - if (!Special.IsFromInstall) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - } - - Hide_Mouse(); - Wait_Vert_Blank(); - if (!Special.IsFromInstall) { - Set_Palette(Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - } - Call_Back(); -// Window_Dialog_Box(hCCLibrary, "DIALOG_1", MainWindow, MakeProcInstance((FARPROC)Start_Game_Proc, hInstance)); -// if (hCCLibrary) FreeLibrary(hCCLibrary); - -#ifdef DEMO - MixFileClass::Cache("DEMO.MIX"); - MixFileClass::Cache("SOUNDS.MIX"); -#else - /* - ** Cache the main game data. This operation can take a very long time. - */ - MixFileClass::Cache("CONQUER.MIX"); - if (SampleType != 0 && !Debug_Quiet) { - MixFileClass::Cache("SOUNDS.MIX"); - if (Special.IsJuvenile) { - new MixFileClass("ZOUNDS.MIX"); // Cached. - MixFileClass::Cache("ZOUNDS.MIX"); - } - } - Call_Back(); -#endif - -// malloc(2); - - /* - ** Perform any special debug-only processing. This includes preparing the - ** monochrome screen. - */ - Mono_Clear_Screen(); - -#ifdef ONHOLD - /* - ** Check for addition options not specified on the command-line. This must - ** be done before the One_Time calls, but after the shape buffer is set up. - */ - Parse_INI_File(); -#endif - - /* - ** Perform one-time game system initializations. - */ - Call_Back(); -// malloc(3); - Map.One_Time(); -// malloc(4); - Logic.One_Time(); -// malloc(5); - Options.One_Time(); - -// malloc(6); - - ObjectTypeClass::One_Time(); - BuildingTypeClass::One_Time(); - BulletTypeClass::One_Time(); - HouseTypeClass::One_Time(); - - TemplateTypeClass::One_Time(); - OverlayTypeClass::One_Time(); - SmudgeTypeClass::One_Time(); - TerrainTypeClass::One_Time(); - UnitTypeClass::One_Time(); - - InfantryTypeClass::One_Time(); - AnimTypeClass::One_Time(); - AircraftTypeClass::One_Time(); - HouseClass::One_Time(); - - /* - ** Speech holding tank buffer. Since speech does not mix, it can be placed - ** into a custom holding tank only as large as the largest speech file to - ** be played. - */ - SpeechBuffer = new char [SPEECH_BUFFER_SIZE]; - Call_Back(); - - /* - ** WWLIB bug: MouseState is in some undefined state; show the mouse until - ** it really shows. - */ - Map.Set_Default_Mouse(MOUSE_NORMAL, false); - Show_Mouse(); -//#ifdef FIX_ME_LATER - while (Get_Mouse_State() > 0) Show_Mouse(); -//#endif //FIX_ME_LATER - Call_Back(); - -#ifndef DEMO - /* - ** Load multiplayer scenario descriptions - */ - Read_Scenario_Descriptions(); -#endif - - /* - ** Initialize the multiplayer score values - */ - MPlayerGamesPlayed = 0; - MPlayerNumScores = 0; - MPlayerCurGame = 0; - for (int i = 0; i < MAX_MULTI_NAMES; i++) { - MPlayerScore[i].Name[0] = '\0'; - MPlayerScore[i].Wins = 0; - for (int j = 0; j < MAX_MULTI_GAMES; j++) { - MPlayerScore[i].Kills[j] = -1; // -1 = this player didn't play this round - } - } - - /* - ** Copy the title screen's palette into the GamePalette & OriginalPalette, - ** because the options Load routine uses these palettes to set the brightness, etc. - */ - memcpy (GamePalette, Palette, 768); - memcpy (OriginalPalette, Palette, 768); - - /* - ** Read game options, so the GameSpeed is initialized when multiplayer - ** dialogs are invoked. (GameSpeed must be synchronized between systems.) - */ - Options.Load_Settings(); - - return(true); -} - - -//#ifndef NOMEMCHECK -void Uninit_Game(void) -{ - delete Map.ShadowPage; - Map.ShadowPage = NULL; - Map.Free_Cells(); - - delete [] SpeechBuffer; - - CCFileClass::Clear_Search_Drives(); - MixFileClass::Free_All(); - - Units.Set_Heap(0); - Factories.Set_Heap(0); - Terrains.Set_Heap(0); - Templates.Set_Heap(0); - Smudges.Set_Heap(0); - Overlays.Set_Heap(0); - Infantry.Set_Heap(0); - Bullets.Set_Heap(0); - Buildings.Set_Heap(0); - Anims.Set_Heap(0); - Aircraft.Set_Heap(0); - Triggers.Set_Heap(0); - TeamTypes.Set_Heap(0); - Teams.Set_Heap(0); - Houses.Set_Heap(0); - - delete [] _ShapeBuffer; - Set_Shape_Buffer(NULL, 0); - delete [] BlackPalette; - delete [] GamePalette; - delete [] OriginalPalette; - delete [] WhitePalette; - - WWDOS_Shutdown(); - delete [] Palette; -} -//#endif - -extern bool Do_The_Internet_Menu_Thang(void); -extern int ShowCommand; - -/*********************************************************************************************** - * Select_Game -- The game's main menu * - * * - * INPUT: * - * fade if true, will fade the palette in gradually * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/05/1995 BRR : Created. * - *=============================================================================================*/ -extern int Com_Fake_Scenario_Dialog(void); -extern int Com_Show_Fake_Scenario_Dialog(void); -extern int WChatMaxAhead; -extern int WChatSendRate; -void Check_From_WChat(char *wchat_name); - -bool Select_Game(bool fade) -{ - enum { - SEL_TIMEOUT = -1, // main menu timeout--go into attract mode -#ifdef NEWMENU - SEL_NEW_SCENARIO, // Expansion scenario to play. -#endif - SEL_START_NEW_GAME, // start a new game -#ifdef BONUS_MISSIONS - SEL_BONUS_MISSIONS, -#endif //BONUS_MISSIONS - SEL_INTERNET, - SEL_LOAD_MISSION, // load a saved game - SEL_MULTIPLAYER_GAME, // play modem/null-modem/network game - SEL_INTRO, // replay the intro - SEL_EXIT, // exit to DOS - SEL_FAME, // view the hall of fame - SEL_NONE, // placeholder default value - }; - bool gameloaded=false; // Has the game been loaded from the menu? - int selection; // the default selection - bool process = true; // false = break out of while loop - bool display = true; - CountDownTimerClass count; - int cd_index; - - MEMORYSTATUS mem_info; - mem_info.dwLength=sizeof(mem_info); - GlobalMemoryStatus(&mem_info); - - /* - ** Enable the DDE Server so we can get internet start game packets from WChat - */ - DDEServer.Enable(); - - if (Special.IsFromInstall) { - /* - ** Special case for machines with 12 megs or less - just play intro, no choose side screen - */ - if (mem_info.dwTotalPhys < 12*1024*1024){ - VisiblePage.Clear(); - Play_Movie("INTRO2", THEME_NONE, false); - BreakoutAllowed = true; - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - fade = true; - VisiblePage.Clear(); - }else{ - display = false; - Show_Mouse(); - } - } - - /* - ** [Re]set any globals that need it, in preparation for a new scenario - */ - GameActive = true; - DoList.Init(); - OutList.Init(); - Frame = 0; - PlayerWins = false; - PlayerLoses = false; - MPlayerObiWan = false; - Debug_Unshroud = false; - Map.Set_Cursor_Shape(0); - Map.PendingObjectPtr = 0; - Map.PendingObject = 0; - Map.PendingHouse = HOUSE_NONE; - - /* - ** Initialize multiplayer-protocol-specific variables: - ** If CommProtocol MULTI_E_COMP is used, you must: - ** Init FrameSendRate to a sensible value (3 is good) - ** Init MPlayerMaxAhead to an even multiple of FrameSendRate, and it must - ** be at least 2 * MPlayerMaxAhead - */ - CommProtocol = COMM_PROTOCOL_SINGLE_NO_COMP; - if (!Special.IsFromWChat){ - FrameSendRate = 3; - } - - ProcessTicks = 0; - ProcessFrames = 0; - DesiredFrameRate = 30; -//#if(TIMING_FIX) - NewMaxAheadFrame1 = 0; - NewMaxAheadFrame2 = 0; -//#endif - - /* - ** Init multiplayer game scores. Let Wins accumulate; just init the current - ** Kills for this game. Kills of -1 means this player didn't play this round. - */ - for (int i = 0 ; i < MAX_MULTI_GAMES; i++) { - MPlayerScore[i].Kills[MPlayerCurGame] = -1; - } - - /* - ** Set default mouse shape - */ - Map.Set_Default_Mouse(MOUSE_NORMAL, false); - - /* - ** If the last game we played was a multiplayer game, jump right to that - ** menu by pre-setting 'selection'. - */ - if (GameToPlay == GAME_NORMAL) { - selection = SEL_NONE; - } else { - selection = SEL_MULTIPLAYER_GAME; - } - - /* - ** Main menu processing; only do this if we're not in editor mode. - */ - if (!Debug_Map) { - - /* - ** Menu selection processing loop - */ - ScenarioInit++; - Theme.Queue_Song(THEME_MAP1); - ScenarioInit--; - - /* - ** If we're playing back a recording, load all pertinant values & skip - ** the menu loop. Hide the now-useless mouse pointer. - */ - if (PlaybackGame && RecordFile.Is_Available()) { - if (RecordFile.Open(READ)) { - Load_Recording_Values(); - process = false; - Theme.Fade_Out(); - } else - PlaybackGame = false; - } - - - /* - ** Handle case where we were spawned from Wchat - */ - if (SpawnedFromWChat){ - Special.IsFromInstall = false; //Dont play intro if we were spawned from wchat - selection = SEL_INTERNET; - Theme.Queue_Song(THEME_NONE); - GameToPlay = GAME_INTERNET; - display = false; - Set_Logic_Page(SeenBuff); - } - - - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Redraw the title page if needed - */ - if (display) { - Hide_Mouse(); - - /* - ** Display the title page; fade it in if this is the first time - ** through the loop, and the 'fade' flag is true - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - memcpy (GamePalette, Palette, 768); - Blit_Hid_Page_To_Seen_Buff(); - - if (fade) { - Fade_Palette_To(Palette, FADE_PALETTE_SLOW, Call_Back); - fade = false; - } - - Set_Logic_Page(SeenBuff); -#ifdef VIRGIN_CHEAT_KEYS - Fancy_Text_Print("V.%d%s", SeenBuff.Get_Width() - 1, SeenBuff.Get_Height() - 10, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, Version_Number(), VersionText, FOREIGN_VERSION_NUMBER); -// Fancy_Text_Print("V.%d%s%02d", 319, 190, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, Version_Number(), VersionText, FOREIGN_VERSION_NUMBER); -#else - -#ifdef DEMO - Version_Number(); - Fancy_Text_Print("DEMO V%s", SeenBuff.Get_Width() - 1, SeenBuff.Get_Height() - 10, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, VersionText); -#else - Fancy_Text_Print("V.%d%s", SeenBuff.Get_Width() - 1, SeenBuff.Get_Height() - 10, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, Version_Number(), VersionText); -#endif -#endif - display = false; - Show_Mouse(); - } else { - if (RunningAsDLL) { - return true;; - } - } - /* - ** Display menu and fetch selection from player. - */ - if (Special.IsFromInstall && mem_info.dwTotalPhys >= 12*1024*1024){ - selection = SEL_START_NEW_GAME; - Theme.Queue_Song(THEME_NONE); - } - - /* - ** Handle case where we were spawned from Wchat - */ - if (Special.IsFromWChat && DDEServer.Get_MPlayer_Game_Info()){ - Check_From_WChat(NULL); - selection = SEL_MULTIPLAYER_GAME; - Theme.Queue_Song(THEME_NONE); - GameToPlay = GAME_INTERNET; - }else{ - /* - ** We werent spawned but we could still receive a DDE packet from wchat - */ - if (DDEServer.Get_MPlayer_Game_Info()){ - Check_From_WChat(NULL); - /* - ** Make sure top and bottom of screen are clear in 640x480 mode - */ - if (ScreenHeight == 480){ - VisiblePage.Fill_Rect (0, 0, 639, 40, 0); - VisiblePage.Fill_Rect (0, 440, 639, 479, 0); - } - } - } - - if (selection == SEL_NONE) { -// selection = Main_Menu(0); - selection = Main_Menu(ATTRACT_MODE_TIMEOUT); - } - Call_Back(); - - switch (selection) { - -#ifdef NEWMENU - - case SEL_INTERNET: - /* - ** Only call up the internet menu code if we dont already have connect info from WChat - */ - if (!DDEServer.Get_MPlayer_Game_Info()){ - CCDebugString ("C&C95 - About to call Internet Menu.\n"); - if (Do_The_Internet_Menu_Thang() && DDEServer.Get_MPlayer_Game_Info()){ - CCDebugString ("C&C95 - About to call Check_From_WChat.\n"); - Check_From_WChat(NULL); - selection = SEL_MULTIPLAYER_GAME; - display = false; - GameToPlay = GAME_INTERNET; - }else{ - selection = SEL_NONE; - display = true; - } - }else{ - CCDebugString ("C&C95 - About to call Check_From_WChat.\n"); - Check_From_WChat(NULL); - display = false; - GameToPlay = GAME_INTERNET; - selection = SEL_MULTIPLAYER_GAME; - } - break; - - - /* - ** Pick an expansion scenario. - */ - case SEL_NEW_SCENARIO: - CarryOverMoney = 0; - if (Expansion_Dialog()) { - Theme.Fade_Out(); -// Theme.Queue_Song(THEME_AOI); - GameToPlay = GAME_NORMAL; - process = false; - } else { - display = true; - selection = SEL_NONE; - } - break; - - -#ifdef BONUS_MISSIONS - - /* - ** User selected to play a bonus scenario. - */ - case SEL_BONUS_MISSIONS: - CarryOverMoney = 0; - - /* - ** Ensure that CD1 or CD2 is in the drive. These missions - ** are not on the covert CD. - */ - cd_index = Get_CD_Index(CCFileClass::Get_CD_Drive(), 1*60); - /* - ** If cd_index == 2 then its a covert CD - */ - if (cd_index == 2){ - RequiredCD = 0; - if (!Force_CD_Available (RequiredCD)){ - Prog_End("Select_Game - CD not found", true); - exit(EXIT_FAILURE); - } - } - - if (Bonus_Dialog()) { - Theme.Fade_Out(); - GameToPlay = GAME_NORMAL; - process = false; - } else { - display = true; - selection = SEL_NONE; - } - break; - - -#endif //BONUS_MISSIONS - -#endif - - /* - ** SEL_START_NEW_GAME: Play the game - */ - case SEL_START_NEW_GAME: - CarryOverMoney = 0; - -#ifdef DEMO - Hide_Mouse(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Load_Title_Screen("PREPICK.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); - while (!Check_Key_Num()) { - Call_Back(); - } - Get_Key_Num(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Show_Mouse(); - - Scenario = 1; - BuildLevel = 1; -#else - Scenario = 1; - BuildLevel = 1; -#endif - ScenPlayer = SCEN_PLAYER_GDI; - ScenDir = SCEN_DIR_EAST; - Whom = HOUSE_GOOD; - -#ifndef DEMO - Theme.Fade_Out(); - Choose_Side(); -#endif - - /* - ** If user is playing special mode, do NOT change Whom; leave it set to - ** GDI or NOD. Ini.cpp will set the player's ActLike to mirror the - ** Whom value. - */ - if (Special.IsJurassic && AreThingiesEnabled) { - ScenPlayer = SCEN_PLAYER_JP; - ScenDir = SCEN_DIR_EAST; - } - - GameToPlay = GAME_NORMAL; - process = false; - break; - - /* - ** Load a saved game. - */ - case SEL_LOAD_MISSION: - if (LoadOptionsClass(LoadOptionsClass::LOAD).Process()) { - //Theme.Fade_Out(); - Theme.Queue_Song(THEME_AOI); - process = false; - gameloaded = true; - } else { - display = true; - selection = SEL_NONE; - } - break; - - /* - ** SEL_MULTIPLAYER_GAME: set 'GameToPlay' to NULL-modem, modem, or - ** network play. - */ - case SEL_MULTIPLAYER_GAME: - -#ifdef DEMO - Hide_Mouse(); - Set_Palette(BlackPalette); - Load_Title_Screen("DEMOPIC.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - Clear_KeyBuffer(); - while (!Check_Key()) { - Call_Back(); - } - Get_Key(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - Show_Mouse(); - display = true; - fade = true; - selection = SEL_NONE; -#else - switch (GameToPlay) { - - /* - ** If 'GameToPlay' isn't already set up for a multiplayer game, - ** we must prompt the user for which type of multiplayer game - ** they want. - */ - case GAME_NORMAL: - GameToPlay = Select_MPlayer_Game(); - if (GameToPlay == GAME_NORMAL) { // 'Cancel' - display = true; - selection = SEL_NONE; - } - break; - - case GAME_NULL_MODEM: - case GAME_MODEM: -#if (0) - if ( NullModem.Num_Connections() ) { - NullModem.Init_Send_Queue(); - - if ((GameToPlay == GAME_NULL_MODEM && - ModemGameToPlay == MODEM_NULL_HOST) || - (GameToPlay == GAME_MODEM && - ModemGameToPlay == MODEM_DIALER) ) { - - if ( !Com_Scenario_Dialog() ) { - GameToPlay = Select_Serial_Dialog(); - if (GameToPlay == GAME_NORMAL) { // user hit Cancel - display = true; - selection = SEL_NONE; - } - } - } else { - if ( !Com_Show_Scenario_Dialog() ) { - GameToPlay = Select_Serial_Dialog(); - if (GameToPlay == GAME_NORMAL) { // user hit Cancel - display = true; - selection = SEL_NONE; - } - } - } - } else { - GameToPlay = Select_MPlayer_Game(); - if (GameToPlay == GAME_NORMAL) { // 'Cancel' - display = true; - selection = SEL_NONE; - } - } -#endif - break; - - - -#ifdef FORCE_WINSOCK - /* - ** Handle being spawned from WChat. Intermnet play based on IPX code now. - */ - case GAME_INTERNET: - CCDebugString ("C&C95 - case GAME_INTERNET:\n"); - if (Special.IsFromWChat){ - //MessageBox (NULL, "About to restore focus to C&C95", "C&C95", MB_OK); - CCDebugString ("C&C95 - About to give myself focus.\n"); - SetForegroundWindow ( MainWindow ); - ShowWindow ( MainWindow, ShowCommand ); - - CCDebugString ("C&C95 - About to initialise Winsock.\n"); - if (Winsock.Init()){ - CCDebugString ("C&C95 - About to read multiplayer settings.\n"); - Read_MultiPlayer_Settings (); - Server = PlanetWestwoodIsHost; - - CCDebugString ("C&C95 - About to set addresses.\n"); - Winsock.Set_Host_Address(PlanetWestwoodIPAddress); - - CCDebugString ("C&C95 - About to call Start_Server or Start_Client.\n"); - if (Server){ - ModemGameToPlay = INTERNET_HOST; - Winsock.Start_Server(); - }else{ - ModemGameToPlay = INTERNET_JOIN; - Winsock.Start_Client(); - } - - -//#if (0) - /* - ** Flush out any pending packets from a previous game. - */ - CCDebugString ("C&C95 - About to flush packet queue.\n"); - CCDebugString ("C&C95 - Allocating scrap memory.\n"); - char *temp_buffer = new char[1024]; - - CCDebugString ("C&C95 - Creating timer class instance.\n"); - CountDownTimerClass ptimer; - - CCDebugString ("C&C95 - Entering read loop.\n"); - while (Winsock.Read(temp_buffer, 1024)){ - - CCDebugString ("C&C95 - Discarding a packet.\n"); - ptimer.Set (30, true); - while (ptimer.Time()){}; - CCDebugString ("C&C95 - Ready to check for more packets.\n"); - - } - CCDebugString ("C&C95 - About to delete scrap memory.\n"); - delete temp_buffer; -//#endif //(0) - - - - }else{ - CCDebugString ("C&C95 - Winsock failed to initialise.\n"); - GameToPlay = GAME_NORMAL; - selection = SEL_EXIT; - Special.IsFromWChat = false; - break; - } - - CCDebugString ("C&C95 - About to call Init_Network.\n"); - Init_Network(); - - if (DDEServer.Get_MPlayer_Game_Info()){ - CCDebugString ("C&C95 - About to call Read_Game_Options.\n"); - Read_Game_Options( NULL ); - }else{ - Read_Game_Options( "C&CSPAWN.INI" ); - } - - if (Server){ - - CCDebugString ("C&C95 - About to call Server_Remote_Connect.\n"); - if (Server_Remote_Connect()){ - CCDebugString ("C&C95 - Server_Remote_Connect returned success.\n"); - break; - }else{ - /* - ** We failed to connect to the other player - * - * SEND FAILURE PACKET TO WCHAT HERE !!!!! - * - */ - Winsock.Close(); - GameToPlay = GAME_NORMAL; - selection = SEL_NONE; - DDEServer.Delete_MPlayer_Game_Info(); // Make sure we dont go round in an infinite loop - //Special.IsFromWChat = false; - break; - } - }else{ - CCDebugString ("C&C95 - About to call Client_Remote_Connect.\n"); - if (Client_Remote_Connect()){ - CCDebugString ("C&C95 - Client_Remote_Connect returned success.\n"); - break; - }else{ - /* - ** We failed to connect to the other player - * - * SEND FAILURE PACKET TO WCHAT HERE !!!!! - * - */ - Winsock.Close(); - GameToPlay = GAME_NORMAL; - selection = SEL_NONE; - DDEServer.Delete_MPlayer_Game_Info(); // Make sure we dont go round in an infinite loop - //Special.IsFromWChat = false; - break; - } - } - - }else{ - GameToPlay = Select_MPlayer_Game(); - if (GameToPlay == GAME_NORMAL) { // 'Cancel' - display = true; - selection = SEL_NONE; - } - } - break; - -#endif //FORCE_WINSOCK - - } - - - switch (GameToPlay) { - /* - ** Internet, Modem or Null-Modem - */ - case GAME_MODEM: - case GAME_NULL_MODEM: - case GAME_INTERNET: - Theme.Fade_Out(); - ScenPlayer = SCEN_PLAYER_2PLAYER; - ScenDir = SCEN_DIR_EAST; - process = false; - Options.ScoreVolume = 0; - break; - - - /* - ** Network (IPX): start a new network game. - */ - case GAME_IPX: - /* - ** Init network system & remote-connect - */ - if (Init_Network() && Remote_Connect()) { -#if (0) - char seed[80]; - sprintf (seed, "Seed: %08x\n", Seed); - CCDebugString (seed); - - sprintf (seed, "rand: %04x\n", rand()); - CCDebugString (seed); - - sprintf (seed, "rand: %04x\n", rand()); - CCDebugString (seed); - - sprintf (seed, "rand: %04x\n", rand()); - CCDebugString (seed); -#endif - Options.ScoreVolume = 0; - ScenPlayer = SCEN_PLAYER_MPLAYER; - ScenDir = SCEN_DIR_EAST; - process = false; - Theme.Fade_Out(); - } else { // user hit cancel, or init failed - GameToPlay = GAME_NORMAL; - display = true; - selection = SEL_NONE; - } - break; - } -#endif - break; - - /* - ** Play a VQ - */ - case SEL_INTRO: - Theme.Fade_Out(); - Theme.Stop(); - Call_Back(); - - Force_CD_Available(-1); - Play_Intro(false); - Hide_Mouse(); - -// verify existance of movie file before playing this sequence. - if (CCFileClass("TRAILER.VQA").Is_Available()) { - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - VisiblePage.Clear(); - if (CCFileClass("ATTRACT2.CPS").Is_Available()){ - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - } - Clear_KeyBuffer(); - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("TRAILER"); // Red Alert teaser. - } - - if (CCFileClass("SIZZLE.VQA").Is_Available()) { - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - VisiblePage.Clear(); - if (CCFileClass("ATTRACT2.CPS").Is_Available()){ - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - } - Clear_KeyBuffer(); - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("SIZZLE"); // Red Alert teaser. - } - - if (CCFileClass("SIZZLE2.VQA").Is_Available()) { - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - VisiblePage.Clear(); - if (CCFileClass("ATTRACT2.CPS").Is_Available()){ - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - } - Clear_KeyBuffer(); - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("SIZZLE2"); // Red Alert teaser. - } - - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - VisiblePage.Clear(); - if (CCFileClass("ATTRACT2.CPS").Is_Available()){ - Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette); - SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398); - Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back); - } - Clear_KeyBuffer(); - count.Set(TIMER_SECOND*3); - while (count.Time()) { - Call_Back(); - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - - Play_Movie("CC2TEASE"); - Show_Mouse(); - - ScenarioInit++; - Theme.Play_Song (THEME_MAP1); - ScenarioInit--; - display = true; - fade = true; - selection = SEL_NONE; - break; - - /* - ** Exit to DOS. - */ - case SEL_EXIT: -#ifdef JAPANESE - Hide_Mouse(); -#endif - Theme.Fade_Out(); - Fade_Palette_To(BlackPalette, FADE_PALETTE_SLOW, NULL); -#ifdef JAPANESE - VisiblePage.Clear(); -#endif - return(false); - - /* - ** Display the hall of fame. - */ - case SEL_FAME: - break; - - case SEL_TIMEOUT: - if (AllowAttract && RecordFile.Is_Available()) { - PlaybackGame = true; - if (RecordFile.Open(READ)) { - Load_Recording_Values(); - process = false; - Theme.Fade_Out(); - } else { - PlaybackGame = false; - selection = SEL_NONE; - } - } else { - selection = SEL_NONE; - } - break; - - default: - break; - } - } - } else { - - /* - ** For Debug_Map (editor) mode, if JP option is on, set to load that scenario - */ - Scenario = 1; - if (Special.IsJurassic && AreThingiesEnabled) { - ScenPlayer = SCEN_PLAYER_JP; - ScenDir = SCEN_DIR_EAST; - } - } - CCDebugString ("C&C95 - About to start game initialisation.\n"); -#ifdef FORCE_WINSOCK - if (GameToPlay == GAME_INTERNET){ - CommProtocol = COMM_PROTOCOL_MULTI_E_COMP; - if (!Special.IsFromWChat){ - FrameSendRate = 5; //3; - } - } -#endif //FORCE_WINSOCK - /* - ** Don't carry stray keystrokes into game. - */ - Kbd.Clear(); - - /* - ** Get a pointer to the compiler's random number seed. - ** the Get_EAX() must follow immediately after the srand(0) in order to save - ** the address of the random seed. (Currently not used.) - */ - srand(0); - //RandSeedPtr = (long *)Get_EAX(); // ST - 1/2/2019 5:26PM - - /* - ** Initialize the random number Seed. For multiplayer, this will have been done - ** in the connection dialogs. For single-player games, AND if we're not playing - ** back a recording, init the Seed to a random value. - */ - if (GameToPlay == GAME_NORMAL && !PlaybackGame) { - srand(timeGetTime()); - //randomize(); - Seed = rand(); - } - - /* - ** If user has specified a desired random number seed, use it for multiplayer games - */ - if (CustomSeed != 0) { - Seed = CustomSeed; - } - - /* - ** Save initialization values if we're recording this game. - ** This must be done after 'Seed' has been initialized. - */ - if (RecordGame) { - if (RecordFile.Open(WRITE)) { - Save_Recording_Values(); - } else { - RecordGame = false; - } - } - - /* - ** Initialize the random-number generator. - */ - //Seed = 1; - - srand(Seed); - RandNumb = Seed; - SimRandIndex = 0; -#if (0) - DWORD actual; - HANDLE sfile = CreateFile("random.txt", GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (sfile != INVALID_HANDLE_VALUE){ - SetFilePointer (sfile, 0, NULL, FILE_END); - - int minimum; - int maximum; - char whatever[80]; - for ( int i=0 ; i<1000 ; i++){ - minimum = rand(); - maximum = rand(); - - sprintf (whatever, "%04x\n", Random_Pick(minimum, maximum)); - WriteFile(sfile, whatever, strlen(whatever), &actual, NULL); - } - CloseHandle (sfile); - } -#endif - - - - /* - ** Load the scenario. Specify variation 'A' for the editor; for the game, - ** don't specify a variation, to make 'Set_Scenario_Name()' pick a random one. - ** Skip this if we've already loaded a save-game. - */ - if (!gameloaded) { - if (Debug_Map) { - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir, SCEN_VAR_A); - } else { - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir); - } - - /* - ** Start_Scenario() changes the palette; so, fade out & clear the screen - ** before calling it. - */ - Hide_Mouse(); - - if (selection != SEL_START_NEW_GAME) { - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - HiddenPage.Clear(); - VisiblePage.Clear(); - } - Show_Mouse(); - - Special.IsFromInstall = 0; - CCDebugString ("C&C95 - Starting scenario.\n"); - if (!Start_Scenario(ScenarioName)) { - return(false); - } - CCDebugString ("C&C95 - Scenario started OK.\n"); - } - - /* - ** For multiplayer games, initialize the inter-player message system. - ** Do this after loading the scenario, so the map's upper-left corner is - ** properly set. - */ - CCDebugString ("C&C95 - Initialising message system.\n"); - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - Messages.Init(Map.TacPixelX, Map.TacPixelY, 6, MAX_MESSAGE_LENGTH, 6*factor+1); - - /* - ** Hide the SeenBuff; force the map to render one frame. The caller can - ** then fade the palette in. - ** (If we loaded a game, this step will fade out the title screen. If we - ** started a scenario, Start_Scenario() will have played a couple of VQ - ** movies, which will have cleared the screen to black already.) - */ - CCDebugString ("C&C95 - About to call Call_Back.\n"); - Call_Back(); - - /* - ** This is desperately sad isnt it? - */ - Hide_Mouse(); - Hide_Mouse(); - Hide_Mouse(); - Hide_Mouse(); - WWMouse->Erase_Mouse(&HidPage, TRUE); - - - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back); - HiddenPage.Clear(); - VisiblePage.Clear(); - Set_Logic_Page(SeenBuff); - Map.Flag_To_Redraw(); - Call_Back(); - Map.Render(); - //Show_Mouse(); - - /* - ** Special hack initialization of 'MPlayerMaxAhead' to accommodate the - ** compression protocol technology. - */ -#ifdef FORCE_WINSOCK - if (CommProtocol==COMM_PROTOCOL_MULTI_E_COMP && GameToPlay!=GAME_NORMAL) { - if (!Special.IsFromWChat){ - MPlayerMaxAhead = FrameSendRate * 3; //2; - }else{ - MPlayerMaxAhead = WChatMaxAhead; - FrameSendRate = WChatSendRate; - } - } -#endif //FORCE_WINSOCK - - if (Debug_Map) { - while (Get_Mouse_State() > 1) { - Show_Mouse(); - } - } - - return(true); -} - - -/*********************************************************************************************** - * Play_Intro -- plays the introduction & logo movies * - * * - * INPUT: * - * for_real if true, this function plays the "real" intro; otherwise, it plays * - * a delicious smorgasbord of visual delights, guaranteed to titillate * - * the ocular & auditory nerve pathways. * - * Well, it plays movies, anyway. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/06/1995 BRR : Created. * - *=============================================================================================*/ -static void Play_Intro(bool for_real) -{ - return; // No game intro movies. - LLL - - bool playright = !Key_Down(KN_LCTRL) || !Key_Down(KN_RCTRL); - static int _counter = -1; - static char * _names[] = { -#ifdef DEMO - "LOGO", - -#else - - "INTRO2", -//#ifdef CHEAT_KEYS - "GDIEND1", - "GDIEND2", - "GDIFINA", - "GDIFINB", - "AIRSTRK", - "AKIRA", - "BANNER", - "BCANYON", - "BKGROUND", - "BOMBAWAY", - "BOMBFLEE", - "BURDET1", - "BURDET2", - "CC2TEASE", - "CONSYARD", - "DESFLEES", - "DESKILL", - "DESOLAT", - "DESSWEEP", - "FLAG", - "FLYY", - "FORESTKL", - "GAMEOVER", - "GDI1", - "GDI10", - "GDI11", - "GDI12", - "GDI13", - "GDI14", - "GDI15", - "GDI2", - "GDI3", - "GDI3LOSE", - "GDI4A", - "GDI4B", - "GDI5", - "GDI6", - "GDI7", - "GDI8A", - "GDI8B", - "GDI9", - "GDILOSE", - "GUNBOAT", - "HELLVALY", - "INSITES", - "KANEPRE", - "LANDING", - "LOGO", - "NAPALM", - "NITEJUMP", - "NOD1", - "NOD10A", - "NOD10B", - "NOD11", - "NOD12", - "NOD13", - "NOD1PRE", - "NOD2", - "NOD3", - "NOD4A", - "NOD4B", - "NOD5", - "NOD6", - "NOD7A", - "NOD7B", - "NOD8", - "NOD9", - "NODEND1", - "NODEND2", - "NODEND3", - "NODEND4", - "NODFINAL", - "NODFLEES", - "NODLOSE", - "NODSWEEP", - "NUKE", - "OBEL", - "PARATROP", - "PINTLE", - "PLANECRA", - "PODIUM", - "REFINT", - "RETRO", - "SABOTAGE", - "SAMDIE", - "SAMSITE", - "SEIGE", - "SETHPRE", - "SPYCRASH", - "STEALTH", - "SUNDIAL", - "TANKGO", - "TANKKILL", - "TBRINFO1", - "TBRINFO2", - "TBRINFO3", - "TIBERFX", - "TRTKIL_D", - "TURTKILL", - "VISOR", -//#endif -#endif - NULL - }; - - Keyboard::Clear(); - if (for_real) { - Hide_Mouse(); - Play_Movie("LOGO", THEME_NONE, false); - Show_Mouse(); - } else { - if (!Debug_Flag) { - _counter = 0; - } else { - if (playright) _counter++; - if (_counter == -1) _counter = 0; - } - Hide_Mouse(); - Play_Movie(_names[_counter], THEME_NONE); - Show_Mouse(); - if (!_names[_counter]) { - _counter = -1; - } - } -} - - -/*********************************************************************************************** - * Anim_Init -- Initialize the VQ animation control structure. * - * * - * VQ animations are controlled by a structure passed to the VQ player. This routine * - * initializes the structure to values required by C&C. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Only need to call this routine once at the beginning of the game. * - * * - * HISTORY: * - * 12/20/1994 JLB : Created. * - *=============================================================================================*/ -//extern LPDIRECTSOUND SoundObject; -//extern LPDIRECTSOUNDBUFFER PrimaryBufferPtr; -void Anim_Init(void) -{ -//PG_TO_FIX -#if (0) - /* Configure player with INI file */ - VQA_DefaultConfig(&AnimControl); -// void const * font = Load_Font(FONT8); -// AnimControl.EVAFont = (char *)font; -// AnimControl.CapFont = (char *)font; - - AnimControl.DrawFlags = VQACFGF_TOPLEFT; - AnimControl.DrawFlags |= VQACFGF_BUFFER; - - AnimControl.DrawFlags |= VQACFGF_NOSKIP; - - //AnimControl.X1 =0; - //AnimControl.Y1 =0; - AnimControl.FrameRate = -1; - AnimControl.DrawRate = -1; - - AnimControl.DrawerCallback = VQ_Call_Back; - AnimControl.ImageWidth = 320; - AnimControl.ImageHeight = 200; - AnimControl.Vmode = 0; - AnimControl.ImageBuf = (unsigned char *)SysMemPage.Get_Offset(); - //AnimControl.VBIBit = VertBlank; - //AnimControl.DrawFlags |= VQACFGF_TOPLEFT; - AnimControl.OptionFlags |= VQAOPTF_CAPTIONS|VQAOPTF_EVA; - - if (SlowPalette) { - AnimControl.OptionFlags |= VQAOPTF_SLOWPAL; - } -#endif -// AnimControl.AudioBuf = (unsigned char *)HidPage.Get_Buffer(); -// AnimControl.AudioBufSize = 32768U; - //AnimControl.DigiCard = NewConfig.DigitCard; - //AnimControl.HMIBufSize = 8192; - //AnimControl.DigiHandle = Get_Digi_Handle(); - //AnimControl.Volume = 0x00FF; - //AnimControl.AudioRate = 22050; -// if (NewConfig.Speed) AnimControl.AudioRate = 11025; - - - //PG_TO_FIX -#if (0) - AnimControl.SoundObject = SoundObject; //Get_Sound_Object(); - AnimControl.PrimaryBufferPtr = PrimaryBufferPtr; //Get_Primart_Buffer(); -#endif - - //if (!Debug_Quiet && Get_Digi_Handle() != -1) { - //AnimControl.OptionFlags |= VQAOPTF_AUDIO; - //} - -#if (0) - if (MonoClass::Is_Enabled()) { - AnimControl.OptionFlags |= VQAOPTF_MONO; - } -#endif -} - - -/*********************************************************************************************** - * Parse_Command_Line -- Parses the command line parameters. * - * * - * This routine should be called before the graphic mode is initialized. It examines the * - * command line parameters and sets the appropriate globals. If there is an error, then * - * it outputs a command summary and then returns false. * - * * - * INPUT: argc -- The number of command line arguments. * - * * - * argv -- Pointer to character string array that holds the individual arguments. * - * * - * OUTPUT: bool; Was the command line parsed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/18/1995 JLB : Created. * - *=============================================================================================*/ -bool Parse_Command_Line(int argc, char *argv[]) -{ - /* - ** Parse the command line and set globals to reflect the parameters - ** passed in. - */ -#ifdef DEMO - Scenario = 3; -#else - Scenario = 1; -#endif - ScenPlayer = SCEN_PLAYER_GDI; - ScenDir = SCEN_DIR_EAST; - Whom = HOUSE_GOOD; - Special.Init(); - - Debug_Map = false; -// Debug_Play_Map = false; - Debug_Unshroud = false; - - for (int index = 1; index < argc; index++) { - char * string; // Pointer to argument. - long code = 0; - - char arg_string[512]; - int str_len = strlen(argv[index]); - char *src = argv[index]; - char *dest = arg_string; - for (int i=0 ; i = Suchpfad fr Daten-Dateien festlegen.\r\n" - " -DESTNET = Netzwerkkennung des Zielrechners festlegen\r\n" - " (Syntax: DESTNETxx.xx.xx.xx)\r\n" - " -SOCKET = Kennung des Netzwerk-Sockets (0 - 16383)\n" - " -STEALTH = Namen im Mehrspieler-Modus verstecken (\"Boss-Modus\")\r\n" - " -MESSAGES = Mitteilungen von auáerhalb des Spiels zulassen\r\n" - // " -ELITE = Fortgeschrittene KI und Gefechtstechniken.\r\n" - "\r\n"); - #else - #ifdef FRENCH - puts("Command & Conquer (c) 1995, Westwood Studios\r\n" - "ParamŠtres:\r\n" -// " -CD = Recherche des fichiers dans le\r\n" -// " r‚pertoire indiqu‚.\r\n" - " -DESTNET = Sp‚cifier le num‚ro de r‚seau du systŠme de destination\r\n" - " (Syntaxe: DESTNETxx.xx.xx.xx)\r\n" - " -SOCKET = ID poste r‚seau (0 … 16383)\r\n" - " -STEALTH = Cacher les noms en mode multijoueurs (\"Mode Boss\")\r\n" - " -MESSAGES = Autorise les messages ext‚rieurs … ce jeu.\r\n" - "\r\n"); - #else - puts("Command & Conquer (c) 1995, 1996 Westwood Studios\r\n" - "Parameters:\r\n" - #ifdef NEVER - " CHEAT = Enable debug keys.\r\n" - " -EDITOR = Enable scenario editor.\r\n" - #endif -// " -CD = Set search path for data files.\r\n" - " -DESTNET = Specify Network Number of destination system\r\n" - " (Syntax: DESTNETxx.xx.xx.xx)\r\n" - " -SOCKET = Network Socket ID (0 - 16383)\n" - " -STEALTH = Hide multiplayer names (\"Boss mode\")\r\n" - " -MESSAGES = Allow messages from outside this game.\r\n" - " -o = Enable compatability with version 1.07.\r\n" -#ifdef JAPANESE - " -ENGLISH = Enable English keyboard compatibility.\r\n" -#endif - // " -ELITE = Advanced AI and combat characteristics.\r\n" - #ifdef NEVER - " -O[options]= Special control options;\r\n" - " 1 : Tiberium grows.\r\n" - " 2 : Tiberium grows and spreads.\r\n" - " A : Aggressive player unit defense enabled.\r\n" - " B : Bargraphs always displayed.\r\n" - " C : Capture the flag mode.\r\n" - " E : Elite defense mode disable (attacker advantage).\r\n" - " D : Deploy reversal allowed for construction yard.\r\n" - " F : Fleeing from direct immediate threats is enabled.\r\n" - " H : Hussled recharge time.\r\n" - " G : Growth for Tiberium slowed in multiplay.\r\n" - " I : Inert weapons -- no damage occurs.\r\n" - " J : 7th grade sound effects.\r\n" - " M : Monochrome debug messages.\r\n" - " N : Name the civilians and buildings.\r\n" - " P : Path algorithm displayed as it works.\r\n" - " Q : Quiet mode (no sound).\r\n" - " R : Road pieces are not added to buildings.\r\n" - " T : Three point turns for wheeled vehicles.\r\n" - " U : U can target and burn trees.\r\n" - " V : Show target selection by opponent.\r\n" - " X : Make a recording of a multiplayer game.\r\n" - " Y : Play a recording of a multiplayer game.\r\n" - " Z : Disaster containment team.\r\n" - #endif - "\r\n"); - #endif - #endif - return(false); - } - - - bool processed = true; - switch (Obfuscate(string)) { - - /* - ** Signal that easy mode is active. - */ - case PARM_EASY: - Special.IsEasy = true; - Special.IsDifficult = false; - break; - - /* - ** Signal that hard mode is active. - */ - case PARM_HARD: - Special.IsEasy = false; - Special.IsDifficult = true; - break; - -#ifdef VIRGIN_CHEAT_KEYS - case PARM_PLAYTEST: - Debug_Playtest = true; - break; -#endif - -#ifdef PARM_CHEATERIK - case PARM_CHEATERIK: - Debug_Playtest = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_CHEATADAM - case PARM_CHEATADAM: - Debug_Playtest = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_CHEATMIKE - case PARM_CHEATMIKE: - Debug_Playtest = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_CHEATDAVID - case PARM_CHEATDAVID: - Debug_Playtest = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_CHEATPHIL - case PARM_CHEATPHIL: - Debug_Playtest = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_CHEATBILL - case PARM_CHEATBILL: - Debug_Playtest = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_CHEAT_STEVET - - case PARM_CHEAT_STEVET: - Debug_Playtest = true; - Debug_Flag = true; - break; - -#endif - -#ifdef PARM_EDITORBILL - case PARM_EDITORBILL: - Debug_Map = true; - Debug_Unshroud = true; - Debug_Flag = true; - break; -#endif - -#ifdef PARM_EDITORERIK - case PARM_EDITORERIK: - Debug_Map = true; - Debug_Unshroud = true; - Debug_Flag = true; - break; -#endif - - case PARM_SPECIAL: - Special.IsJurassic = true; - AreThingiesEnabled = true; - break; - - /* - ** Special flag - is C&C being run from the install program? - */ - case PARM_INSTALL: -#ifndef DEMO - Special.IsFromInstall = true; -#endif - break; - - default: - processed = false; - break; - } - if (processed) continue; - - -#ifdef CHEAT_KEYS - /* - ** Scenario Editor Mode - */ - if (stricmp(string, "-CHECKMAP") == 0) { - Debug_Check_Map = true; - continue; - } - -#endif - - /* - ** Older version override. - */ - if (stricmp(string, "-O") == 0 || stricmp(string, "-0") == 0) { - IsV107 = true; - continue; - } - - /* - ** File search path override. - */ - if (strstr(string, "-CD")) { - CCFileClass::Set_Search_Drives(&string[3]); - continue; - } -#ifdef JAPANESE - /* - ** Enable english-compatible keyboard - */ - if (!stricmp(string,"-ENGLISH")) { - ForceEnglish = true; - continue; - } -#endif - - /* - ** Specify destination connection for network play - */ - if (strstr(string, "-DESTNET")) { - NetNumType net; - NetNodeType node; - - /* - ** Scan the command-line string, pulling off each address piece - */ - int i = 0; - char * p = strtok(string + 8,"."); - while (p) { - int x; - - sscanf(p,"%x",&x); // convert from hex string to int - if (i < 4) { - net[i] = (char)x; // fill NetNum - } else { - node[i-4] = (char)x; // fill NetNode - } - i++; - p = strtok(NULL,"."); - } - - /* - ** If all the address components were successfully read, fill in the - ** BridgeNet with a broadcast address to the network across the bridge. - */ - if (i >= 4) { - IsBridge = 1; - memset(node, 0xff, 6); - BridgeNet = IPXAddressClass(net, node); - } - continue; - } - - /* - ** Specify socket ID, as an offset from 0x4000. - */ - if (strstr(string, "-SOCKET")) { - unsigned short socket; - - socket = (unsigned short)(atoi(string + strlen("SOCKET"))); - socket += 0x4000; - if (socket >= 0x4000 && socket < 0x8000) { - Ipx.Set_Socket (socket); - } - continue; - } - - /* - ** Set the Net Stealth option - */ - if (strstr(string, "-STEALTH")) { - NetStealth = true; - continue; - } - - /* - ** Set the Net Protection option - */ - if (strstr(string, "-MESSAGES")) { - NetProtect = false; - continue; - } - - /* - ** Allow "attract" mode - */ - if (strstr(string, "-ATTRACT")) { - AllowAttract = true; - continue; - } - - /* - ** Set screen to 640x480 instead of 640x400 - */ - if (strstr(string,"-480")){ - ScreenHeight = 480; - continue; - } - - /* - ** Check for spawn from WChat - */ - if (strstr(string,"-WCHAT")){ - SpawnedFromWChat = true; - } - - /* - ** Allow use of MMX instructions - */ - if (strstr(string,"-MMX")){ - MMXAvailable = true; - continue; - } - - -#ifdef CHEAT_KEYS - /* - ** Allow solo net play - */ - if (stricmp(string, "-HANSOLO") == 0) { - MPlayerSolo = true; - continue; - } - - /* - ** Specify the random number seed (for debugging) - */ - if (strstr(string, "-SEED")) { - CustomSeed = (unsigned short)(atoi(string + strlen("SEED"))); - continue; - } -#endif - -#ifdef NEVER - /* - ** Handle the prog init differently in this case. - */ - if (strstr(string, "-V")) { - continue; - } -#endif - -#ifdef FIX_ME_LATER - /* - ** look for passed-in video mode to default to - */ - if (strnicmp(string, "-V", strlen("-V")) == 0) { - Set_Video_Mode(MCGA_MODE); // do this to get around first_time variable... - Set_Original_Video_Mode(atoi(string+2)); - continue; - } -#endif //FIX_ME_LATER - - /* - ** Special command line control parsing. - */ - if (strnicmp(string, "-X", strlen("-O")) == 0) { - string += strlen("-X"); - while (*string) { - char code = *string++; - switch (toupper(code)) { - -#ifdef ONHOLD - /* - ** Should human generated sound effects be used? - */ - case 'J': - Special.IsJuvenile = true; - break; -#endif - -#ifdef CHEAT_KEYS - /* - ** Monochrome debug screen enable. - */ - case 'M': - Special.IsMonoEnabled = true; - break; - - /* - ** Inert weapons -- no units take damage. - */ - case 'I': - Special.IsInert = true; - break; -#endif - -#ifdef CHEAT_KEYS - /* - ** Hussled recharge timer. - */ - case 'H': - Special.IsSpeedBuild = true; - break; - - /* - ** Turn on super-record mode, which thrashes your disk terribly, - ** but is really really cool. Well, sometimes it is, anyway. - ** At least, it can be. Once in a while. - ** This flag tells the recording system to re-open the file for - ** each write, so the recording survives a crash. - */ - case 'S': - SuperRecord = 1; - break; - - /* - ** "Record" a multi-player game - */ - case 'X': - RecordGame = 1; - break; - - /* - ** "Play Back" a multi-player game - */ - case 'Y': - PlaybackGame = 1; - break; -#endif - -#ifdef ONHOLD - /* - ** Bonus scenario enable. - */ - case 'Z': - Special.IsJurassic = true; - break; -#endif - - /* - ** Quiet mode override control. - */ - case 'Q': - Debug_Quiet = true; - break; - -#ifdef CHEAT_KEYS - /* - ** Target selection by human opponent (network/modem play) will - ** be visible to the player? - */ - case 'V': - Special.IsVisibleTarget = true; - break; -#endif - - default: -#ifdef GERMAN - puts("Ungltiger Parameter.\n"); -#else -#ifdef FRENCH - puts("Commande d'option invalide.\n"); -#else - puts("Invalid option switch.\n"); -#endif -#endif - return(false); - } - - } - - if (Special.IsMonoEnabled) { - MonoClass::Enable(); - } - continue; - } - } - return(true); -} - - -#ifdef ONHOLD -/*********************************************************************************************** - * Parse_INI_File -- Parses CONQUER.INI for certain options * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/18/1995 BRR : Created. * - *=============================================================================================*/ -void Parse_INI_File(void) -{ - char *buffer; // INI staging buffer pointer. - char buf[128]; - static char section[40]; - static char entry[40]; - static char name[40]; - int len; - int i; - - /* - ** These arrays store the coded version of the names Geologic, Period, & Jurassic. - ** Decode them by subtracting 83. For you curious types, the names look like: - ** š¸Â¿Âº¼¶ - ** £¸Å¼Â· - ** ÈÅ´ÆÆ¼¶ - ** If these INI entries aren't found, the IsJurassic flag does nothing. - */ - static char coded_section[] = {154,184,194,191,194,186,188,182,0}; - static char coded_entry[] = {163,184,197,188,194,183,0}; - static char coded_name[] = {157,200,197,180,198,198,188,182,0}; - - /*------------------------------------------------------------------------ - Fetch working pointer to the INI staging buffer. Make sure that the buffer - is cleared out before proceeding. - ------------------------------------------------------------------------*/ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - /*------------------------------------------------------------------------ - Decode the desired section, entry, & name - ------------------------------------------------------------------------*/ - strcpy (section,coded_section); - len = strlen(coded_section); - for (i = 0; i < len; i++) { - section[i] -= 83; - } - - strcpy (entry,coded_entry); - len = strlen(coded_entry); - for (i = 0; i < len; i++) { - entry[i] -= 83; - } - - strcpy (name,coded_name); - len = strlen(coded_name); - for (i = 0; i < len; i++) { - name[i] -= 83; - } - - /*------------------------------------------------------------------------ - Create filename and read the file. - ------------------------------------------------------------------------*/ - CCFileClass file ("CONQUER.INI"); - if (!file.Is_Available()) { - return; - } else { - file.Read(buffer, _ShapeBufferSize-1); - } - file.Close(); - - WWGetPrivateProfileString(section, entry, "", buf, sizeof(buf), buffer); - - if (!stricmp (buf,name)) - AreThingiesEnabled = true; - - memset (section, 0, sizeof(section)); - memset (entry, 0, sizeof(entry)); - memset (name, 0, sizeof(name)); -} -#endif - - -/*********************************************************************************************** - * Version_Number -- Determines the version number. * - * * - * This routine will determine the version number by analyzing the date and teim that the * - * program was compiled and then generating a unique version number based on it. The * - * version numbers are guaranteed to be larger for later dates. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the version number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/24/1995 JLB : Created. * - *=============================================================================================*/ -int Version_Number(void) -{ -#ifdef OBSOLETE - static bool initialized = false; - static int version; - static char * date = __DATE__; - static char * time = __TIME__; - static char const * months = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; - - if (!initialized) { - char * ptr; - char * tok; - - /* - ** Fetch the month and place in the first two digit positions. - */ - strupr(date); - tok = strtok(date, " "); - ptr = strstr(months, tok); - if (ptr) { - version = (((ptr - months) / 3)+1) * 10000; - } - - /* - ** Fetch the date and place that in the next two digit positions. - */ - tok = strtok(NULL, " "); - if (tok) { - version += atoi(tok) * 100; - } - - /* - ** Fetch the time and place that in the last two digit positions. - */ - tok = strtok(time, ": "); - if (tok) { - version += atoi(tok); - } - - - /* - ** Fetch the virgin text file (if present). - */ - RawFileClass file("VERSION.TXT"); - if (file.Is_Available()) { - file.Read(VersionText, sizeof(VersionText)); - VersionText[sizeof(VersionText)-1] = '\0'; - while (VersionText[sizeof(VersionText)-1] == '\r') { - VersionText[sizeof(VersionText)-1] = '\0'; - } - } else { - VersionText[0] = '\0'; - } - - initialized = true; - } - return(version); -#endif - -#ifdef WIN32 - -#if (FRENCH) - sprintf(VersionText, ".02"); // Win95 french version number -#endif //FRENCH - -#if (GERMAN) - sprintf(VersionText, ".01"); // Win95 german version number -#endif //GERMAN - -#if (JAPANESE) - sprintf(VersionText, ".01"); // Win95 german version number -#endif //GERMAN - -#if !(FRENCH | GERMAN | JAPANESE) - sprintf(VersionText, ".07"); // Win95 USA version number -#endif //FRENCH | GERMAN - - RawFileClass file("VERSION.TXT"); - char version [16]; - memset (version, 0, sizeof (version)); - if (file.Is_Available()){ - file.Read (version, sizeof (version)); - } - strncat (VersionText, version, sizeof (VersionText) - strlen (VersionText) - 1); - -#if (FRENCH) - return (1); // Win95 french version number -#endif //FRENCH - -#if (GERMAN) - return (1); // Win95 german version number -#endif //GERMAN - -#if (JAPANESE) - return (1); // Win95 german version number -#endif //GERMAN - -#if !(FRENCH | GERMAN | JAPANESE) - return (1); // Win95 USA version number -#endif //FRENCH | GERMAN - -#else - - -#ifdef PATCH - - #ifdef DEMO - sprintf(VersionText, " 1.0a"); // Demo version. - #else - strcpy(VersionText, ".34 "); - #endif - return(1); - -#else - - #ifdef DEMO - sprintf(VersionText, " 1.0a"); // Demo version. - #else - // sprintf(VersionText, ".%02dp", 13); // Patch version. - sprintf(VersionText, ".%02d", 14); // Master version. - #endif - return(1); -#endif - -#endif //WIN32 -} - - -/*************************************************************************** - * Save_Recording_Values -- Saves recording values to a recording file * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/15/1995 BRR : Created. * - *=========================================================================*/ -void Save_Recording_Values(void) -{ - RecordFile.Write(&GameToPlay, sizeof(GameToPlay)); - RecordFile.Write(&ModemGameToPlay, sizeof(ModemGameToPlay)); - RecordFile.Write(&BuildLevel, sizeof(BuildLevel)); - RecordFile.Write(MPlayerName, sizeof(MPlayerName)); - RecordFile.Write(&MPlayerPrefColor, sizeof(MPlayerPrefColor)); - RecordFile.Write(&MPlayerColorIdx, sizeof(MPlayerColorIdx)); - RecordFile.Write(&MPlayerHouse, sizeof(MPlayerHouse)); - RecordFile.Write(&MPlayerLocalID, sizeof(MPlayerLocalID)); - RecordFile.Write(&MPlayerCount, sizeof(MPlayerCount)); - RecordFile.Write(&MPlayerBases, sizeof(MPlayerBases)); - RecordFile.Write(&MPlayerCredits, sizeof(MPlayerCredits)); - RecordFile.Write(&MPlayerTiberium, sizeof(MPlayerTiberium)); - RecordFile.Write(&MPlayerGoodies, sizeof(MPlayerGoodies)); - RecordFile.Write(&MPlayerGhosts, sizeof(MPlayerGhosts)); - RecordFile.Write(&MPlayerUnitCount, sizeof(MPlayerUnitCount)); - RecordFile.Write(MPlayerID, sizeof(MPlayerID)); - RecordFile.Write(MPlayerHouses, sizeof(MPlayerHouses)); - RecordFile.Write(&Seed, sizeof(Seed)); - RecordFile.Write(&Scenario, sizeof(Scenario)); - RecordFile.Write(&ScenPlayer, sizeof(ScenPlayer)); - RecordFile.Write(&ScenDir, sizeof(ScenDir)); - RecordFile.Write(&Whom, sizeof(Whom)); - RecordFile.Write(&Special, sizeof(SpecialClass)); - RecordFile.Write(&Options, sizeof(GameOptionsClass)); - RecordFile.Write(&FrameSendRate, sizeof(FrameSendRate)); - RecordFile.Write(&CommProtocol, sizeof(CommProtocol)); - - if (SuperRecord) { - RecordFile.Close(); - } -} - - -/*************************************************************************** - * Load_Recording_Values -- Loads recording values from recording file * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/15/1995 BRR : Created. * - *=========================================================================*/ -void Load_Recording_Values(void) -{ - Read_MultiPlayer_Settings(); - - RecordFile.Read(&GameToPlay, sizeof(GameToPlay)); - RecordFile.Read(&ModemGameToPlay, sizeof(ModemGameToPlay)); - RecordFile.Read(&BuildLevel, sizeof(BuildLevel)); - RecordFile.Read(MPlayerName, sizeof(MPlayerName)); - RecordFile.Read(&MPlayerPrefColor, sizeof(MPlayerPrefColor)); - RecordFile.Read(&MPlayerColorIdx, sizeof(MPlayerColorIdx)); - RecordFile.Read(&MPlayerHouse, sizeof(MPlayerHouse)); - RecordFile.Read(&MPlayerLocalID, sizeof(MPlayerLocalID)); - RecordFile.Read(&MPlayerCount, sizeof(MPlayerCount)); - RecordFile.Read(&MPlayerBases, sizeof(MPlayerBases)); - RecordFile.Read(&MPlayerCredits, sizeof(MPlayerCredits)); - RecordFile.Read(&MPlayerTiberium, sizeof(MPlayerTiberium)); - RecordFile.Read(&MPlayerGoodies, sizeof(MPlayerGoodies)); - RecordFile.Read(&MPlayerGhosts, sizeof(MPlayerGhosts)); - RecordFile.Read(&MPlayerUnitCount, sizeof(MPlayerUnitCount)); - RecordFile.Read(MPlayerID, sizeof(MPlayerID)); - RecordFile.Read(MPlayerHouses, sizeof(MPlayerHouses)); - RecordFile.Read(&Seed, sizeof(Seed)); - RecordFile.Read(&Scenario, sizeof(Scenario)); - RecordFile.Read(&ScenPlayer, sizeof(ScenPlayer)); - RecordFile.Read(&ScenDir, sizeof(ScenDir)); - RecordFile.Read(&Whom, sizeof(Whom)); - RecordFile.Read(&Special, sizeof(SpecialClass)); - RecordFile.Read(&Options, sizeof(GameOptionsClass)); - RecordFile.Read(&FrameSendRate, sizeof(FrameSendRate)); - RecordFile.Read(&CommProtocol, sizeof(CommProtocol)); -} - - -/*********************************************************************************************** - * Obfuscate -- Sufficiently transform parameter to thwart casual hackers. * - * * - * This routine borrows from CRC and PGP technology to sufficiently alter the parameter * - * in order to make it difficult to reverse engineer the key phrase. This is designed to * - * be used for hidden game options that will be released at a later time over Westwood's * - * Web page or through magazine hint articles. * - * * - * Since this is a one way transformation, it becomes much more difficult to reverse * - * engineer the pass phrase even if the resultant pass code is known. This has an added * - * benefit of making this algorithm immune to traditional cyrptographic attacks. * - * * - * The largest strength of this transformation algorithm lies in the restriction on the * - * source vector being legal ASCII uppercase characters. This restriction alone makes even * - * a simple CRC transformation practically impossible to reverse engineer. This algorithm * - * uses far more than a simple CRC transformation to achieve added strength from advanced * - * attack methods. * - * * - * INPUT: string -- Pointer to the key phrase that will be transformed into a code. * - * * - * OUTPUT: Returns with the code that the key phrase is translated into. * - * * - * WARNINGS: A zero length pass phrase results in a 0x00000000 result code. * - * * - * HISTORY: * - * 08/19/1995 JLB : Created. * - *=============================================================================================*/ -long Obfuscate(char const * string) -{ - char buffer[1024]; - - if (!string) return(0); - memset(buffer, '\xA5', sizeof(buffer)); - - /* - ** Copy key phrase into a working buffer. This hides any transformation done - ** to the string. - */ - strncpy(buffer, string, sizeof(buffer)); - buffer[sizeof(buffer)-1] = '\0'; - int length = strlen(buffer); - - /* - ** Only upper case letters are significant. - */ - strupr(buffer); - - /* - ** Ensure that only visible ASCII characters compose the key phrase. This - ** discourages the direct forced illegal character input method of attack. - */ - int index; - for (index = 0; index < length; index++) { - if (!isgraph(buffer[index])) { - buffer[index] = 'A' + (index%26); - } - } - - /* - ** Increase the strength of even short pass phrases by extending the - ** length to be at least a minimum number of characters. This helps prevent - ** a weak pass phrase from compromising the obfuscation process. This - ** process also forces the key phrase to be an even multiple of four. - ** This is necessary to support the cypher process that occurs later. - */ - if (length < 16 || (length & 0x03)) { - int maxlen = 16; - if (((length+3) & 0x00FC) > maxlen) { - maxlen = ((length+3) & 0x00FC); - } - for (index = length; index < maxlen; index++) { - buffer[index] = 'A' + ((('?' ^ buffer[index-length]) + index) % 26); - } - length = index; - buffer[length] = '\0'; - } - - /* - ** Transform the buffer into a number. This transformation is character - ** order dependant. - */ - long code = Calculate_CRC(buffer, length); - - /* - ** Record a copy of this initial transformation to be used in a later - ** self referential transformation. - */ - long copy = code; - - /* - ** Reverse the character string and combine with the previous transformation. - ** This doubles the workload of trying to reverse engineer the CRC calculation. - */ - strrev(buffer); - code ^= Calculate_CRC(buffer, length); - - /* - ** Perform a self referential transformation. This makes a reverse engineering - ** by using a cause and effect attack more difficult. - */ - code = code ^ copy; - - /* - ** Unroll and combine the code value into the pass phrase and then perform - ** another self referential transformation. Although this is a trivial cypher - ** process, it gives the sophisticated hacker false hope since the strong - ** cypher process occurs later. - */ - strrev(buffer); // Restore original string order. - for (index = 0; index < length; index++) { - code ^= (unsigned char)buffer[index]; - unsigned char temp = (unsigned char)code; - buffer[index] ^= temp; - code >>= 8; - code |= (((long)temp)<<24); - } - - /* - ** Introduce loss into the vector. This strengthens the key against traditional - ** cryptographic attack engines. Since this also weakens the key against - ** unconventional attacks, the loss is limited to less than 10%. - */ - for (index = 0; index < length; index++) { - static unsigned char _lossbits[] = {0x00,0x08,0x00,0x20,0x00,0x04,0x10,0x00}; - static unsigned char _addbits[] = {0x10,0x00,0x00,0x80,0x40,0x00,0x00,0x04}; - - buffer[index] |= _addbits[index % (sizeof(_addbits)/sizeof(_addbits[0]))]; - buffer[index] &= ~_lossbits[index % (sizeof(_lossbits)/sizeof(_lossbits[0]))]; - } - - /* - ** Perform a general cypher transformation on the vector - ** and use the vector itself as the cypher key. This is a variation on the - ** cypher process used in PGP. It is a very strong cypher process with no known - ** weaknesses. However, in this case, the cypher key is the vector itself and this - ** opens up a weakness against attacks that have access to this transformation - ** algorithm. The sheer workload of reversing this transformation should be enough - ** to discourage even the most determined hackers. - */ - for (index = 0; index < length; index += 4) { - short key1 = buffer[index]; - short key2 = buffer[index+1]; - short key3 = buffer[index+2]; - short key4 = buffer[index+3]; - short val1 = key1; - short val2 = key2; - short val3 = key3; - short val4 = key4; - - val1 *= key1; - val2 += key2; - val3 += key3; - val4 *= key4; - - short s3 = val3; - val3 ^= val1; - val3 *= key1; - short s2 = val2; - val2 ^= val4; - val2 += val3; - val2 *= key3; - val3 += val2; - - val1 ^= val2; - val4 ^= val3; - - val2 ^= s3; - val3 ^= s2; - - buffer[index] = val1; - buffer[index+1] = val2; - buffer[index+2] = val3; - buffer[index+3] = val4; - } - - /* - ** Convert this final vector into a cypher key code to be - ** returned by this routine. - */ - code = Calculate_CRC(buffer, length); - - /* - ** Return the final code value. - */ - return(code); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/INTERNET.CPP b/code/TIBERIANDAWN/INTERNET.CPP deleted file mode 100644 index 0e9ec22..0000000 --- a/code/TIBERIANDAWN/INTERNET.CPP +++ /dev/null @@ -1,886 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/************************************************************************************* - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - ************************************************************************************* - * * - * Project Name : Command & Conquer - Red Alert * - * * - * File Name : INTERNET.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : March 11th, 1996 * - * * - * Last Update : August 5th, 1996 [ST] * - * * - *-----------------------------------------------------------------------------------* - * Overview: * - * * - * Miscellaneous junk related to H2H internet connection. * - * * - *-----------------------------------------------------------------------------------* - * Functions: * - * Check_From_WChat -- Interprets start game packet from WChat * - * Read_Game_Options -- Read the game setup options from the wchat packet * - * Is_User_WChat_Registered -- retrieve the users wchat entry from registry * - * Spawn_WChat -- spawns or switches focus to wchat * - * Spawn_Registration_App -- spawns the C&C/Planet westwood registration app * - * Do_The_Internet_Menu_Thang -- Handle case where user clicks on 'Internet' button * - * * - * * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" -#include "tcpip.h" -#include "ccdde.h" - - - -/*************************************************************************** -** Internet specific globals -*/ -char PlanetWestwoodHandle[] = {"Handle"}; //Planet WW user name -char PlanetWestwoodPassword[] = {"Password"}; //Planet WW password -char PlanetWestwoodIPAddress[IP_ADDRESS_MAX] = {"206.154.108.87"}; //IP of server or other player -long PlanetWestwoodPortNumber = 1234; //Port number to send to -bool PlanetWestwoodIsHost = false; //Flag true if player has control of game options -unsigned long PlanetWestwoodGameID; //Game ID -unsigned long PlanetWestwoodStartTime; //Time that game was started -HWND WChatHWND = 0; //Handle to Wchat window. -bool UseVirtualSubnetServer; -int InternetMaxPlayers; -int WChatMaxAhead; -int WChatSendRate; - - -int Read_Game_Options(void); - -extern bool SpawnedFromWChat; - - - - - - -/*********************************************************************************************** - * Check_From_WChat -- This function reads in C&CSPAWN.INI and interprets it * - * C&CSPAWN.INI is now sent to us by WCHAT via DDE * - * * - * * - * * - * INPUT: Name of C&CSPAWN.INI file. If NULL then get file from DDE Server * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/9/96 1:44PM ST : Created * - *=============================================================================================*/ -void Check_From_WChat(char *wchat_name) -{ -#ifndef DEMO - - char default_string[] = {"Error"}; - char key_string[256]; - char *ini_file; - RawFileClass wchat_file; - - /* - ** Get a pointer to C&CSPAWN.INI either by reading it from disk or getting it from - ** the DDE server. - */ - if (wchat_name){ - ini_file = new char [8192]; - }else{ - ini_file = DDEServer.Get_MPlayer_Game_Info(); -#if (0) - /* - ** Save it to disk as well so I can see it - */ - RawFileClass anotherfile ("FROMCHAT.TXT"); - anotherfile.Write(ini_file, DDEServer.Get_MPlayer_Game_Info_Length()); -#endif //(0) - } - - if (wchat_name){ - wchat_file.Set_Name(wchat_name); - } - - if (!wchat_name || wchat_file.Is_Available()){ - - /* - ** Read the ini file from disk if we founf it there - */ - if (wchat_name){ - wchat_file.Read(ini_file, wchat_file.Size()); - } - - /* - ** Get the IP address - */ - key_string[0] = 0; - - WWGetPrivateProfileString("Internet", - "Address", - default_string, - key_string, - sizeof(key_string), - ini_file); - - - if (!strcmp (key_string, default_string)) { - if (wchat_name) delete ini_file; - return; - } - strcpy (PlanetWestwoodIPAddress, key_string); - - - - /* - ** Get the port number - */ - key_string[0] = 0; - - WWGetPrivateProfileString("Internet", - "Port", - default_string, - key_string, - sizeof(key_string), - ini_file); - - - if (!strcmp (key_string, default_string)) { - if (wchat_name) delete ini_file; - return; - } - - PlanetWestwoodPortNumber = atol(key_string); - - - /* - ** Get host or client - */ - key_string[0] = 0; - - WWGetPrivateProfileString("Internet", - "Host", - default_string, - key_string, - sizeof(key_string), - ini_file); - - - if (!strcmp (key_string, default_string)) { - if (wchat_name) delete ini_file; - return; - } - - if (strchr (key_string, '1')){ - PlanetWestwoodIsHost = true; - }else{ - PlanetWestwoodIsHost = false; - } - - UseVirtualSubnetServer = WWGetPrivateProfileInt("Internet", "UseVSS", 0, ini_file); - - Special.IsFromWChat = true; - } - - if (wchat_name) delete ini_file; - -#else //DEMO - - wchat_name = wchat_name; - -#endif //DEMO - -} - -//EventClass Wibble; - - -/*************************************************************************** - * Read_Game_Options -- reads multiplayer game options from disk * - * * - * This routine is used for multiplayer games which read the game options * - * from disk, rather than through a connection dialog. * - * * - * INPUT: * - * name of C&CSPAWN.INI file. Null if data should be got from DDE server* * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: \ * - * none. * - * * - * HISTORY: * - * 01/11/1996 BRR : Created. * - *=========================================================================*/ -int Read_Game_Options(char *name) -{ - char *buffer; - - char filename[256] = {"INVALID.123"}; - - if (name){ - strcpy (filename, name); - } - - /*------------------------------------------------------------------------ - Create filename and read the file. - ------------------------------------------------------------------------*/ - CCFileClass file (filename); - - if (name && !file.Is_Available()) { - return(0); - } else { - if (name){ - buffer = new char [8192]; // INI staging buffer pointer. - memset(buffer, '\0', 8192); - file.Read(buffer, 8192-1); - file.Close(); - }else{ - buffer = DDEServer.Get_MPlayer_Game_Info(); - } - } - - /*------------------------------------------------------------------------ - Get the player's name - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString("Options", "Handle", "Noname", MPlayerName, - sizeof(MPlayerName), buffer); - strcpy(MPlayerGameName, MPlayerName); - MPlayerColorIdx = WWGetPrivateProfileInt("Options", "Color", 0, buffer); - MPlayerPrefColor = MPlayerColorIdx; - MPlayerHouse = (HousesType)WWGetPrivateProfileInt("Options", "Side", - HOUSE_GOOD, buffer); - - MPlayerCredits = WWGetPrivateProfileInt("Options", "Credits", 0, buffer); - MPlayerBases = WWGetPrivateProfileInt("Options", "Bases", 0, buffer); - MPlayerTiberium = WWGetPrivateProfileInt("Options", "Tiberium", 0, buffer); - MPlayerGoodies = WWGetPrivateProfileInt("Options", "Crates", 0, buffer); - MPlayerGhosts = WWGetPrivateProfileInt("Options", "AI", 0, buffer); - BuildLevel = WWGetPrivateProfileInt("Options", "BuildLevel", 0, buffer); - MPlayerUnitCount = WWGetPrivateProfileInt("Options", "UnitCount", 0, buffer); - Seed = WWGetPrivateProfileInt("Options", "Seed", 0, buffer); - Special.IsCaptureTheFlag = WWGetPrivateProfileInt("Options", "CaptureTheFlag", 0, buffer); - PlanetWestwoodGameID = WWGetPrivateProfileInt("Internet", "GameID", 0, buffer); - PlanetWestwoodStartTime = WWGetPrivateProfileInt ("Internet", "StartTime", 0, buffer); - WChatHWND = (HWND) WWGetPrivateProfileInt("Internet", "HWND", (int)FindWindow("OWL_Window", "Westwood Chat"), buffer); - - InternetMaxPlayers = WWGetPrivateProfileInt("Internet", "MaxPlayers", 2, buffer); - - - if (MPlayerTiberium) { - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - } else { - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - } - ScenarioIdx = WWGetPrivateProfileInt("Options", "Scenario", 0, buffer); - Scenario = ScenarioIdx; //MPlayerFilenum[ScenarioIdx]; - - Options.GameSpeed = 0; - - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - MPlayerMaxAhead = WChatMaxAhead = WWGetPrivateProfileInt("Timing", "MaxAhead", 9, buffer); - FrameSendRate = WChatSendRate = WWGetPrivateProfileInt("Timing", "SendRate", 3, buffer); - - if (name) delete buffer; - return (1); - -} - - - - -/*********************************************************************************************** - * Get_Registry_Sub_Key -- search a registry key for a sub-key * - * * - * * - * * - * INPUT: handle of key to search * - * text to search for * - * true if old key should be closed when new key opened * - * * - * OUTPUT: handle to the key we found or 0 * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 1/12/96 2:11PM ST : Created * - *=============================================================================================*/ - -extern HKEY Get_Registry_Sub_Key (HKEY base_key, char *search_key, BOOL close); - - - -void Just_Path(char *path, char *destpath) -{ - char *terminator = NULL; //He'll be back. - - strcpy (destpath, path); - terminator = strrchr (destpath, '\\'); - if (terminator){ - *terminator = 0; - } -} - - - - - -/*********************************************************************************************** - * Is_User_WChat_Registered -- retrieve the users wchat entry from the registry * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: TRUE if users wchat entry was found in the registry * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 1/12/96 2:13PM ST : Created * - *=============================================================================================*/ -bool Is_User_WChat_Registered(char *buffer, int buffer_len) -{ - buffer; - buffer_len; - return false; - -#if (0) //ST - 1/2/2019 5:54PM - - HKEY key; - char user_handle[256]; - DWORD user_handle_size = sizeof (user_handle); - char user_pword[256]; - DWORD user_pword_size = sizeof (user_pword); - - - /* - ** Check HKEY_CLASSES_ROOT first. Old versions of Wchat register there - */ - key = Get_Registry_Sub_Key (HKEY_CLASSES_ROOT, "Wchat", FALSE); - - if (key){ - key = Get_Registry_Sub_Key (key, "Nick1", TRUE); - if (key){ - - if (RegQueryValue(key, "Nick", user_handle, (long*)&user_handle_size) == ERROR_SUCCESS){ - - if (RegQueryValue(key, "Pass", user_pword, (long*)&user_pword_size) == ERROR_SUCCESS){ - - /* - ** If the first char of the users name is non-numberic and there is a password - ** then return success - */ - if ((user_handle[0] < '0' || user_handle[0] > '9') && user_pword[0]){ - RegCloseKey( key ); - return (TRUE); - } - } - } - } - - RegCloseKey ( key ); - } - - - - /* - ** Check HKEY_LOCAL_MACKINE/Software - */ - user_handle_size = sizeof (user_handle); - - key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "SOFTWARE", FALSE); - if (!key) return (FALSE); - - key = Get_Registry_Sub_Key (key, "Westwood", TRUE); - if (!key) return (FALSE); - - key = Get_Registry_Sub_Key (key, "InetReg", TRUE); - if (!key) return (FALSE); - - //key = Get_Registry_Sub_Key (key, "UserName", TRUE); - //if (!key) return (FALSE); - - //key = Get_Registry_Sub_Key (key, "Nick", TRUE); - //if (!key) return (FALSE); - - if (RegQueryValueEx(key, "UserName", NULL, NULL, (unsigned char*)user_handle, &user_handle_size) != ERROR_SUCCESS){ - RegCloseKey(key); - return (FALSE); - } - - RegCloseKey(key); - memcpy (buffer, user_handle, min((unsigned)buffer_len, user_handle_size)); - - /* - ** If the first char of the users name is non-numeric then return success - */ - if (user_handle[0] < '0' || user_handle[0] > '9'){ - return (TRUE); - }else{ - return (FALSE); - } -#endif -} - - - -/*********************************************************************************************** - * Spawn_WChat -- spawns or switches focus to wchat * - * * - * * - * * - * INPUT: can launch. If set then we are allowed to launch WChat if not already running * - * * - * OUTPUT: True if wchat was spawned * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 12:33PM ST : Created * - *=============================================================================================*/ -bool Poke_WChat(void); -bool Spawn_WChat(bool can_launch) -{ - can_launch; - return false; - -#if (0) - CCDebugString ("C&C95 - In Spawn_WChat.\n"); - char packet[10] = {"Hello"}; - HWND chat_window = NULL; - - /* - ** See if WChat is already running... - */ - if (WChatHWND && IsWindow (WChatHWND) ){ - chat_window = WChatHWND; - }else{ - chat_window = FindWindow ( "OWL_Window", "Westwood Chat" ); - } - - if (chat_window){ - /* - ** WChat is already running. Minimize myself then try to give it focus. - */ - Set_Palette(BlackPalette); - VisiblePage.Clear(); - ShowWindow (MainWindow, SW_MINIMIZE); - /* - ** Give windoze a couple of secs to sort itself out. - */ - CountDownTimerClass wibble_timer; - wibble_timer.Set ( 60 * 3, true); - - while (wibble_timer.Time()){ - /* - ** Call our message loop to make sure we get all the messages that are sent to us - ** when we minimise. - */ - Keyboard::Check(); - } - - /* - ** Send chat a tickle message so it knows to send the game stats to the server. - */ - if (GameStatisticsPacketSent && !PlanetWestwoodIsHost) { - Send_Data_To_DDE_Server (packet, strlen(packet), DDEServerClass::DDE_TICKLE); - } - /* - ** Give the focus to WChat - */ - SetForegroundWindow ( chat_window ); - ShowWindow ( chat_window, SW_RESTORE ); - return(true); - } - - /* - ** Fail if we aren't allowed to launch wchat and we couldnt find its window. - */ - if (!can_launch) return (false); - - /* - ** Find where WChat was installed to - */ - - HKEY key; - char wchat_loc[256]; - DWORD wchat_loc_size = 256; - - key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "SOFTWARE", FALSE); - if (!key) return (FALSE); - - key = Get_Registry_Sub_Key (key, "Westwood", TRUE); - if (!key) return (FALSE); - - key = Get_Registry_Sub_Key (key, "WChat", TRUE); - if (!key) return (FALSE); - - //key = Get_Registry_Sub_Key (key, "UserName", TRUE); - //if (!key) return (FALSE); - - //key = Get_Registry_Sub_Key (key, "Nick", TRUE); - //if (!key) return (FALSE); - - if (RegQueryValueEx(key, "InstallPath", NULL, NULL, (unsigned char*)wchat_loc, &wchat_loc_size) != ERROR_SUCCESS){ - RegCloseKey(key); - return (FALSE); - } - - RegCloseKey(key); - - PROCESS_INFORMATION process_info; - STARTUPINFO start_info; - memset ((void*)&start_info, 0, sizeof(start_info)); - start_info.cb = sizeof(start_info); - char justpath [256]; - Just_Path(wchat_loc, justpath); - - /* - ** We found WChat in the registry. Minimize myself then try to spawn it. - */ - Set_Palette(BlackPalette); - VisiblePage.Clear(); - ShowWindow (MainWindow, SW_MINIMIZE); - /* - ** Give windoze a couple of secs to sort itself out. - */ - CountDownTimerClass wibble_timer; - wibble_timer.Set ( 60 * 3, true); - - while (wibble_timer.Time()){ - /* - ** Call our message loop to make sure we get all the messages that are sent to us - ** when we minimise. - */ - Keyboard::Check(); - } - bool success = CreateProcess (wchat_loc, NULL, NULL, NULL, false, 0, NULL, justpath, &start_info, &process_info); - - if (success){ - return (true); - }else{ - ShowWindow (MainWindow, SW_RESTORE); - while ( Keyboard::Check() ) {}; - return (false); - } -#endif - -} - - - - -/*********************************************************************************************** - * Spawn_Registration_App -- spawns the C&C/Planet westwood registration app * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: True if app was spawned * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/8/96 12:33PM ST : Created * - *=============================================================================================*/ -bool Spawn_Registration_App(void) -{ - return false; -#if (0) //ST - 1/2/2019 5:53PM - /* - ** Find where inetreg was installed to - */ - - HKEY key; - char inetreg_loc[256]; - DWORD inetreg_loc_size = 256; - - key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "SOFTWARE", FALSE); - if (!key) return (FALSE); - - key = Get_Registry_Sub_Key (key, "Westwood", TRUE); - if (!key) return (FALSE); - - key = Get_Registry_Sub_Key (key, "InetReg", TRUE); - if (!key) return (FALSE); - - if (RegQueryValueEx(key, "InstallPath", NULL, NULL, (unsigned char*)inetreg_loc, &inetreg_loc_size) != ERROR_SUCCESS){ - RegCloseKey(key); - return (FALSE); - } - - RegCloseKey(key); - - PROCESS_INFORMATION process_info; - STARTUPINFO start_info; - char justpath [256]; - memset ((void*)&start_info, 0, sizeof(start_info)); - start_info.cb = sizeof(start_info); - Just_Path(inetreg_loc, justpath); - - BOOL success = CreateProcess (inetreg_loc, NULL, NULL, NULL, false, 0, NULL, justpath, &start_info, &process_info); - if (success){ - //WaitForSingleObject (process_info.hProcess, 1000*10000); - //SetForegroundWindow ( MainWindow ); - //ShowWindow ( MainWindow, SW_RESTORE ); - } - return (success); -#endif - -} - - - - - -/*********************************************************************************************** - * Do_The_Internet_Menu_Thang -- Handle case where user clicks on 'Internet' button * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 8:30PM ST : Created * - *=============================================================================================*/ -bool Do_The_Internet_Menu_Thang(void) -{ -#ifndef DEMO - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - /* - ** Dialog & button dimensions - */ - int d_dialog_w = 120 *factor; // dialog width - int d_dialog_h = 80*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_margin1=10; - int d_txt6_h=15; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50*factor; -#else - int d_cancel_w = 40*factor; -#endif - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx - d_cancel_w / 2; - int d_cancel_y = d_dialog_y + d_dialog_h - 20*factor; - - char packet[10] = {"Hello"}; - -#if (GERMAN | FRENCH) - int width=160*factor; - int height=80*factor; -#else - int width=120*factor; - int height=80*factor; -#endif //GERMAN | FRENCH - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String((char*)Text_String (TXT_CONNECTING), SeenBuff.Get_Height(), width, height); - -#if (GERMAN | FRENCH) - d_dialog_w = width + 25*factor; - d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - d_cancel_x = d_dialog_cx - (d_cancel_w / 2); -#endif - - /* - ** Button Enumerations - */ - enum { - BUTTON_CANCEL = 100, - }; - - /* - ** Buttons - */ - //TextButtonClass *buttons; // button list - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - //buttons = &cancelbtn; - - Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - - char users_name[256]; - int buffer_len = sizeof (users_name); - bool process; - bool display; - KeyNumType input; - - - if (!Special.IsFromWChat && !SpawnedFromWChat){ - /* - ** If the user is registered with Planet Westwood then spawn WChat. - */ - if (Is_User_WChat_Registered(users_name, buffer_len)){ - GameStatisticsPacketSent = false; - if (!Spawn_WChat(true)){ - Set_Logic_Page(SeenBuff); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - CCMessageBox().Process(TXT_ERROR_UNABLE_TO_RUN_WCHAT, TXT_OK); - LogicPage->Clear(); - return(false); - } - }else{ - Set_Logic_Page(SeenBuff); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - if (CCMessageBox().Process(TXT_EXPLAIN_REGISTRATION, TXT_REGISTER, TXT_CANCEL)){ - LogicPage->Clear(); - return(false); - }else{ - LogicPage->Clear(); - Spawn_Registration_App(); - return(false); - } - } - } - - /* - ** - ** User is registered and we spawned WChat. Wait for a game start message from WChat. - ** - */ - - process = true; - display = true; - - while (process){ - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored = FALSE; - display = true; - } - - if (display) { - - Set_Logic_Page(SeenBuff); - - Hide_Mouse(); - /* - ** Redraw backgound & dialog box - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /* - ** Dialog & Field labels - */ - Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print(TXT_CONNECTING, d_dialog_cx-width/2, d_dialog_y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - //cancelbtn.Zap(); - //buttons = &cancelbtn; - - /* - .................... Rebuild the button list .................... - */ - //buttons->Draw_All(); - cancelbtn.Draw_Me(true); - - Show_Mouse(); - display = false; - } - - - - /* - ** See if the game start packet has arrived from wchat yet. - */ - if (DDEServer.Get_MPlayer_Game_Info()){ - //MessageBox (NULL, "About to restore focus to C&C95", "C&C95", MB_OK); - //SetForegroundWindow ( MainWindow ); - //ShowWindow ( MainWindow, SW_SHOWMAXIMIZED ); - return(true); - } - - //input = buttons->Input(); - input = cancelbtn.Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - - /* - ** Cancel. Just return to the main menu - */ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - process = false; - Send_Data_To_DDE_Server (packet, strlen(packet), DDEServerClass::DDE_CONNECTION_FAILED); - GameStatisticsPacketSent = false; - Spawn_WChat(false); - break; - } - - } - -#endif //DEMO - - return (false); - - -} - - - - - - diff --git a/code/TIBERIANDAWN/INTERPAL.CPP b/code/TIBERIANDAWN/INTERPAL.CPP deleted file mode 100644 index fdc6430..0000000 --- a/code/TIBERIANDAWN/INTERPAL.CPP +++ /dev/null @@ -1,457 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INTERPAL.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : December 7th 1995 * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * This module contains functions to allow use of old 320x200 animations on a 640x400 screen * - * * - * Functions: * - * Read_Interpolation_Palette -- reads an interpolation palette table from disk * - * Write_Interpolation_Palette -- writes an interpolation palette to disk * - * Create_Palette_Interpolation_Table -- build the palette interpolation table * - * Increase_Palette_Luminance -- increase the contrast of a palette * - * Interpolate_2X_Scale -- Stretch a 320x200 graphic buffer into 640x400 * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -BOOL InterpolationPaletteChanged = FALSE; -extern "C" { -extern void __cdecl Asm_Interpolate (unsigned char* src_ptr , - unsigned char* dest_ptr , - int lines , - int src_width , - int dest_width); - -extern void __cdecl Asm_Interpolate_Line_Double (unsigned char* src_ptr , - unsigned char* dest_ptr , - int lines , - int src_width , - int dest_width); - -extern void __cdecl Asm_Interpolate_Line_Interpolate (unsigned char* src_ptr , - unsigned char* dest_ptr , - int lines , - int src_width , - int dest_width); - -} - -extern "C"{ - unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE]; - unsigned char *InterpolationPalette; -} - - - -/*********************************************************************************************** - * Read_Interpolatioin_Palette -- reads an interpolation palette table from disk * - * * - * * - * * - * INPUT: name of palette file * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 12/12/95 12:15PM ST : Created * - *=============================================================================================*/ - -void Read_Interpolation_Palette (char const *palette_file_name) -{ - CCFileClass palette_file(palette_file_name); - - if (palette_file.Is_Available()){ - palette_file.Open(READ); - palette_file.Read(&PaletteInterpolationTable[0][0],256*256); - palette_file.Close(); - InterpolationPaletteChanged = FALSE; - } -} - - -/*********************************************************************************************** - * Write_Interpolatioin_Palette -- writes an interpolation palette table to disk * - * * - * * - * * - * INPUT: name of palette file * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 12/12/95 12:15PM ST : Created * - *=============================================================================================*/ - -void Write_Interpolation_Palette (char const *palette_file_name) -{ - CCFileClass palette_file(palette_file_name); - - if (!palette_file.Is_Available()){ - palette_file.Open(WRITE); - palette_file.Write(&PaletteInterpolationTable[0][0],256*256); - palette_file.Close(); - } -} - - - - - -/*************************************************************************** - * CREATE_PALETTE_INTERPOLATION_TABLE * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 12/06/1995 MG : Created. * - *=========================================================================*/ -void Create_Palette_Interpolation_Table( void ) -{ - -//Don't think we need this. ST - 12/20/2018 2:25PM - //Asm_Create_Palette_Interpolation_Table(); - - #if (0) - - int i; - int j; - int p; - unsigned char *first_palette_ptr; - unsigned char *second_palette_ptr; - unsigned char *match_pal_ptr; - int first_r; - int first_g; - int first_b; - int second_r; - int second_g; - int second_b; - int diff_r; - int diff_g; - int diff_b; - int dest_r; - int dest_g; - int dest_b; - int distance; - int closest_distance; - int index_of_closest_color; - - // - // Create an interpolation table for the current palette. - // - first_palette_ptr = (unsigned char *) InterpolationPalette; - for ( i = 0; i < SIZE_OF_PALETTE; i ++ ) { - - // - // Get the first palette entry's RGB. - // - first_r = *first_palette_ptr; - first_palette_ptr ++; - first_g = *first_palette_ptr; - first_palette_ptr ++; - first_b = *first_palette_ptr; - first_palette_ptr ++; - - second_palette_ptr = (unsigned char *) InterpolationPalette; - for ( j = 0; j < SIZE_OF_PALETTE; j ++ ) { - // - // Get the second palette entry's RGB. - // - second_r = *second_palette_ptr; - second_palette_ptr ++; - second_g = *second_palette_ptr; - second_palette_ptr ++; - second_b = *second_palette_ptr; - second_palette_ptr ++; - - // - // Now calculate the RGB halfway between the first and second colors. - // - dest_r = ( first_r + second_r ) >> 1; - dest_g = ( first_g + second_g ) >> 1; - dest_b = ( first_b + second_b ) >> 1; - - // - // Now find the color in the palette that most closely matches the interpolated color. - // - index_of_closest_color = 0; -// closest_distance = (256 * 256) * 3; - closest_distance = 500000; - match_pal_ptr = (unsigned char *) InterpolationPalette; - for ( p = 0; p < SIZE_OF_PALETTE; p ++ ) { - diff_r = ( ((int) (*match_pal_ptr)) - dest_r ); - match_pal_ptr ++; - diff_g = ( ((int) (*match_pal_ptr)) - dest_g ); - match_pal_ptr ++; - diff_b = ( ((int) (*match_pal_ptr)) - dest_b ); - match_pal_ptr ++; - - distance = ( diff_r * diff_r ) + ( diff_g * diff_g ) + ( diff_b * diff_b ); - if ( distance < closest_distance ) { - closest_distance = distance; - index_of_closest_color = p; - } - } - - PaletteInterpolationTable[ i ][ j ] = (unsigned char) index_of_closest_color; - } - } - - #endif - InterpolationPaletteChanged = FALSE; - return; - -} - - - - - - - - - -/*********************************************************************************************** - * Increase_Palette_Luminance -- increase contrast of colours in a palette * - * * - * * - * * - * INPUT: ptr to palette * - * percentage increase of red * - * percentage increase of green * - * percentage increase of blue * - * cap value for colours * - * * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 12/12/95 12:16PM ST : Created * - *=============================================================================================*/ - -void Increase_Palette_Luminance (unsigned char *palette , int red_percentage , int green_percentage , int blue_percentage ,int cap) -{ - - unsigned int red; - unsigned int green; - unsigned int blue; - for (int i=0 ; iGet_IsDirectDraw()){ - if (!source->Lock()){ - if (dest == &SeenBuff) Show_Mouse(); - return; - } - source_locked = TRUE; - } - if (dest->Get_IsDirectDraw()){ - if (!dest->Lock()) { - if (source_locked){ - source->Unlock(); - } - if (dest == &SeenBuff) Show_Mouse(); - return; - } - dest_locked = TRUE; - } - - - // - // Get pointers to the source and destination buffers. - // - src_ptr = (unsigned char *) source->Get_Offset(); - dest_ptr = (unsigned char *) dest->Get_Offset(); - end_of_source = src_ptr + ( source->Get_Width() * source->Get_Height() ); - - // - // Get width of source and dest buffers. - // - src_width = source->Get_Width(); - dest_width = 2*(dest->Get_Width() + dest->Get_XAdd() + dest->Get_Pitch()); - last_dest_ptr = dest_ptr; - - /* - ** Call the appropriate assembly language copy routine - */ -#if (1) - switch (CopyType){ - case 0: - Asm_Interpolate ( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width); - break; - - case 1: - Asm_Interpolate_Line_Double( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width); - break; - - case 2: - Asm_Interpolate_Line_Interpolate( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width); - break; - } -#endif - -#if (0) - // - // Copy over the first pixel (upper left). - // - *dest_ptr = *src_ptr; - src_ptr ++; - dest_ptr ++; - - // - // Scale copy. - // - width_counter = 0; - while ( src_ptr < end_of_source ) { - - // - // Blend this pixel with the one to the left and place this new color in the dest buffer. - // - *dest_ptr = PaletteInterpolationTable[ (*src_ptr) ][ (*( src_ptr - 1 )) ]; - dest_ptr ++; - - // - // Now place the source pixel into the dest buffer. - // - *dest_ptr = *src_ptr; - - src_ptr ++; - dest_ptr ++; - - width_counter ++; - if ( width_counter == src_width ) { - width_counter = 0; - last_dest_ptr += dest_width; - dest_ptr = last_dest_ptr; - } - } - -#endif - if (source_locked) source->Unlock(); - if (dest_locked) dest->Unlock(); - if (dest == &SeenBuff) Show_Mouse(); -#endif -} -#endif - - - diff --git a/code/TIBERIANDAWN/INTRO.CPP b/code/TIBERIANDAWN/INTRO.CPP deleted file mode 100644 index c1a0af3..0000000 --- a/code/TIBERIANDAWN/INTRO.CPP +++ /dev/null @@ -1,323 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\intro.cpv 1.6 16 Oct 1995 16:50:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INTRO.H * - * * - * Programmer : Barry W. Green * - * * - * Start Date : May 8, 1995 * - * * - * Last Update : May 8, 1995 [BWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "textblit.h" - -#ifndef DEMO - - -#if (0) //PG_TO_FIX -VQAHandle *Open_Movie(char *name); -VQAHandle *Open_Movie(char *name) -{ - if (!Debug_Quiet && Get_Digi_Handle() != -1) { - AnimControl.OptionFlags |= VQAOPTF_AUDIO; - } else { - AnimControl.OptionFlags &= ~VQAOPTF_AUDIO; - } - - VQAHandle * vqa = VQA_Alloc(); - if (vqa) { - VQA_Init(vqa, MixFileHandler); - - if (VQA_Open(vqa, name, &AnimControl) != 0) { - VQA_Free(vqa); - vqa = 0; - } - } - return(vqa); -} -#endif //(0) - -/*********************************************************************************************** - * Choose_Side -- play the introduction movies, select house * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 5/08/1995 BWG : Created. * - *=============================================================================================*/ -void Choose_Side(void) -{ - //static char const _yellowpal[]={0x0,0x0,0xC9,0x0,0xBA,0x0,0x93,0x0,0x61,0x0,0x0,0x0,0x0,0x0,0xEE,0x0}; - //static char const _redpal[] ={0x0,0x0,0xA8,0x0,0xD9,0x0,0xDA,0x0,0xE1,0x0,0x0,0x0,0x0,0x0,0xD4,0x0}; - //static char const _graypal[] ={0x0,0x0,0x17,0x0,0x10,0x0,0x12,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x1C,0x0}; - - // PG_TO_FIX - // Chose GDI - Whom = HOUSE_GOOD; - ScenPlayer = SCEN_PLAYER_GDI; - return; - -#if (0) - - - static char const _yellowpal[]={0x0,0xC9,0xBA,0x93,0x61,0xEE,0xee,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; - static char const _redpal[] ={0x0,0xa8,0xd9,0xda,0xe1,0xd4,0xDA,0x0,0xE1,0x0,0x0,0x0,0x0,0x0,0xD4,0x0}; - static char const _graypal[] ={0x0,0x17,0x10,0x12,0x14,0x1c,0x12,0x1c,0x14,0x0,0x0,0x0,0x0,0x0,0x1C,0x0}; - - - void *anim; - VQAHandle *gdibrief=0, *nodbrief=0; - void const *staticaud, *oldfont; - void const *speechg, *speechn, *speech; - int statichandle, speechhandle, speechplaying = 0; - int oldfontxspacing = FontXSpacing; - int setpalette = 0; - int gdi_start_palette; - - MEMORYSTATUS mem_info; - mem_info.dwLength=sizeof(mem_info); - GlobalMemoryStatus(&mem_info); - - TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height(), (void*)NULL); - TextPrintBuffer->Clear(); - BlitList.Clear(); - PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL); - int frame = 0, endframe = 255, selection = 0, lettersdone = 0; - - Hide_Mouse(); -/* Change to the six-point font for Text_Print */ - oldfont = Set_Font(ScoreFontPtr); - - Call_Back(); - - staticaud = Load_Alloc_Data(CCFileClass("STRUGGLE.AUD")); - speechg = Load_Alloc_Data(CCFileClass("GDI_SLCT.AUD")); - speechn = Load_Alloc_Data(CCFileClass("NOD_SLCT.AUD")); - -// staticaud = MixFileClass::Retrieve("STRUGGLE.AUD"); -// speechg = MixFileClass::Retrieve("GDI_SLCT.AUD"); -// speechn = MixFileClass::Retrieve("NOD_SLCT.AUD"); - - if (Special.IsFromInstall){ - if (mem_info.dwTotalPhys >= 12*1024*1024){ - VisiblePage.Clear(); - PreserveVQAScreen = 1; - Play_Movie("INTRO2", THEME_NONE, false); - } - BreakoutAllowed = true; - } - - //anim = Open_Animation("CHOOSE.WSA",NULL,0L,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - anim = Open_Animation("CHOOSE.WSA",NULL,0L,(WSAOpenType)(WSA_OPEN_FROM_DISK | WSA_OPEN_TO_PAGE),Palette); - Call_Back(); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = Palette; - Read_Interpolation_Palette("SIDES.PAL"); - - nodbrief = Open_Movie("NOD1PRE.VQA"); - gdi_start_palette = Load_Interpolated_Palettes("NOD1PRE.VQP"); - Call_Back(); - gdibrief = Open_Movie("GDI1.VQA"); - Load_Interpolated_Palettes("GDI1.VQP" , TRUE); - - WWMouse->Erase_Mouse(&HidPage, TRUE); - HiddenPage.Clear(); - PseudoSeenBuff->Clear(); - SysMemPage.Clear(); - //if (!Special.IsFromInstall) { - VisiblePage.Clear(); - Set_Palette(Palette); - //} else { - //setpalette = 1; - //} - - statichandle = Play_Sample(staticaud,255,64); - CountDownTimerClass sample_timer; - sample_timer.Set(0x3f); - Alloc_Object(new ScorePrintClass(TXT_GDI_NAME, 0, 180,_yellowpal)); -#ifdef FRENCH - Alloc_Object(new ScorePrintClass(TXT_GDI_NAME2, 0, 187,_yellowpal)); -#endif - Alloc_Object(new ScorePrintClass(TXT_NOD_NAME, 180, 180,_redpal)); - -#ifdef GERMAN - Alloc_Object(new ScorePrintClass(TXT_SEL_TRANS,57, 190,_graypal)); -#else -#ifdef FRENCH - Alloc_Object(new ScorePrintClass(TXT_SEL_TRANS,103, 194,_graypal)); -#else - Alloc_Object(new ScorePrintClass(TXT_SEL_TRANS,103, 190,_graypal)); -#endif -#endif - Keyboard::Clear(); - - while (Get_Mouse_State()) Show_Mouse(); - - while (endframe != frame || (speechplaying && Is_Sample_Playing(speech)) ) { - Animate_Frame(anim, SysMemPage, frame++); - if (setpalette) { - Wait_Vert_Blank(); - Set_Palette(Palette); - setpalette = 0; - } - SysMemPage.Blit(*PseudoSeenBuff,0,22, 0,22, 320,156); - - /* - ** If the sample has stopped or is about to then restart it - */ - if (!Is_Sample_Playing(staticaud) || !sample_timer.Time()) { - Stop_Sample(statichandle); - statichandle = Play_Sample(staticaud,255,64); - sample_timer.Set(0x3f); - } - Call_Back_Delay(3); // delay only if haven't clicked - - /* keep the mouse hidden until the letters are thru printing */ - if (!lettersdone) { - lettersdone = true; - for(int i=0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) lettersdone = 0; - if (lettersdone) { - Show_Mouse(); - } - } - if (frame >= Get_Animation_Frame_Count(anim)) frame = 0; - if (Keyboard::Check() && endframe == 255) { - if ((Keyboard::Get() & 0x10FF) == KN_LMOUSE) { - if ((_Kbd->MouseQY > 48*2) && (_Kbd->MouseQY < 150*2)) { - if ((_Kbd->MouseQX > 18*2) && (_Kbd->MouseQX < 148*2)) { - - // Chose GDI - Whom = HOUSE_GOOD; - ScenPlayer = SCEN_PLAYER_GDI; - endframe = 0; - speechhandle = Play_Sample(speechg); - speechplaying = true; - speech = speechg; - - } else if ((_Kbd->MouseQX > 160*2) && (_Kbd->MouseQX < 300*2)) { - // Chose Nod - selection = 1; - endframe = 14; - Whom = HOUSE_BAD; - ScenPlayer = SCEN_PLAYER_NOD; - speechhandle = Play_Sample(speechn); - speechplaying = true; - speech = speechn; - } - } - } - } - } - - Hide_Mouse(); - Close_Animation(anim); - - // erase the "choose side" text - PseudoSeenBuff->Fill_Rect(0,180,319,199,0); - SeenBuff.Fill_Rect(0,180*2, 319*2, 199*2, 0); - Interpolate_2X_Scale (PseudoSeenBuff , &SeenBuff ,"SIDES.PAL"); - Keyboard::Clear(); - SysMemPage.Clear(); - - /* - ** Skip the briefings if we're in special mode. - */ - if (Special.IsJurassic && AreThingiesEnabled) { - if (nodbrief) { - VQA_Close(nodbrief); - VQA_Free(nodbrief); - nodbrief = NULL; - } - if (gdibrief) { - VQA_Close(gdibrief); - VQA_Free(gdibrief); - gdibrief = NULL; - } - } - - /* play the scenario 1 briefing movie */ - if (Whom == HOUSE_GOOD) { - if (nodbrief) { - VQA_Close(nodbrief); - VQA_Free(nodbrief); - } - if (gdibrief) { - PaletteCounter = gdi_start_palette; - VQA_Play(gdibrief, VQAMODE_RUN); - VQA_Close(gdibrief); - VQA_Free(gdibrief); - } - } else { - if (gdibrief) { - VQA_Close(gdibrief); - VQA_Free(gdibrief); - } - if (nodbrief) { - VQA_Play(nodbrief, VQAMODE_RUN); - VQA_Close(nodbrief); - VQA_Free(nodbrief); - } - } - - Free_Interpolated_Palettes(); - Set_Primary_Buffer_Format(); -/* get rid of all the animating objects */ - for (int i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) { - delete ScoreObjs[i]; - ScoreObjs[i] = 0; - } - - if (Whom == HOUSE_GOOD) { - /* - ** Make sure the screen's fully clear after the movie plays - */ - VisiblePage.Clear(); - memset(BlackPalette, 0x01, 768); - Set_Palette(BlackPalette); - memset(BlackPalette, 0x00, 768); - } else { - PreserveVQAScreen = 1; - } - Free(staticaud); - Free(speechg); - Free(speechn); - - Set_Font(oldfont); - FontXSpacing = oldfontxspacing; - - delete PseudoSeenBuff; - delete TextPrintBuffer; - TextPrintBuffer = NULL; - BlitList.Clear(); - -#endif -} -#endif diff --git a/code/TIBERIANDAWN/INTRO.H b/code/TIBERIANDAWN/INTRO.H deleted file mode 100644 index 01f5ed6..0000000 --- a/code/TIBERIANDAWN/INTRO.H +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : INTRO.H * - * * - * Programmer : Barry W. Green * - * * - * Start Date : May 8, 1995 * - * * - * Last Update : May 8, 1995 [BWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef INTRO_H -#define INTRO_H - -void Choose_Side(void); - -#endif diff --git a/code/TIBERIANDAWN/IOMAP.CPP b/code/TIBERIANDAWN/IOMAP.CPP deleted file mode 100644 index b5bb117..0000000 --- a/code/TIBERIANDAWN/IOMAP.CPP +++ /dev/null @@ -1,1121 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\iomap.cpv 2.18 16 Oct 1995 16:50:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IOMAP.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : January 16, 1995 * - * * - * Last Update : January 16, 1995 [BR] * - * * - *---------------------------------------------------------------------------------------------* - * All map-related loading/saving routines should go in this module, so it can be overlayed. * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CellClass::Code_Pointers -- codes class's pointers for load/save * - * CellClass::Decode_Pointers -- decodes pointers for load/save * - * CellClass::Load -- Reads from a save game file. * - * CellClass::Save -- Write to a save game file. * - * CellClass::Should_Save -- Should the cell be written to disk? * - * DisplayClass::Code_Pointers -- codes class's pointers for load/save * - * DisplayClass::Decode_Pointers -- decodes pointers for load/save * - * GScreenClass::Code_Pointers -- codes class's pointers for load/save * - * GScreenClass::Decode_Pointers -- decodes pointers for load/save * - * HelpClass::Code_Pointers -- codes class's pointers for load/save * - * HelpClass::Decode_Pointers -- decodes pointers for load/save * - * MapClass::Code_Pointers -- codes class's pointers for load/save * - * MapClass::Decode_Pointers -- decodes pointers for load/save * - * MouseClass::Code_Pointers -- codes class's pointers for load/save * - * MouseClass::Decode_Pointers -- decodes pointers for load/save * - * MouseClass::Load -- Loads from a save game file. * - * MouseClass::Save -- Saves to a save game file. * - * PowerClass::Code_Pointers -- codes class's pointers for load/save * - * PowerClass::Decode_Pointers -- decodes pointers for load/save * - * RadarClass::Code_Pointers -- codes class's pointers for load/save * - * RadarClass::Decode_Pointers -- decodes pointers for load/save * - * ScrollClass::Code_Pointers -- codes class's pointers for load/save * - * ScrollClass::Decode_Pointers -- decodes pointers for load/save * - * SidebarClass::Code_Pointers -- codes class's pointers for load/save * - * SidebarClass::Decode_Pointers -- decodes pointers for load/save * - * SidebarClass::StripClass::Code_Pointers -- codes class's pointers for load/save * - * SidebarClass::StripClass::Decode_Pointers -- decodes pointers for load/save * - * TabClass::Code_Pointers -- codes class's pointers for load/save * - * TabClass::Decode_Pointers -- decodes pointers for load/save * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#pragma warning (disable : 4302) // Truncation from pointer to TARGET - -/*********************************************************************************************** - * CellClass::Should_Save -- Should the cell be written to disk? * - * * - * This function will determine if the cell needs to be written to disk. Any cell that * - * contains special data should be written to disk. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Should this cell's data be written to disk? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool CellClass::Should_Save(void) const -{ - return( - (Smudge != SMUDGE_NONE) || - (TType != TEMPLATE_NONE) || - (Overlay != OVERLAY_NONE) || - IsMapped || - IsVisible || - IsMappedByPlayerMask || - IsVisibleByPlayerMask || - IsTrigger || - Flag.Composite || - OccupierPtr || - Overlapper[0] || Overlapper[1] || Overlapper[2] - ); -} - - -/*********************************************************************************************** - * CellClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool CellClass::Load(FileClass & file) -{ - int rc; - TriggerClass * trig; - - /* - -------------------------- Load the object data -------------------------- - */ - rc = Read_Object(this, sizeof(CellClass), file, false); - - /* - ------------------------ Load the trigger pointer ------------------------ - */ - if (rc) { - if (IsTrigger) { - if (file.Read(&trig,sizeof(trig)) != sizeof(trig)) - return(false); - CellTriggers[Cell_Number()] = trig; - } - } - - return(rc); -} - - -/*********************************************************************************************** - * CellClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool CellClass::Save(FileClass & file) -{ - int rc; - TriggerClass * trig; - - /* - -------------------------- Save the object data -------------------------- - */ - rc = Write_Object(this, sizeof(CellClass), file); - - /* - ------------------------ Save the trigger pointer ------------------------ - */ - if (rc) { - if (IsTrigger) { - trig = CellTriggers[Cell_Number()]; - if (file.Write(&trig,sizeof(trig)) != sizeof(trig)) - return(false); - } - } - - return(rc); -} - - -/*********************************************************************************************** - * CellClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void CellClass::Code_Pointers(void) -{ - if (Cell_Occupier()) { - OccupierPtr = (ObjectClass *)OccupierPtr->As_Target(); - } - - if (Overlapper[0]) { - Overlapper[0] = (ObjectClass *)Overlapper[0]->As_Target(); - } - - if (Overlapper[1]) { - Overlapper[1] = (ObjectClass *)Overlapper[1]->As_Target(); - } - - if (Overlapper[2]) { - Overlapper[2] = (ObjectClass *)Overlapper[2]->As_Target(); - } - - /* - ------------------------ Convert trigger pointer ------------------------- - */ - if (IsTrigger) { - CellTriggers[Cell_Number()] = (TriggerClass *)CellTriggers[Cell_Number()]->As_Target(); - } - - /* - ------------------------ Convert flag pointer ------------------------- - */ - assert(CTFFlag == NULL); -} - - -/*********************************************************************************************** - * CellClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void CellClass::Decode_Pointers(void) -{ - char bad[128]; - - if (OccupierPtr) { - OccupierPtr = As_Object((TARGET)OccupierPtr, false); - Check_Ptr((void *)OccupierPtr,__FILE__,__LINE__); - - /* - ** Check for bad occupier that was saved. ST - 10/3/2019 11:50AM - */ - ObjectClass * optr = Cell_Occupier(); - if (optr->IsActive == false) { - CellClass *cell0 = &Map[0]; - int cell_number = this - cell0; - sprintf(bad, "Found bad cell occupier in cell %d", cell_number); - GlyphX_Debug_Print(bad); - OccupierPtr = NULL; - } - } - - if (Overlapper[0]) { - Overlapper[0] = As_Object((TARGET)Overlapper[0], false); - Check_Ptr((void *)Overlapper[0],__FILE__,__LINE__); - } - - if (Overlapper[1]) { - Overlapper[1] = As_Object((TARGET)Overlapper[1], false); - Check_Ptr((void *)Overlapper[1],__FILE__,__LINE__); - } - - if (Overlapper[2]) { - Overlapper[2] = As_Object((TARGET)Overlapper[2], false); - Check_Ptr((void *)Overlapper[2],__FILE__,__LINE__); - } - - /* - ** Check for bad overlappers that were saved. ST - 10/3/2019 11:50AM - */ - for (int i=0 ; i <= 2 ; i++) { - if (Overlapper[i]) { - ObjectClass * optr = Overlapper[i]; - if (optr->IsActive == false) { - CellClass *cell0 = &Map[0]; - int cell_number = this - cell0; - sprintf(bad, "Found bad cell overlapper in slot %d of cell %d", i, cell_number); - GlyphX_Debug_Print(bad); - Overlapper[i] = NULL; - } - } - } - - - /* - ** Convert trigger pointer. - */ - if (IsTrigger) { - CellTriggers[Cell_Number()] = As_Trigger( (TARGET)CellTriggers[Cell_Number()], false ); - Check_Ptr((void *)CellTriggers[Cell_Number()],__FILE__,__LINE__); - } - - /* - ** Convert flag pointer. - */ - CTFFlag = NULL; -} - - -/*********************************************************************************************** - * MouseClass::Load -- Loads from a save game file. * - * * - * Loading the map is very complicated. Here are the steps: * - * - Read the Theater for this save-game * - * - call Init_Theater to perform theater-specific inits * - * - call Free_Cells to free the cell array, because loading the map object will overwrite * - * the pointer to the cell array * - * - read the map object from disk * - * - call Alloc_Cells to re-allocate the cell array * - * - call Init_Cells to set the cells to a known state, because not every cell will be loaded * - * - read the cell objects into the cell array * - * - After the map & all objects have been loaded & the pointers decoded, Init_IO() >MUST< be * - * called to restore the map's button list to the proper state. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool MouseClass::Load(FileClass & file) -{ - unsigned count; - CELL cell = 0; - int index; -// int rc; -// int i; -// int j; - - /*------------------------------------------------------------------------ - Load Theater: Even though this value is located in the DisplayClass, - it must be loaded first so initialization can be done before any other - map data is loaded. If initialization isn't done first, data read from - disk will be over-written when initialization occurs. This code must - go in the most-derived Map class. - ------------------------------------------------------------------------*/ - if (file.Read (&Theater,sizeof(Theater)) != sizeof(Theater)) - return(false); - - /* - ** Remove any old theater specific uncompressed shapes - */ - if (Theater != LastTheater){ - Reset_Theater_Shapes(); - } - - /* - ------------------------- Init display mixfiles -------------------------- - */ - Init_Theater(Theater); - TerrainTypeClass::Init(Theater); - TemplateTypeClass::Init(Theater); - OverlayTypeClass::Init(Theater); - UnitTypeClass::Init(Theater); - InfantryTypeClass::Init(Theater); - BuildingTypeClass::Init(Theater); - BulletTypeClass::Init(Theater); - AnimTypeClass::Init(Theater); - AircraftTypeClass::Init(Theater); - SmudgeTypeClass::Init(Theater); - - LastTheater = Theater; - - /* - ** Free the cell array, because we're about to overwrite its pointers - */ - Free_Cells(); - - /* - ** Read the entire map object in. Only read in sizeof(MouseClass), so if we're - ** in editor mode, none of the map editor object is read in. - */ - if (!Read_Object(this, sizeof(MouseClass), file, true)) { - return(false); - } - - /* - ** Reallocate the cell array - */ - Alloc_Cells(); - - /* - ** Init all cells to empty - */ - Init_Cells(); - - /* - --------------------------- Read # cells saved --------------------------- - */ - if (file.Read(&count, sizeof(count)) != sizeof(count)) { - return(false); - } - - /* - ------------------------------- Read cells ------------------------------- - */ - for (index = 0; index < (int)count; index++) { - if (file.Read(&cell, sizeof(cell)) != sizeof(cell)) - return(false); - - if (!(*this)[cell].Load(file)) - return(false); - } - - return(true); -} - - -/*********************************************************************************************** - * MouseClass::Save -- Save to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool MouseClass::Save(FileClass & file) -{ - unsigned count; - long pos; - - /* - -------------------------- Save Theater >first< -------------------------- - */ - if (file.Write (&Theater,sizeof(Theater)) != sizeof(Theater)) - return(false); - - if (!Write_Object(this, sizeof(MouseClass), file)) - return(false); - - /* - ---------------------- Record current file position ---------------------- - */ - pos = file.Seek(0, SEEK_CUR); - - /* - ---------------------- write out placeholder bytes ----------------------- - */ - if (file.Write(&count, sizeof(count)) != sizeof(count)) - return(false); - - /* - ------------------------ Save cells that need it ------------------------- - */ - count = 0; - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { - - if ((*this)[cell].Should_Save()) { - if (file.Write(&cell, sizeof(cell)) != sizeof(cell)) - return(false); - - count++; - - if (!(*this)[cell].Save(file)) - return(false); - } - } - - /* - -------------------------- Save # cells written -------------------------- - */ - file.Seek(pos, SEEK_SET); - - if (file.Write(&count, sizeof(count)) != sizeof(count)) - return(false); - - file.Seek(0, SEEK_END); - - return(true); -} - - -/*********************************************************************************************** - * MouseClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void MouseClass::Code_Pointers(void) -{ -// Control.Code_Pointers(); - - ScrollClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * MouseClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void MouseClass::Decode_Pointers(void) -{ -// Control.Decode_Pointers(); - - ScrollClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * ScrollClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void ScrollClass::Code_Pointers(void) -{ - HelpClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * ScrollClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void ScrollClass::Decode_Pointers(void) -{ - HelpClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * HelpClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void HelpClass::Code_Pointers(void) -{ - TabClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * HelpClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void HelpClass::Decode_Pointers(void) -{ - TabClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * TabClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TabClass::Code_Pointers(void) -{ - SidebarClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * TabClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TabClass::Decode_Pointers(void) -{ - SidebarClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * PowerClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void PowerClass::Code_Pointers(void) -{ - RadarClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * PowerClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void PowerClass::Decode_Pointers(void) -{ - RadarClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * SidebarClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void SidebarClass::Code_Pointers(void) -{ - for (int i = 0; i < COLUMNS; i++) { - Column[i].Code_Pointers(); - } - - PowerClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * SidebarClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void SidebarClass::Decode_Pointers(void) -{ - for (int i = 0; i < COLUMNS; i++) { - Column[i].Decode_Pointers(); - } - - PowerClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Code_Pointers(void) -{ -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Decode_Pointers(void) -{ -} - - -/*********************************************************************************************** - * RadarClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void RadarClass::Code_Pointers(void) -{ - DisplayClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * RadarClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void RadarClass::Decode_Pointers(void) -{ - DisplayClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * DisplayClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void DisplayClass::Code_Pointers(void) -{ - /* - ** Code PendingObjectPtr. - */ - if (PendingObjectPtr) { - PendingObjectPtr = (ObjectClass *)PendingObjectPtr->As_Target(); - } - - /* - ** Fix for saving game while in structure placement mode. ST - 4/15/2020 2:41PM - */ - memset(CursorShapeSave, 0, sizeof(CursorShapeSave)); - if (CursorSize && CursorSize != CursorShapeSave) { - - int save_buffer_element_size = sizeof(CursorShapeSave) / sizeof(CursorShapeSave[0]); - - int index = 0; - - while (index < save_buffer_element_size - 2 && CursorSize[index] != REFRESH_EOL) { - CursorShapeSave[index] = CursorSize[index]; - index++; - } - CursorShapeSave[index] = REFRESH_EOL; - } - - /* - ** Chain to parent. - */ - MapClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * DisplayClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void DisplayClass::Decode_Pointers(void) -{ - /* - ** Decode PendingObjectPtr. We can't decode PendingObject here, because we'd - ** have to reference PendingObjectPtr->Class_Of(), and the object that - ** PendingObjectPtr is pointing to hasn't been decoded yet. Since we can't - ** decode PendingObjectPtr, we can't set the placement cursor shape here - ** either. These have to be done as last-minute fixups. - */ - if (PendingObjectPtr) { - PendingObjectPtr = As_Object((TARGET)PendingObjectPtr, false); - Check_Ptr((void *)PendingObjectPtr,__FILE__,__LINE__); - } - - if (CursorSize) { - CursorSize = CursorShapeSave; - } - - /* - ** Chain to parent. - */ - MapClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * MapClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void MapClass::Code_Pointers(void) -{ - CELL cell; - - /* - ------------------------- Destroy all flag animations -------------------- - */ - for (cell = 0; cell < MAP_CELL_TOTAL; cell++) { - (*this)[cell].Flag_Destroy(); - } - - /* - ------------------------- Code the cell pointers ------------------------- - */ - for (cell = 0; cell < MAP_CELL_TOTAL; cell++) { - (*this)[cell].Code_Pointers(); - } - - GScreenClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * MapClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void MapClass::Decode_Pointers(void) -{ - CELL cell; - - /* - ------------------------ Decode the cell pointers ------------------------ - */ - for (cell = 0; cell < MAP_CELL_TOTAL; cell++) { - (*this)[cell].Decode_Pointers(); - } - - GScreenClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * GScreenClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void GScreenClass::Code_Pointers(void) -{ -} - - -/*********************************************************************************************** - * GScreenClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void GScreenClass::Decode_Pointers(void) -{ -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/IOOBJ.CPP b/code/TIBERIANDAWN/IOOBJ.CPP deleted file mode 100644 index 17ae31d..0000000 --- a/code/TIBERIANDAWN/IOOBJ.CPP +++ /dev/null @@ -1,2698 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ioobj.cpv 2.18 16 Oct 1995 16:51:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IOOBJ.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : January 16, 1995 * - * * - * Last Update : January 16, 1995 [BR] * - * * - *---------------------------------------------------------------------------------------------* - * All object-related loading/saving routines should go in this module, so it can be overlayed.* - *---------------------------------------------------------------------------------------------* - * Functions: * - * TeamTypeClass::Load -- Reads from a save game file. * - * TeamTypeClass::Save -- Write to a save game file. * - * TeamTypeClass::Code_Pointers -- codes class's pointers for load/save * - * TeamTypeClass::Decode_Pointers -- decodes pointers for load/save * - * TeamClass::Load -- Reads from a save game file. * - * TeamClass::Save -- Write to a save game file. * - * TeamClass::Code_Pointers -- codes class's pointers for load/save * - * TeamClass::Decode_Pointers -- decodes pointers for load/save * - * TriggerClass::Load -- Reads from a save game file. * - * TriggerClass::Save -- Write to a save game file. * - * TriggerClass::Code_Pointers -- codes class's pointers for load/save * - * TriggerClass::Decode_Pointers -- decodes pointers for load/save * - * AircraftClass::Load -- Reads from a save game file. * - * AircraftClass::Save -- Write to a save game file. * - * AircraftClass::Code_Pointers -- codes class's pointers for load/save * - * AircraftClass::Decode_Pointers -- decodes pointers for load/save * - * AnimClass::Load -- Reads from a save game file. * - * AnimClass::Save -- Write to a save game file. * - * AnimClass::Code_Pointers -- codes class's pointers for load/save * - * AnimClass::Decode_Pointers -- decodes pointers for load/save * - * BuildingClass::Load -- Reads from a save game file. * - * BuildingClass::Save -- Write to a save game file. * - * BuildingClass::Code_Pointers -- codes class's pointers for load/save * - * BuildingClass::Decode_Pointers -- decodes pointers for load/save * - * BulletClass::Load -- Reads from a save game file. * - * BulletClass::Save -- Write to a save game file. * - * BulletClass::Code_Pointers -- codes class's pointers for load/save * - * BulletClass::Decode_Pointers -- decodes pointers for load/save * - * InfantryClass::Load -- Reads from a save game file. * - * InfantryClass::Save -- Write to a save game file. * - * InfantryClass::Code_Pointers -- codes class's pointers for load/save * - * InfantryClass::Decode_Pointers -- decodes pointers for load/save * - * OverlayClass::Load -- Reads from a save game file. * - * OverlayClass::Save -- Write to a save game file. * - * OverlayClass::Code_Pointers -- codes class's pointers for load/save * - * OverlayClass::Decode_Pointers -- decodes pointers for load/save * - * ReinforcementClass::Load -- Reads from a save game file. * - * ReinforcementClass::Save -- Write to a save game file. * - * ReinforcementClass::Code_Pointers -- codes class's pointers for load/save * - * ReinforcementClass::Decode_Pointers -- decodes pointers for load/save * - * SmudgeClass::Load -- Reads from a save game file. * - * SmudgeClass::Save -- Write to a save game file. * - * SmudgeClass::Code_Pointers -- codes class's pointers for load/save * - * SmudgeClass::Decode_Pointers -- decodes pointers for load/save * - * TemplateClass::Load -- Reads from a save game file. * - * TemplateClass::Save -- Write to a save game file. * - * TemplateClass::Code_Pointers -- codes class's pointers for load/save * - * TemplateClass::Decode_Pointers -- decodes pointers for load/save * - * TerrainClass::Load -- Reads from a save game file. * - * TerrainClass::Save -- Write to a save game file. * - * TerrainClass::Code_Pointers -- codes class's pointers for load/save * - * TerrainClass::Decode_Pointers -- decodes pointers for load/save * - * UnitClass::Load -- Reads from a save game file. * - * UnitClass::Save -- Write to a save game file. * - * UnitClass::Code_Pointers -- codes class's pointers for load/save * - * UnitClass::Decode_Pointers -- decodes pointers for load/save * - * FactoryClass::Load -- Reads from a save game file. * - * FactoryClass::Save -- Write to a save game file. * - * FactoryClass::Code_Pointers -- codes class's pointers for load/save * - * FactoryClass::Decode_Pointers -- decodes pointers for load/save * - * LayerClass::Load -- Reads from a save game file. * - * LayerClass::Save -- Write to a save game file. * - * LayerClass::Code_Pointers -- codes class's pointers for load/save * - * LayerClass::Decode_Pointers -- decodes pointers for load/save * - * HouseClass::Load -- Reads from a save game file. * - * HouseClass::Save -- Write to a save game file. * - * HouseClass::Code_Pointers -- codes class's pointers for load/save * - * HouseClass::Decode_Pointers -- decodes pointers for load/save * - * ScoreClass::Load -- Reads from a save game file. * - * ScoreClass::Save -- Write to a save game file. * - * ScoreClass::Code_Pointers -- codes class's pointers for load/save * - * ScoreClass::Decode_Pointers -- decodes pointers for load/save * - * FlyClass::Code_Pointers -- codes class's pointers for load/save * - * FlyClass::Decode_Pointers -- decodes pointers for load/save * - * FuseClass::Code_Pointers -- codes class's pointers for load/save * - * FuseClass::Decode_Pointers -- decodes pointers for load/save * - * TarComClass::Code_Pointers -- codes class's pointers for load/save * - * TarComClass::Decode_Pointers -- decodes pointers for load/save * - * TurretClass::Code_Pointers -- codes class's pointers for load/save * - * TurretClass::Decode_Pointers -- decodes pointers for load/save * - * DriveClass::Code_Pointers -- codes class's pointers for load/save * - * DriveClass::Decode_Pointers -- decodes pointers for load/save * - * FootClass::Code_Pointers -- codes class's pointers for load/save * - * FootClass::Decode_Pointers -- decodes pointers for load/save * - * RadioClass::Code_Pointers -- codes class's pointers for load/save * - * RadioClass::Decode_Pointers -- decodes pointers for load/save * - * TechnoClass::Code_Pointers -- codes class's pointers for load/save * - * TechnoClass::Decode_Pointers -- decodes pointers for load/save * - * FlasherClass::Code_Pointers -- codes class's pointers for load/save * - * FlasherClass::Decode_Pointers -- decodes pointers for load/save * - * CargoClass::Code_Pointers -- codes class's pointers for load/save * - * CargoClass::Decode_Pointers -- decodes pointers for load/save * - * MissionClass::Code_Pointers -- codes class's pointers for load/save * - * MissionClass::Decode_Pointers -- decodes pointers for load/save * - * ObjectClass::Code_Pointers -- codes class's pointers for load/save * - * ObjectClass::Decode_Pointers -- decodes pointers for load/save * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#pragma warning (disable : 4302) // Truncation from pointer to TARGET - - -/*********************************************************************************************** - * TeamTypeClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TeamTypeClass::Load(FileClass & file) -{ - ::new (this) TeamTypeClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractTypeClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * TeamTypeClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TeamTypeClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * TeamTypeClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TeamTypeClass::Code_Pointers(void) -{ - /* - -------------------------- Code the Class array -------------------------- - */ - for (int i = 0; i < ClassCount; i++) { - Class[i] = (TechnoTypeClass *)TechnoType_To_Target(Class[i]); - } -} - - -/*********************************************************************************************** - * TeamTypeClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TeamTypeClass::Decode_Pointers(void) -{ - /* - ------------------------- Decode the Class array ------------------------- - */ - for (int i = 0; i < ClassCount; i++) { - Class[i] = Target_To_TechnoType((TARGET)Class[i]); - Check_Ptr((void *)Class[i],__FILE__,__LINE__); - } -} - - -/*********************************************************************************************** - * TeamClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TeamClass::Load(FileClass & file) -{ - ::new (this) TeamClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * TeamClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TeamClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * TeamClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TeamClass::Code_Pointers(void) -{ - TeamTypeClass const * cls; - - /* - -------------------- Code Class & House for this team -------------------- - */ - cls = Class; - ((TeamTypeClass *&)Class) = (TeamTypeClass *)cls->As_Target(); - ((HouseClass *&)House) = (HouseClass *)House->Class->House; - - /* - --------------------------- Code the 'Member' ---------------------------- - */ - if (Member) { - Member = (FootClass *)Member->As_Target(); - } -} - - -/*********************************************************************************************** - * TeamClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TeamClass::Decode_Pointers(void) -{ - /* - ------------------- Decode Class & House for this team ------------------- - */ - ((TeamTypeClass *&)Class) = As_TeamType((TARGET)Class); - Check_Ptr((void *)Class,__FILE__,__LINE__); - ((HouseClass *&)House) = HouseClass::As_Pointer(*((HousesType*)&House)); - Check_Ptr((void *)House,__FILE__,__LINE__); - - /* - -------------------------- Decode the 'Member' --------------------------- - */ - if (Member) { - switch (Target_Kind((TARGET)Member)) { - case KIND_INFANTRY: - Member = As_Infantry((TARGET)Member, false); - break; - - case KIND_UNIT: - Member = As_Unit((TARGET)Member, false); - break; - - case KIND_AIRCRAFT: - Member = As_Aircraft((TARGET)Member, false); - break; - - default: - Member = 0; - break; - } - - Check_Ptr((void *)Member,__FILE__,__LINE__); - } -} - - -/*********************************************************************************************** - * TriggerClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TriggerClass::Load(FileClass & file) -{ - ::new (this) TriggerClass(); - int rc = Read_Object(this, sizeof(*this), file, false); - - //int rc = Read_Object(this, sizeof(*this), sizeof(*this), file, 0); - - /* - -------------------------- Add to HouseTriggers -------------------------- - */ - if (rc) { - if (House != HOUSE_NONE) { - HouseTriggers[House].Add(this); - } - } - - return(rc); -} - - -/*********************************************************************************************** - * TriggerClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TriggerClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * TriggerClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TriggerClass::Code_Pointers(void) -{ - if (Team) { - Team = (TeamTypeClass *)Team->As_Target(); - } -} - - -/*********************************************************************************************** - * TriggerClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TriggerClass::Decode_Pointers(void) -{ - if (Team) { - Team = As_TeamType((TARGET)Team); - Check_Ptr((void *)Team,__FILE__,__LINE__); - } -} - - -/*********************************************************************************************** - * AircraftClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Load(FileClass & file) -{ - ::new (this) AircraftClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * AircraftClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool AircraftClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * AircraftClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void AircraftClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((AircraftTypeClass *&)Class) = (AircraftTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - FootClass::Code_Pointers(); - FlyClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * AircraftClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void AircraftClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((AircraftTypeClass const *&)Class) = &AircraftTypeClass::As_Reference(*((AircraftType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - FootClass::Decode_Pointers(); - FlyClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * AnimClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool AnimClass::Load(FileClass & file) -{ - ::new (this) AnimClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * AnimClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool AnimClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * AnimClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void AnimClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((AnimTypeClass *&)Class) = (AnimTypeClass *)Class->Type; - - /* - ----------------------------- Code 'Object' ------------------------------ - */ - if (Object) { - Object = (ObjectClass *)Object->As_Target(); - } - - /* - ----------------------------- Code 'VirtualAnim' ------------------------- - */ - if (VirtualAnim) { - VirtualAnim = (AnimClass *)VirtualAnim->As_Target(); - } - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Code_Pointers(); - StageClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * AnimClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void AnimClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((AnimTypeClass const *&)Class) = &AnimTypeClass::As_Reference(*((AnimType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Decode 'Object' ----------------------------- - */ - if (Object) { - Object = As_Object((TARGET)Object, false); - Check_Ptr((void *)Object,__FILE__,__LINE__); - } - - /* - ---------------------------- Decode 'VirtualAnim' ------------------------ - */ - if (VirtualAnim) { - VirtualAnim = As_Animation((TARGET)VirtualAnim, false); - Check_Ptr((void *)VirtualAnim, __FILE__, __LINE__); - } - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Decode_Pointers(); - StageClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * BuildingClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Load(FileClass & file) -{ - ::new (this) BuildingClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * BuildingClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool BuildingClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * BuildingClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void BuildingClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((BuildingTypeClass const *&)Class) = (BuildingTypeClass *)Class->Type; - - /*------------------------------------------------------------------------ - Code the Factory value; there's not target conversion routine for factories, - so just use its Array ID, plus 1 so it doesn't look like a NULL value when - it's converted back - ------------------------------------------------------------------------*/ - if (Factory) { - Factory = (FactoryClass *)(Factories.ID(Factory) + 1); - } - - /* - ---------------------------- Chain to parent ----------------------------- - */ - TechnoClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * BuildingClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void BuildingClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((BuildingTypeClass const *&)Class) = &BuildingTypeClass::As_Reference(*((StructType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /*------------------------------------------------------------------------ - Decode the Factory value, subtracting off the '1' we added when coding it - ------------------------------------------------------------------------*/ - if (Factory) { - Factory = Factories.Raw_Ptr((int)Factory - 1); - Check_Ptr((void *)Factory,__FILE__,__LINE__); - } - - /* - ---------------------------- Chain to parent ----------------------------- - */ - TechnoClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * BulletClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool BulletClass::Load(FileClass & file) -{ - ::new (this) BulletClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * BulletClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool BulletClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * BulletClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void BulletClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((BulletTypeClass *&)Class) = (BulletTypeClass *)Class->Type; - - /* - ----------------------------- Code 'Payback' ----------------------------- - */ - if (Payback) - Payback = (TechnoClass *)Payback->As_Target(); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Code_Pointers(); - FlyClass::Code_Pointers(); - FuseClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * BulletClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void BulletClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((BulletTypeClass const *&)Class) = &BulletTypeClass::As_Reference(*((BulletType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Decode 'Payback' ---------------------------- - */ - if (Payback) { - Payback = As_Techno((TARGET)Payback, false); - Check_Ptr((void *)Payback,__FILE__,__LINE__); - } - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Decode_Pointers(); - FlyClass::Decode_Pointers(); - FuseClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * InfantryClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryClass::Load(FileClass & file) -{ - ::new (this) InfantryClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * InfantryClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool InfantryClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * InfantryClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void InfantryClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((InfantryTypeClass *&)Class) = (InfantryTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - FootClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * InfantryClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void InfantryClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((InfantryTypeClass const *&)Class) = &InfantryTypeClass::As_Reference(*((InfantryType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - FootClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * OverlayClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool OverlayClass::Load(FileClass & file) -{ - ::new (this) OverlayClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * OverlayClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool OverlayClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * OverlayClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void OverlayClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((OverlayTypeClass *&)Class) = (OverlayTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * OverlayClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void OverlayClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((OverlayTypeClass const *&)Class) = &OverlayTypeClass::As_Reference(*((OverlayType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * SmudgeClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool SmudgeClass::Load(FileClass & file) -{ - ::new (this) SmudgeClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * SmudgeClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool SmudgeClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * SmudgeClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void SmudgeClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((SmudgeTypeClass const *&)Class) = (SmudgeTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * SmudgeClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void SmudgeClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((SmudgeTypeClass const *&)Class) = &SmudgeTypeClass::As_Reference(*((SmudgeType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * TemplateClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TemplateClass::Load(FileClass & file) -{ - ::new (this) TemplateClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * TemplateClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TemplateClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * TemplateClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TemplateClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((TemplateTypeClass *&)Class) = (TemplateTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * TemplateClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TemplateClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((TemplateTypeClass const *&)Class) = &TemplateTypeClass::As_Reference(*((TemplateType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * TerrainClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TerrainClass::Load(FileClass & file) -{ - ::new (this) TerrainClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * TerrainClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool TerrainClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * TerrainClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TerrainClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((TerrainTypeClass *&)Class) = (TerrainTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Code_Pointers(); - StageClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * TerrainClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TerrainClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((TerrainTypeClass const *&)Class) = &TerrainTypeClass::As_Reference(*((TerrainType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - ObjectClass::Decode_Pointers(); - StageClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * UnitClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Load(FileClass & file) -{ - ::new (this) UnitClass(); - return(Read_Object(this, sizeof(*this), file, true)); - - //return(Read_Object(this, sizeof(AbstractClass), sizeof(*this), file, VTable)); -} - - -/*********************************************************************************************** - * UnitClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * UnitClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void UnitClass::Code_Pointers(void) -{ - TarComClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * UnitClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void UnitClass::Decode_Pointers(void) -{ - TarComClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * FactoryClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Load(FileClass & file) -{ - ::new (this) FactoryClass(); - return(Read_Object(this, sizeof(*this), file, false)); - - //return(Read_Object(this, sizeof(StageClass), sizeof(*this), file, 0)); -} - - -/*********************************************************************************************** - * FactoryClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool FactoryClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * FactoryClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FactoryClass::Code_Pointers(void) -{ - if (Object) { - Object = (TechnoClass *)Object->As_Target(); - } - - ((HouseClass *&)House) = (HouseClass *)House->Class->House; - - StageClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * FactoryClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FactoryClass::Decode_Pointers(void) -{ - if (Object) { - Object = As_Techno((TARGET)Object, false); - Check_Ptr((void *)Object,__FILE__,__LINE__); - } - - ((HouseClass *&)House) = HouseClass::As_Pointer(*((HousesType*)&House)); - Check_Ptr((void *)House,__FILE__,__LINE__); - - StageClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * LayerClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool LayerClass::Load(FileClass & file) -{ - int count; - int i; - ObjectClass * ptr; - - /* - ---------------------- Read # elements in the layer ---------------------- - */ - if (file.Read(&count,sizeof(count)) != sizeof(count)) { - return(false); - } - - /* - ---------------------------- Clear the array ----------------------------- - */ - Clear(); - - /* - ----------------------- Read in all array elements ----------------------- - */ - for (i = 0; i < count; i++) { - if (file.Read(&ptr, sizeof(ObjectClass *)) != sizeof(ObjectClass *)) { - return(false); - } - Add(ptr); - } - - return(true); -} - - -/*********************************************************************************************** - * LayerClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool LayerClass::Save(FileClass & file) -{ - int count; - int i; - ObjectClass * ptr; - - /* - ------------------------- Save # array elements -------------------------- - */ - count = Count(); - if (file.Write(&count, sizeof(count)) != sizeof(count)) - return(false); - - /* - --------------------------- Save all elements ---------------------------- - */ - for (i = 0; i < count; i++) { - ptr = (*this)[i]; - if (file.Write(&ptr, sizeof(ObjectClass *)) != sizeof(ObjectClass *)) - return(false); - } - - return(true); -} - - -/*********************************************************************************************** - * LayerClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void LayerClass::Code_Pointers(void) -{ - ObjectClass *obj; - - for (int i = 0; i < Count(); i++) { - obj = (*this)[i]; - (*this)[i] = (ObjectClass *)(obj->As_Target()); - } -} - - -/*********************************************************************************************** - * LayerClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void LayerClass::Decode_Pointers(void) -{ - TARGET target; - - for (int i = 0; i < Count(); i++) { - target = (TARGET)(*this)[i]; - (*this)[i] = (ObjectClass *)As_Object(target, false); - Check_Ptr((*this)[i],__FILE__,__LINE__); - } -} - - -/*********************************************************************************************** - * HouseClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Load(FileClass & file) -{ - ::new (this) HouseClass(); - return(Read_Object(this, sizeof(*this), file, false)); - - //return(Read_Object(this, sizeof(*this), sizeof(*this), file, 0)); -} - - -/*********************************************************************************************** - * HouseClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool HouseClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * HouseClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void HouseClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((HouseTypeClass const *&)Class) = (HouseTypeClass const *)Class->House; -} - - -/*********************************************************************************************** - * HouseClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void HouseClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((HouseTypeClass const *&)Class) = &HouseTypeClass::As_Reference(*((HousesType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); -} - - -/*********************************************************************************************** - * ScoreClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the cell's data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool ScoreClass::Load(FileClass & file) -{ - ::new (this) ScoreClass(); - return(Read_Object(this, sizeof(*this), file, false)); - - //return(Read_Object(this, sizeof(*this), sizeof(*this), file, 0)); -} - - -/*********************************************************************************************** - * ScoreClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the cell's data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -bool ScoreClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -/*********************************************************************************************** - * ScoreClass::Code_Pointers -- codes class's pointers for load/save * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void ScoreClass::Code_Pointers(void) -{ -} - - -/*********************************************************************************************** - * ScoreClass::Decode_Pointers -- decodes pointers for load/save * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void ScoreClass::Decode_Pointers(void) -{ -} - - -/*********************************************************************************************** - * FlyClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FlyClass::Code_Pointers(void) -{ -} - - -/*********************************************************************************************** - * FlyClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FlyClass::Decode_Pointers(void) -{ -} - - -/*********************************************************************************************** - * FuseClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FuseClass::Code_Pointers(void) -{ -} - - -/*********************************************************************************************** - * FuseClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FuseClass::Decode_Pointers(void) -{ -} - - -/*********************************************************************************************** - * TarComClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TarComClass::Code_Pointers(void) -{ - TurretClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * TarComClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TarComClass::Decode_Pointers(void) -{ - TurretClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * TurretClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TurretClass::Code_Pointers(void) -{ - DriveClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * TurretClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TurretClass::Decode_Pointers(void) -{ - DriveClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * DriveClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void DriveClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Class' ------------------------------ - */ - ((UnitTypeClass *&)Class) = (UnitTypeClass *)Class->Type; - - /* - ---------------------------- Chain to parent ----------------------------- - */ - FootClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * DriveClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void DriveClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Class' ----------------------------- - */ - ((UnitTypeClass const *&)Class) = &UnitTypeClass::As_Reference(*((UnitType*)&Class)); - Check_Ptr((void *)Class,__FILE__,__LINE__); - - /* - ---------------------------- Chain to parent ----------------------------- - */ - FootClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * FootClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FootClass::Code_Pointers(void) -{ - if (Team) - Team = (TeamClass *)Team->As_Target(); - - if (Member) { - Member = (FootClass *)Member->As_Target(); - } - - TechnoClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * FootClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FootClass::Decode_Pointers(void) -{ - if (Team) { - Team = As_Team((TARGET)Team, false); - Check_Ptr((void *)Team,__FILE__,__LINE__); - } - - if (Member) { - Member = (FootClass *)As_Techno((TARGET)Member, false); - Check_Ptr((void *)Member,__FILE__,__LINE__); - } - - TechnoClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * RadioClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void RadioClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'Radio' ------------------------------ - */ - if (Radio) { - Radio = (RadioClass *)Radio->As_Target(); - } - - MissionClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * RadioClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void RadioClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'Radio' ----------------------------- - */ - if (Radio) { - Radio = As_Techno((TARGET)Radio, false); - Check_Ptr((void *)Radio,__FILE__,__LINE__); - } - - MissionClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * TechnoClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TechnoClass::Code_Pointers(void) -{ - /* - ------------------------------ Code 'House' ------------------------------ - */ - ((HouseClass *&)House) = (HouseClass *)(House->Class->House); - - FlasherClass::Code_Pointers(); - StageClass::Code_Pointers(); - CargoClass::Code_Pointers(); - DoorClass::Code_Pointers(); - - RadioClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * TechnoClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void TechnoClass::Decode_Pointers(void) -{ - /* - ----------------------------- Decode 'House' ----------------------------- - */ - ((HouseClass *&)House) = HouseClass::As_Pointer(*((HousesType*)&House)); - Check_Ptr((void *)House,__FILE__,__LINE__); - - FlasherClass::Decode_Pointers(); - StageClass::Decode_Pointers(); - CargoClass::Decode_Pointers(); - DoorClass::Decode_Pointers(); - - RadioClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * FlasherClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FlasherClass::Code_Pointers(void) -{ -} - - -/*********************************************************************************************** - * FlasherClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void FlasherClass::Decode_Pointers(void) -{ -} - - -/*********************************************************************************************** - * CargoClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void CargoClass::Code_Pointers(void) -{ - /* - ---------------------------- Code 'CargoHold' ---------------------------- - */ - if (CargoHold) { - CargoHold = (FootClass *)CargoHold->As_Target(); - } -} - - -/*********************************************************************************************** - * CargoClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void CargoClass::Decode_Pointers(void) -{ - /* - --------------------------- Decode 'CargoHold' --------------------------- - */ - if (CargoHold) { - CargoHold = (FootClass *)As_Techno((TARGET)CargoHold, false); - Check_Ptr((void *)CargoHold,__FILE__,__LINE__); - } -} - - -/*********************************************************************************************** - * MissionClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void MissionClass::Code_Pointers(void) -{ - ObjectClass::Code_Pointers(); -} - - -/*********************************************************************************************** - * MissionClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void MissionClass::Decode_Pointers(void) -{ - ObjectClass::Decode_Pointers(); -} - - -/*********************************************************************************************** - * ObjectClass::Code_Pointers -- codes class's pointers for load/save * - * * - * This routine "codes" the pointers in the class by converting them to a number * - * that still represents the object pointed to, but isn't actually a pointer. This * - * allows a saved game to properly load without relying on the games data still * - * being in the exact same location. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void ObjectClass::Code_Pointers(void) -{ - if (Next) { - Next = (ObjectClass *)Next->As_Target(); - } - - if (Trigger) { - Trigger = (TriggerClass *)Trigger->As_Target(); - } -} - - -/*********************************************************************************************** - * ObjectClass::Decode_Pointers -- decodes pointers for load/save * - * * - * This routine "decodes" the pointers coded in Code_Pointers by converting the * - * code values back into object pointers. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/02/1995 BR : Created. * - *=============================================================================================*/ -void ObjectClass::Decode_Pointers(void) -{ - if (Next) { - Next = As_Object((TARGET)Next, false); - Check_Ptr((void *)Next,__FILE__,__LINE__); - } - - if (Trigger) { - Trigger = As_Trigger((TARGET)Trigger, false); - Check_Ptr((void *)Trigger,__FILE__,__LINE__); - } -} diff --git a/code/TIBERIANDAWN/IPX.CPP b/code/TIBERIANDAWN/IPX.CPP deleted file mode 100644 index 6082f3f..0000000 --- a/code/TIBERIANDAWN/IPX.CPP +++ /dev/null @@ -1,1108 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipx.cpv 2.17 16 Oct 1995 16:49:34 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPX.CPP * - * * - * Programmer : Barry Nance * - * from Client/Server LAN Programming * - * Westwood-ized by Bill Randolph * - * * - * Start Date : December 14, 1994 * - * * - * Last Update : December 15, 1994 [BR] * - * * - *-------------------------------------------------------------------------* - * Pitfalls: * - * - Never try to use a closed socket; always check the return code from * - * IPX_Open_Socket(). * - * - Always give IPX an outstanding ECB for listening, before you send. * - * - It turns out that IPX is pretty bad about saving registers, so if * - * you have any register variables in your program, they may get * - * trashed. To circumvent this, all functions in this module save & * - * restore the registers before invoking any IPX or NETX function. * - * * - *-------------------------------------------------------------------------* - * Functions: * - * IPX_SPX_Installed -- checks for installation of IPX/SPX * - * IPX_Open_Socket -- opens an IPX socket for sending or receiving * - * IPX_Close_Socket -- closes an open socket * - * IPX_Get_Connection_Number -- gets local Connection Number * - * IPX_Get_1st_Connection_Num -- gets 1st Connect Number for given user * - * IPX_Get_Internet_Address -- gets Network Number & Node Address * - * IPX_Get_User_ID -- gets user ID from Connection Number * - * IPX_Listen_For_Packet -- commands IPX to listen for a packet * - * IPX_Send_Packet -- commands IPX to send a packet * - * IPX_Get_Local_Target -- fills in ImmediateAddress field of ECB * - * IPX_Cancel_Event -- cancels an operation in progress * - * Let_IPX_Breath -- gives IPX some CPU time * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "ipx95.h" - - -/*************************************************************************** - * IPX_SPX_Installed -- checks for installation of IPX/SPX * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = not installed; 1 = IPX only, 2 = IPX and SPX are installed * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/14/1994 BR : Created. * - *=========================================================================*/ -int IPX_SPX_Installed(void) -{ - -#ifndef NOT_FOR_WIN95 - - return (IPX_Initialise()); - -#else //NOT_FOR_WIN95 - - union REGS regs; - struct SREGS sregs; - RMIType rmi; - - /*------------------------------------------------------------------------ - Init all registers to 0's - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - - /*------------------------------------------------------------------------ - Fill in registers for the DPMI call, function 0x300 - ------------------------------------------------------------------------*/ - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = 0x002f; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - - /*------------------------------------------------------------------------ - Fill in registers for the real-mode interrupt handler. - To test for the presence of IPX, set AH to 0x7a, AL to 0, and invoke - interrupt 0x2f (the "multiplex" interrupt). If IPX is installed, - AL will be 0xff, and ES:DI will contain the IPX/SPX function address. - ------------------------------------------------------------------------*/ - rmi.eax = 0x00007a00; - - /*------------------------------------------------------------------------ - call DPMI - ------------------------------------------------------------------------*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - /*------------------------------------------------------------------------ - If IPX isn't there, return 0 - ------------------------------------------------------------------------*/ - if ( (rmi.eax & 0x00ff) != 0xff) { - return(0); - } - - /*------------------------------------------------------------------------ - Test for SPX by invoking the IPX_SPX function with BX = 0x10, and AL = 0. - If SPX is present, AL will be 0xff. - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = 0x00000010; - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - /*------------------------------------------------------------------------ - SPX is installed; return '2' - ------------------------------------------------------------------------*/ - if ( (rmi.eax & 0x00ff) == 0xff) { - return(2); - } - - /*------------------------------------------------------------------------ - SPX is not installed; return '1' - ------------------------------------------------------------------------*/ - return(1); -#endif //NOT_FOR_WIN95 -} /* end of IPX_SPX_Installed */ - - -/*************************************************************************** - * IPX_Open_Socket -- opens an IPX socket for sending or receiving * - * * - * INPUT: * - * socket the socket number to open * - * * - * OUTPUT: * - * 0 = OK * - * -1 = IPX not installed * - * 0xfe = socket table is full * - * 0xff = socket is already open * - * * - * WARNINGS: * - * The application must define its socket number carefully. Use * - * values from 0x4000 to 0x8000 for custom socket numbers. The app * - * must know its own socket number as well as the socket number of * - * a destination workstation. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Open_Socket(unsigned short socket) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - int rc; - - /*------------------------------------------------------------------------ - Open the socket: - DX = socket number - AL = 0 for short-lived socket, 0xff for long-lived socket - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG (&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF (&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_OPEN_SOCKET; // function code - rmi.edx = socket; // desired socket # - rmi.eax = 0x00ff; // make this a long-lived socket - /*........................................................................ - call DPMI - ........................................................................*/ - int386x (DPMI_INT, ®s, ®s, &sregs); - - rc = (rmi.eax & 0xff); - - return(rc); - -} /* end of IPX_Open_Socket */ - -#endif -/*************************************************************************** - * IPX_Close_Socket -- closes an open socket * - * * - * INPUT: * - * socket socket number to close * - * * - * OUTPUT: * - * 0 = ok, -1 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Close_Socket(unsigned short socket) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - - /*------------------------------------------------------------------------ - Close the socket: - DX = socket number - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_CLOSE_SOCKET; - rmi.edx = socket; - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - return(0); - -} /* end of IPX_Close_Socket */ -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Get_Connection_Number -- gets local Connection Number * - * * - * This Novell call will the return the user's local "Connection Number". * - * This value will be 0 if the user isn't logged into Novell, so this * - * routine can be used to detect if other calls (such as Get_Local_Target) * - * will be OK. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * Connection Number, 0 = none * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Get_Connection_Number(void) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - int num; - - /*------------------------------------------------------------------------ - Call Interrupt 0x21, with AH = 0xdc. This tells Novell to put the local - connection number into AL. - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = 0x21; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.eax = 0x0000dc00; - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - num = rmi.eax & 0x00ff; - - return(num); - -} /* end of IPX_Get_Connection_Number */ - -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Get_1st_Connection_Num -- gets 1st Connect Number for given user * - * * - * This gets the Connection Number for the given User ID. Since a user * - * may be logged in more than once, this just returns the first connection * - * found and ignores the others. * - * * - * INPUT: * - * username name of the user to get the Connection Number for * - * * - * OUTPUT: * - * first-found Connection Number for that user, 0 if user not logged in * - * * - * WARNINGS: * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Get_1st_Connection_Num (char *username) -{ - struct request_buffer { - unsigned short len; // username length + 5 - unsigned char buffer_type; // ConnectionNum = 0x15 - unsigned short object_type; // set ot 0x0100 - unsigned char name_len; // length of username - char name [48]; // copy of username - unsigned short reserved; - }; - struct reply_buffer { - unsigned short len; - unsigned char number_connections; // will be 0 - 100 - unsigned char connection_num [100]; // array of connection numbers - unsigned short reserved[2]; - }; - union REGS regs; - struct SREGS sregs; - RMIType rmi; - struct request_buffer *reqbuf; - struct reply_buffer *replybuf; - unsigned short segment; // for DOS allocation - unsigned short selector; // for DOS allocation - int num_conns; // # connections returned - int conn_num; // connection number - int rc; - - /*------------------------------------------------------------------------ - Allocate DOS memory to store the buffers passed to the interrupt - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_ALLOC_DOS_MEM; // DPMI function to call - regs.x.ebx = (sizeof(struct request_buffer) + // # paragraphs to allocate - sizeof(struct reply_buffer) + 15) >> 4; - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - return(0); - } - - /*........................................................................ - Get pointers to allocated memory. - 'reqbuf' is just the returned real-mode segment, multiplied by 16. - 'replybuf' is an offset from 'reqbuf'. - ........................................................................*/ - segment = regs.w.ax; - selector = regs.w.dx; - reqbuf = (struct request_buffer *)(segment << 4); - replybuf = (struct reply_buffer *) - (((char *)reqbuf) + sizeof (struct request_buffer)); - - /*------------------------------------------------------------------------ - Init the contents of the request & reply buffers - ------------------------------------------------------------------------*/ - reqbuf->len = (unsigned short)(strlen(username) + 5); - reqbuf->buffer_type = 0x15; - reqbuf->object_type = 0x0100; - reqbuf->name_len = (unsigned char) strlen(username); - strcpy(reqbuf->name, username); - reqbuf->reserved = reqbuf->reserved; // prevent compiler warning - replybuf->len = 101; - replybuf->reserved[0] = replybuf->reserved[0]; // prevent compiler warning - replybuf->reserved[0] = replybuf->reserved[1]; // prevent compiler warning - - /*------------------------------------------------------------------------ - Invoke Int 21 with AH=0xe3, DS:SI=&request_buffer, ES:DI=&reply_buffer - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = 0x21; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.eax = 0x0000e300; - rmi.ds = segment; - rmi.esi = 0; - rmi.es = segment; - rmi.edi = sizeof(struct request_buffer); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - /*------------------------------------------------------------------------ - Stash the 1st connection number - ------------------------------------------------------------------------*/ - rc = (rmi.eax & 0x00ff); // if AL !=0, error - num_conns = replybuf->number_connections; // # times user is logged in - conn_num = (int )replybuf->connection_num[0]; // 1st connection # - - /*------------------------------------------------------------------------ - Free DOS memory - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_FREE_DOS_MEM; // DPMI function to call - regs.x.edx = selector; // ptr to free - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - - /*------------------------------------------------------------------------ - Return error if function failed, or user not logged in - ------------------------------------------------------------------------*/ - if (rc != 0 || num_conns==0) { - return(0); - } else { - return(conn_num); - } -} -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Get_Internet_Address -- gets Network Number & Node Address * - * * - * Once you've obtained a Connection Number from IPX_Get_Connection_Number * - * or IPX_Get_1st_Connection_Num, use this function to translate it into * - * a Network Number and Node Address; then, place those numbers in the * - * IPX header for outgoing packets. * - * * - * INPUT: * - * connection_number Connection Number to translate * - * network_number ptr: will hold Network Number * - * physical_node ptr: will hold Node Address * - * * - * OUTPUT: * - * 0 = OK, -1 = error * - * * - * WARNINGS: * - * If connection_number is 0 and NETX isn't running, this routine * - * will just put garbage into the network_number and physical_node. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Get_Internet_Address(int connection_number, - unsigned char *network_number, unsigned char *physical_node) -{ - struct request_buffer { - unsigned short len; - unsigned char buffer_type; // Internet = 0x13 - unsigned char connection_number; // Conn. Number to translate - }; - struct reply_buffer { - unsigned short len; - unsigned char network_number [4]; // filled in by IPX - unsigned char physical_node [6]; // filled in by IPX - unsigned short server_socket; // filled in by IPX, but don't use! - }; - union REGS regs; - struct SREGS sregs; - RMIType rmi; - struct request_buffer *reqbuf; - struct reply_buffer *replybuf; - unsigned short segment; // for DOS allocation - unsigned short selector; // for DOS allocation - - /*------------------------------------------------------------------------ - Error if invalid connection is given - ------------------------------------------------------------------------*/ - if (connection_number==0) - return(-1); - - /*------------------------------------------------------------------------ - Allocate DOS memory to store the buffers passed to the interrupt - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_ALLOC_DOS_MEM; // DPMI function to call - regs.x.ebx = (sizeof(struct request_buffer) + // # paragraphs to allocate - sizeof(struct reply_buffer) + 15) >> 4; - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - return(-1); - } - - /*........................................................................ - Get pointers to allocated memory. - 'reqbuf' is just the returned real-mode segment, multiplied by 16. - 'replybuf' is an offset from 'reqbuf'. - ........................................................................*/ - segment = regs.w.ax; - selector = regs.w.dx; - reqbuf = (struct request_buffer *)(segment << 4); - replybuf = (struct reply_buffer *) - (((char *)reqbuf) + sizeof (struct request_buffer)); - - /*------------------------------------------------------------------------ - Init the contents of the request & reply buffers - ------------------------------------------------------------------------*/ - reqbuf->len = 2; - reqbuf->buffer_type = 0x13; - reqbuf->connection_number = (unsigned char)connection_number; - replybuf->len = 12; - replybuf->network_number[0] = replybuf->network_number[0]; // suppress warning - replybuf->physical_node[0] = replybuf->physical_node[0]; // suppress warning - replybuf->server_socket = replybuf->server_socket; // suppress warning - - /*------------------------------------------------------------------------ - Invoke Int 21 with AH=0xe3, DS:SI=&request_buffer, ES:DI=&reply_buffer - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = 0x21; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.eax = 0x0000e300; - rmi.ds = segment; - rmi.esi = 0; - rmi.es = segment; - rmi.edi = sizeof(struct request_buffer); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - memcpy(network_number, replybuf->network_number, 4); - memcpy(physical_node, replybuf->physical_node, 6); - - /*------------------------------------------------------------------------ - Free DOS memory - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_FREE_DOS_MEM; // DPMI function to call - regs.x.edx = selector; // ptr to free - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - - return(0); - -} /* end of IPX_Get_Internet_Address */ - -#endif // NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Get_User_ID -- gets user ID from Connection Number * - * * - * INPUT: * - * connection_number Connection Number to get User ID for * - * user_id ptr to buffer to put User ID into; * - * size must be >= 48 chars * - * * - * OUTPUT: * - * 0 = OK, -1 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Get_User_ID(int connection_number, char *user_id) -{ - struct request_buffer { - unsigned short len; - unsigned char buffer_type; // 0x16 = UserID buffer type - unsigned char connection_number; // Connection Number to get ID for - }; - struct reply_buffer { - unsigned short len; - unsigned char object_id[4]; - unsigned char object_type[2]; - char object_name[48]; - char login_time[7]; - unsigned short reserved; - }; - union REGS regs; - struct SREGS sregs; - RMIType rmi; - struct request_buffer *reqbuf; - struct reply_buffer *replybuf; - unsigned short segment; // for DOS allocation - unsigned short selector; // for DOS allocation - - /*------------------------------------------------------------------------ - Error if invalid connection is given - ------------------------------------------------------------------------*/ - if (connection_number==0) - return(-1); - - /*------------------------------------------------------------------------ - Allocate DOS memory to store the buffers passed to the interrupt - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_ALLOC_DOS_MEM; // DPMI function to call - regs.x.ebx = (sizeof(struct request_buffer) + // # paragraphs to allocate - sizeof(struct reply_buffer) + 15) >> 4; - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - return(-1); - } - - /*........................................................................ - Get pointers to allocated memory. - 'reqbuf' is just the returned real-mode segment, multiplied by 16. - 'replybuf' is an offset from 'reqbuf'. - ........................................................................*/ - segment = regs.w.ax; - selector = regs.w.dx; - reqbuf = (struct request_buffer *)(segment << 4); - replybuf = (struct reply_buffer *) - (((char *)reqbuf) + sizeof (struct request_buffer)); - - /*------------------------------------------------------------------------ - Init the contents of the request & reply buffers - ------------------------------------------------------------------------*/ - reqbuf->len = 2; - reqbuf->buffer_type = 0x16; - reqbuf->connection_number = (unsigned char)connection_number; - replybuf->len = sizeof(struct reply_buffer) - 2; - replybuf->object_id[0] = replybuf->object_id[0]; // suppress warnings - replybuf->object_type[0] = replybuf->object_type[0]; // suppress warnings - replybuf->login_time[0] = replybuf->login_time[0]; // suppress warnings - replybuf->reserved = replybuf->reserved; // suppress warnings - - /*------------------------------------------------------------------------ - Invoke Int 21 with AH=0xe3, DS:SI=&request_buffer, ES:DI=&reply_buffer - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = 0x21; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.eax = 0x0000e300; - rmi.ds = segment; - rmi.esi = 0; - rmi.es = segment; - rmi.edi = sizeof(struct request_buffer); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - /*------------------------------------------------------------------------ - Fill in the caller's buffer with the user name - ------------------------------------------------------------------------*/ - strncpy(user_id, replybuf->object_name, 48); - - /*------------------------------------------------------------------------ - Free DOS memory - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_FREE_DOS_MEM; // DPMI function to call - regs.x.edx = selector; // ptr to free - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - - return(0); - -} /* end of IPX_Get_User_ID */ -#endif //NOT_FOR_WIN95 - - -/*************************************************************************** - * IPX_Listen_For_Packet -- commands IPX to listen for a packet * - * * - * Before calling this function, you must fill in an ECB: * - * SocketNumber: must contain the socket you've opened, * - * and are "listening" on * - * Event_Service_Routine: optionally points to a callback routine * - * PacketCount: set to 2, to tell IPX there are 2 areas to * - * store the incoming data in * - * Packet[0].Address: set to the address of an IPXHeaderType * - * Packet[0].Length: sizeof(IPXHeaderType) * - * Packet[1].Address: address of data buffer, for the packet * - * Packet[1].Length: size of the data buffer * - * * - * When the packet is received, ECBType.CompletionCode will be 0 if * - * successful. Otherwise, some error occurred. * - * * - * You should initialize the ECB to 0's before filling it in. * - * * - * INPUT: * - * ecb_ptr pointer to a filled-in ECB; MUST be real-mode memory * - * * - * OUTPUT: * - * 0 = OK, IPX error otherwise * - * * - * WARNINGS: * - * The ECB must be located in real-mode memory, as well as the values * - * pointed to in the ECB (the IPX Header, the buffer to send, etc.) * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Listen_For_Packet(struct ECB *ecb_ptr) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - - /*------------------------------------------------------------------------ - Call IPX with ES:SI=ecb_ptr - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_LISTEN_FOR_PACKET; - rmi.es = (short)((long)ecb_ptr >> 4); - rmi.esi = (long)((long)ecb_ptr & 0x000f); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - return(rmi.eax & 0x00ff); - -} /* end of IPX_Listen_For_Packet */ -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Send_Packet -- commands IPX to send a packet * - * * - * Before calling this function, you must fill in an ECB: * - * SocketNumber: must contain the socket you've opened, * - * and are sending on * - * Event_Service_Routine: optionally points to a callback routine * - * PacketCount: set to 2, to tell IPX there are 2 areas the * - * outgoing data is stored in * - * Packet[0].Address: set to the address of an IPXHeaderType * - * Packet[0].Length: sizeof(IPXHeaderType) * - * Packet[1].Address: address of buffer containing data to send * - * Packet[1].Length: size of the data buffer * - * ImmediateAddress: must be filled in with the node address of * - * the bridge that will route the message; * - * fill this in by calling IPX_Get_Local_Target * - * * - * Also, you must fill in the IPXHeaderType with certain values: * - * PacketType: set to 4 for IPX * - * DestNetworkNumber: Network Number of the destination system * - * DestNetworkNode: Node Address of the destination system * - * DestNetworkSocket: the destination system's socket to send to; * - * this doesn't have to be the same as the * - * socket opened on the local machine. * - * * - * You should initialize the ECB & IPXHeader to 0's before filling them in.* - * * - * INPUT: * - * ecb_ptr pointer to a filled-in ECB * - * * - * OUTPUT: * - * none. This function doesn't return anything; the caller must check * - * its ECB.CompletionCode for: 0 = OK, IPX Error otherwise. * - * * - * WARNINGS: * - * The ECB must be located in real-mode memory, as well as the values * - * pointed to in the ECB (the IPX Header, the buffer to send, etc.) * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -void IPX_Send_Packet(struct ECB *ecb_ptr) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - - /*------------------------------------------------------------------------ - Call IPX with ES:SI=ecb_ptr - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_SEND_PACKET; - rmi.es = (short)((long)ecb_ptr >> 4); - rmi.esi = (long)((long)ecb_ptr & 0x000f); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - -} /* end of IPX_Send_Packet */ -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Get_Local_Target -- fills in ImmediateAddress field of ECB * - * * - * Use this function to fill in the ECB's ImmediateAddress field when * - * sending a packet. The Immediate Address is the node address of the * - * bridge that must route the message. If there is no bridge, it's * - * filled in with the destination Node Address. In either case, it * - * will contain the proper value for sending. * - * * - * INPUT: * - * dest_network destination Network Number * - * dest_node destination Node Address * - * dest_socket destination Socket Number * - * bridge_address field to fill in with Immediate Address * - * * - * OUTPUT: * - * 0 = OK, error otherwise * - * * - * WARNINGS: * - * If the Connection Number is 0 (user not logged in), dest_network * - * and dest_node will be garbage, and this routine will probably crash. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Get_Local_Target(unsigned char *dest_network, unsigned char *dest_node, - unsigned short dest_socket, unsigned char *bridge_address) -{ - struct request_buffer { - unsigned char network_number [4]; - unsigned char physical_node [6]; - unsigned short socket; - }; - struct reply_buffer { - unsigned char local_target [6]; - }; - unsigned int rc; - union REGS regs; - struct SREGS sregs; - RMIType rmi; - struct request_buffer *reqbuf; - struct reply_buffer *replybuf; - unsigned short segment; // for DOS allocation - unsigned short selector; // for DOS allocation - - /*------------------------------------------------------------------------ - Allocate DOS memory to store the buffers passed to the interrupt - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_ALLOC_DOS_MEM; // DPMI function to call - regs.x.ebx = (sizeof(struct request_buffer) + // # paragraphs to allocate - sizeof(struct reply_buffer) + 15) >> 4; - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - return(-1); - } - - /*........................................................................ - Get pointers to allocated memory. - 'reqbuf' is just the returned real-mode segment, multiplied by 16. - 'replybuf' is an offset from 'reqbuf'. - ........................................................................*/ - segment = regs.w.ax; - selector = regs.w.dx; - reqbuf = (struct request_buffer *)(segment << 4); - replybuf = (struct reply_buffer *) - (((char *)reqbuf) + sizeof (struct request_buffer)); - - /*------------------------------------------------------------------------ - Init the contents of the request & reply buffers - ------------------------------------------------------------------------*/ - memcpy(reqbuf->network_number, dest_network, 4); - memcpy(reqbuf->physical_node, dest_node, 6); - reqbuf->socket = dest_socket; - - /*------------------------------------------------------------------------ - Invoke IPX with DS:SI=&request_buffer, ES:DI=&reply_buffer - ------------------------------------------------------------------------*/ - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_GET_LOCAL_TARGET; - rmi.ds = segment; - rmi.esi = 0; - rmi.es = segment; - rmi.edi = sizeof(struct request_buffer); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - rc = (rmi.eax & 0x00ff); - memcpy(bridge_address, replybuf->local_target, 6); - - /*------------------------------------------------------------------------ - Free DOS memory - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_FREE_DOS_MEM; // DPMI function to call - regs.x.edx = selector; // ptr to free - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - - return(rc); - -} /* end of IPX_Get_Local_Target */ - -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * IPX_Cancel_Event -- cancels an operation in progress * - * * - * INPUT: * - * ecb_ptr pointer to ECB event to cancel * - * * - * OUTPUT: * - * ??? * - * * - * WARNINGS: * - * The ECB must be located in real-mode memory, as well as the values * - * pointed to in the ECB (the IPX Header, the buffer to send, etc.) * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -int IPX_Cancel_Event(struct ECB *ecb_ptr) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - unsigned int rc; - - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_CANCEL_EVENT; - rmi.es = (short)((long)ecb_ptr >> 4); - rmi.esi = (long)((long)ecb_ptr & 0x000f); - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - - rc = (rmi.eax & 0x00ff); - - return(rc); - -} /* end of IPX_Cancel_Event */ -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * Let_IPX_Breath -- gives IPX some CPU time * - * * - * Use this function if you're polling the ECB's InUse flag, waiting * - * for it to go to 0: * - * * - * while ECBType.InUse * - * Let_IPX_Breath(); * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/15/1994 BR : Created. * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -void Let_IPX_Breath(void) -{ - union REGS regs; - struct SREGS sregs; - RMIType rmi; - - /*........................................................................ - Fill in registers for the DPMI call - ........................................................................*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - memset (&rmi, 0 ,sizeof(rmi)); - regs.w.ax = DPMI_CALL_REAL_INT; // DPMI function to call - regs.w.bx = IPX_INT; // interrupt # to invoke - sregs.es = FP_SEG(&rmi); // tell DPMI where the RMI is - regs.x.edi = FP_OFF(&rmi); - /*........................................................................ - Fill in registers for the interrupt call - ........................................................................*/ - rmi.ebx = IPX_RELINQUISH_CONTROL; - /*........................................................................ - call DPMI - ........................................................................*/ - int386x(DPMI_INT, ®s, ®s, &sregs); - -} /* end of Let_IPX_Breath */ -#endif //NOT_FOR_WIN95 diff --git a/code/TIBERIANDAWN/IPX.H b/code/TIBERIANDAWN/IPX.H deleted file mode 100644 index e0effe3..0000000 --- a/code/TIBERIANDAWN/IPX.H +++ /dev/null @@ -1,185 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipx.h_v 2.17 16 Oct 1995 16:46:26 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPX.H * - * * - * Programmer : Barry Nance * - * from Client/Server LAN Programming * - * Westwood-ized by Bill Randolph * - * * - * Start Date : December 14, 1994 * - * * - * Last Update : December 14, 1994 [BR] * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef IPX_H -#define IPX_H - -/* -******************************** Structures ********************************* -*/ -typedef unsigned char NetNumType[4]; -typedef unsigned char NetNodeType[6]; -typedef char UserID[48]; - -/*--------------------------------------------------------------------------- -This is the IPX Packet structure. It's followed by the data itself, which -can be up to 546 bytes long. Annotation of 'IPX' means IPX will set this -field; annotation of 'APP' means the application must set the field. -NOTE: All header fields are ordered high-byte,low-byte. ----------------------------------------------------------------------------*/ -typedef struct IPXHEADER { - unsigned short CheckSum; // IPX: Not used; always 0xffff - unsigned short Length; // IPX: Total size, incl header & data - unsigned char TransportControl; // IPX: # bridges message crossed - unsigned char PacketType; // APP: Set to 4 for IPX (5 for SPX) - unsigned char DestNetworkNumber[4]; // APP: destination Network Number - unsigned char DestNetworkNode[6]; // APP: destination Node Address - unsigned short DestNetworkSocket; // APP: destination Socket Number - unsigned char SourceNetworkNumber[4]; // IPX: source Network Number - unsigned char SourceNetworkNode[6]; // IPX: source Node Address - unsigned short SourceNetworkSocket; // IPX: source Socket Number -} IPXHeaderType; - -/*--------------------------------------------------------------------------- -This is the IPX Event Control Block. It serves as a communications area -between IPX and the application for a single IPX operation. You should set -up a separate ECB for each IPX operation you perform. ----------------------------------------------------------------------------*/ -typedef struct ECB { - void *Link_Address; - void (*Event_Service_Routine)(void); // APP: event handler (NULL=none) - unsigned char InUse; // IPX: 0 = event complete - unsigned char CompletionCode; // IPX: event's return code - unsigned short SocketNumber; // APP: socket to send data through - unsigned short ConnectionID; // returned by Listen (???) - unsigned short RestOfWorkspace; - unsigned char DriverWorkspace[12]; - unsigned char ImmediateAddress[6]; // returned by Get_Local_Target - unsigned short PacketCount; - struct { - void *Address; - unsigned short Length; - } Packet[2]; -} ECBType; - - -/*--------------------------------------------------------------------------- -This structure is used for calling DPMI function 0x300, Call-Real-Mode- -Interrupt. It passes register values to & from the interrupt handler. ----------------------------------------------------------------------------*/ -typedef struct { - long edi; - long esi; - long ebp; - long Reserved; - long ebx; - long edx; - long ecx; - long eax; - short Flags; - short es; - short ds; - short fs; - short gs; - short ip; - short cs; - short sp; - short ss; -} RMIType; - -/* -********************************** Defines ********************************** -*/ -/*--------------------------------------------------------------------------- -These defines are for the IPX functions. The function number is specified -by placing it in BX when IPX is called. There are two ways to invoke IPX: -use interrupt 0x7a, or use a function whose address is obtained by calling -interrupt 0x2f with AX=0x7a00; the function address is returned in ES:DI. -This is the preferred method, since other apps are known to use int 0x7a. ----------------------------------------------------------------------------*/ -#define IPX_OPEN_SOCKET 0x0000 -#define IPX_CLOSE_SOCKET 0x0001 -#define IPX_GET_LOCAL_TARGET 0x0002 -#define IPX_SEND_PACKET 0x0003 -#define IPX_LISTEN_FOR_PACKET 0x0004 -#define IPX_SCHEDULE_EVENT 0x0005 -#define IPX_CANCEL_EVENT 0x0006 -#define IPX_GET_INTERVAL_MARKER 0x0008 -#define IPX_GET_INTERNETWORK_ADDRESS 0x0009 -#define IPX_RELINQUISH_CONTROL 0x000A -#define IPX_DISCONNECT_FROM_TARGET 0x000B - -/*--------------------------------------------------------------------------- -These defines are for various IPX error codes: ----------------------------------------------------------------------------*/ -#define IPXERR_CONNECTION_SEVERED 0x00ec -#define IPXERR_CONNECTION_FAILED 0x00ed -#define IPXERR_NO_CONNECTION 0x00ee -#define IPXERR_CONNECTION_TABLE_FULL 0x00ef -#define IPXERR_NO_CANCEL_ECB 0x00f9 -#define IPXERR_NO_PATH 0x00fa -#define IPXERR_ECB_INACTIVE 0x00fc -#define IPXERR_INVALID_PACKET_LENGTH 0x00fd -#define IPXERR_SOCKET_TABLE_FULL 0x00fe -#define IPXERR_SOCKET_ERROR 0x00ff - -/*--------------------------------------------------------------------------- -These defines are for various interrupt vectors and DPMI functions: ----------------------------------------------------------------------------*/ -#define IPX_INT 0x007a -#define DPMI_INT 0x0031 -#define DPMI_ALLOC_DOS_MEM 0x0100 -#define DPMI_FREE_DOS_MEM 0x0101 -#define DPMI_CALL_REAL_INT 0x0300 -#define DPMI_LOCK_MEM 0x0600 -#define DPMI_UNLOCK_MEM 0x0601 - -/* -******************************** Prototypes ********************************* -*/ -/*--------------------------------------------------------------------------- -NOTE: All routines return 0 for a success code and one of the above IPX -error codes if there's an error, EXCEPT: -- IPX_SPX_Installed (0 = not installed) -- Get_Connection_Number / Get_1st_Connection_Number (0 = no connection) ----------------------------------------------------------------------------*/ -/* -.................................. ipx.cpp .................................. -*/ -int IPX_SPX_Installed(void); -int IPX_Open_Socket(unsigned short socket); -int IPX_Close_Socket(unsigned short socket); -int IPX_Get_Connection_Number(void); -int IPX_Get_1st_Connection_Num (char *username); -int IPX_Get_Internet_Address(int connection_number, - unsigned char *network_number, unsigned char *physical_node); -int IPX_Get_User_ID(int connection_number, char *user_id); -int IPX_Listen_For_Packet(struct ECB *ecb_ptr); -void IPX_Send_Packet(struct ECB *ecb_ptr); -int IPX_Get_Local_Target(unsigned char *dest_network, unsigned char *dest_node, - unsigned short dest_socket, unsigned char *bridge_address); -int IPX_Cancel_Event(struct ECB *ecb_ptr); -void Let_IPX_Breath(void); - -#endif diff --git a/code/TIBERIANDAWN/IPX95.CPP b/code/TIBERIANDAWN/IPX95.CPP deleted file mode 100644 index 9a94203..0000000 --- a/code/TIBERIANDAWN/IPX95.CPP +++ /dev/null @@ -1,103 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPX95PP * - * * - * Programmer : Steve Tall * - * * - * Start Date : January 22nd, 1996 * - * * - * Last Update : January 22nd, 1996 [ST] * - * * - *-------------------------------------------------------------------------* - * * - * * - * * - *-------------------------------------------------------------------------* - * Functions: * - * * - * * - * * - * * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "ipx95.h" - - -// Stub in old IPX here ST - 12/20/2018 1:53PM -extern "C"{ - extern BOOL __stdcall IPX_Initialise(void) {return 0;} - extern BOOL __stdcall IPX_Get_Outstanding_Buffer95(unsigned char *buffer) {return 0;} - extern void __stdcall IPX_Shut_Down95(void) {} - extern int __stdcall IPX_Send_Packet95(unsigned char *, unsigned char *, int, unsigned char*, unsigned char*) {return 0;} - extern int __stdcall IPX_Broadcast_Packet95(unsigned char *, int){return 0;} - extern BOOL __stdcall IPX_Start_Listening95(void){return 0;} - extern int __stdcall IPX_Open_Socket95(int socket){return 0;} - extern void __stdcall IPX_Close_Socket95(int socket){} - extern int __stdcall IPX_Get_Connection_Number95(void){return 0;} - extern int __stdcall IPX_Get_Local_Target95(unsigned char *, unsigned char*, unsigned short, unsigned char*){return 0;} -} - - - -int IPX_Open_Socket(unsigned short socket) -{ - return -1; - //return (IPX_Open_Socket95((int)socket)); //ST - 12/20/2018 11:34AM -} - - -int IPX_Close_Socket(unsigned short socket) -{ - //IPX_Close_Socket95((int)socket); //ST - 12/20/2018 11:34AM - return (0); -} - - -int IPX_Get_Connection_Number(void) -{ - //return (IPX_Get_Connection_Number95()); //ST - 12/20/2018 11:34AM - return -1; -} - - - -int IPX_Broadcast_Packet(unsigned char *buf, int buflen) -{ - //return(IPX_Broadcast_Packet95(buf, buflen)); //ST - 12/20/2018 11:34AM - return 0; -} - -//extern "C"{ -// extern void __cdecl Int3(void); -//} -//ST - 12/20/2018 11:34AM - -int IPX_Get_Local_Target(unsigned char *dest_network, unsigned char *dest_node, - unsigned short dest_socket, unsigned char *bridge_address) -{ - //Int3(); - // return (IPX_Get_Local_Target95(dest_network, dest_node, dest_socket, bridge_address)); //ST - 12/20/2018 11:34AM - return 0; -} - diff --git a/code/TIBERIANDAWN/IPX95.H b/code/TIBERIANDAWN/IPX95.H deleted file mode 100644 index 79a740d..0000000 --- a/code/TIBERIANDAWN/IPX95.H +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPX95PP * - * * - * Programmer : Steve Tall * - * * - * Start Date : January 22nd, 1996 * - * * - * Last Update : January 22nd, 1996 [ST] * - * * - *-------------------------------------------------------------------------* - * * - * * - * * - *-------------------------------------------------------------------------* - * Functions: * - * * - * * - * * - * * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -extern "C"{ - extern BOOL __stdcall IPX_Initialise(void); - extern BOOL __stdcall IPX_Get_Outstanding_Buffer95(unsigned char *buffer); - extern void __stdcall IPX_Shut_Down95(void); - extern int __stdcall IPX_Send_Packet95(unsigned char *, unsigned char *, int, unsigned char*, unsigned char*); - extern int __stdcall IPX_Broadcast_Packet95(unsigned char *, int); - extern BOOL __stdcall IPX_Start_Listening95(void); - extern int __stdcall IPX_Open_Socket95(int socket); - extern void __stdcall IPX_Close_Socket95(int socket); - extern int __stdcall IPX_Get_Connection_Number95(void); - extern int __stdcall IPX_Get_Local_Target95(unsigned char *, unsigned char*, unsigned short, unsigned char*); -} diff --git a/code/TIBERIANDAWN/IPXADDR.CPP b/code/TIBERIANDAWN/IPXADDR.CPP deleted file mode 100644 index 6953eb6..0000000 --- a/code/TIBERIANDAWN/IPXADDR.CPP +++ /dev/null @@ -1,491 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxaddr.cpv 2.17 16 Oct 1995 16:50:58 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXADDR.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : December 19, 1994 [BR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * IPXAddressClass::IPXAddressClass -- class constructor * - * IPXAddressClass::IPXAddressClass -- class constructor form 2 * - * IPXAddressClass::IPXAddressClass -- class constructor form 3 * - * IPXAddressClass::Set_Address -- sets the IPX address values * - * IPXAddressClass::Set_Address -- sets the IPX values from a header * - * IPXAddressClass::Get_Address -- retrieves the IPX address values * - * IPXAddressClass::Get_Address -- copies address into an IPX header * - * IPXAddressClass::Is_Broadcast -- tells if this is a broadcast address * - * IPXAddressClass::operator== -- overloaded comparison operator * - * IPXAddressClass::operator!= -- overloaded comparison operator * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "tcpip.h" - -/*************************************************************************** - * IPXAddressClass::IPXAddressClass -- class constructor * - * * - * This default constructor generates a broadcast address. * - * * - * INPUT: * - * net Network Number for this address * - * node Node Address for this address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -IPXAddressClass::IPXAddressClass(void) -{ - NetworkNumber[0] = 0xff; - NetworkNumber[1] = 0xff; - NetworkNumber[2] = 0xff; - NetworkNumber[3] = 0xff; - NodeAddress[0] = 0xff; - NodeAddress[1] = 0xff; - NodeAddress[2] = 0xff; - NodeAddress[3] = 0xff; - NodeAddress[4] = 0xff; - NodeAddress[5] = 0xff; - -} /* end of IPXAddressClass */ - - -/*************************************************************************** - * IPXAddressClass::IPXAddressClass -- class constructor form 2 * - * * - * INPUT: * - * net Network Number for this address * - * node Node Address for this address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -IPXAddressClass::IPXAddressClass(NetNumType net, NetNodeType node) -{ - memcpy(NetworkNumber,net,4); - memcpy(NodeAddress,node,6); - -} /* end of IPXAddressClass */ - - -/*************************************************************************** - * IPXAddressClass::IPXAddressClass -- class constructor form 3 * - * * - * This form of the constructor takes an IPX header as an argument. It * - * extracts the address from the Source address fields in the header. * - * * - * INPUT: * - * header Header from which to extract the address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -IPXAddressClass::IPXAddressClass(IPXHeaderType *header) -{ - memcpy(NetworkNumber,header->SourceNetworkNumber,4); - memcpy(NodeAddress,header->SourceNetworkNode,6); - -} /* end of IPXAddressClass */ - - -/*************************************************************************** - * IPXAddressClass::Set_Address -- sets the IPX address values * - * * - * INPUT: * - * net Network Number for this address * - * node Node Address for this address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -void IPXAddressClass::Set_Address(NetNumType net, NetNodeType node) -{ - memcpy(NetworkNumber,net,4); - memcpy(NodeAddress,node,6); - -} /* end of Set_Address */ - - -/*************************************************************************** - * IPXAddressClass::Set_Address -- sets the IPX values from a header * - * * - * This routine extracts the source addresses from the given IPX header. * - * * - * INPUT: * - * net Network Number for this address * - * node Node Address for this address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -void IPXAddressClass::Set_Address(IPXHeaderType *header) -{ - -#ifdef VIRTUAL_SUBNET_SERVER - if (Winsock.Get_Connected()){ - memset(NetworkNumber, 1 ,4); - memset(NodeAddress, 0, 6); - unsigned short target_mask = *(unsigned short*)header; - /* - ** If this is a head to head game (no VSS) -- - ** If mask is 0 then this packet was broadcast from the other player - ** Otherwise exclusive or with 3 to get other players mask - */ - if (!UseVirtualSubnetServer){ - if (target_mask == 0){ - target_mask = 1 << PlanetWestwoodIsHost; - } - target_mask ^= 3; - } - - *(unsigned short*) &NodeAddress[0] = target_mask; - - }else{ - memcpy(NetworkNumber,header->SourceNetworkNumber,4); - memcpy(NodeAddress,header->SourceNetworkNode,6); - } -#else //VIRTUAL_SUBNET_SERVER - if (header){ - memcpy(NetworkNumber,header->SourceNetworkNumber,4); - memcpy(NodeAddress,header->SourceNetworkNode,6); - }else{ - /* - ** Address is meaningless when using winsock - */ - memset(NetworkNumber, 1 ,4); - memset(NodeAddress, 1, 6); - } -#endif //VIRTUAL_SUBNET_SERVER -} /* end of Set_Address */ - - -/*************************************************************************** - * IPXAddressClass::Get_Address -- retrieves the IPX address values * - * * - * INPUT: * - * net Network Number for this address * - * node Node Address for this address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -void IPXAddressClass::Get_Address(NetNumType net, NetNodeType node) -{ - memcpy(net,NetworkNumber,4); - memcpy(node,NodeAddress,6); - -} /* end of Get_Address */ - - -/*************************************************************************** - * IPXAddressClass::Get_Address -- copies address into an IPX header * - * * - * INPUT: * - * net Network Number for this address * - * node Node Address for this address * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -void IPXAddressClass::Get_Address(IPXHeaderType *header) -{ - memcpy(header->DestNetworkNumber,NetworkNumber,4); - memcpy(header->DestNetworkNode,NodeAddress,6); - -} /* end of Get_Address */ - - -/*************************************************************************** - * IPXAddressClass::Is_Broadcast -- tells if this is a broadcast address * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -bool IPXAddressClass::Is_Broadcast(void) -{ - if ( NetworkNumber[0] == 0xff && - NetworkNumber[1] == 0xff && - NetworkNumber[2] == 0xff && - NetworkNumber[3] == 0xff && - NodeAddress[0] == 0xff && - NodeAddress[1] == 0xff && - NodeAddress[2] == 0xff && - NodeAddress[3] == 0xff && - NodeAddress[4] == 0xff && - NodeAddress[5] == 0xff) { - return(true); - } else { - return(false); - } -} - - -/*************************************************************************** - * IPXAddressClass::operator== -- overloaded comparison operator * - * * - * Since, if NETX isn't running, the network number on a received packet * - * can be bogus (all 0's), only the node address is used for comparison * - * purposes here. * - * * - * INPUT: * - * addr address to compare to * - * * - * OUTPUT: * - * 0 = not equal, 1 = equal * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -int IPXAddressClass::operator == (IPXAddressClass & addr) -{ - /*------------------------------------------------------------------------ - If either Network Number is all 0's (which can happen if the system is - not running NETX), compare only the Node Addresses. - ------------------------------------------------------------------------*/ - if ( (NetworkNumber[0]==0 && - NetworkNumber[1]==0 && - NetworkNumber[2]==0 && - NetworkNumber[3]==0) || - (addr.NetworkNumber[0]==0 && - addr.NetworkNumber[1]==0 && - addr.NetworkNumber[2]==0 && - addr.NetworkNumber[3]==0) ) { - - if (memcmp(NodeAddress,addr.NodeAddress,6)==0) { - return(true); - } else { - return(false); - } - - } else { - - /*------------------------------------------------------------------------ - Otherwise, compare both the Network Numbers and Node Addresses - ------------------------------------------------------------------------*/ - if (memcmp(NodeAddress,addr.NodeAddress,6)==0 && memcmp(NetworkNumber,addr.NetworkNumber,4)==0) { - return(true); - } else { - return(false); - } - } -} - - -/*************************************************************************** - * IPXAddressClass::operator!= -- overloaded comparison operator * - * * - * Since, if NETX isn't running, the network number on a received packet * - * can be bogus (all 0's), only the node address is used for comparison * - * purposes here. * - * * - * INPUT: * - * addr address to compare to * - * * - * OUTPUT: * - * 0 = equal, 1 = not equal * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -int IPXAddressClass::operator != (IPXAddressClass & addr) -{ - /*------------------------------------------------------------------------ - If either Network Number is all 0's (which can happen if the system is - not running NETX), compare only the Node Addresses. - ------------------------------------------------------------------------*/ - if ( (NetworkNumber[0]==0 && - NetworkNumber[1]==0 && - NetworkNumber[2]==0 && - NetworkNumber[3]==0) || - (addr.NetworkNumber[0]==0 && - addr.NetworkNumber[1]==0 && - addr.NetworkNumber[2]==0 && - addr.NetworkNumber[3]==0) ) { - - if (memcmp(NodeAddress,addr.NodeAddress,6)==0) { - return(false); - } else { - return(true); - } - } else { - - /*------------------------------------------------------------------------ - Otherwise, compare both the Network Numbers and Node Addresses - ------------------------------------------------------------------------*/ - if (memcmp(NodeAddress,addr.NodeAddress,6)==0 && memcmp(NetworkNumber,addr.NetworkNumber,4)==0) { - return(false); - } else { - return(true); - } - } -} - - -/*************************************************************************** - * IPXAddressClass::operator > -- overloaded comparison operator * - * * - * INPUT: * - * addr address to compare to * - * * - * OUTPUT: * - * TRUE = greater, FALSE = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -int IPXAddressClass::operator > (IPXAddressClass & addr) -{ - return(memcmp(this, &addr, 10) > 0); - -} /* end of operator != */ - - -/*************************************************************************** - * IPXAddressClass::operator < -- overloaded comparison operator * - * * - * INPUT: * - * addr address to compare to * - * * - * OUTPUT: * - * TRUE = less, FALSE = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -int IPXAddressClass::operator < (IPXAddressClass & addr) -{ - return(memcmp(this, &addr, 10) < 0); - -} /* end of operator != */ - - -/*************************************************************************** - * IPXAddressClass::operator >= -- overloaded comparison operator * - * * - * INPUT: * - * addr address to compare to * - * * - * OUTPUT: * - * TRUE = greater or equal, FALSE = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -int IPXAddressClass::operator >= (IPXAddressClass & addr) -{ - return(memcmp(this, &addr, 10) >= 0); - -} /* end of operator != */ - - -/*************************************************************************** - * IPXAddressClass::operator <= -- overloaded comparison operator * - * * - * INPUT: * - * addr address to compare to * - * * - * OUTPUT: * - * TRUE = less or equal, FALSE = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/19/1994 BR : Created. * - *=========================================================================*/ -int IPXAddressClass::operator <= (IPXAddressClass & addr) -{ - return(memcmp(this, &addr, 10) <= 0); - -} /* end of operator != */ - - diff --git a/code/TIBERIANDAWN/IPXADDR.H b/code/TIBERIANDAWN/IPXADDR.H deleted file mode 100644 index 92adcf6..0000000 --- a/code/TIBERIANDAWN/IPXADDR.H +++ /dev/null @@ -1,103 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxaddr.h_v 2.19 16 Oct 1995 16:44:54 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXADDR.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : December 19, 1994 [BR] * - * * - * This class is useful for any IPX-related code. It's just a utility * - * to help manage those annoying IPX address fields. This class lets you * - * compare addresses, copy addresses to & from the IPX header, etc. * - * * - * The class has no virtual functions, so you can treat this class just * - * like a data structure; it can be loaded & saved, and even transmitted * - * across the net. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef IPXADDR_H -#define IPXADDR_H - -#include "ipx.h" // for NetNumType & NetNodeType - - -/* -***************************** Class Declaration ***************************** -*/ -class IPXAddressClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Constructors: - .....................................................................*/ - IPXAddressClass(void); - IPXAddressClass(NetNumType net, NetNodeType node); - IPXAddressClass(IPXHeaderType *header); - - /*..................................................................... - Set the address from explicit variables, or from the SOURCE values - in an IPX packet header. - .....................................................................*/ - void Set_Address(NetNumType net, NetNodeType node); - void Set_Address(IPXHeaderType *header); - /*..................................................................... - Get the address values explicitly, or copy them into the DESTINATION - values in an IPX packet header. - .....................................................................*/ - void Get_Address (NetNumType net, NetNodeType node); - void Get_Address(IPXHeaderType *header); - - /*..................................................................... - Tells if this address is a broadcast address - .....................................................................*/ - bool Is_Broadcast(void); - - /*..................................................................... - Overloaded operators: - .....................................................................*/ - int operator == (IPXAddressClass & addr); - int operator != (IPXAddressClass & addr); - int operator > (IPXAddressClass &addr); - int operator < (IPXAddressClass &addr); - int operator >= (IPXAddressClass &addr); - int operator <= (IPXAddressClass &addr); - /* - -------------------------- Protected Interface --------------------------- - */ - protected: - /* - --------------------------- Private Interface ---------------------------- - */ - private: - NetNumType NetworkNumber; - NetNodeType NodeAddress; -}; - -#endif -/**************************** end of ipxaddr.h *****************************/ diff --git a/code/TIBERIANDAWN/IPXCONN.CPP b/code/TIBERIANDAWN/IPXCONN.CPP deleted file mode 100644 index 28dc6c4..0000000 --- a/code/TIBERIANDAWN/IPXCONN.CPP +++ /dev/null @@ -1,677 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxconn.cpv 1.9 16 Oct 1995 16:50:52 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXCONN.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 20, 1994 * - * * - * Last Update : April 9, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * IPXConnClass::IPXConnClass -- class constructor * - * IPXConnClass::~IPXConnClass -- class destructor * - * IPXConnClass::Init -- hardware-specific initialization routine * - * IPXConnClass::Configure -- One-time initialization routine * - * IPXConnClass::Start_Listening -- commands IPX to listen * - * IPXConnClass::Stop_Listening -- commands IPX to stop listen * - * IPXConnClass::Send -- sends a packet; invoked by SequencedConnection * - * IPXConnClass::Open_Socket -- opens communications socket * - * IPXConnClass::Close_Socket -- closes the socket * - * IPXConnClass::Send_To -- sends the packet to the given address * - * IPXConnClass::Broadcast -- broadcasts the given packet * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "ipx95.h" -#include "tcpip.h" - -/* -********************************* Globals *********************************** -*/ -unsigned short IPXConnClass::Socket; -int IPXConnClass::ConnectionNum; -ECBType * IPXConnClass::ListenECB; -IPXHeaderType * IPXConnClass::ListenHeader; -char * IPXConnClass::ListenBuf; -ECBType * IPXConnClass::SendECB; -IPXHeaderType * IPXConnClass::SendHeader; -char * IPXConnClass::SendBuf; -long IPXConnClass::Handler; -int IPXConnClass::Configured = 0; -int IPXConnClass::SocketOpen = 0; -int IPXConnClass::Listening = 0; -int IPXConnClass::PacketLen; - - -/*************************************************************************** - * IPXConnClass::IPXConnClass -- class constructor * - * * - * INPUT: * - * numsend desired # of entries for the send queue * - * numreceive desired # of entries for the recieve queue * - * maxlen max length of an application packet * - * magicnum the packet "magic number" for this connection * - * address address of destination (NULL = no address) * - * id connection's unique numerical ID * - * name connection's name * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -IPXConnClass::IPXConnClass (int numsend, int numreceive, int maxlen, - unsigned short magicnum, IPXAddressClass *address, int id, char *name) : -#ifdef SEQ_NET - SequencedConnClass (numsend, numreceive, maxlen, magicnum, -#else - NonSequencedConnClass (numsend, numreceive, maxlen, magicnum, -#endif - 2, // retry delta - -1, // max retries - 60) // timeout -{ - NetNumType net; - NetNodeType node; - - /*------------------------------------------------------------------------ - Save the values passed in - ------------------------------------------------------------------------*/ - if (address) - Address = (*address); - ID = id; - strcpy (Name, name); - - if (!Winsock.Get_Connected()){ - /*------------------------------------------------------------------------ - If our Address field is an actual address (ie NULL wasn't passed to the - constructor), pre-compute the ImmediateAddress value for the SendECB. - This allows pre-computing of the ImmediateAddress for all connections - created after Configure() is called. - ------------------------------------------------------------------------*/ - if (!Address.Is_Broadcast() && Configured==1) { - Address.Get_Address(net,node); - /*..................................................................... - If the user is logged in & has a valid Novell Connection Number, get the - bridge address the "official" way - .....................................................................*/ - if (ConnectionNum != 0) { - if (IPX_Get_Local_Target (net, node, Socket, ImmediateAddress)!=0) - memcpy(ImmediateAddress,node,6); - } else { - - /*..................................................................... - Otherwise, use the destination node address as the ImmediateAddress, and - just hope there's no network bridge in the path. - .....................................................................*/ - memcpy(ImmediateAddress,node,6); - } - - Immed_Set = 1; - } else { - memset (ImmediateAddress, 0, 6); - Immed_Set = 0; - } - } - -} /* end of IPXConnClass */ - - -/*************************************************************************** - * IPXConnClass::Init -- hardware-specific initialization routine * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -void IPXConnClass::Init (void) -{ - /*------------------------------------------------------------------------ - Invoke the parent's Init routine - ------------------------------------------------------------------------*/ -#ifdef SEQ_NET - SequencedConnClass::Init(); -#else - NonSequencedConnClass::Init(); -#endif -} - - -/*************************************************************************** - * IPXConnClass::Configure -- One-time initialization routine * - * * - * This routine sets up static members that are shared by all IPX * - * connections (ie those variables used by the Send/Listen/Broadcast * - * routines). * - * * - * INPUT: * - * socket socket ID for sending & receiving * - * conn_num local IPX Connection Number (0 = not logged in) * - * listen_ecb ptr to ECBType for listening * - * send_ecb ptr to ECBType for sending * - * listen_header ptr to IPXHeaderType for listening * - * send_header ptr to IPXHeaderType for sending * - * listen_buf ptr to buffer for listening * - * send_buf ptr to buffer for sending * - * handler_rm_ptr REAL-MODE pointer to event service routine * - * (high word = segment, low word = offset) * - * maxpacketlen max packet size to listen for * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * - All pointers must be protected-mode pointers, but must point to * - * DOS real-mode memory (except the Handler segment/offset) * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -void IPXConnClass::Configure (unsigned short socket, int conn_num, - ECBType *listen_ecb, ECBType *send_ecb, IPXHeaderType *listen_header, - IPXHeaderType *send_header, char *listen_buf, char *send_buf, - long handler_rm_ptr, int maxpacketlen) -{ - /*------------------------------------------------------------------------ - Save the values passed in - ------------------------------------------------------------------------*/ - Socket = socket; - ConnectionNum = conn_num; - ListenECB = listen_ecb; - SendECB = send_ecb; - ListenHeader = listen_header; - SendHeader = send_header; - ListenBuf = listen_buf; - SendBuf = send_buf; - Handler = handler_rm_ptr; - PacketLen = maxpacketlen; - - Configured = 1; - -} /* end of Configure */ - - -/*************************************************************************** - * IPXConnClass::Start_Listening -- commands IPX to listen * - * * - * This routine may be used to start listening in polled mode (if the * - * ECB's Event_Service_Routine is NULL), or in interrupt mode; it's * - * up to the caller to fill the ECB in. If in polled mode, Listening * - * must be restarted every time a packet comes in. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * - The ListenECB must have been properly filled in by the IPX Manager.* - * - Configure must be called before calling this routine. * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -bool IPXConnClass::Start_Listening(void) -{ - -#ifndef NOT_FOR_WIN95 - - if (Winsock.Get_Connected()) return (true); - - /*------------------------------------------------------------------------ - Open the Socket - ------------------------------------------------------------------------*/ - if (!Open_Socket(Socket)) - return(false); - - if (IPX_Start_Listening95()){ - Listening =1; - return (TRUE); - }else{ - return (FALSE); - } - -#else - - void *hdr_ptr; - unsigned long hdr_val; - void *buf_ptr; - unsigned long buf_val; - int rc; - - /*------------------------------------------------------------------------ - Don't do a thing unless we've been configured, and we're not listening. - ------------------------------------------------------------------------*/ - if (Configured==0 || Listening==1) - return(false); - - /*------------------------------------------------------------------------ - Open the Socket - ------------------------------------------------------------------------*/ - if (!Open_Socket(Socket)) - return(false); - - /*------------------------------------------------------------------------ - Clear the ECB & header - ------------------------------------------------------------------------*/ - memset(ListenECB, 0, sizeof(ECBType)); - memset(ListenHeader, 0, sizeof(IPXHeaderType)); - - /*------------------------------------------------------------------------ - Convert protected-mode ptrs to real-mode ptrs - ------------------------------------------------------------------------*/ - hdr_val = (unsigned long)ListenHeader; - hdr_ptr = (void *)(((hdr_val & 0xffff0) << 12) | (hdr_val & 0x000f)); - - buf_val = (unsigned long)ListenBuf; - buf_ptr = (void *)(((buf_val & 0xffff0) << 12) | (buf_val & 0x000f)); - - /*------------------------------------------------------------------------ - Fill in the ECB - ------------------------------------------------------------------------*/ - ListenECB->SocketNumber = Socket; - ListenECB->PacketCount = 2; - ListenECB->Packet[0].Address = hdr_ptr; - ListenECB->Packet[0].Length = sizeof(IPXHeaderType); - ListenECB->Packet[1].Address = buf_ptr; - ListenECB->Packet[1].Length = (unsigned short)PacketLen; - - ((long &)ListenECB->Event_Service_Routine) = Handler; - - /*------------------------------------------------------------------------ - Command IPX to listen - ------------------------------------------------------------------------*/ - rc = IPX_Listen_For_Packet(ListenECB); - if (rc!=0) { - Close_Socket(Socket); - return(false); - } else { - Listening = 1; - return(true); - } - -#endif //NOT_FOR_WIN95 -} /* end of Start_Listening */ - - -/*************************************************************************** - * IPXConnClass::Stop_Listening -- commands IPX to stop listen * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * - This routine MUST NOT be called if IPX is not listening already! * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -bool IPXConnClass::Stop_Listening(void) -{ - /*------------------------------------------------------------------------ - Don't do anything unless we're already Listening. - ------------------------------------------------------------------------*/ - if (Listening==0) - return(false); - -#ifndef NOT_FOR_WIN95 - - if (Winsock.Get_Connected()){ - Listening = 0; - return (true); - }else{ - IPX_Shut_Down95(); - Close_Socket(Socket); - } - -#else //NOT_FOR_WIN95 - - /*------------------------------------------------------------------------ - Shut IPX down. - ------------------------------------------------------------------------*/ - IPX_Cancel_Event(ListenECB); - Close_Socket(Socket); - -#endif //NOT_FOR_WIN95 - - Listening = 0; - - /*------------------------------------------------------------------------ - All done. - ------------------------------------------------------------------------*/ - return(true); - -} /* end of Stop_Listening */ - - -/*************************************************************************** - * IPXConnClass::Send -- sends a packet; invoked by SequencedConnection * - * * - * INPUT: * - * socket desired socket ID number * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -int IPXConnClass::Send(char *buf, int buflen) -{ - /*------------------------------------------------------------------------ - Invoke our own Send_To routine, filling in our Address as the destination. - ------------------------------------------------------------------------*/ - if (Immed_Set) { - return(Send_To (buf, buflen, &Address, ImmediateAddress)); - } else { - return(Send_To (buf, buflen, &Address, NULL)); - } - -} /* end of Send */ - - -/*************************************************************************** - * IPXConnClass::Open_Socket -- opens communications socket * - * * - * INPUT: * - * socket desired socket ID number * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -int IPXConnClass::Open_Socket(unsigned short socket) -{ - int rc; - - if (Winsock.Get_Connected()){ - SocketOpen = 1; - return (true); - } - - SocketOpen = 0; - - /*------------------------------------------------------------------------ - Try to open a listen socket. The socket may have been left open by - a previously-crashed program, so ignore the state of the SocketOpen - flag for this call; use IPX to determine if the socket was already open. - ------------------------------------------------------------------------*/ - rc = IPX_Open_Socket(socket); - if (rc) { - /* - ................. If already open, close & reopen it .................. - */ - if (rc==IPXERR_SOCKET_ERROR) { - IPX_Close_Socket(socket); - rc = IPX_Open_Socket(socket); - /* - .................. Still can't open: return error .................. - */ - if (rc) { - return(false); - } - } - } - - SocketOpen = 1; - - return(true); -} - - -/*************************************************************************** - * IPXConnClass::Close_Socket -- closes the socket * - * * - * INPUT: * - * socket desired socket ID number * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * Calling this routine when the sockets aren't open may crash! * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -void IPXConnClass::Close_Socket(unsigned short socket) -{ - if (Winsock.Get_Connected()){ - SocketOpen = 0; - return; - } - /*------------------------------------------------------------------------ - Never, ever, ever, under any circumstances whatsoever, close a socket - that isn't open. You'll regret it forever (or until at least until you're - through rebooting, which, if you're on a Pentium is the same thing). - ------------------------------------------------------------------------*/ - if (SocketOpen==1) - IPX_Close_Socket(socket); - - SocketOpen = 0; - -} /* end of Close_Socket */ - - -/*************************************************************************** - * IPXConnClass::Send_To -- sends the packet to the given address * - * * - * The "ImmediateAddress" field of the SendECB must be filled in with the * - * address of a bridge, or the node address of the destination if there * - * is no bridge. The NETX call to find this address will always crash * - * if NETX isn't loaded (ConnectionNum is 0), so this case is trapped & * - * prevented. * - * Also, if the address of this IPX connection is known when the * - * constructor is called, and Configure has been called, Get_Local_Target * - * is called to precompute the ImmediateAddress; this case is detected & * - * if the value is already computed, it's just memcpy'd over. * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buffer * - * address Address to send to * - * immed ImmediateAddress value, NULL if none * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -//#pragma off (unreferenced) -int IPXConnClass::Send_To(char *buf, int buflen, IPXAddressClass *address, - NetNodeType immed) -{ - - //void *hdr_ptr; - //void *buf_ptr; - //unsigned long hdr_val; - //unsigned long buf_val; - NetNumType net; - NetNodeType node; - int rc; - - //unsigned short target_mask; - - unsigned char send_address[6]; - - if (Winsock.Get_Connected()){ - -#ifdef VIRTUAL_SUBNET_SERVER - if (immed){ - memcpy(send_address, immed, 6); - }else{ - address->Get_Address(net,node); - memcpy (send_address, node, 6); - } - /* - ** Use first two bytes of ipx address as target mask - */ - unsigned short *maskptr = (unsigned short*)&send_address[0]; - target_mask = *maskptr; - - char *tempsend = new char [buflen + sizeof (target_mask)]; - - *(unsigned short*)tempsend = htons(target_mask); - memcpy (tempsend+2, buf, buflen); -#if (0) -char tempbuf[256]; -CommHeaderType *packet = (CommHeaderType *)(&tempsend[2]); -static char pcode [4][18]={ - "PACKET_DATA_ACK", // this is a data packet requiring an ACK - "PACKET_DATA_NOACK", // this is a data packet not requiring an ACK - "PACKET_ACK", // this is an ACK for a packet - "PACKET_COUNT" // for computational purposes -}; - -sprintf (tempbuf, "Sending unicast packet type %d, ID=%d, code=%s, length=%d\n", tempsend[sizeof(CommHeaderType)+2], - packet->PacketID, - pcode[packet->Code], - buflen + sizeof (target_mask)); -CCDebugString (tempbuf); -#endif //(0) - - Winsock.Write((void*)tempsend, buflen + sizeof (target_mask)); - delete [] tempsend; -#else // VIRTUAL_SUBNET_SERVER - Winsock.Write((void*)buf, buflen); -#endif // VIRTUAL_SUBNET_SERVER - - return (true); - } - - - - if (immed) { - memcpy(send_address, immed, 6); - //memcpy(node, immed, 6); - //memset (net, 0, sizeof(net) ); - address->Get_Address(net,node); - } else { - address->Get_Address(net,node); - /*..................................................................... - If the user is logged in & has a valid Novell Connection Number, get the - bridge address the "official" way - .....................................................................*/ - if (ConnectionNum != 0) { - rc = IPX_Get_Local_Target (net, node, Socket, &send_address[0]); - if (rc!=0) { - return(false); - } - } else { - /*..................................................................... - Otherwise, use the destination node address as the ImmediateAddress, and - just hope there's no network bridge in the path. - .....................................................................*/ - memcpy(send_address,node,6); - } - } - - return (IPX_Send_Packet95(&send_address[0], (unsigned char*)buf, buflen, (unsigned char*)net, (unsigned char*)node)); - - -} -//#pragma on (unreferenced) - -/*************************************************************************** - * IPXConnClass::Broadcast -- broadcasts the given packet * - * * - * INPUT: * - * socket desired socket ID number * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/16/1994 BR : Created. * - *=========================================================================*/ -int IPXConnClass::Broadcast(char *buf, int buflen) -{ - - if (Winsock.Get_Connected()){ -#ifdef VIRTUAL_SUBNET_SERVER - char *tempsend = new char [buflen + sizeof (unsigned short)]; - memcpy (tempsend+2, buf, buflen); - *tempsend = 0; - *(tempsend+1) = 0; -#if (0) -char tempbuf[256]; -CommHeaderType *packet = (CommHeaderType *)(&tempsend[2]); -static char pcode [4][18]={ - "PACKET_DATA_ACK", // this is a data packet requiring an ACK - "PACKET_DATA_NOACK", // this is a data packet not requiring an ACK - "PACKET_ACK", // this is an ACK for a packet - "PACKET_COUNT" // for computational purposes -}; - -sprintf (tempbuf, "Sending multicast packet type %d, ID=%d, code=%s, length=%d\n", tempsend[sizeof(CommHeaderType)+2], - packet->PacketID, - pcode[packet->Code], - buflen + sizeof (unsigned short)); -CCDebugString (tempbuf); -#endif //(0) - - Winsock.Write((void*)tempsend, buflen + sizeof (unsigned short)); - delete [] tempsend; -#else // VIRTUAL_SUBNET_SERVER - Winsock.Write((void*)buf, buflen); -#endif // VIRTUAL_SUBNET_SERVER - return(true); - }else{ - return (IPX_Broadcast_Packet95((unsigned char*)buf, buflen)); - } - -} - diff --git a/code/TIBERIANDAWN/IPXCONN.H b/code/TIBERIANDAWN/IPXCONN.H deleted file mode 100644 index e929aec..0000000 --- a/code/TIBERIANDAWN/IPXCONN.H +++ /dev/null @@ -1,208 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxconn.h_v 1.12 16 Oct 1995 16:45:10 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXCONN.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 9, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This is the Connection Class for IPX communications. It inherits * - * a Queue, PacketBuf, timeout variables from ConnectionClass. It * - * inherits its Send_/Receive_/Get_Packet functions, and the sequenced * - * ACK/Retry logic in Service_Send_Queue & Service_Recieve_Queue from * - * SequencedConnClass. It guarantees order of delivery of packets. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef IPXCONN_H -#define IPXCONN_H - - -/* -********************************* Includes ********************************** -*/ -#ifdef SEQ_NET -#include "seqconn.h" -#else -#include "noseqcon.h" -#endif -#include "ipxaddr.h" - - -/* -***************************** Class Declaration ***************************** -*/ -#ifdef SEQ_NET -class IPXConnClass : public SequencedConnClass -#else -class IPXConnClass : public NonSequencedConnClass -#endif -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Various useful enums: - .....................................................................*/ - enum IPXConnTag { - CONN_NAME_MAX = 40, // max # chars allowed for connection name - CONNECTION_NONE = -1, // value of an invalid connection ID - }; - - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - IPXConnClass(int numsend, int numrecieve, int maxlen, - unsigned short magicnum, IPXAddressClass *address, int id, char *name); - virtual ~IPXConnClass () {}; - - /*..................................................................... - Initialization. - .....................................................................*/ - virtual void Init (void); - - /*..................................................................... - The Configure function is for configuring all connections at once. - It's static because it doesn't apply to any specific connection, but - all of them. - .....................................................................*/ - static void Configure(unsigned short socket, - int conn_num, ECBType *listen_ecb, ECBType *send_ecb, - IPXHeaderType *listen_header, IPXHeaderType *send_header, - char *listen_buf, char *send_buf, long handler_rm_ptr, - int maxpacketlen); - - /*..................................................................... - These routines tell IPX to start listening for packets, and to stop - listening for packets. They're static because they affect all - connections at once (there's no way to turn listening on for only one - connection; it's all or nothing). - .....................................................................*/ - static bool Start_Listening (void); - static bool Stop_Listening (void); - - /*..................................................................... - The Destination IPX Address for this connection - .....................................................................*/ - IPXAddressClass Address; - - /*..................................................................... - The "Immediate" (Bridge) address for this connection, and a flag - telling if the address has been precomputed. - .....................................................................*/ - NetNodeType ImmediateAddress; - int Immed_Set; - - /*..................................................................... - Each IPX Connection can have a Name & Unique numerical ID - .....................................................................*/ - int ID; - char Name[CONN_NAME_MAX]; - - /* - -------------------------- Protected Interface --------------------------- - */ - protected: - - /*..................................................................... - This is the overloaded Send routine declared in ConnectionClass, and - used in SequencedConnClass. - .....................................................................*/ - virtual int Send (char *buf, int buflen); - - /*..................................................................... - These are the routines that access IPX. Open_Socket & Close_Socket are - static because they're called by Start_Listening & Stop_Listening. - Send_To & Broadcast are static since they're direct interfaces to IPX, - and there's only one IPX instance running. - .....................................................................*/ - static int Open_Socket(unsigned short socket); - static void Close_Socket(unsigned short socket); - static int Send_To(char *buf, int buflen, IPXAddressClass *address, NetNodeType immed); - static int Broadcast(char *buf, int buflen); - - /*..................................................................... - The socket ID for this connection - .....................................................................*/ - static unsigned short Socket; - - /*..................................................................... - User's local Connection # (0 = not logged in) - .....................................................................*/ - static int ConnectionNum; - - /*..................................................................... - This is a static version of MaxPacketLen, which is the size of the - app's packets, plus our internal CommHeaderType. It's used in the - Start_Listening routine. - .....................................................................*/ - static int PacketLen; - - /*..................................................................... - Variables for Listening (created by the IPXManagerClass, and passed - in via Init). All IPX connections share these buffers. - .....................................................................*/ - static ECBType *ListenECB; - static IPXHeaderType *ListenHeader; - static char *ListenBuf; - - /*..................................................................... - Variables for Sending (created by the IPXManagerClass, and passed - in via Init). All IPX connections share these buffers. - .....................................................................*/ - static ECBType *SendECB; - static IPXHeaderType *SendHeader; - static char *SendBuf; - - /*..................................................................... - This is a REAL-MODE pointer to the event-service-routine for IPX. - If it's 0, IPX will operate in polled mode. Otherwise, the high word - must contain the segment, and the low word must contain the offset. - CS will be the high word value when the routine is called. (Requiring - the segment/offset to be computed by the caller gives the caller - control over CS.) - .....................................................................*/ - static long Handler; - - /*..................................................................... - This status flag tells us if Configure() has been called or not. - .....................................................................*/ - static int Configured; - - /*..................................................................... - This status flag tells us if the socket has been opened or not. - .....................................................................*/ - static int SocketOpen; - - /*..................................................................... - This status flag tells us if Start_Listening() has been called or not. - .....................................................................*/ - static int Listening; -}; - -#endif diff --git a/code/TIBERIANDAWN/IPXGCONN.CPP b/code/TIBERIANDAWN/IPXGCONN.CPP deleted file mode 100644 index 8d4ac8d..0000000 --- a/code/TIBERIANDAWN/IPXGCONN.CPP +++ /dev/null @@ -1,470 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxgconn.cpv 1.9 16 Oct 1995 16:51:00 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXGCONN.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 20, 1994 * - * * - * Last Update : July 6, 1995 [BRR] * - *-------------------------------------------------------------------------* - * Functions: * - * IPXGlobalConnClass::IPXGlobalConnClass -- class constructor * - * IPXGlobalConnClass::~IPXGlobalConnClass -- class destructor * - * IPXGlobalConnClass::Send_Packet -- adds a packet to the send queue * - * IPXGlobalConnClass::Receive_Packet -- adds packet to the receive queue* - * IPXGlobalConnClass::Get_Packet -- gets a packet from the receive queue* - * IPXGlobalConnClass::Send -- sends a packet * - * IPXGlobalConnClass::Service_Receive_Queue -- services recieve queue * - * IPXGlobalConnClass::Set_Bridge -- Sets up connection to cross a bridge* -* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * IPXGlobalConnClass::IPXGlobalConnClass -- class constructor * - * * - * This routine chains to the parent constructor, but it adjusts the size * - * of the packet by the added bytes in the GlobalHeaderType structure. * - * This forces the parent classes to allocate the proper sized PacketBuf * - * for outgoing packets, and to set MaxPacketLen to the proper value. * - * * - * INPUT: * - * numsend desired # of entries for the send queue * - * numreceive desired # of entries for the recieve queue * - * maxlen max length of an application packet * - * product_id unique ID for this product * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -IPXGlobalConnClass::IPXGlobalConnClass (int numsend, int numreceive, int maxlen, - unsigned short product_id) : - IPXConnClass (numsend, numreceive, - maxlen + sizeof(GlobalHeaderType) - sizeof(CommHeaderType), - GLOBAL_MAGICNUM, // magic number for this connection - NULL, // IPX Address (none) - 0, // Connection ID - "") // Connection Name -{ - ProductID = product_id; - IsBridge = 0; - -} /* end of IPXGlobalConnClass */ - - -/*************************************************************************** - * IPXGlobalConnClass::Send_Packet -- adds a packet to the send queue * - * * - * This routine prefixes the given buffer with a GlobalHeaderType and * - * queues the resulting packet into the Send Queue. The packet's * - * MagicNumber, Code, PacketID, destination Address and ProductID are set * - * here. * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buffer * - * address address to send the packet to (NULL = Broadcast) * - * ack_req true = ACK is required for this packet; false = isn't * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXGlobalConnClass::Send_Packet (void * buf, int buflen, - IPXAddressClass *address, int ack_req) -{ - /*------------------------------------------------------------------------ - Store the packet's Magic Number - ------------------------------------------------------------------------*/ - ((GlobalHeaderType *)PacketBuf)->Header.MagicNumber = MagicNum; - - /*------------------------------------------------------------------------ - If this is a ACK-required packet, sent to a specific system, mark it as - ACK-required; otherwise, mark as no-ACK-required. - ------------------------------------------------------------------------*/ - if (ack_req && address != NULL) { - ((GlobalHeaderType *)PacketBuf)->Header.Code = PACKET_DATA_ACK; - } else { - ((GlobalHeaderType *)PacketBuf)->Header.Code = PACKET_DATA_NOACK; - } - - /*------------------------------------------------------------------------ - Fill in the packet ID. This will have very limited meaning; it only - allows us to determine if an ACK packet we receive later goes with this - packet; it doesn't let us detect re-sends of other systems' packets. - ------------------------------------------------------------------------*/ - ((GlobalHeaderType *)PacketBuf)->Header.PacketID = Queue->Send_Total(); - - /*------------------------------------------------------------------------ - Set the product ID for this packet. - ------------------------------------------------------------------------*/ - ((GlobalHeaderType *)PacketBuf)->ProductID = ProductID; - - /*------------------------------------------------------------------------ - Set this packet's destination address. If no address is specified, use - a Broadcast address (which IPXAddressClass's default constructor creates). - ------------------------------------------------------------------------*/ - if (address != NULL) { - ((GlobalHeaderType *)PacketBuf)->Address = (*address); - } else { - ((GlobalHeaderType *)PacketBuf)->Address = IPXAddressClass(); - } - - /*------------------------------------------------------------------------ - Copy the application's data - ------------------------------------------------------------------------*/ - memcpy(PacketBuf + sizeof(GlobalHeaderType), buf, buflen); - - /*------------------------------------------------------------------------ - Queue it - ------------------------------------------------------------------------*/ - return(Queue->Queue_Send(PacketBuf,buflen + sizeof(GlobalHeaderType))); - -} /* end of Send_Packet */ - - -/*************************************************************************** - * IPXGlobalConnClass::Receive_Packet -- adds packet to the receive queue * - * * - * INPUT: * - * buf buffer to process (already includes GlobalHeaderType) * - * buflen length of buffer to process * - * address the address of the sender (the IPX Manager class must * - * extract this from the IPX Header of the received packet.) * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXGlobalConnClass::Receive_Packet (void * buf, int buflen, - IPXAddressClass *address) -{ - GlobalHeaderType *packet; // ptr to this packet - SendQueueType *send_entry; // ptr to send entry header - GlobalHeaderType *entry_data; // ptr to queue entry data - int i; - - /* - --------------------------- Check the magic # ---------------------------- - */ - packet = (GlobalHeaderType *)buf; - if (packet->Header.MagicNumber!=MagicNum) { - return(false); - } - - /*------------------------------------------------------------------------ - Process the packet based on its Code - ------------------------------------------------------------------------*/ - switch (packet->Header.Code) { - /*..................................................................... - DATA: Save the given address in the message buffer (so Get_Message() - can extract it later), and queue this message. - Don't bother checking for a Re-Send; since this queue is receiving data - from multiple systems, the Total_Receive() value for this queue will - have nothing to do with the packet's ID. The application must deal - with this by being able to handle multiple receipts of the same packet. - .....................................................................*/ - case PACKET_DATA_ACK: - case PACKET_DATA_NOACK: - packet->Address = (*address); - Queue->Queue_Receive (buf, buflen); - break; - - /*..................................................................... - ACK: If this ACK is for any of my packets, mark that packet as - acknowledged, then throw this packet away. Otherwise, ignore the ACK - (if we re-sent before we received the other system's first ACK, this - ACK will be a leftover) - .....................................................................*/ - case PACKET_ACK: - for (i = 0; i < Queue->Num_Send(); i++) { - /* - ..................... Get queue entry ptr ....................... - */ - send_entry = Queue->Get_Send(i); - /* - ............. If ptr is valid, get ptr to its data .............. - */ - entry_data = (GlobalHeaderType *)(send_entry->Buffer); - /* - .............. If ACK is for this entry, mark it ................ - */ - if (packet->Header.PacketID==entry_data->Header.PacketID && - entry_data->Header.Code == PACKET_DATA_ACK) { - send_entry->IsACK = 1; - break; - } - } - break; - - /*..................................................................... - Default: ignore the packet - .....................................................................*/ - default: - break; - - } /* end of switch */ - - return(true); -} - - -/*************************************************************************** - * IPXGlobalConnClass::Get_Packet -- gets a packet from the receive queue * - * * - * INPUT: * - * buf location to store buffer * - * buflen filled in with length of 'buf' * - * address filled in with sender's address * - * product_id filled in with sender's ProductID * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXGlobalConnClass::Get_Packet (void * buf, int *buflen, - IPXAddressClass *address, unsigned short *product_id) -{ - ReceiveQueueType *rec_entry; // ptr to receive entry header - GlobalHeaderType *packet; - int packetlen; // size of received packet - - /* - ------------------------ Return if nothing to do ------------------------- - */ - if (Queue->Num_Receive() == 0) { - return(false); - } - - /* - ------------------ Get ptr to the next available entry ------------------- - */ - rec_entry = Queue->Get_Receive(0); - - /* - ------------------------ Read it if it's un-read ------------------------- - */ - if (rec_entry!=NULL && rec_entry->IsRead==0) { - /* - ........................... Mark as read .............................. - */ - rec_entry->IsRead = 1; - - /* - .......................... Copy data packet ........................... - */ - packet = (GlobalHeaderType *)(rec_entry->Buffer); - packetlen = rec_entry->BufLen - sizeof(GlobalHeaderType); - if (packetlen > 0) - memcpy(buf, rec_entry->Buffer + sizeof(GlobalHeaderType), packetlen); - (*buflen) = packetlen; - (*address) = packet->Address; - (*product_id) = packet->ProductID; - - return(true); - } - - return(false); -} - - -/*************************************************************************** - * IPXGlobalConnClass::Send -- sends a packet * - * * - * This routine gets invoked by NonSequencedConn, when it's processing * - * the Send & Receive Queues. The buffer provided will already have the * - * GlobalHeaderType header embedded in it. * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buffer * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXGlobalConnClass::Send(char *buf, int buflen) -{ - IPXAddressClass *addr; - int rc; - - /*------------------------------------------------------------------------ - Extract the packet's embedded IPX address - ------------------------------------------------------------------------*/ - addr = &(((GlobalHeaderType *)buf)->Address); - - /*------------------------------------------------------------------------ - If it's a broadcast address, broadcast it - ------------------------------------------------------------------------*/ - if (addr->Is_Broadcast()) { - return(Broadcast (buf, buflen)); - } else { - /*------------------------------------------------------------------------ - Otherwise, send it - ------------------------------------------------------------------------*/ - if (IsBridge && !memcmp (addr, BridgeNet, 4)) { - rc = Send_To (buf, buflen, &(((GlobalHeaderType *)buf)->Address), - BridgeNode); - } else { - rc = Send_To (buf, buflen, &(((GlobalHeaderType *)buf)->Address), NULL); - } - return (rc); - } - -} /* end of Send */ - - -/*************************************************************************** - * IPXGlobalConnClass::Service_Receive_Queue -- services the recieve queue * - * * - * This routine is necessary because the Global Connection has to ACK * - * a packet differently from other types of connections; its Send routine * - * assumes that the destination address is embedded within the outgoing * - * packet, so we have to create our ACK Packet using the GlobalHeaderType, * - * not the CommHeaderType. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXGlobalConnClass::Service_Receive_Queue (void) -{ - GlobalHeaderType ackpacket; // ACK packet to send - ReceiveQueueType *rec_entry; // ptr to receive entry header - GlobalHeaderType *packet_hdr; // packet header - - /*------------------------------------------------------------------------ - Get a pointer to the next received entry - ------------------------------------------------------------------------*/ - rec_entry = Queue->Get_Receive(0); - if (rec_entry==NULL) - return(1); - - /*------------------------------------------------------------------------ - If this packet doesn't require an ACK, mark it as ACK'd. - ------------------------------------------------------------------------*/ - packet_hdr = (GlobalHeaderType *)(rec_entry->Buffer); - if (packet_hdr->Header.Code==PACKET_DATA_NOACK) - rec_entry->IsACK = 1; - - /*------------------------------------------------------------------------ - If this packet hasn't been ACK'd, send an ACK: - - Fill in the MagicNum & the Code - - Set the PacketID to the same ID that the sending system used, so the - sending system knows which packet the ACK is for - ------------------------------------------------------------------------*/ - if (rec_entry->IsACK==0) { - ackpacket.Header.MagicNumber = MagicNum; - ackpacket.Header.Code = PACKET_ACK; - ackpacket.Header.PacketID = packet_hdr->Header.PacketID; - ackpacket.Address = packet_hdr->Address; - ackpacket.ProductID = ProductID; - - Send ((char *)&ackpacket, sizeof(GlobalHeaderType)); - - rec_entry->IsACK = 1; - } - - /*------------------------------------------------------------------------ - If this packet has been read by the application, and has been ACK'd, and - there is another packet in the queue behind this one, it means the other - system got the ACK we sent for this packet; remove this packet from the - queue. - ------------------------------------------------------------------------*/ - if (rec_entry!=NULL && rec_entry->IsRead && rec_entry->IsACK && - Queue->Num_Receive() > 1) - Queue->UnQueue_Receive(NULL,NULL,0); - - return(1); - -} /* end of Service_Receive_Queue */ - -/*************************************************************************** - * Set_Bridge -- Sets up connection to cross a bridge * - * * - * This routine is designed to prevent the connection from having to * - * call Get_Local_Target, except the minimum number of times, since that * - * routine is buggy & goes away for long periods sometimes. * - * * - * INPUT: * - * bridge network number of the destination bridge * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 07/06/1995 BRR : Created. * - *=========================================================================*/ -void IPXGlobalConnClass::Set_Bridge(NetNumType bridge) -{ - if (Configured) { - memcpy (BridgeNet, bridge, 4); - memset (BridgeNode, 0xff, 6); - - if (IPX_Get_Local_Target (BridgeNet, BridgeNode, Socket, BridgeNode)==0) { - IsBridge = 1; - } else { - IsBridge = 0; - } - } -} - diff --git a/code/TIBERIANDAWN/IPXGCONN.H b/code/TIBERIANDAWN/IPXGCONN.H deleted file mode 100644 index 527d6e6..0000000 --- a/code/TIBERIANDAWN/IPXGCONN.H +++ /dev/null @@ -1,158 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxgconn.h_v 1.10 16 Oct 1995 16:47:30 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXGCONN.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 11, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This class is a special type of IPX Connection. It can talk to more * - * than one system at a time. It can Broadcast packets to all systems, * - * or send a packet to one individual system. The packets it sends to * - * individual systems can be DATA_NOACK or DATA_ACK packets, but the * - * packets broadcast have to be DATA_NOACK packets. This class is for * - * only the crudest "Who-are-you" type of network communications. Once * - * the IPX Address of another system is identified, a "real" IPX * - * Connection should be created, & further communications done through it. * - * * - * This means that the packet ID field no longer can be used to detect * - * resends, since the receive queue may recieve a lot more packets than * - * we send out. So, re-sends cannot be detected; the application must be * - * designed so that it can handle multiple copies of the same packet. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef IPXGLOBALCONN_H -#define IPXGLOBALCONN_H - - -#include "ipxconn.h" - - -/* -********************************** Defines ********************************** -*/ -/*--------------------------------------------------------------------------- -This is the header for Global Connection messages. It includes the usual -"standard" header that the other connections do; but it also includes an -IPX address field, so the application can get the address of the sender -of this message. This address field must be provided in by the IXP -Connection Manager class, when it calls this class's Receive_Packet function. ----------------------------------------------------------------------------*/ -typedef struct { - CommHeaderType Header; - IPXAddressClass Address; - unsigned short ProductID; -} GlobalHeaderType; - - -/* -***************************** Class Declaration ***************************** -*/ -class IPXGlobalConnClass : public IPXConnClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Here are some useful enums: - .....................................................................*/ - enum GlobalConnectionEnum { - /*.................................................................. - This is the magic number for all Global Connections. Having the - same magic number across products lets us ID different products - on the net. - ..................................................................*/ - GLOBAL_MAGICNUM = 0x1234, - /*.................................................................. - These are the values used for the ProductID field in the Global - Message structure. It also should be the Magic Number used for the - private connections within that product. - This list should be continually updated & kept current. Never ever - ever use an old product ID for your product! - ..................................................................*/ - COMMAND_AND_CONQUER = 0xaa01, - }; - - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - IPXGlobalConnClass (int numsend, int numrecieve, int maxlen, - unsigned short product_id); - virtual ~IPXGlobalConnClass () {}; - - /*..................................................................... - Send/Receive routines. - .....................................................................*/ - virtual int Send_Packet (void * buf, int buflen, - IPXAddressClass *address, int ack_req); - virtual int Receive_Packet (void * buf, int buflen, - IPXAddressClass *address); - virtual int Get_Packet (void * buf, int *buflen, - IPXAddressClass *address, unsigned short *product_id); - - /*..................................................................... - This is for telling the connection it can cross a bridge. - .....................................................................*/ - void Set_Bridge (NetNumType bridge); - - /*..................................................................... - The Product ID for this product. - .....................................................................*/ - unsigned short ProductID; - - /*..................................................................... - This describes the address of a bridge we have to cross. This class - supports crossing only one bridge. Storing the bridge's network number - allows us to obtain its local target address only once, then re-use it. - .....................................................................*/ - NetNumType BridgeNet; - NetNodeType BridgeNode; - int IsBridge; - - /* - -------------------------- Protected Interface --------------------------- - */ - protected: - - /*..................................................................... - This is the overloaded Send routine declared in ConnectionClass, and - used in SequencedConnClass. This special version sends to the address - embedded within the GlobalHeaderType. - .....................................................................*/ - virtual int Send (char *buf, int buflen); - - /*..................................................................... - This routine is overloaded from SequencedConnClass, because the - Global Connection needs to ACK its packets differently from the - other connections. - .....................................................................*/ - virtual int Service_Receive_Queue (void); -}; - -#endif diff --git a/code/TIBERIANDAWN/IPXMGR.CPP b/code/TIBERIANDAWN/IPXMGR.CPP deleted file mode 100644 index f3b5f48..0000000 --- a/code/TIBERIANDAWN/IPXMGR.CPP +++ /dev/null @@ -1,1969 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxmgr.cpv 1.9 16 Oct 1995 16:48:22 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXMGR.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 20, 1994 * - * * - * Last Update : May 4, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * IPXManagerClass::IPXManagerClass -- class constructor * - * IPXManagerClass::~IPXManagerClass -- class destructor * - * IPXManagerClass::Init -- initialization routine * - * IPXManagerClass::Is_IPX -- tells if IPX is installed or not * - * IPXManagerClass::Set_Timing -- sets timing for all connections * - * IPXManagerClass::Create_Connection -- creates a new connection * - * IPXManagerClass::Delete_Connection -- deletes a connection * - * IPXManagerClass::Num_Connections -- gets the # of connections * - * IPXManagerClass::Connection_ID -- gets the given connection's ID * - * IPXManagerClass::Connection_Name -- gets name for given connection * - * IPXManagerClass::Connection_Address -- retrieves connection's address * - * IPXManagerClass::Connection_Index -- gets given connection's index * - * IPXManagerClass::Send_Global_Message -- sends a Global Message * - * IPXManagerClass::Get_Global_Message -- polls the Global Message queue * - * IPXManagerClass::Send_Private_Message -- Sends a Private Message * - * IPXManagerClass::Get_Private_Message -- Polls Private Message queue * - * IPXManagerClass::Service -- main polling routine for IPX Connections * - * IPXManagerClass::Get_Bad_Connection -- returns bad connection ID * - * IPXManagerClass::Global_Num_Send -- gets # entries in send queue * - * IPXManagerClass::Global_Num_Receive -- gets # entries in recv queue * - * IPXManagerClass::Private_Num_Send -- gets # entries in send queue * - * IPXManagerClass::Private_Num_Receive -- gets # entries in recv queue * - * IPXManagerClass::Set_Bridge -- prepares to cross a bridge * - * IPXManagerClass::Set_Socket -- sets socket ID for all connections * - * IPXManagerClass::Response_Time -- Returns largest Avg Response Time * - * IPXManagerClass::Global_Response_Time -- Returns Avg Response Time * - * IPXManagerClass::Reset_Response_Time -- Reset response time * - * IPXManagerClass::Oldest_Send -- gets ptr to oldest send buf * - * IPXManagerClass::Mono_Debug_Print -- debug output routine * - * IPXManagerClass::Alloc_RealMode_Mem -- allocates real-mode memory * - * IPXManagerClass::Free_RealMode_Mem -- frees real-mode memory * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "ipx95.h" -#include "tcpip.h" - -/*************************************************************************** - * IPXManagerClass::IPXManagerClass -- class constructor * - * * - * INPUT: * - * glb_maxlen Global Channel maximum packet length * - * pvt_maxlen Private Channel maximum packet length * - * socket socket ID to use * - * product_id a unique numerical ID for this product * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * The socket number is byte-swapped, since IPX requires socket ID's * - * to be stored high/low. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -IPXManagerClass::IPXManagerClass (int glb_maxlen, int pvt_maxlen, - int glb_num_packets, int pvt_num_packets, unsigned short socket, - unsigned short product_id) -{ - int i; - - /*------------------------------------------------------------------------ - Initialize data members - ------------------------------------------------------------------------*/ - /*........................................................................ - IPXStatus = 1 if IPX is installed, 0 if not - ........................................................................*/ - if (IPX_SPX_Installed()==0) { - IPXStatus = 0; - } else { - IPXStatus = 1; - } - - /*........................................................................ - Set listening state flag to off - ........................................................................*/ - Listening = 0; - - /*........................................................................ - No memory has been alloc'd yet - ........................................................................*/ - RealMemAllocd = 0; - - /*........................................................................ - Set max packet sizes, for allocating real-mode memory - ........................................................................*/ - Glb_MaxPacketLen = glb_maxlen; - Glb_NumPackets = glb_num_packets; - Pvt_MaxPacketLen = pvt_maxlen; - Pvt_NumPackets = pvt_num_packets; - - /*........................................................................ - Save the app's product ID - ........................................................................*/ - ProductID = product_id; - - /*........................................................................ - Save our socket ID number - ........................................................................*/ - Socket = (unsigned short)( (((unsigned long)socket & 0x00ff) << 8) | - (((unsigned long)socket & 0xff00) >> 8)); - - /*........................................................................ - Get the user's IPX local connection number - ........................................................................*/ - if (IPXStatus) { - ConnectionNum = IPX_Get_Connection_Number(); - } else { - ConnectionNum = 0; - } - - /*........................................................................ - Init connection states - ........................................................................*/ - NumConnections = 0; - CurConnection = 0; - for (i = 0; i < CONNECT_MAX; i++) - Connection[i] = 0; - GlobalChannel = 0; - - SendOverflows = 0; - ReceiveOverflows = 0; - BadConnection = IPXConnClass::CONNECTION_NONE; - - /*........................................................................ - Init timing parameters - ........................................................................*/ - RetryDelta = 2; // 2 ticks between retries - MaxRetries = -1; // disregard # retries - Timeout = 60; // report bad connection after 1 second - -} /* end of IPXManagerClass */ - - -/*************************************************************************** - * IPXManagerClass::~IPXManagerClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -IPXManagerClass::~IPXManagerClass() -{ - int i; - - /*------------------------------------------------------------------------ - Stop all IPX events - ------------------------------------------------------------------------*/ - if (Listening) { - IPXConnClass::Stop_Listening(); - Listening = 0; - } - - /*------------------------------------------------------------------------ - Free all protected-mode memory - ------------------------------------------------------------------------*/ - if (GlobalChannel) { - delete GlobalChannel; - GlobalChannel = 0; - } - for (i = 0; i < NumConnections; i++) { - delete Connection[i]; - Connection[i] = 0; - } - NumConnections = 0; - - /*------------------------------------------------------------------------ - Free all real-mode memory - ------------------------------------------------------------------------*/ - if (RealMemAllocd) { - Free_RealMode_Mem(); - RealMemAllocd = 0; - } - -} /* end of ~IPXManagerClass */ - - -/*************************************************************************** - * IPXManagerClass::Init -- initialization routine * - * * - * This routine allocates memory, - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Init() -{ - int i; - - if (!(GameToPlay == GAME_INTERNET)){ - /* - ----------------------- Error if IPX not installed ----------------------- - */ - if (!IPXStatus) { - return(false); - } - - /*------------------------------------------------------------------------ - Stop Listening - ------------------------------------------------------------------------*/ - if (Listening) { - IPXConnClass::Stop_Listening(); - Listening = 0; - } - - /*------------------------------------------------------------------------ - Free Real-mode memory - ------------------------------------------------------------------------*/ - if (RealMemAllocd) { - Free_RealMode_Mem(); - RealMemAllocd = 0; - } - }else{ - /* - ** Pretend IPX is available for Internet games whether it is or not - */ - IPXStatus = 1; - } - - /*------------------------------------------------------------------------ - Free protected-mode memory - ------------------------------------------------------------------------*/ - if (GlobalChannel) { - delete GlobalChannel; - GlobalChannel = 0; - } - for (i = 0; i < NumConnections; i++) { - delete Connection[i]; - Connection[i] = 0; - } - NumConnections = 0; - - - if (!(GameToPlay == GAME_INTERNET)){ - /*------------------------------------------------------------------------ - Allocate real-mode memory - ------------------------------------------------------------------------*/ - if (!Alloc_RealMode_Mem()) return(false); - RealMemAllocd = 1; - } - - /*------------------------------------------------------------------------ - Allocate the Global Channel - ------------------------------------------------------------------------*/ - GlobalChannel = new IPXGlobalConnClass (Glb_NumPackets, Glb_NumPackets, - Glb_MaxPacketLen, ProductID); - if (!GlobalChannel) - return(false); - GlobalChannel->Init(); - GlobalChannel->Set_Retry_Delta (RetryDelta); - GlobalChannel->Set_Max_Retries (MaxRetries); - GlobalChannel->Set_TimeOut (Timeout); - - /*------------------------------------------------------------------------ - Configure the IPX Connections - ------------------------------------------------------------------------*/ - IPXConnClass::Configure(Socket, ConnectionNum, ListenECB, SendECB, - FirstHeaderBuf, SendHeader, FirstDataBuf, SendBuf, Handler, PacketLen); - - /*------------------------------------------------------------------------ - Start Listening - ------------------------------------------------------------------------*/ - if (!(GameToPlay == GAME_INTERNET)){ - if (!IPXConnClass::Start_Listening()) return(false); - } - - Listening = 1; - - return(true); -} - - -/*************************************************************************** - * IPXManagerClass::Is_IPX -- tells if IPX is installed or not * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = IPX is installed; 0 = isn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Is_IPX(void) -{ - return(IPXStatus); - -} /* end of Is_IPX */ - - -/*************************************************************************** - * IPXManagerClass::Set_Timing -- sets timing for all connections * - * * - * This will set the timing parameters for all existing connections, and * - * all connections created from now on. This allows an application to * - * measure the Response_Time while running, and adjust timing accordingly. * - * * - * INPUT: * - * retrydelta value to set for retry delta * - * maxretries value to set for max # retries * - * timeout value to set for connection timeout * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/02/1995 BR : Created. * - *=========================================================================*/ -void IPXManagerClass::Set_Timing (unsigned long retrydelta, - unsigned long maxretries, unsigned long timeout) -{ - int i; - - RetryDelta = retrydelta; - MaxRetries = maxretries; - Timeout = timeout; - - if (GlobalChannel) { - GlobalChannel->Set_Retry_Delta (RetryDelta); - GlobalChannel->Set_Max_Retries (MaxRetries); - GlobalChannel->Set_TimeOut (Timeout); - } - - for (i = 0; i < NumConnections; i++) { - Connection[i]->Set_Retry_Delta (RetryDelta); - Connection[i]->Set_Max_Retries (MaxRetries); - Connection[i]->Set_TimeOut (Timeout); - } - -} /* end of Set_Timing */ - - -/*************************************************************************** - * IPXManagerClass::Create_Connection -- creates a new connection * - * * - * INPUT: * - * id application-specific numerical ID for this connection * - * node ptr to IPXNodeIDType (name & address) * - * address IPX address for this connection * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * Never create a connection with an 'id' of -1. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -bool IPXManagerClass::Create_Connection(int id, char *name, IPXAddressClass *address) -{ -#if (0) - char temp[80]; - - NetNumType num; - NetNodeType node; - - address->Get_Address (num, node); - - sprintf (temp, "Address:%02x %02x %02x %02x %02x %02x\n", node[0], - node[1], - node[2], - node[3], - node[4], - node[5]); - CCDebugString (temp); - - sprintf (temp, "Network:%02x %02x %02x %02x\n", num[0], - num[1], - num[2], - num[3]); - CCDebugString (temp); -#endif //(0) - - /* - ----------------------- Error if IPX not installed ----------------------- - */ - if (!IPXStatus) - return(false); - - /* - ------------------------- Error if no more room -------------------------- - */ - if (NumConnections==CONNECT_MAX) - return(false); - - /* - ------------------------- Create new connection -------------------------- - */ - Connection[NumConnections] = new IPXConnClass(Pvt_NumPackets, - Pvt_NumPackets, Pvt_MaxPacketLen, ProductID, address, id, name); - if (!Connection[NumConnections]) - return(false); - - Connection[NumConnections]->Init (); - Connection[NumConnections]->Set_Retry_Delta (RetryDelta); - Connection[NumConnections]->Set_Max_Retries (MaxRetries); - Connection[NumConnections]->Set_TimeOut (Timeout); - - NumConnections++; - - return(true); - -} /* end of Create_Connection */ - - -/*************************************************************************** - * IPXManagerClass::Delete_Connection -- deletes a connection * - * * - * INPUT: * - * id ID of connection to delete * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -bool IPXManagerClass::Delete_Connection(int id) -{ - int i,j; - - /* - ----------------------- Error if IPX not installed ----------------------- - */ - if (!IPXStatus) - return(false); - - /* - ------------------- Error if no connections to delete -------------------- - */ - if (NumConnections==0) - return(false); - - /* - ---------------------- Loop through all connections ---------------------- - */ - for (i = 0; i < NumConnections; i++) { - /* - ........................ If a match, delete it ........................ - */ - if (Connection[i]->ID==id) { - delete Connection[i]; - /* - ................ Move array elements back one index ................ - */ - for (j = i; j < NumConnections - 1; j++) { - Connection[j] = Connection[j+1]; - } - /* - ......................... Adjust counters .......................... - */ - NumConnections--; - if (CurConnection >= NumConnections) - CurConnection = 0; - return(true); - } - } - - /* - ---------------------------- No match; error ----------------------------- - */ - return(false); - -} /* end of Delete_Connection */ - - -/*************************************************************************** - * IPXManagerClass::Num_Connections -- gets the # of connections * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * # of connections * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Num_Connections(void) -{ -#ifdef VIRTUAL_SUBNET_SERVER - /* - ** If we are connected to the VSS then dont coumt that in the number of connections. - */ - if (Connection_Index (VSS_ID) == IPXConnClass::CONNECTION_NONE){ - return(NumConnections); - }else{ - return(NumConnections -1); - } -#else // VIRTUAL_SUBNET_SERVER - - return(NumConnections); - -#endif //VIRTUAL_SUBNET_SERVER - -} /* end of Num_Connections */ - - -/*************************************************************************** - * IPXManagerClass::Connection_ID -- gets the given connection's ID * - * * - * INPUT: * - * index index of connection to retrieve * - * * - * OUTPUT: * - * ID for that connection, CONNECTION_NONE if invalid index * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Connection_ID(int index) -{ - if (index >= 0 && index < NumConnections) { - return(Connection[index]->ID); - } else { - return(IPXConnClass::CONNECTION_NONE); - } -} - - -/*************************************************************************** - * IPXManagerClass::Connection_Name -- retrieves name for given connection * - * * - * INPUT: * - * id ID of connection to get name of * - * * - * OUTPUT: * - * ptr to connection's name, NULL if not found * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -char *IPXManagerClass::Connection_Name(int id) -{ - int i; - - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->ID==id) { - return(Connection[i]->Name); - } - } - - return(NULL); - -} /* end of Connection_Name */ - - -/*************************************************************************** - * IPXManagerClass::Connection_Address -- retrieves connection's address * - * * - * INPUT: * - * id ID of connection to get address for * - * * - * OUTPUT: * - * pointer to IXPAddressClass, NULL if not found * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/19/1995 BR : Created. * - *=========================================================================*/ -IPXAddressClass * IPXManagerClass::Connection_Address(int id) -{ - int i; - - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->ID==id) { - return(&Connection[i]->Address); - } - } - - return(NULL); - -} /* end of Connection_Address */ - - -/*************************************************************************** - * IPXManagerClass::Connection_Index -- gets given connection's index * - * * - * INPUT: * - * ID to retrieve index for * - * * - * OUTPUT: * - * index for this connection, CONNECTION_NONE if not found * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Connection_Index(int id) -{ - int i; - - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->ID==id) - return(i); - } - - return(IPXConnClass::CONNECTION_NONE); - -} /* end of Connection_Index */ - - -/*************************************************************************** - * IPXManagerClass::Send_Global_Message -- sends a Global Message * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buf * - * ack_req 1 = ACK required; 0 = no ACK required * - * address address to send to; NULL = broadcast * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Send_Global_Message(void *buf, int buflen, - int ack_req, IPXAddressClass *address) -{ - int rc; - - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening) return(false); - - rc = GlobalChannel->Send_Packet (buf, buflen, address, ack_req); - if (!rc) - SendOverflows++; - - return(rc); -} - - -/*************************************************************************** - * IPXManagerClass::Get_Global_Message -- polls the Global Message queue * - * * - * INPUT: * - * buf buffer to store received packet * - * buflen length of data placed in 'buf' * - * address IPX address of sender * - * product_id product ID of sender * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Get_Global_Message(void *buf, int *buflen, - IPXAddressClass *address, unsigned short *product_id) -{ - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening) return(false); - - return(GlobalChannel->Get_Packet (buf, buflen, address, product_id)); -} - - -/*************************************************************************** - * IPXManagerClass::Send_Private_Message -- Sends a Private Message * - * * - * INPUT: * - * buf buffer to send * - * buflen length of 'buf' * - * conn_id connection ID to send to (CONNECTION_NONE = all) * - * ack_req 1 = ACK required; 0 = no ACK required * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Send_Private_Message(void *buf, int buflen, int ack_req, - int conn_id) -{ - int i; // loop counter - int connect_idx; // index of channel to send to, if specified - - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening || (NumConnections==0)) return(false); - - /*------------------------------------------------------------------------ - Send the message to all connections - ------------------------------------------------------------------------*/ - if (conn_id==IPXConnClass::CONNECTION_NONE) { - - /* - ** If this is an internet game and no ack is reqired then we only need to send - ** the packet to the VSS and it will forward it to all the other players. - */ - -#ifdef VIRTUAL_SUBNET_SERVER - if (ack_req || (!Winsock.Get_Connected() || !UseVirtualSubnetServer)){ -#endif //VIRTUAL_SUBNET_SERVER - /*..................................................................... - Check for room in all connections - .....................................................................*/ - for (i = 0; i < NumConnections; i++) { -#ifdef VIRTUAL_SUBNET_SERVER - if (Connection[i]->ID != VSS_ID){ -#endif //VIRTUAL_SUBNET_SERVER - if (Connection[i]->Queue->Num_Send()==Connection[i]->Queue->Max_Send()) { - SendOverflows++; - return(false); - } -#ifdef VIRTUAL_SUBNET_SERVER - } -#endif // VIRTUAL_SUBNET_SERVER - } - - /*..................................................................... - Send packet to all connections - .....................................................................*/ - - for (i = 0; i < NumConnections; i++) { -#ifdef VIRTUAL_SUBNET_SERVER - if (Connection[i]->ID != VSS_ID){ -#endif //VIRTUAL_SUBNET_SERVER - Connection[i]->Send_Packet (buf, buflen, ack_req); -#ifdef VIRTUAL_SUBNET_SERVER - } -#endif //VIRTUAL_SUBNET_SERVER - } - -#ifdef VIRTUAL_SUBNET_SERVER - }else{ - /* - ** Send the packet to the VSS with a 0 header so it gets forwarded to all players. - */ - if (Connection[ Connection_Index(VSS_ID) ]->Queue->Num_Send() == Connection[ Connection_Index(VSS_ID) ]->Queue->Max_Send()) { - SendOverflows++; - return(false); - } - Connection[ Connection_Index(VSS_ID) ]->Send_Packet (buf, buflen, 0); - } -#endif // VIRTUAL_SUBNET_SERVER - - return(true); - - - } else { - - /*------------------------------------------------------------------------ - Send the message to the specified connection - ------------------------------------------------------------------------*/ - connect_idx = Connection_Index (conn_id); - if (connect_idx == IPXConnClass::CONNECTION_NONE) { - SendOverflows++; - return(false); - } - - /*..................................................................... - Check for room in the connection - .....................................................................*/ - if (Connection[connect_idx]->Queue->Num_Send() == - Connection[connect_idx]->Queue->Max_Send()) { - SendOverflows++; - return(false); - } - - /*..................................................................... - Send the packet to that connection - .....................................................................*/ - Connection[connect_idx]->Send_Packet (buf, buflen, ack_req); - return(true); - } -} - - -/*************************************************************************** - * IPXManagerClass::Get_Private_Message -- Polls the Private Message queue * - * * - * INPUT: * - * buf buffer to store incoming packet * - * buflen length of data placed in 'buf' * - * conn_id filled in with connection ID of sender * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Get_Private_Message(void *buf, int *buflen, int *conn_id) -{ - int i; - int rc; - int c_id; -#ifdef VIRTUAL_SUBNET_SERVER - int vss = 0; -#endif // VIRTUAL_SUBNET_SERVER - - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening || (NumConnections==0)) return(false); - -#ifdef VIRTUAL_SUBNET_SERVER - if (Winsock.Get_Connected()){ - vss = (int) UseVirtualSubnetServer; - } -#endif //VIRTUAL_SUBNET_SERVER - - /*------------------------------------------------------------------------ - Safety check: ensure CurConnection is in range. - ------------------------------------------------------------------------*/ -#ifdef VIRTUAL_SUBNET_SERVER - if (CurConnection >= NumConnections - vss) -#else // VIRTUAL_SUBNET_SERVER - if (CurConnection >= NumConnections) -#endif //VIRTUAL_SUBNET_SERVER - CurConnection = 0; - - /*------------------------------------------------------------------------ - Scan all connections for a received packet, starting with 'CurConnection' - ------------------------------------------------------------------------*/ -#ifdef VIRTUAL_SUBNET_SERVER - for (i = 0; i < NumConnections - vss; i++) { -#else // VIRTUAL_SUBNET_SERVER - for (i = 0; i < NumConnections; i++) { -#endif // VIRTUAL_SUBNET_SERVER - /*..................................................................... - Check this connection for a packet - .....................................................................*/ - rc = Connection[CurConnection]->Get_Packet (buf, buflen); - c_id = Connection[CurConnection]->ID; - - /*..................................................................... - Increment CurConnection to the next connection index - .....................................................................*/ - CurConnection++; -#ifdef VIRTUAL_SUBNET_SERVER - if (CurConnection >= NumConnections - vss) -#else // VIRTUAL_SUBNET_SERVER - if (CurConnection >= NumConnections) -#endif // VIRTUAL_SUBNET_SERVER - CurConnection = 0; - - /*..................................................................... - If we got a packet, return the connection ID - .....................................................................*/ - if (rc) { - (*conn_id) = c_id; - return(true); - } - } - - return(false); -} - - -/*************************************************************************** - * IPXManagerClass::Service -- main polling routine for IPX Connections * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Service(void) -{ - - int rc = 1; - int i; - CommHeaderType *packet; - int packetlen; - IPXAddressClass address; - - - -#ifndef NOT_FOR_WIN95 - - unsigned char temp_receive_buffer[1024]; - int recv_length; - - if (Winsock.Get_Connected()){ - - while ((recv_length = Winsock.Read(temp_receive_buffer, 1024))!=0){ - -#ifdef VIRTUAL_SUBNET_SERVER - /* - ** Get a pointer to the data header and swap the bit mask - */ - CurHeaderBuf = (IPXHEADER*)&temp_receive_buffer[0]; //NULL; - unsigned short *swapptr = (unsigned short*)CurHeaderBuf; - *swapptr = ntohs (*swapptr); - - CurDataBuf = (char*)&temp_receive_buffer[2]; - - /*..................................................................... - Compute the length of the packet (byte-swap the length in the IPX hdr) - .....................................................................*/ - packetlen = recv_length-2; -#else //VIRTUAL_SUBNET_SERVER - CurHeaderBuf = NULL; - CurDataBuf = (char*)&temp_receive_buffer[0]; - - /*..................................................................... - Compute the length of the packet (byte-swap the length in the IPX hdr) - .....................................................................*/ - packetlen = recv_length; - -#endif //VIRTUAL_SUBNET_SERVER - - - /*..................................................................... - Extract the sender's address from the IPX header - .....................................................................*/ - address.Set_Address (CurHeaderBuf); - - /*..................................................................... - Examine the Magic Number of the received packet to determine if this - packet goes into the Global Queue, or into one of the Private Queues - .....................................................................*/ - packet = (CommHeaderType *)CurDataBuf; -#if (0) -char tempbuf[256]; - -static char pcode [4][18]={ - "PACKET_DATA_ACK", // this is a data packet requiring an ACK - "PACKET_DATA_NOACK", // this is a data packet not requiring an ACK - "PACKET_ACK", // this is an ACK for a packet - "PACKET_COUNT" // for computational purposes -}; - -sprintf (tempbuf, "Received packet type %d, ID=%d, code=%s, length=%d \n", CurDataBuf[sizeof(CommHeaderType)], - packet->PacketID, - pcode[packet->Code], - recv_length); -CCDebugString (tempbuf); -#endif //(0) - if (packet->MagicNumber == GlobalChannel->Magic_Num()) { - /*.................................................................. - Put the packet in the Global Queue - ..................................................................*/ - if (!GlobalChannel->Receive_Packet (packet, packetlen, &address)) - ReceiveOverflows++; - } else { - if (packet->MagicNumber == ProductID) { - /*.................................................................. - Find the Private Queue that this packet is for - ..................................................................*/ - for (i = 0; i < NumConnections; i++) { -#ifdef VIRTUAL_SUBNET_SERVER - if (Connection[i]->Address == address && Connection[i]->ID != VSS_ID) { -#else //VIRTUAL_SUBNET_SERVER - if (Connection[i]->Address == address) { -#endif //VIRTUAL_SUBNET_SERVER - if (!Connection[i]->Receive_Packet (packet, packetlen)) - ReceiveOverflows++; - break; - } - } - } - } - - } - }else{ - - while (IPX_Get_Outstanding_Buffer95(&temp_receive_buffer[0])){ - - CurHeaderBuf = (IPXHEADER*)&temp_receive_buffer[0]; - CurDataBuf = (char*)&temp_receive_buffer[sizeof(IPXHeaderType)]; - - /*..................................................................... - Compute the length of the packet (byte-swap the length in the IPX hdr) - .....................................................................*/ - packetlen = ((CurHeaderBuf->Length & 0xff) << 8) | - (CurHeaderBuf->Length >> 8); - packetlen -= sizeof(IPXHeaderType); - - /*..................................................................... - Extract the sender's address from the IPX header - .....................................................................*/ - address.Set_Address (CurHeaderBuf); - - /*..................................................................... - Examine the Magic Number of the received packet to determine if this - packet goes into the Global Queue, or into one of the Private Queues - .....................................................................*/ - packet = (CommHeaderType *)CurDataBuf; - - if (packet->MagicNumber == GlobalChannel->Magic_Num()) { - /*.................................................................. - Put the packet in the Global Queue - ..................................................................*/ - if (!GlobalChannel->Receive_Packet (packet, packetlen, &address)) - ReceiveOverflows++; - } else { - if (packet->MagicNumber == ProductID) { - /*.................................................................. - Find the Private Queue that this packet is for - ..................................................................*/ - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->Address == address) { - if (!Connection[i]->Receive_Packet (packet, packetlen)) - ReceiveOverflows++; - break; - } - } - } - } - - } - } - - //IPX_Start_Listening95(); - - -#else //NOT_FOR_WIN95 - - - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening) - return(false); - - /*------------------------------------------------------------------------ - Loop until there are no more packets to process. - ------------------------------------------------------------------------*/ - for (;;) { - /*..................................................................... - Check the BufferFlags for the "current" buffer; if it's empty, - break; out of the loop. - .....................................................................*/ - if (BufferFlags[CurIndex]==0) - break; - - /*..................................................................... - Compute the length of the packet (byte-swap the length in the IPX hdr) - .....................................................................*/ - packetlen = ((CurHeaderBuf->Length & 0xff) << 8) | - (CurHeaderBuf->Length >> 8); - packetlen -= sizeof(IPXHeaderType); - - /*..................................................................... - Extract the sender's address from the IPX header - .....................................................................*/ - address.Set_Address (CurHeaderBuf); - - /*..................................................................... - Examine the Magic Number of the received packet to determine if this - packet goes into the Global Queue, or into one of the Private Queues - .....................................................................*/ - packet = (CommHeaderType *)CurDataBuf; - if (packet->MagicNumber == GlobalChannel->Magic_Num()) { - /*.................................................................. - Put the packet in the Global Queue - ..................................................................*/ - if (!GlobalChannel->Receive_Packet (packet, packetlen, &address)) - ReceiveOverflows++; - } else { - if (packet->MagicNumber == ProductID) { - /*.................................................................. - Find the Private Queue that this packet is for - ..................................................................*/ - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->Address == address) { - if (!Connection[i]->Receive_Packet (packet, packetlen)) - ReceiveOverflows++; - break; - } - } - } - } - - /*..................................................................... - Set the current BufferFlags to 0 (since we've cleaned out this buffer) - .....................................................................*/ - BufferFlags[CurIndex] = 0; - - /*..................................................................... - Go to the next packet buffer - .....................................................................*/ - CurIndex++; - CurHeaderBuf = (IPXHeaderType *)(((char *)CurHeaderBuf) + FullPacketLen); - CurDataBuf = ((char *)CurDataBuf) + FullPacketLen; - if (CurIndex >= NumBufs) { - CurHeaderBuf = FirstHeaderBuf; - CurDataBuf = FirstDataBuf; - CurIndex = 0; - } - - } - -#endif //NOT_FOR_WIN95 - - /*------------------------------------------------------------------------ - Service all connections. If a connection reports that it's gone "bad", - report an error to the caller. If it's the Global Channel, un-queue the - send entry that's holding things up. This will keep the Global Channel - from being clogged by one un-ACK'd outgoing packet. - ------------------------------------------------------------------------*/ - if (GlobalChannel) { - if (!GlobalChannel->Service()) { - GlobalChannel->Queue->UnQueue_Send (NULL, NULL, 0); - rc = 0; - } - } - for (i = 0; i < NumConnections; i++) { - if (!Connection[i]->Service()) { -#ifdef VIRTUAL_SUBNET_SERVER - if (Connection[i]->ID != VSS_ID){ -#endif //VIRTUAL_SUBNET_SERVER - rc = 0; - BadConnection = Connection[i]->ID; -#ifdef VIRTUAL_SUBNET_SERVER - } -#endif //VIRTUAL_SUBNET_SERVER - } - } - - if (rc) - BadConnection = IPXConnClass::CONNECTION_NONE; - - return(rc); - - -} /* end of Service */ - - -/*************************************************************************** - * IPXManagerClass::Get_Bad_Connection -- returns bad connection ID * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * ID of bad connection; CONNECTION_NONE if none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/04/1995 BRR : Created. * - *=========================================================================*/ -int IPXManagerClass::Get_Bad_Connection(void) -{ - return(BadConnection); - -} /* end of Get_Bad_Connection */ - - -/*************************************************************************** - * IPXManagerClass::Global_Num_Send -- reports # entries in send queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * # entries in the Global Send Queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Global_Num_Send(void) -{ - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening) - return(0); - - return(GlobalChannel->Queue->Num_Send()); - -} /* end of Global_Num_Send */ - - -/*************************************************************************** - * IPXManagerClass::Global_Num_Receive -- reports # entries in recv queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * # entries in the Global Receive Queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Global_Num_Receive(void) -{ - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening) - return(0); - - return(GlobalChannel->Queue->Num_Receive()); - -} /* end of Global_Num_Receive */ - - -/*************************************************************************** - * IPXManagerClass::Private_Num_Send -- reports # entries in send queue * - * * - * INPUT: * - * # entries in the Private Send Queue * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Private_Num_Send(int id) -{ - int i; - int maxnum; - - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening || (NumConnections==0)) return(false); - - /*------------------------------------------------------------------------ - If connection ID specified, return that connection's # of packets - ------------------------------------------------------------------------*/ - if (id != IPXConnClass::CONNECTION_NONE) { - i = Connection_Index(id); - if (i != IPXConnClass::CONNECTION_NONE) { - return(Connection[i]->Queue->Num_Send()); - } else { - return(false); - } - } else { - - /*------------------------------------------------------------------------ - Otherwise, return the max # of all connections - ------------------------------------------------------------------------*/ - maxnum = 0; - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->Queue->Num_Send() > maxnum) { - maxnum = Connection[i]->Queue->Num_Send(); - } - } - return(maxnum); - } -} - - -/*************************************************************************** - * IPXManagerClass::Private_Num_Receive -- reports # entries in recv queue * - * * - * INPUT: * - * id ID of connection to query * - * * - * OUTPUT: * - * # entries in the Private Receive Queue * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Private_Num_Receive(int id) -{ - int i; - int maxnum; - - /* - ------------ Error if IPX not installed or not Listening ----------------- - */ - if (!IPXStatus || !Listening || (NumConnections==0)) - return(0); - - /*------------------------------------------------------------------------ - If connection ID specified, return that connection's # of packets - ------------------------------------------------------------------------*/ - if (id != IPXConnClass::CONNECTION_NONE) { - i = Connection_Index(id); - if (i != IPXConnClass::CONNECTION_NONE) { - return(Connection[i]->Queue->Num_Receive()); - } else { - return(0); - } - } else { - - /*------------------------------------------------------------------------ - Otherwise, return the max # of all connections - ------------------------------------------------------------------------*/ - maxnum = 0; - for (i = 0; i < NumConnections; i++) { - if (Connection[i]->Queue->Num_Receive() > maxnum) - maxnum = Connection[i]->Queue->Num_Receive(); - } - return(maxnum); - } -} - - -/*************************************************************************** - * IPXManagerClass::Set_Socket -- sets socket ID for all connections * - * * - * INPUT: * - * socket new socket ID to use * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * Do not call this function after communications have started; you * - * must call it before calling Init(). * - * The socket number is byte-swapped, since IPX requires socket ID's * - * to be stored high/low. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -void IPXManagerClass::Set_Socket(unsigned short socket) -{ - Socket = (unsigned short)( (((unsigned long)socket & 0x00ff) << 8) | - (((unsigned long)socket & 0xff00) >> 8)); - -} /* end of Set_Socket */ - - -/*************************************************************************** - * IPXManagerClass::Response_Time -- Returns largest Avg Response Time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * largest avg response time * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/04/1995 BRR : Created. * - *=========================================================================*/ -unsigned long IPXManagerClass::Response_Time(void) -{ - unsigned long resp; - unsigned long maxresp = 0; - int i; -#ifdef VIRTUAL_SUBNET_SERVER - int vss=0; - - if (Winsock.Get_Connected()){ - vss = (int) UseVirtualSubnetServer; - } - - for (i = 0; i < NumConnections - vss; i++) { -#else //VIRTUAL_SUBNET_SERVER - for (i = 0; i < NumConnections; i++) { -#endif // VIRTUAL_SUBNET_SERVER - resp = Connection[i]->Queue->Avg_Response_Time(); - if (resp > maxresp) - maxresp = resp; - } - - return(maxresp); -} - - -/*************************************************************************** - * IPXManagerClass::Global_Response_Time -- Returns Avg Response Time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * avg global channel response time * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/04/1995 BRR : Created. * - *=========================================================================*/ -unsigned long IPXManagerClass::Global_Response_Time(void) -{ - if (GlobalChannel) { - return (GlobalChannel->Queue->Avg_Response_Time()); - } else { - return (0); - } -} - - -/*************************************************************************** - * IPXManagerClass::Reset_Response_Time -- Reset response time * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/04/1995 BRR : Created. * - *=========================================================================*/ -void IPXManagerClass::Reset_Response_Time(void) -{ - int i; - - for (i = 0; i < NumConnections; i++) { - Connection[i]->Queue->Reset_Response_Time(); - } - - if (GlobalChannel) - GlobalChannel->Queue->Reset_Response_Time(); - -} /* end of Reset_Response_Time */ - - -/*************************************************************************** - * IPXManagerClass::Oldest_Send -- gets ptr to oldest send buf * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * buf ptr * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/04/1995 BRR : Created. * - *=========================================================================*/ -void * IPXManagerClass::Oldest_Send(void) -{ - int i,j; - unsigned long time; - unsigned long mintime = 0xffffffff; - SendQueueType *send_entry; // ptr to send entry header - CommHeaderType *packet; - void *buf = NULL; - - for (i = 0; i < NumConnections; i++) { - - send_entry = NULL; - - for (j = 0; j < Connection[i]->Queue->Num_Send(); j++) { - send_entry = Connection[i]->Queue->Get_Send(j); - if (send_entry) { - packet = (CommHeaderType *)send_entry->Buffer; - if (packet->Code == ConnectionClass::PACKET_DATA_ACK && send_entry->IsACK == 0) { - break; - } else { - send_entry = NULL; - } - } - } - - if (send_entry!=NULL) { - - time = send_entry->FirstTime; - - if (time < mintime) { - mintime = time; - buf = send_entry->Buffer; - } - } - } - - return(buf); - -} /* end of Oldest_Send */ - - -/*************************************************************************** - * IPXManagerClass::Set_Bridge -- prepares to cross a bridge * - * * - * This routine is designed to prevent the connection from having to * - * call Get_Local_Target, except the minimum number of times, since that * - * routine is buggy & goes away for long periods sometimes. * - * * - * INPUT: * - * bridge network number of the destination bridge * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 07/06/1995 BRR : Created. * - *=========================================================================*/ -void IPXManagerClass::Set_Bridge(NetNumType bridge) -{ - if (GlobalChannel) { - GlobalChannel->Set_Bridge(bridge); - } -} - - -/*************************************************************************** - * IPXManagerClass::Configure_Debug -- sets up special debug values * - * * - * Mono_Debug_Print2() can look into a packet to pull out a particular * - * ID, and can print both that ID and a string corresponding to * - * that ID. This routine configures these values so it can find * - * and decode the ID. This ID is used in addition to the normal * - * CommHeaderType values. * - * * - * INPUT: * - * index connection index to configure (-1 = Global Channel) * - * offset ID's byte offset into packet * - * size size of ID, in bytes; 0 if none * - * names ptr to array of names; use ID as an index into this * - * maxnames max # in the names array; 0 if none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * Names shouldn't be longer than 12 characters. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -void IPXManagerClass::Configure_Debug(int index, int offset, int size, - char **names, int maxnames) -{ - if (index == -1) { - GlobalChannel->Queue->Configure_Debug (offset, size, names, maxnames); - } else { - if (Connection[index]) { - Connection[index]->Queue->Configure_Debug (offset, size, names, maxnames); - } - } -} - - -/*************************************************************************** - * IPXManagerClass::Mono_Debug_Print -- debug output routine * - * * - * INPUT: * - * index index of connection to display (-1 = Global Channel) * - * refresh 1 = complete screen refresh * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/25/1995 BR : Created. * - *=========================================================================*/ -void IPXManagerClass::Mono_Debug_Print(int index, int refresh) -{ -#ifdef WWLIB32_H - char txt[80]; - int i; - - if (index == -1) - GlobalChannel->Queue->Mono_Debug_Print (refresh); - else if (Connection[index]) - Connection[index]->Queue->Mono_Debug_Print (refresh); - - if (refresh) { - Mono_Set_Cursor (20,1); - Mono_Printf ("IPX Queue:"); - - Mono_Set_Cursor (9,2); - Mono_Printf ("Average Response Time:"); - - Mono_Set_Cursor (43,1); - Mono_Printf ("Send Overflows:"); - - Mono_Set_Cursor (40,2); - Mono_Printf ("Receive Overflows:"); - - } - - Mono_Set_Cursor (32,1); - Mono_Printf ("%d",index); - - Mono_Set_Cursor (32,2); - if (index == -1) { - Mono_Printf ("%d ", GlobalChannel->Queue->Avg_Response_Time()); - } else { - Mono_Printf ("%d ", Connection[index]->Queue->Avg_Response_Time()); - } - - Mono_Set_Cursor (59,1); - Mono_Printf ("%d ", SendOverflows); - - Mono_Set_Cursor (59,2); - Mono_Printf ("%d ", ReceiveOverflows); - - for (i = 0; i < NumBufs; i++) { - if (BufferFlags[i]) { - txt[i] = 'X'; - } else { - txt[i] = '_'; - } - } - txt[i] = 0; - Mono_Set_Cursor ((80-NumBufs)/2,3); - Mono_Printf ("%s",txt); - -#else - index = index; - refresh = refresh; -#endif -} /* end of Mono_Debug_Print */ - - -/*************************************************************************** - * IPXManagerClass::Alloc_RealMode_Mem -- allocates real-mode memory * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Alloc_RealMode_Mem(void) -{ -#ifdef NOT_FOR_WIN95 - union REGS regs; - struct SREGS sregs; - int size; // required size of allocation - unsigned char *realmode; // start addresses of real-mode data - int realmodelen; // length of real-mode data - unsigned long func_val; - char *p; // for parsing buffer - int i; - - /*------------------------------------------------------------------------ - Compute # of buffers we need to allocate, & the max size of each one - ------------------------------------------------------------------------*/ - NumBufs = Glb_NumPackets + (Pvt_NumPackets * CONNECT_MAX); - - PacketLen = Glb_MaxPacketLen + sizeof (GlobalHeaderType); - if (Pvt_MaxPacketLen + sizeof (CommHeaderType) > PacketLen) - PacketLen = Pvt_MaxPacketLen + sizeof (CommHeaderType); - - FullPacketLen = PacketLen + sizeof(IPXHeaderType); - - /*------------------------------------------------------------------------ - Compute the size of everything we'll ever need, allocate it in one big - chunk. The memory is used as follows: - - Real-mode assembly IPX callback routine, plus its data, - (which includes the ListenECB) - - Array of IPX Packet buffers (IPXHeader plus data buffer) - - SendECB: ECB for sending - - SendHeader: IPX Header for sending - - SendBuf: Packet buffer for sending - - BufferFlags: 1 byte for each incoming packet buffer; 1=in use, 0=free - ------------------------------------------------------------------------*/ - realmode = (unsigned char *)Get_RM_IPX_Address(); - realmodelen = Get_RM_IPX_Size(); - size = realmodelen + // assembly routine & its data - (FullPacketLen * NumBufs) + // array of packet buffers - sizeof(ECBType) + // SendECB - FullPacketLen + // SendHeader & SendBuf - NumBufs; // BufferFlags - if (size > 65535) - return(false); - - /*------------------------------------------------------------------------ - Allocate DOS memory for the ECB, IPXHeader & packet buffers: - AX = 0x100 - BX = # paragraphs to allocate - - if Success, AX = real-mode segment, DX = selector - - if Failure, carry flag is set - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_ALLOC_DOS_MEM; // DPMI function to call - regs.x.ebx = ((size + 15) >> 4); // # paragraphs to allocate - int386x (DPMI_INT, ®s, ®s, &sregs); // allocate the memory - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - return(false); - } - - /*........................................................................ - Save the values of the returned segment & selector - ........................................................................*/ - Selector = regs.w.dx; - Segment = regs.w.ax; - RealMemSize = size; - RealModeData = (RealModeDataType *)(((long)Segment) << 4); - - /*------------------------------------------------------------------------ - Lock the memory (since we're servicing interrupts with it) - AX = 0x600 - BX:CX = starting linear address of memory to lock - SI:DI = size of region to lock (in bytes) - - If Failure, carry flag is set. - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_LOCK_MEM; // DPMI function to call - regs.x.ebx = ((long)RealModeData & 0xffff0000) >> 16; - regs.x.ecx = ((long)RealModeData & 0x0000ffff); - regs.x.esi = ((long)RealMemSize & 0xffff0000) >> 16; - regs.x.edi = ((long)RealMemSize & 0x0000ffff); - int386x (DPMI_INT, ®s, ®s, &sregs); // call DPMI - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_FREE_DOS_MEM; // DPMI function to call - regs.x.edx = Selector; // ptr to free - int386x (DPMI_INT, ®s, ®s, &sregs); // free the memory - return(false); - } - - /*------------------------------------------------------------------------ - Copy the Real-mode code into our memory buffer - ------------------------------------------------------------------------*/ - p = (char *)(((long)Segment) << 4); - memcpy (p,realmode,realmodelen); - p += realmodelen; - - /*------------------------------------------------------------------------ - Compute & save the entry point for the real-mode packet handler - ------------------------------------------------------------------------*/ - func_val = (unsigned long)RealModeData; - Handler = (((func_val & 0xffff0) << 12) | - ((func_val & 0x000f) + RealModeData->FuncOffset)); - - /*------------------------------------------------------------------------ - Fill in buffer pointers - ------------------------------------------------------------------------*/ - ListenECB = &(RealModeData->ListenECB); - - FirstHeaderBuf = (IPXHeaderType *)p; - FirstDataBuf = (((char *)FirstHeaderBuf) + sizeof(IPXHeaderType)); - CurIndex = 0; - CurHeaderBuf = FirstHeaderBuf; - CurDataBuf = FirstDataBuf; - p += FullPacketLen * NumBufs; - - SendECB = (ECBType *)p; - p += sizeof (ECBType); - - SendHeader = (IPXHeaderType *)p; - p += sizeof (IPXHeaderType); - - SendBuf = (char *)p; - p += PacketLen; - - BufferFlags = (char *)p; - - /*------------------------------------------------------------------------ - Fill in the real-mode routine's data (The ECB will be filled in when we - command IPX to Listen). - ------------------------------------------------------------------------*/ - RealModeData->NumBufs = (short)NumBufs; - RealModeData->BufferFlags = (char *) - ((((long)BufferFlags & 0xffff0) << 12) | - ((long)BufferFlags & 0x0000f)); - RealModeData->PacketSize = (short)FullPacketLen; - RealModeData->FirstPacketBuf = (IPXHeaderType *) - ((((long)FirstHeaderBuf & 0xffff0) << 12) | - ((long)FirstHeaderBuf & 0x0000f)); - RealModeData->CurIndex = 0; - RealModeData->CurPacketBuf = RealModeData->FirstPacketBuf; - RealModeData->Semaphore = 0; - RealModeData->ReEntrantCount = 0; - - /*------------------------------------------------------------------------ - Init state of all buffers to empty - ------------------------------------------------------------------------*/ - for (i = 0; i < NumBufs; i++) - BufferFlags[i] = 0; - - /*------------------------------------------------------------------------ - Check the start & end markers in the real-mode memory area - ------------------------------------------------------------------------*/ - if (RealModeData->Marker1 != 0x1111 || - RealModeData->Marker2 != 0x2222) { - Free_RealMode_Mem(); - return(false); - } else { - return(true); - } -#else //NOT_FOR_WIN95 - - return (TRUE); - -#endif //NOT_FOR_WIN95 -} - - -/*************************************************************************** - * IPXManagerClass::Free_RealMode_Mem -- frees real-mode memory * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int IPXManagerClass::Free_RealMode_Mem(void) -{ -#ifdef NOT_FOR_WIN95 - union REGS regs; - struct SREGS sregs; - int rc = 1; - - /*------------------------------------------------------------------------ - Unlock the memory - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_UNLOCK_MEM; // DPMI function to call - regs.x.ebx = ((long)RealModeData & 0xffff0000) >> 16; - regs.x.ecx = ((long)RealModeData & 0x0000ffff); - regs.x.esi = ((long)RealMemSize & 0xffff0000) >> 16; - regs.x.edi = ((long)RealMemSize & 0x0000ffff); - int386x (DPMI_INT, ®s, ®s, &sregs); // call DPMI - /*........................................................................ - If the carry flag is set, DPMI is indicating an error. - ........................................................................*/ - if (regs.x.cflag) { - rc = 0; - } - - /*------------------------------------------------------------------------ - Free DOS memory - ------------------------------------------------------------------------*/ - memset (®s, 0 ,sizeof(regs)); - segread (&sregs); - regs.x.eax = DPMI_FREE_DOS_MEM; // DPMI function to call - regs.x.edx = Selector; // ptr to free - int386x (DPMI_INT, ®s, ®s, &sregs); // free the memory - - return(rc); - -#else // NOT_FOR_WIN95 - - return (1); - -#endif // NOT_FOR_WIN95 -} /* end of Free_RealMode_Mem */ - - diff --git a/code/TIBERIANDAWN/IPXMGR.H b/code/TIBERIANDAWN/IPXMGR.H deleted file mode 100644 index 8263f6d..0000000 --- a/code/TIBERIANDAWN/IPXMGR.H +++ /dev/null @@ -1,392 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\ipxmgr.h_v 1.10 16 Oct 1995 16:47:34 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : IPXMGR.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 3, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This is the Connection Manager for IPX network communications. It * - * creates, manages, & orchestrates multiple IPX connections, as well as * - * the "global" connection ("Global Channel"), which can talk to any * - * system on the net. * - * * - * Use the Global Channel to query systems for their names, ID's, & * - * IPX addresses. Then, create a Private Connection with each system * - * that joins your game, and use the Private Channel to send game packets * - * (the private channel will perform somewhat faster, & gives you better * - * control than the Global Channel; it can detect retries, and the Global * - * Channel can't). * - * * - * HOW THIS CLASS WORKS: * - * This class has to set up an IPX Event Service Routine in low (DOS) * - * memory. So, it uses DPMI to allocate & lock a chunk of DOS memory; * - * this memory is used for all incoming packet buffers, the outgoing * - * packet buffer, and the actual code for the event handler. The real- * - * mode handler code & this class share a portion of memory that's mapped * - * into a "RealModeDataType" structure. As packets come in, the handler * - * points IPX to the next available packet buffer & restarts listening; * - * it sets a flag to tell this class that a packet is present at that * - * buffer slot. This class must read all the packets & determine which * - * connection they go with (the Global Channel, or one of the Private * - * Channels). This parsing is done in the Service routine for this class. * - * * - * Constructor: Just inits some variables, checks to see if IPX is there * - * Destructor: Complete shutdown; stops IPX listening, frees all memory * - * Init: Should only be called once (but can be called more); * - * allocates all memory, creates the Global Channel * - * connection, starts IPX listening. By not placing this * - * step in the constructor, the app can control when * - * listening actually starts; also, you don't get a bunch * - * of allocations just by declaring an IPXManagerClass * - * instance. You have to call Init() for the allocations * - * to occur. * - * Connection utilities: Create & manage Private Connections. Each * - * connection has its own IPX address, numerical ID, and * - * character name (presumably the name of the other * - * player). * - * Send/Get_Global_Message: adds a packet to the Global Connection queue, * - * or reads from the queue. The caller should check the * - * ProductID value from returned packets to be sure it's * - * talking to the right product. * - * Send/Get_Private_Message: adds a packet to a Private Connection queue, * - * or reads from the queue * - * Service: Checks the Real-Mode-Memory packet array to see if any * - * new packets have come in; if they have, it parses them * - * & distributes them to the right connection queue. The * - * queue's Service routine handles ACK'ing or Resending * - * packets. * - * * - * Here's a memory map of the Real-Mode memory block. 'N' is the number * - * of packet buffers allocated in low memory: * - * * - * ---------------------------------- * - * | Shared-memory data | * - * |--------------------------------| * - * | Real-mode event handler code | * - * |--------------------------------| * - * | IPX Header & Packet Buffer 0 | * - * |--------------------------------| * - * | IPX Header & Packet Buffer 1 | * - * |--------------------------------| * - * | IPX Header & Packet Buffer 2 | * - * |--------------------------------| * - * | . . . | * - * |--------------------------------| * - * | IPX Header & Packet Buffer N | * - * |--------------------------------| * - * | Send Event Control Block | * - * |--------------------------------| * - * | Send IPX Header | * - * |--------------------------------| * - * | Send Packet Buffer | * - * |--------------------------------| * - * | Flags Array [N] | * - * ---------------------------------- * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef IPXMANAGER_H -#define IPXMANAGER_H - - -/* -********************************* Includes ********************************** -*/ -#include "ipxconn.h" -#include "ipxgconn.h" -#include "ipxaddr.h" -#include "connmgr.h" - -/* -********************************** Defines ********************************** -*/ -/*--------------------------------------------------------------------------- -This is Virgin Interactive Entertainment's registered socket ID. ----------------------------------------------------------------------------*/ -#define VIRGIN_SOCKET 0x8813 - -/*--------------------------------------------------------------------------- -This is the maximum number of IPX connections supported. Just change this -value to support more. ----------------------------------------------------------------------------*/ -#define CONNECT_MAX 6 - -/*--------------------------------------------------------------------------- -These routines report the location & length of the real-mode routine, as -it's stored in protected-mode memory. ----------------------------------------------------------------------------*/ -extern "C" { - void *Get_RM_IPX_Address(void); - long Get_RM_IPX_Size(void); -} - -/* -***************************** Class Declaration ***************************** -*/ -class IPXManagerClass : public ConnManClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - IPXManagerClass (int glb_maxlen, int pvt_maxlen, int glb_num_packets, - int pvt_num_packets, unsigned short socket, unsigned short product_id); - virtual ~IPXManagerClass (); // stop listening - - /*..................................................................... - Initialization routines. - .....................................................................*/ - int Init (void); - int Is_IPX(void); - virtual void Set_Timing (unsigned long retrydelta, unsigned long maxretries, - unsigned long timeout); - void Set_Bridge(NetNumType bridge); - - /*..................................................................... - These routines control creation of the "Connections" (data queues) for - each remote system. - .....................................................................*/ - bool Create_Connection(int id, char *name, IPXAddressClass *address); - bool Delete_Connection(int id); - virtual int Num_Connections(void); - virtual int Connection_ID(int index); - char *Connection_Name(int id); - IPXAddressClass * Connection_Address(int id); - virtual int Connection_Index(int id); - - /*..................................................................... - This is how the application sends & receives messages. - .....................................................................*/ - int Send_Global_Message (void *buf, int buflen, int ack_req = 0, - IPXAddressClass *address = NULL); - int Get_Global_Message (void *buf, int *buflen, IPXAddressClass *address, - unsigned short *product_id); - - virtual int Send_Private_Message (void *buf, int buflen, - int ack_req = 1, int conn_id = CONNECTION_NONE); - virtual int Get_Private_Message (void *buf, int *buflen, int *conn_id); - - /*..................................................................... - The main polling routine; should be called as often as possible. - .....................................................................*/ - virtual int Service (void); - - /*..................................................................... - This routine reports which connection has an error on it. - .....................................................................*/ - int Get_Bad_Connection(void); - - /*..................................................................... - Queue utility routines. The application can determine how many - messages are in the send/receive queues. - .....................................................................*/ - virtual int Global_Num_Send(void); - virtual int Global_Num_Receive(void); - virtual int Private_Num_Send(int id = CONNECTION_NONE); - virtual int Private_Num_Receive(int id = CONNECTION_NONE); - - /*..................................................................... - This routine changes the socket ID assigned the IPX Manager when it - was constructed. Do not call this function after calling Init()! - The Socket ID should be known by both ends of the communications before - any packets are sent. - .....................................................................*/ - void Set_Socket(unsigned short socket); - - /*..................................................................... - Routines to return the largest average queue response time, and to - reset the response time for all queues. - .....................................................................*/ - virtual unsigned long Response_Time(void); - unsigned long Global_Response_Time(void); - virtual void Reset_Response_Time(void); - - /*..................................................................... - This routine returns a pointer to the oldest non-ACK'd buffer I've sent. - .....................................................................*/ - void * Oldest_Send(void); - - /*..................................................................... - Debug routines - .....................................................................*/ - virtual void Configure_Debug(int index, int offset, int size, - char **names, int maxnames); - virtual void Mono_Debug_Print(int index, int refresh = 0); - - /* - --------------------------- Private Interface ---------------------------- - */ - private: - /*..................................................................... - These routines allocate & free the DOS Real-mode memory block. - .....................................................................*/ - int Alloc_RealMode_Mem(void); - int Free_RealMode_Mem(void); - - /*..................................................................... - Misc variables - .....................................................................*/ - unsigned int IPXStatus : 1; // 0 = no IPX, 1 = IPX found - unsigned int Listening : 1; // 1 = Listening is on - unsigned int RealMemAllocd : 1; // 1 = Real-mode memory has been alloc'd - - /*..................................................................... - Packet Sizes, used for allocating real-mode memory - .....................................................................*/ - int Glb_MaxPacketLen; // Global Channel maximum packet size - int Glb_NumPackets; // # Global send/receive packets - int Pvt_MaxPacketLen; // Private Channel maximum packet size - int Pvt_NumPackets; // # Private send/receive packets - - /*..................................................................... - The ProductID is used in the Global Channel's packet header, and it's - used for the Private Channels' Magic Number. - .....................................................................*/ - unsigned short ProductID; // product ID - - /*..................................................................... - The Socket ID, and local Novell Connection Number - .....................................................................*/ - unsigned short Socket; // Our socket ID for sending/receiving - int ConnectionNum; // local connection #, 0=not logged in - - /*..................................................................... - Array of connection queues - .....................................................................*/ - IPXConnClass * Connection[CONNECT_MAX]; // array of connection object ptrs - int NumConnections; // # connection objects in use - IPXGlobalConnClass *GlobalChannel; // the Global Channel - - /*..................................................................... - Current queue for polling for received packets - .....................................................................*/ - int CurConnection; - - /*..................................................................... - Timing parameters for all connections - .....................................................................*/ - unsigned long RetryDelta; - unsigned long MaxRetries; - unsigned long Timeout; - - /*--------------------------------------------------------------------- - Real-mode memory pointers and such - ---------------------------------------------------------------------*/ - /*..................................................................... - This is a structure that mirrors data in real-mode memory: - .....................................................................*/ - typedef struct { - short Marker1; // the byte ID marker - ECBType ListenECB; // the Listening ECB - short NumBufs; // # of buffers we're giving to the handler - char *BufferFlags; // array of buffer-avail flags - short PacketSize; // size of packet including IPX header - IPXHeaderType *FirstPacketBuf; // ptr to 1st packet buffer - short CurIndex; // handler's current packet index - IPXHeaderType *CurPacketBuf; // handler's current packet buf - short FuncOffset; // contains offset of code - char Semaphore; // prevents re-entrancy - short ReEntrantCount; // times we've been called re-entrantly - short StackPtr; // real-mode stack pointer - short StackSeg; // real-mode stack segment - short StackPtr_int; // internal stack pointer - short StackSeg_int; // internal stack segment - short StackCheck; // stack check value (0x1234) - short Stack[256]; // actual stack space - short StackSpace; // label for top of stack - short Marker2; // the byte ID marker - } RealModeDataType; - - /*..................................................................... - The number & size of packet buffers in low memory - .....................................................................*/ - int NumBufs; // # packet buffers allocated - int PacketLen; // size of packet without IPX header - int FullPacketLen; // size of packet including IPX header - - /*..................................................................... - Selector & Segment of the DOS allocation; - Size of the allocation; - Ptr to the real-mode assembly data area - .....................................................................*/ - unsigned short Selector; // selector of DOS allocation pointer - unsigned short Segment; // real-mode segment of DOS allocation - int RealMemSize; // size of real mode memory allocated - RealModeDataType *RealModeData; // assembly routine & its data - - /*..................................................................... - This is a real-mode pointer to the address of the real-mode assembly - entry point. - .....................................................................*/ - long Handler; - - /*..................................................................... - Event Control Block for listening; contained within the real-mode - assembly routine's data area - .....................................................................*/ - ECBType *ListenECB; // ECB for listening - - /*..................................................................... - ptr to the 1st header & data buffers in the packet buffer array - .....................................................................*/ - IPXHeaderType *FirstHeaderBuf; // array of packet headers & buffers - char *FirstDataBuf; // 1st data buffer area - - /*..................................................................... - Current packet index & ptrs for parsing packets - .....................................................................*/ - int CurIndex; // Current packet index, for reading - IPXHeaderType *CurHeaderBuf; // Current packet ptr, for reading - char *CurDataBuf; // Current actual data ptr - - /*..................................................................... - ECB, header, & buffer for sending - .....................................................................*/ - ECBType *SendECB; // ECB for sending - IPXHeaderType *SendHeader; // Header for sending - char *SendBuf; // buffer for sending - - /*..................................................................... - Flags indicating whether a buffer contains data or not (1 = full) - The IPXManager must clear this flag; the real-mode routine will set it. - .....................................................................*/ - char *BufferFlags; // array of rx-buffer-avail flags - - /*..................................................................... - Various Statistics - .....................................................................*/ - int SendOverflows; - int ReceiveOverflows; - int BadConnection; -}; - -#endif -/*************************** end of ipxmgr.h *******************************/ diff --git a/code/TIBERIANDAWN/IPXPROT.ASM b/code/TIBERIANDAWN/IPXPROT.ASM deleted file mode 100644 index e5bf9d6..0000000 --- a/code/TIBERIANDAWN/IPXPROT.ASM +++ /dev/null @@ -1,110 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - - -;!!!!!!!!!!!!!!!!!!! lock the allocation - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : VQLIB * -;* * -;* File Name : HANDLER.ASM * -;* * -;* Programmer : Bill Randolph * -;* * -;* Start Date : April 7, 1995 * -;* * -;* Last Update : April 7, 1995 [BRR] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* IPXHandler -- callback routine for IPX * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -;********************* Model & Processor Directives ************************ -IDEAL -P386 -MODEL USE32 FLAT -LOCALS ?? - - -;******************************** Includes ********************************* - - -;******************************** Defines *********************************** - - -;****************************** Declarations ******************************** -global C Get_RM_IPX_Address:NEAR -global C Get_RM_IPX_Size:NEAR - -;********************************* Data ************************************ - DATASEG - -LABEL RealBinStart BYTE -include "obj\ipxreal.ibn" -LABEL RealBinEnd BYTE - -;********************************* Data ************************************ - CODESEG - -;*************************************************************************** -;* Get_RM_IPX_Address -- Return address of real mode code for copy. * -;* * -;* INPUT: * -;* none * -;* * -;* OUTPUT: * -;* VOID * to the address of the real mode IPX code * -;* * -;* PROTO: * -;* VOID *Get_RM_IPX_Address(VOID); * -;* * -;* HISTORY: * -;* 07/06/1994 SKB : Created. * -;*=========================================================================* - PROC Get_RM_IPX_Address C Near - - mov eax, OFFSET RealBinStart - ret - - ENDP - -;*************************************************************************** -;* Get_RM_IPX_Size -- return size of real mode IPX code. * -;* * -;* INPUT: * -;* none * -;* * -;* OUTPUT: * -;* LONG size of the real mode IPX code * -;* * -;* PROTO: * -;* LONG Get_RM_IPX_Size(VOID); * -;* * -;* HISTORY: * -;* 07/06/1994 SKB : Created. * -;*=========================================================================* - PROC Get_RM_IPX_Size C Near - - mov eax, OFFSET RealBinEnd - OFFSET RealBinStart - ret - - ENDP - - END - -;************************** End of handler.asm ***************************** diff --git a/code/TIBERIANDAWN/IPXREAL.ASM b/code/TIBERIANDAWN/IPXREAL.ASM deleted file mode 100644 index 7e53501..0000000 --- a/code/TIBERIANDAWN/IPXREAL.ASM +++ /dev/null @@ -1,316 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : VQLIB * -;* * -;* File Name : HANDLER.ASM * -;* * -;* Programmer : Bill Randolph * -;* * -;* Start Date : April 7, 1995 * -;* * -;* Last Update : April 7, 1995 [BRR] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* IPXHandler -- callback routine for IPX * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -;********************* Model & Processor Directives ************************ -IDEAL -MODEL LARGE -P386N -LOCALS ?? - - -;******************************** Includes ********************************* - - -;******************************** Defines *********************************** - - -;****************************** Declarations ******************************** -global C IPXHandler:FAR - - -;********************************* Code ************************************ - CODESEG - - -;--------------------------------------------------------------------------- -; The markers let the application verify that it's mapping this memory -; correctly. -;--------------------------------------------------------------------------- -Marker1 DW 1111h ; placeholder to find data start - -;--------------------------------------------------------------------------- -; This is the IPX Event Control Block: -;--------------------------------------------------------------------------- -ECB_LinkAddress DD ? -ECB_EventServiceRoutine DD ? ; Event Handler ptr -ECB_InUse DB ? ; 0 = event is complete -ECB_CompletionCode DB ? ; 0 = OK, IPX error otherwise -ECB_SocketNumber DW ? ; socket to listen/send on -ECB_ConnectionID DW ? -ECB_RestOfWorkspace DW ? -ECB_DriverWorkSpace DB 12 DUP (?) -ECB_ImmediateAddress DB 6 DUP (?) ; bridge address -ECB_PacketCount DW ? ; # data areas (2) -ECB_HeaderAddress DD ? ; ptr to IPX header buffer -ECB_HeaderLength DW ? ; length of IPX header buffer -ECB_PacketAddress DD ? ; ptr to packet buffer -ECB_PacketLength DW ? ; length of packet buffer - -;--------------------------------------------------------------------------- -; The rest of the variables are for telling IPX which buffer to store the -; next incoming packet in. They must be initialized by the application. -;--------------------------------------------------------------------------- -NumBufs DW 0 ; # buffers provided by app -BufferFlags DD 0 ; array of in-use flags (1 = in use) -PacketSize DW 0 ; total size of 1 buf (incl IPX hdr) -FirstPacketBuf DD 0 ; ptr to 1st packet buffer -CurIndex DW 0 ; current packet/flag index -CurPacketBuf DD 0 ; ptr to current packet buf -FuncOffset DW StartLabel ; offset of our routine - -;--------------------------------------------------------------------------- -; These values are for preventing re-entrancy; they're currently not used. -;--------------------------------------------------------------------------- -Semaphore DB 0 ; prevents re-entrancy -ReEntrantCount DW 0 ; times we've been called re-entrantly - -;--------------------------------------------------------------------------- -; Local stack space -;--------------------------------------------------------------------------- -StackPtr DW 0 ; saved copy of stack ptr -StackSeg DW 0 ; saved copy of stack seg -StackPtr_int DW 0 ; our internal stack ptr -StackSeg_int DW 0 ; our internal stack seg -StackCheck DW 1234h ; check for stack overflow - DW 256 DUP (0) ; stack storage space -StackSpace DW 0 ; label for our stack space - -;--------------------------------------------------------------------------- -; These bytes mark the end of the real-mode data area -;--------------------------------------------------------------------------- -Marker2 DW 2222h ; placeholder to find data end - - -;*************************************************************************** -;* IPXHandler -- IPX callback routine * -;* * -;* This routine is assembled as a stand-alone executable, then loaded * -;* into low DOS memory by a protected-mode application. * -;* * -;* INPUT: * -;* none. * -;* * -;* OUTPUT: * -;* none. * -;* * -;* WARNINGS: * -;* none. * -;* * -;* HISTORY: * -;* 04/07/1995 BRR : Created. * -;*=========================================================================* - label StartLabel - PROC IPXHandler C FAR USES - - ;................................................................... - ; Turn off interrupts; make sure memory copies go forward - ;................................................................... - pushf - cli - cld - - ;................................................................... - ; Set up segment registers to point DS to CS - ;................................................................... - push ds - push ax - mov ax,cs - mov ds,ax - - ;................................................................... - ; Set up our local stack; save SS & SP first. - ;................................................................... - mov [StackSeg],ss - mov [StackPtr],sp - mov [StackPtr_int], OFFSET StackSpace - mov [StackSeg_int], SEG StackSpace - lss sp, [DWORD PTR StackPtr_int] - - - ;................................................................... - ; Save all registers - ;................................................................... - pushad - push es - - ;................................................................... - ; If we've been called re-entrantly, just exit - ;................................................................... - cmp [Semaphore],0 - jz ??Start_Handler - add [ReEntrantCount],1 - jmp ??Exit_Handler - -??Start_Handler: - ;................................................................... - ; Set our semaphore - ;................................................................... - mov [Semaphore],1 - - ;------------------------------------------------------------------- - ; Set 'CurIndex' to the index of the next-available receive buffer, - ; and 'CurPacketBuf to the next-available packet buffer - ;------------------------------------------------------------------- - ;................................................................... - ; Get 'CurIndex' & increment it. Wrap to 0 if we reach 'NumBufs' - ; Since I'm treating 'CurPacketBuf' as a long integer (and not as - ; a segment:offset), the entire data area can't be larger than 64K. - ;................................................................... - mov dx,[CurIndex] ; DX = CurIndex - mov eax,[CurPacketBuf] ; EAX = current packet buffer addr - inc dx ; DX = next index - add ax,[PacketSize] ; EAX = next buffer ptr - cmp dx,[NumBufs] ; see if DX is past # buffers - jb ??Get_Flag - mov dx,0 ; wrap to 1st index - mov eax,[FirstPacketBuf] ; wrap to 1st packet buffer - -??Get_Flag: - ;................................................................... - ; Get the next buffer-in-use flag; if it's 0, load [CurIndex] with - ; the value of SI (the next index). If it's 1, skip the updating of - ; the index, flag & buffer ptr. - ; DX = new CurIndex - ; EAX = new CurPacketBuf - ;................................................................... - les di,[BufferFlags] ; ES:DI = BufferFlags address - mov bx,di ; BX = DI + new CurIndex - add bx,dx - - cmp [BYTE PTR es:bx],0 ; compare next flag to 0 (avail) - jne ??Set_ECB ; if not avail, skip setting new values - - ;................................................................... - ; The next buffer is available; so, set this buffer's In-Use flag - ; to 1, and move on to the next buffer. Do not set this buffer's - ; flag to 1 until we move on to the next buffer, to prevent the - ; application from reading the currently-in-use packet buffer. - ; DX = new CurIndex - ; EAX = new CurPacketBuf - ; ES:DI = BufferFlags address - ;................................................................... - mov bx,di ; BX = DI + old CurIndex - add bx,[CurIndex] - mov [BYTE PTR es:bx],1 ; set old BufferFlags value to in-use - - mov [CurIndex],dx ; save new index - mov [CurPacketBuf],eax ; save new packet address - - ;------------------------------------------------------------------- - ; Set up the Event Control Block to tell IPX to start listening. - ; The following entries are filled in by the app, and should be left - ; alone: - ; - EventServiceRoutine - ; - SocketNumber - ; The rest should be re-initialized. Note that EBX is now pointing - ; to an unavailable buffer if the next buffer was already in use; - ; so it must be reloaded with the correct buffer address from - ; [CurPacketBuf]. - ;------------------------------------------------------------------- -??Set_ECB: - mov [ECB_LinkAddress],0 ; default - mov [ECB_InUse],0 ; default - mov [ECB_CompletionCode],0 ; default - mov [ECB_ConnectionID],0 ; default - mov [ECB_RestOfWorkspace],0 ; default - mov [ECB_DriverWorkSpace],0 ; default - mov [ECB_ImmediateAddress],0 ; default - mov [ECB_PacketCount],2 ; use 2 data areas - mov ebx,[CurPacketBuf] ; get current buffer address - mov [ECB_HeaderAddress],ebx ; set header address - mov [ECB_HeaderLength],30 ; size of IPX header - add ebx,30 ; point to past the header - mov [ECB_PacketAddress],ebx ; set packet data address - mov ax,[PacketSize] ; get size of one buffer - sub ax,30 ; remove size of IPX header - mov [ECB_PacketLength],ax ; set size of packet data - - ;------------------------------------------------------------------- - ; Clear the IPX header for this packet - ;------------------------------------------------------------------- - les di,[ECB_HeaderAddress] ; ES:DI = IPX Listen Header - mov cx,30 ; (30 bytes = size of header) - mov al,0 - rep stosb ; clear to 0's - - ;------------------------------------------------------------------- - ; Command IPX to start listening again. - ;------------------------------------------------------------------- - mov bx,4 ; IPX code for Listen - mov ax,ds ; ES = segment of ListenECB - mov es,ax - mov ax,OFFSET ECB_LinkAddress - mov si,ax ; ES:SI = address of ECB - int 07ah ; call IPX interrupt - - ;................................................................... - ; Clear our semaphore - ;................................................................... - mov [Semaphore],0 - -??Exit_Handler: - ;................................................................... - ; Pop values from our local stack - ;................................................................... - pop es - popad - - ;................................................................... - ; Check our stack-check value; if the stack has overflowed, generate - ; a debugger break. - ;................................................................... - cmp [StackCheck],1234h - je ??Restore_Stack - int 3 - - ;................................................................... - ; Restore the stack to its previous value - ;................................................................... -??Restore_Stack: - lss sp, [DWORD PTR StackPtr] - - ;................................................................... - ; Pop the rest of the registers - ;................................................................... - pop ax - pop ds - - popf - - ret - -ENDP IPXHandler - -END - -;************************** End of handler.asm ***************************** diff --git a/code/TIBERIANDAWN/JSHELL.CPP b/code/TIBERIANDAWN/JSHELL.CPP deleted file mode 100644 index 56c8dbe..0000000 --- a/code/TIBERIANDAWN/JSHELL.CPP +++ /dev/null @@ -1,434 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\jshell.cpv 2.18 16 Oct 1995 16:51:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : JSHELL.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 2, 1994 * - * * - * Last Update : May 11, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Build_Translucent_Table -- Creates a translucent control table. * - * Translucent_Table_Size -- Determines the size of a translucent table. * - * Conquer_Build_Translucent_Table -- Builds fading table for shadow colors only. * - * Load_Alloc_Data -- Allocates a buffer and loads the file into it. * - * Load_Uncompress -- Loads and uncompresses data to a buffer. * - * Fatal -- General purpose fatal error handler. * - * Set_Window -- Sets the window dimensions to that specified. * - * Small_Icon -- Create a small icon from a big one. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "wwfile.h" - -#include - -/*********************************************************************************************** - * Small_Icon -- Create a small icon from a big one. * - * * - * This routine will extract the specified icon from the icon data file and convert that * - * incon into a small (3x3) representation. Typicall use of this mini-icon is for the radar * - * map. * - * * - * INPUT: iconptr -- Pointer to the icon data file. * - * * - * iconnum -- The embedded icon number to convert into a small image. * - * * - * OUTPUT: Returns with a pointer to the small icon imagery. This is exactly 9 bytes long. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/11/1995 JLB : Created. * - *=============================================================================================*/ -void * Small_Icon(void const * iconptr, int iconnum) -{ - static unsigned char _icon[9]; - IControl_Type const * iptr = (IControl_Type const *)iconptr; - unsigned char * data; - - if (iconptr) { - iconnum = iptr->Map[iconnum]; - data = &iptr->Icons[iconnum*(24*24)]; - - for (int index = 0; index < 9; index++) { - int _offsets[9] = { - 4+4*24, - 12+4*24, - 20+4*24, - 4+12*24, - 12+12*24, - 20+12*24, - 4+20*24, - 12+20*24, - 20+20*24 - }; - _icon[index] = data[_offsets[index]]; - } - } - - return(_icon); -} - - -/*********************************************************************************************** - * Set_Window -- Sets the window dimensions to that specified. * - * * - * Use this routine to set the windows dimensions to the coordinates and dimensions * - * specified. * - * * - * INPUT: x -- Window X pixel position. * - * * - * y -- Window Y pixel position. * - * * - * w -- Window width in pixels. * - * * - * h -- Window height in pixels. * - * * - * OUTPUT: none * - * * - * WARNINGS: The X and width values are truncated to an even 8 pixel boundary. This is * - * the same as stripping off the lower 3 bits. * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void Set_Window(int window, int x, int y, int w, int h) -{ - WindowList[window][WINDOWWIDTH] = w >> 3; - WindowList[window][WINDOWHEIGHT] = h; - WindowList[window][WINDOWX] = x >> 3; - WindowList[window][WINDOWY] = y; -} - - -/*********************************************************************************************** - * Fatal -- General purpose fatal error handler. * - * * - * This is a very simple general purpose fatal error handler. It goes directly to text * - * mode, prints the error, and then aborts with a failure code. * - * * - * INPUT: message -- The text message to display. * - * * - * ... -- Any optional parameters that are used in formatting the message. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine never returns. The game exits immediately. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void Fatal(char const *message, ...) -{ - va_list va; - - va_start(va, message); - Prog_End(); - vfprintf(stderr, message, va); - Mono_Printf(message); - GlyphX_Debug_Print("Fatal"); - GlyphX_Debug_Print(message); - - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } else { - *((int*)0) = 0; - } -} - - -#ifdef NEVER -void File_Fatal(char const *message) -{ - Prog_End(); - perror(message); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } -} -#endif - - - -/*********************************************************************************************** - * Load_Uncompress -- Loads and uncompresses data to a buffer. * - * * - * This is the C++ counterpart to the Load_Uncompress function. It will load the file * - * specified into the graphic buffer indicated and uncompress it. * - * * - * INPUT: file -- The file to load and uncompress. * - * * - * uncomp_buff -- The graphic buffer that initial loading will use. * - * * - * dest_buff -- The buffer that will hold the uncompressed data. * - * * - * reserved_data -- This is an optional pointer to a buffer that will hold any * - * reserved data the compressed file may contain. This is * - * typically a palette. * - * * - * OUTPUT: Returns with the size of the uncompressed data in the destination buffer. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -long Load_Uncompress(FileClass &file, BuffType &uncomp_buff, BuffType &dest_buff, void *reserved_data) -{ - unsigned short size; - void *sptr = uncomp_buff.Get_Buffer(); - void *dptr = dest_buff.Get_Buffer(); - int opened = false; - CompHeaderType header; - - /* - ** The file must be opened in order to be read from. If the file - ** isn't opened, then open it. Record this fact so that it can be - ** restored to its closed state at the end. - */ - if (!file.Is_Open()) { - if (!file.Open()) { - return(0); - } - opened = true; - } - - /* - ** Read in the size of the file (supposedly). - */ - file.Read(&size, sizeof(size)); - - /* - ** Read in the header block. This block contains the compression type - ** and skip data (among other things). - */ - file.Read(&header, sizeof(header)); - size -= sizeof(header); - - /* - ** If there are skip bytes then they must be processed. Either read - ** them into the buffer provided or skip past them. No check is made - ** to ensure that the reserved data buffer is big enough (watch out!). - */ - if (header.Skip) { - size -= header.Skip; - if (reserved_data) { - file.Read(reserved_data, header.Skip); - } else { - file.Seek(header.Skip, SEEK_CUR); - } - header.Skip = 0; - } - - /* - ** Determine where is the proper place to load the data. If both buffers - ** specified are identical, then the data should be loaded at the end of - ** the buffer and decompressed at the beginning. - */ - if (uncomp_buff.Get_Buffer() == dest_buff.Get_Buffer()) { - sptr = Add_Long_To_Pointer(sptr, uncomp_buff.Get_Size()-(size+sizeof(header))); - } - - /* - ** Read in the bulk of the data. - */ - Mem_Copy(&header, sptr, sizeof(header)); - file.Read(Add_Long_To_Pointer(sptr, sizeof(header)), size); - - /* - ** Decompress the data. - */ - size = (unsigned int) Uncompress_Data(sptr, dptr); - - /* - ** Close the file if necessary. - */ - if (opened) { - file.Close(); - } - return((long)size); -} - - -/*********************************************************************************************** - * Load_Alloc_Data -- Allocates a buffer and loads the file into it. * - * * - * This is the C++ replacement for the Load_Alloc_Data function. It will allocate the * - * memory big enough to hold the file and then read the file into it. * - * * - * INPUT: file -- The file to read. * - * * - * mem -- The memory system to use for allocation. * - * * - * OUTPUT: Returns with a pointer to the allocated and filled memory block. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void * Load_Alloc_Data(FileClass &file) -{ - void *ptr = 0; - long size = file.Size(); - - ptr = new char [size]; - if (ptr) { - file.Read(ptr, size); - } - return(ptr); -} - - -/*********************************************************************************************** - * Translucent_Table_Size -- Determines the size of a translucent table. * - * * - * Use this routine to determine how big the translucent table needs * - * to be given the specified number of colors. This value is typically * - * used when allocating the buffer for the translucent table. * - * * - * INPUT: count -- The number of colors that are translucent. * - * * - * OUTPUT: Returns the size of the translucent table. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/02/1994 JLB : Created. * - *=============================================================================================*/ -long Translucent_Table_Size(int count) -{ - return(256L + (256L * count)); -} - - -/*********************************************************************************************** - * Build_Translucent_Table -- Creates a translucent control table. * - * * - * The table created by this routine is used by Draw_Shape (GHOST) to * - * achieve a translucent affect. The original color of the shape will * - * show through. This differs from the fading effect, since that * - * affect only alters the background color toward a single destination * - * color. * - * * - * INPUT: palette -- Pointer to the control palette. * - * * - * control -- Pointer to array of structures that control how * - * the translucent table will be built. * - * * - * count -- The number of entries in the control array. * - * * - * buffer -- Pointer to buffer to place the translucent table. * - * If NULL is passed in, then the buffer will be * - * allocated. * - * * - * OUTPUT: Returns with pointer to the translucent table. * - * * - * WARNINGS: This routine is exceedingly slow. Use sparingly. * - * * - * HISTORY: * - * 04/02/1994 JLB : Created. * - *=============================================================================================*/ -void *Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer) -{ - unsigned char const *table; // Remap table pointer. - int index; // Working color index. - - if (count && control && palette) { - if (!buffer) { - buffer = new char [Translucent_Table_Size(count)]; - } - - if (buffer) { - memset(buffer, -1, 256); - table = (unsigned char*)Add_Long_To_Pointer((void*)buffer, 256); - - /* - ** Build the individual remap tables for each translucent color. - */ - for (index = 0; index < count; index++) { - ((unsigned char*)buffer)[control[index].SourceColor] = index; - Build_Fading_Table(palette, (void*)table, control[index].DestColor, control[index].Fading); - table = (unsigned char*)Add_Long_To_Pointer((void*)table, 256); - } - } - } - return(buffer); -} - - -/*********************************************************************************************** - * Conquer_Build_Translucent_Table -- Builds fading table for shadow colors only. * - * * - * This routine will build a translucent (fading) table to remap colors into the shadow * - * color region of the palette. Shadow colors are not affected by this translucent table. * - * This means that a shape can be overlapped any number of times and the imagery will * - * remain deterministic (and constant). * - * * - * INPUT: palette -- Pointer to the palette to base the translucent process on. * - * * - * control -- Pointer to special control structure that specifies the * - * target color, and percentage of fade. * - * * - * count -- The number of colors to be remapped (entries in the control array). * - * * - * buffer -- Pointer to the staging buffer that will hold the translucent table * - * data. If this parameter is NULL, then an appropriate sized table * - * will be allocated. * - * * - * OUTPUT: Returns with a pointer to the translucent table data. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/27/1994 JLB : Created. * - *=============================================================================================*/ -void *Conquer_Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer) -{ - unsigned char const *table; // Remap table pointer. - int index; // Working color index. - - if (count && control && palette) { - if (!buffer) { - buffer = new char [Translucent_Table_Size(count)]; - } - - if (buffer) { - memset(buffer, -1, 256); - table = (unsigned char*)Add_Long_To_Pointer((void*)buffer, 256); - - /* - ** Build the individual remap tables for each translucent color. - */ - for (index = 0; index < count; index++) { - ((unsigned char*)buffer)[control[index].SourceColor] = index; - Conquer_Build_Fading_Table(palette, (void*)table, control[index].DestColor, control[index].Fading); - table = (unsigned char*)Add_Long_To_Pointer((void*)table, 256); - } - } - } - return(buffer); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/JSHELL.H b/code/TIBERIANDAWN/JSHELL.H deleted file mode 100644 index b4d98c4..0000000 --- a/code/TIBERIANDAWN/JSHELL.H +++ /dev/null @@ -1,248 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\jshell.h_v 2.16 16 Oct 1995 16:45:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : JSHELL.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/13/95 * - * * - * Last Update : March 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef JSHELL_H -#define JSHELL_H - -/* -** Interface class to the keyboard. This insulates the game from library vagaries. Most -** notable being the return values are declared as "int" in the library whereas C&C -** expects it to be of KeyNumType. -*/ -class Keyboard -{ - public: - static KeyNumType Get(void) {return (KeyNumType)Get_Key_Num();}; - static KeyNumType Check(void) {return (KeyNumType)Check_Key_Num();}; - static KeyASCIIType To_ASCII(KeyNumType key) {return (KeyASCIIType)KN_To_KA(key);}; - static void Clear(void) {Clear_KeyBuffer();}; - static void Stuff(KeyNumType key) {Stuff_Key_Num(key);}; - static int Down(KeyNumType key) {return Key_Down(key);}; - static int Mouse_X(void) {return Get_Mouse_X();}; - static int Mouse_Y(void) {return Get_Mouse_Y();}; -}; - - -#ifdef NEVER -inline void * operator delete(void * data) -{ - Free(data); -} - -inline void * operator delete[] (void * data) -{ - Free(data); -} -#endif - - -/* -** These templates allow enumeration types to have simple bitwise -** arithmatic performed. The operators must be instatiated for the -** enumerated types desired. -*/ -template inline T operator ++(T & a) -{ - a = (T)((int)a + (int)1); - return(a); -} -template inline T operator ++(T & a, int) -{ - T aa = a; - a = (T)((int)a + (int)1); - return(aa); -} -template inline T operator --(T & a) -{ - a = (T)((int)a - (int)1); - return(a); -} -template inline T operator --(T & a, int) -{ - T aa = a; - a = (T)((int)a - (int)1); - return(aa); -} -template inline T operator |(T t1, T t2) -{ - return((T)((int)t1 | (int)t2)); -} -template inline T operator &(T t1, T t2) -{ - return((T)((int)t1 & (int)t2)); -} -template inline T operator ~(T t1) -{ - return((T)(~(int)t1)); -} - - -/* -** The shape flags are likely to be "or"ed together and other such bitwise -** manipulations. These instatiated operator templates allow this. -*/ -//inline ShapeFlags_Type operator |(ShapeFlags_Type, ShapeFlags_Type); -//inline ShapeFlags_Type operator &(ShapeFlags_Type, ShapeFlags_Type); -//inline ShapeFlags_Type operator ~(ShapeFlags_Type); - - - -//#pragma aux Set_Bit parm [esi] [ecx] [eax] -void __cdecl Set_Bit(void * array, int bit, int value); - - -//#pragma aux Get_Bit parm [esi] [eax] -int __cdecl Get_Bit(void const * array, int bit); - -//#pragma aux First_True_Bit parm [esi] -int __cdecl First_True_Bit(void const * array, int size); - -//#pragma aux First_False_Bit parm [esi] -int __cdecl First_False_Bit(void const * array, int size); - -//#pragma aux Bound parm [eax] [ebx] [ecx] -int __cdecl Bound(int original, int min, int max); - - -#if (0) -void Set_Bit(void * array, int bit, int value); -#pragma aux Set_Bit parm [esi] [ecx] [eax] \ - modify [esi ebx] = \ - "mov ebx,ecx" \ - "shr ebx,5" \ - "and ecx,01Fh" \ - "btr [esi+ebx*4],ecx" \ - "or eax,eax" \ - "jz ok" \ - "bts [esi+ebx*4],ecx" \ - "ok:" - -int Get_Bit(void const * array, int bit); -#pragma aux Get_Bit parm [esi] [eax] \ - modify [esi ebx] \ - value [eax] = \ - "mov ebx,eax" \ - "shr ebx,5" \ - "and eax,01Fh" \ - "bt [esi+ebx*4],eax" \ - "setc al" - -int First_True_Bit(void const * array); -#pragma aux First_True_Bit parm [esi] \ - modify [esi ebx] \ - value [eax] = \ - "mov eax,-32" \ - "again:" \ - "add eax,32" \ - "mov ebx,[esi]" \ - "add esi,4" \ - "bsf ebx,ebx" \ - "jz again" \ - "add eax,ebx" - -int First_False_Bit(void const * array); -#pragma aux First_False_Bit parm [esi] \ - modify [esi ebx] \ - value [eax] = \ - "mov eax,-32" \ - "again:" \ - "add eax,32" \ - "mov ebx,[esi]" \ - "not ebx" \ - "add esi,4" \ - "bsf ebx,ebx" \ - "jz again" \ - "add eax,ebx" - -extern int Bound(int original, int min, int max); -#pragma aux Bound parm [eax] [ebx] [ecx] \ - modify [eax] \ - value [eax] = \ - "cmp ebx,ecx" \ - "jl okorder" \ - "xchg ebx,ecx" \ - "okorder: cmp eax,ebx" \ - "jg okmin" \ - "mov eax,ebx" \ - "okmin: cmp eax,ecx" \ - "jl okmax" \ - "mov eax,ecx" \ - "okmax:" - -#ifdef NEVER -extern unsigned Bound(unsigned original, unsigned min, unsigned max); -#pragma aux Bound parm [eax] [ebx] [ecx] \ - modify [eax] \ - value [eax] = \ - "cmp ebx,ecx" \ - "jb okorder" \ - "xchg ebx,ecx" \ - "okorder: cmp eax,ebx" \ - "ja okmin" \ - "mov eax,ebx" \ - "okmin: cmp eax,ecx" \ - "jb okmax" \ - "mov eax,ecx" \ - "okmax:" -#endif - - -unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed); -#pragma aux Fixed_To_Cardinal parm [eax] [edx] \ - modify [edx] \ - value [eax] = \ - "mul edx" \ - "add eax,080h" \ - "test eax,0FF000000h" \ - "jz ok" \ - "mov eax,000FFFFFFh" \ - "ok:" \ - "shr eax,8" - - -unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal); -#pragma aux Cardinal_To_Fixed parm [ebx] [eax] \ - modify [edx] \ - value [eax] = \ - "or ebx,ebx" \ - "jz fini" \ - "shl eax,8" \ - "xor edx,edx" \ - "div ebx" \ - "fini:" - -#endif //(0) - - -#endif diff --git a/code/TIBERIANDAWN/KEYFBUFF.ASM b/code/TIBERIANDAWN/KEYFBUFF.ASM deleted file mode 100644 index 8a2e19c..0000000 --- a/code/TIBERIANDAWN/KEYFBUFF.ASM +++ /dev/null @@ -1,4015 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Command & Conquer * -;* * -;* File Name : KEYFBUFF.ASM * -;* * -;* Programmer : David R. Dettmer * -;* * -;* Start Date : March 3, 1995 * -;* * -;* Last Update : * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Buffer_Frame_To_Page -- Copies a linear buffer to a virtual viewport * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -;********************** Model & Processor Directives *********************** -;IDEAL -;P386 -;MODEL USE32 FLAT -;jumps - -.MODEL FLAT -;.386 - -;******************************** Includes ********************************* -;INCLUDE "gbuffer.inc" -;include "profile.inc" - -OPTIMAL_BYTE_COPY equ 14 - -GraphicViewPort STRUCT -GVPOffset DD ? ; offset to virtual viewport -GVPWidth DD ? ; width of virtual viewport -GVPHeight DD ? ; height of virtual viewport -GVPXAdd DD ? ; x mod to get to next line -GVPXPos DD ? ; x pos relative to Graphic Buff -GVPYPos DD ? ; y pos relative to Graphic Buff -GVPPitch dd ? ; modulo of graphic view port -GVPBuffPtr DD ? ; ptr to associated Graphic Buff -GraphicViewPort ENDS - -;******************************** Equates ********************************** - -TRUE equ 1 ; Boolean 'true' value -FALSE equ 0 ; Boolean 'false' value - -;*=========================================================================*/ -;* The following are defines used to control what functions are linked * -;* in for Buffer_Frame_To_Page. * -;*=========================================================================*/ -;USE_NORMAL EQU TRUE -;USE_HORZ_REV EQU TRUE -;USE_VERT_REV EQU TRUE -;USE_SCALING EQU TRUE - - -FLAG_NORMAL EQU 0 -FLAG_TRANS EQU 1 -FLAG_GHOST EQU 2 -FLAG_FADING EQU 4 -FLAG_PREDATOR EQU 8 - -FLAG_MASK EQU 0Fh - - -SHAPE_NORMAL EQU 0000h ; Standard shape -;SHAPE_HORZ_REV EQU 0001h ; Flipped horizontally -;SHAPE_VERT_REV EQU 0002h ; Flipped vertically -;SHAPE_SCALING EQU 0004h ; Scaled (WORD scale_x, WORD scale_y) -;SHAPE_VIEWPORT_REL EQU 0010h ; Coords are window-relative -;SHAPE_WIN_REL EQU 0010h ; Coordinates are window relative instead of absolute. -SHAPE_CENTER EQU 0020h ; Coords are based on shape's center pt -SHAPE_TRANS EQU 0040h ; has transparency - -SHAPE_FADING EQU 0100h ; Fading effect (VOID * fading_table, - ; WORD fading_num) -SHAPE_PREDATOR EQU 0200h ; Transparent warping effect -;SHAPE_COMPACT EQU 0400h ; Never use this bit -;SHAPE_PRIORITY EQU 0800h ; Use priority system when drawing -SHAPE_GHOST EQU 1000h ; Shape is drawn ghosted -;SHAPE_SHADOW EQU 2000h -SHAPE_PARTIAL EQU 4000h -;SHAPE_COLOR EQU 8000h ; Remap the shape's colors - ; (VOID * color_table) - - -; -;.......................... Shadow Effect .................................. -; -SHADOW_COL EQU 00FFh ; magic number for shadows - -;......................... Priority System ................................. -; -CLEAR_UNUSED_BITS EQU 0007h ; and with 0000-0111 to clear - ; non-walkable high bit and - ; scaling id bits -NON_WALKABLE_BIT EQU 0080h ; and with 1000-0000 to clear all - ; but non-walkable bit -; -;......................... Predator Effect ................................. -; -;PRED_MASK EQU 0007h ; mask used for predator pixel puts -PRED_MASK EQU 000Eh ; mask used for predator pixel puts - - -;--------------------------------------------------------------------------- -; -; Use a macro to make code a little cleaner. -; The parameter varname is optional. -; Syntax to use macro is : -; WANT equ expression -; USE func [,varname] -; If the 'varname' is defined, a table declaration is created like: -; GLOBAL TableName:DWORD -; Then, the table entry is created: -; If WANT is true, the table entry is created for the given function: -; varname DD func -; If WANT is not TRUE, a Not_Supported entry is put in the table: -; varname DD Not_Supported -; The resulting tables look like: -; -; GLOBAL ExampTable:DWORD -; ExampTable DD routine1 -; DD routine2 -; DD routine3 -; ... -; Thus, each table is an array of function pointers. -; -;--------------------------------------------------------------------------- -USE MACRO func, varname - IF WANT - varname DD func - ELSE - varname DD Not_Supported - ENDIF -ENDM - -prologue macro -endm - - - -epilogue macro -endm - - -; IFNB -; GLOBAL varname:DWORD -; ENDIF - -;--------------------------------------------------------------------------- - - -.DATA - -;--------------------------------------------------------------------------- -; Predator effect variables -;--------------------------------------------------------------------------- -; make table for negative offset and use the used space for other variables - -BFPredNegTable DW -1, -3, -2, -5, -2, -4, -3, -1 - ; 8 words below calculated - DW 0, 0, 0, 0, 0, 0, 0, 0 ; index ffffff00 - DD 0, 0, 0, 0 ; index ffffff10 -BFPredOffset DD 0, 0, 0, 0 ; index ffffff20 - DD 0, 0, 0, 0 ; index ffffff30 - ; partially faded predator effect value -BFPartialPred DD 0, 0, 0, 0 ; index ffffff40 -BFPartialCount DD 0, 0, 0, 0 ; index ffffff50 - DD 0, 0, 0, 0 ; index ffffff60 - DD 0, 0, 0, 0 ; index ffffff70 - DD 0, 0, 0, 0 ; index ffffff80 - DD 0, 0, 0, 0 ; index ffffff90 - DD 0, 0, 0, 0 ; index ffffffa0 - DD 0, 0, 0, 0 ; index ffffffb0 - DD 0, 0, 0, 0 ; index ffffffc0 - DD 0, 0, 0, 0 ; index ffffffd0 - DD 0, 0, 0, 0 ; index ffffffe0 - DD 0, 0, 0, 0 ; index fffffff0 -BFPredTable DW 1, 3, 2, 5, 2, 3, 4, 1 -;BFPredTable DB 1, 3, 2, 5, 4, 3, 2, 1 - - - - - - - extern C BigShapeBufferStart:dword - extern C UseBigShapeBuffer:dword - extern C TheaterShapeBufferStart:dword - extern C IsTheaterShape:dword - ;extern C Single_Line_Trans_Entry:near - ;extern C Next_Line:near - extern C MMX_Done:near - extern C MMXAvailable:dword - ;extern C EndNewShapeJumpTable:byte - ;extern C NewShapeJumpTable:dword - - -;********************************************************************************** -; -; Jump tables for new line header system -; -; Each line of shape data now has a header byte which describes the data on the line. -; - -; -; Header byte control bits -; -BLIT_TRANSPARENT =1 -BLIT_GHOST =2 -BLIT_FADING =4 -BLIT_PREDATOR =8 -BLIT_SKIP =16 -BLIT_ALL =BLIT_TRANSPARENT or BLIT_GHOST or BLIT_FADING or BLIT_PREDATOR or BLIT_SKIP - - -ShapeHeaderType STRUCT - - draw_flags dd ? - shape_data dd ? - shape_buffer dd ? - -ShapeHeaderType ENDS - - - -; -; Global definitions for routines that draw a single line of a shape -; - ;extern Short_Single_Line_Copy:near - ;extern Single_Line_Trans:near - ;extern Single_Line_Ghost:near - ;extern Single_Line_Ghost_Trans:near - ;extern Single_Line_Fading:near - ;extern Single_Line_Fading_Trans:near - ;extern Single_Line_Ghost_Fading:near - ;extern Single_Line_Ghost_Fading_Trans:near - ;extern Single_Line_Predator:near - ;extern Single_Line_Predator_Trans:near - ;extern Single_Line_Predator_Ghost:near - ;extern Single_Line_Predator_Ghost_Trans:near - ;extern Single_Line_Predator_Fading:near - ;extern Single_Line_Predator_Fading_Trans:near - ;extern Single_Line_Predator_Ghost_Fading:near - ;extern Single_Line_Predator_Ghost_Fading_Trans:near - ;extern Single_Line_Skip:near - - ;extern Single_Line_Single_Fade:near - ;extern Single_Line_Single_Fade_Trans:near - -;externdef AllFlagsJumpTable:dword -; -externdef NewShapeJumpTable:dword -externdef EndNewShapeJumpTable:byte -externdef CriticalFadeRedirections:dword -;externdef BufferFrameTable:dword - -;externdef CriticalFadeRedirections:dword -;externdef CriticalFadeRedirections:dword -;externdef CriticalFadeRedirections:dword -;externdef BF_Copy:far ptr -;externdef BF_Trans:dword -;externdef BF_Ghost:dword -;externdef BF_Ghost_Trans:dword -;externdef BF_Fading:dword -;externdef BF_Fading_Trans:dword -;externdef BF_Ghost_Fading:dword -;externdef BF_Ghost_Fading_Trans:dword -;externdef BF_Predator:dword -;externdef BF_Predator_Trans:dword -;externdef BF_Predator_Ghost:dword -;externdef BF_Predator_Ghost_Trans:dword -;externdef BF_Predator_Fading:dword -;externdef BF_Predator_Fading_Trans:dword -;externdef BF_Predator_Ghost_Fading:dword -;externdef BF_Predator_Ghost_Fading_Trans:dword - -externdef C Single_Line_Trans:near -externdef C Single_Line_Trans_Entry:near -externdef C Next_Line:near - - -.CODE - - -;--------------------------------------------------------------------------- -; Code Segment Tables: -; This code uses the USE macro to set up tables of function addresses. -; The tables have the following format: -; Tables defined are: -; BufferFrameTable -;--------------------------------------------------------------------------- - -WANT equ -USE BF_Copy, BufferFrameTable - -WANT equ -USE BF_Trans - -WANT equ -USE BF_Ghost - -WANT equ -USE BF_Ghost_Trans - -WANT equ -USE BF_Fading - -WANT equ -USE BF_Fading_Trans - -WANT equ -USE BF_Ghost_Fading - -WANT equ -USE BF_Ghost_Fading_Trans - -WANT equ -USE BF_Predator - -WANT equ -USE BF_Predator_Trans - -WANT equ -USE BF_Predator_Ghost - -WANT equ -USE BF_Predator_Ghost_Trans - -WANT equ -USE BF_Predator_Fading - -WANT equ -USE BF_Predator_Fading_Trans - -WANT equ -USE BF_Predator_Ghost_Fading - -WANT equ -USE BF_Predator_Ghost_Fading_Trans - - - -.DATA - -;NewShapeJumpTable label near ptr dword - -; -; Jumptable for shape line drawing with no flags set -; - -NewShapeJumpTable dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy -;CriticalFadeRedirections label dword -CriticalFadeRedirections dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with transparent flags set -; - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost and transparent flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - -; -; Jumptable for shape line drawing routines with fading flag set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Fading - dd Single_Line_Fading - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and transparent flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and ghost flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - -; -; Jumptable for shape line drawing routines with fading, transparent and ghost flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - - -; -; Jumptable for shape line drawing with predator flag set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with transparent and predator flags set -; - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost and predator flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost and transparent and predator flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - -; -; Jumptable for shape line drawing routines with fading and predator flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and transparent and predator flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading_Trans - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and ghost and predator flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Ghost_Fading - dd Single_Line_Predator_Ghost_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - - - -; -; Jumptable for shape line drawing routines with all flags set -; - -AllFlagsJumpTable label dword - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost_Trans - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading_Trans - dd Single_Line_Predator_Ghost_Fading - dd Single_Line_Predator_Ghost_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -EndNewShapeJumpTable db 0 - -.CODE - - - -;--------------------------------------------------------------------------- - - - - -;********************************************************************************************* -;* Set_Shape_Header -- create the line header bytes for a shape * -;* * -;* INPUT: Shape width * -;* Shape height * -;* ptr to raw shape data * -;* ptr to shape headers * -;* shape flags * -;* ptr to translucency table * -;* IsTranslucent * -;* * -;* OUTPUT: none * -;* * -;* Warnings: * -;* * -;* HISTORY: * -;* 11/29/95 10:09AM ST : Created. * -;*===========================================================================================* - - Setup_Shape_Header proc C pixel_width:DWORD, pixel_height:DWORD, src:DWORD, headers:DWORD, flags:DWORD, Translucent:DWORD, IsTranslucent:DWORD - - ;ARG pixel_width :DWORD ; width of rectangle to blit - ;ARG pixel_height :DWORD ; height of rectangle to blit - ;ARG src :DWORD ; this is a member function - ;ARG headers :DWORD - ;ARG flags :DWORD - ;ARG Translucent :DWORD - ;ARG IsTranslucent :DWORD - LOCAL trans_count :DWORD - - pushad - - - mov esi,[src] ;ptr to raw shape data - mov edi,[headers] ;ptr to headers we are going to set up - mov eax,[flags] - and eax,SHAPE_TRANS or SHAPE_FADING or SHAPE_PREDATOR or SHAPE_GHOST - mov [edi].ShapeHeaderType.draw_flags,eax ;save old flags in header - add edi,size ShapeHeaderType - mov edx,[pixel_height] ;number of shape lines to scan - -outer_loop: mov ecx,[pixel_width] ;number of pixels in shape line - xor bl,bl ;flag the we dont know anything about this line yet - mov [trans_count],0 ;we havnt scanned any transparent pixels yet - -; -; Scan one shape line to see what kind of data it contains -; -inner_loop: xor eax,eax - mov al,[esi] - inc esi - -; -; Check for transparent pixel -; - test al,al - jnz not_transp - test [flags],SHAPE_TRANS - jz not_transp - or bl,BLIT_TRANSPARENT ;flag that pixel is transparent - inc [trans_count] ;keep count of the number of transparent pixels on the line - jmp end_lp - -; -; Check for predator effect on this line -; -not_transp: test [flags],SHAPE_PREDATOR - jz not_pred - or bl,BLIT_PREDATOR - -; -; Check for ghost effects -; -not_pred: test [flags],SHAPE_GHOST - jz not_ghost - push edi - mov edi,[IsTranslucent] - cmp byte ptr [edi+eax],-1 - pop edi - jz not_ghost - or bl,BLIT_GHOST - -; -; Check if fading is required -; -not_ghost: test [flags],SHAPE_FADING - jz end_lp - or bl,BLIT_FADING - -end_lp: dec ecx - jnz inner_loop - - -; -; Interpret the info we have collected and decide which routine will be -; used to draw this line -; - xor bh,bh - - test bl,BLIT_TRANSPARENT - jz no_transparencies - or bh,BLIT_TRANSPARENT - mov ecx,[pixel_width] - cmp ecx,[trans_count] - jnz not_all_trans - -; all pixels in the line were transparent so we dont need to draw it at all - mov bh,BLIT_SKIP - jmp got_line_type - -not_all_trans: -no_transparencies: - mov al,bl - and al,BLIT_PREDATOR - or bh,al - mov al,bl - and al,BLIT_GHOST - or bh,al - mov al,bl - and al,BLIT_FADING - or bh,al - -; -; Save the line header and do the next line -; -got_line_type:mov [edi],bh - inc edi - - dec edx - jnz outer_loop - - - popad - ret - -Setup_Shape_Header endp - - - - -;************************************************************** -; -; Macro to fetch the header of the next line and jump to the appropriate routine -; -next_line macro - - add edi , [ dest_adjust_width ] ;add in dest modulo - dec edx ;line counter - jz real_out ;return - mov ecx,[save_ecx] ;ecx is pixel count - mov eax,[header_pointer] ;ptr to next header byte - mov al,[eax] - inc [header_pointer] - and eax,BLIT_ALL ;Make sure we dont jump to some spurious address - ; if the header is wrong then its better to draw with the wrong - ; shape routine than to die - shl eax,2 - add eax,[ShapeJumpTableAddress] ;get the address to jump to - jmp dword ptr [eax] ;do the jump - - endm - - - - - - -;*************************************************************************** -;* VVC::TOPAGE -- Copies a linear buffer to a virtual viewport * -;* * -;* INPUT: WORD x_pixel - x pixel on viewport to copy from * -;* WORD y_pixel - y pixel on viewport to copy from * -;* WORD pixel_width - the width of copy region * -;* WORD pixel_height - the height of copy region * -;* BYTE * src - buffer to copy from * -;* VVPC * dest - virtual viewport to copy to * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: Coordinates and dimensions will be adjusted if they exceed * -;* the boundaries. In the event that no adjustment is * -;* possible this routine will abort. If the size of the * -;* region to copy exceeds the size passed in for the buffer * -;* the routine will automatically abort. * -;* * -;* HISTORY: * -;* 06/15/1994 PWG : Created. * -;*=========================================================================* -Buffer_Frame_To_Page proc C public USES eax ebx ecx edx esi edi x_pixel:DWORD, y_pixel:DWORD, pixel_width:DWORD, pixel_height:DWORD, src:DWORD, dest:DWORD, flags:DWORD - - ;USES eax,ebx,ecx,edx,esi,edi - - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ;ARG x_pixel :DWORD ; x pixel position in source - ;ARG y_pixel :DWORD ; y pixel position in source - ;ARG pixel_width :DWORD ; width of rectangle to blit - ;ARG pixel_height:DWORD ; height of rectangle to blit - ;ARG src :DWORD ; this is a member function - ;ARG dest :DWORD ; what are we blitting to - - ;ARG flags :DWORD ; flags passed - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL IsTranslucent :DWORD ; ptr to the is_translucent table - LOCAL Translucent :DWORD ; ptr to the actual translucent table - LOCAL FadingTable :DWORD ; extracted fading table pointer - LOCAL FadingNum :DWORD ; get the number of times to fade - - LOCAL StashECX :DWORD ; temp variable for ECX register - - LOCAL jflags :DWORD ; flags used to goto correct buff frame routine - LOCAL BufferFrameRout :DWORD ; ptr to the buffer frame routine - - LOCAL jmp_loc :DWORD ; calculated jump location - LOCAL loop_cnt :DWORD - - LOCAL x1_pixel :DWORD - LOCAL y1_pixel :DWORD - LOCAL scr_x :DWORD - LOCAL scr_y :DWORD - LOCAL dest_adjust_width :DWORD - LOCAL scr_adjust_width :DWORD - LOCAL header_pointer :DWORD - LOCAL use_old_draw :DWORD - LOCAL save_ecx :DWORD - LOCAL ShapeJumpTableAddress :DWORD - LOCAL shape_buffer_start :DWORD - - prologue - cmp [ src ] , 0 - jz real_out - - ; - ; Save the line attributes pointers and - ; Modify the src pointer to point to the actual image - ; - cmp [UseBigShapeBuffer],0 - jz do_args ;just use the old shape drawing system - - mov edi,[src] - mov [header_pointer],edi - - mov eax,[BigShapeBufferStart] - cmp [edi].ShapeHeaderType.shape_buffer,0 - jz is_ordinary_shape - mov eax,[TheaterShapeBufferStart] -is_ordinary_shape: - mov [shape_buffer_start],eax - - mov edi,[edi].ShapeHeaderType.shape_data - add edi,[shape_buffer_start] - mov [src],edi - mov [use_old_draw],0 - - - ;==================================================================== - ; Pull off optional arguments: - ; EDI is used as an offset from the 'flags' parameter, to point - ; to the optional argument currently being processed. - ;==================================================================== -do_args: - mov edi , 4 ; optional params start past flags - mov [ jflags ] , 0 ; clear jump flags - -check_centering: - ;------------------------------------------------------------------- - ; See if we need to center the frame - ;------------------------------------------------------------------- - test [ flags ] , SHAPE_CENTER ; does this need to be centered? - je check_trans ; if not the skip over this stuff - - mov eax , [ pixel_width ] - mov ebx , [ pixel_height ] - sar eax , 1 - sar ebx , 1 - sub [ x_pixel ] , eax - sub [ y_pixel ] , ebx - -check_trans: - test [ flags ] , SHAPE_TRANS - jz check_ghost - - or [ jflags ] , FLAG_TRANS - - ;-------------------------------------------------------------------- - ; SHAPE_GHOST: DWORD is_translucent tbl - ;-------------------------------------------------------------------- -check_ghost: - test [ flags ] , SHAPE_GHOST ; are we ghosting this shape - jz check_fading - - mov eax , [ flags + edi ] - or [ jflags ] , FLAG_GHOST - mov [ IsTranslucent ] , eax ; save ptr to is_trans. tbl - add eax , 0100h ; add 256 for first table - add edi , 4 ; next argument - mov [ Translucent ] , eax ; save ptr to translucent tbl - - - -check_fading: - ;______________________________________________________________________ - ; If this is the first time through for this shape then - ; set up the shape header - ;______________________________________________________________________ - pushad - - cmp [UseBigShapeBuffer],0 - jz new_shape - - mov edi,[header_pointer] - cmp [edi].ShapeHeaderType.draw_flags,-1 - jz setup_headers - mov eax,[flags] ;Redo the shape headers if this shape was - and eax,SHAPE_TRANS or SHAPE_FADING or SHAPE_PREDATOR or SHAPE_GHOST ;initially set up with different flags - cmp eax,[edi].ShapeHeaderType.draw_flags - jz no_header_setup -new_shape: - mov [use_old_draw],1 - jmp no_header_setup - -setup_headers: - push [IsTranslucent] - push [Translucent] - push [flags] - push [header_pointer] - push [src] - push [pixel_height] - push [pixel_width] - call Setup_Shape_Header - add esp,7*4 - mov [ShapeJumpTableAddress], offset AllFlagsJumpTable - jmp headers_set -no_header_setup: - - xor eax,eax - test [flags],SHAPE_PREDATOR - jz not_shape_predator - or al,BLIT_PREDATOR - -not_shape_predator: - test [flags],SHAPE_FADING - jz not_shape_fading - or al,BLIT_FADING - -not_shape_fading: - - test [flags],SHAPE_TRANS - jz not_shape_transparent - or al,BLIT_TRANSPARENT - -not_shape_transparent: - - test [flags],SHAPE_GHOST - jz not_shape_ghost - or al,BLIT_GHOST - -not_shape_ghost: - - - shl eax,7 - add eax, offset NewShapeJumpTable - mov [ShapeJumpTableAddress],eax - ;call Init_New_Shape_Jump_Table_Address - - -headers_set: - popad - - ;-------------------------------------------------------------------- - ; SHAPE_FADING: DWORD fade_table[256], DWORD fade_count - ;-------------------------------------------------------------------- - test [ flags ] , SHAPE_FADING ; are we fading this shape - jz check_predator - - mov eax , [ flags + edi ] - mov [ FadingTable ] , eax ; save address of fading tbl - mov eax , [ flags + edi + 4 ] ; get fade num - or [ jflags ] , FLAG_FADING - and eax , 03fh ; no need for more than 63 - add edi , 8 ; next argument - cmp eax , 0 ; check if it's 0 - jnz set_fading ; if not, store fade num - - and [ flags ] , NOT SHAPE_FADING ; otherwise, don't fade - -set_fading: - mov [ FadingNum ] , eax - - mov ebx,[ShapeJumpTableAddress] - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx],offset Single_Line_Single_Fade - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx+4],offset Single_Line_Single_Fade_Trans - cmp eax,1 - jz single_fade - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx],offset Single_Line_Fading - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx+4],offset Single_Line_Fading_Trans - -single_fade: - - ;-------------------------------------------------------------------- - ; SHAPE_PREDATOR: DWORD init_pred_lookup_offset (0-7) - ;-------------------------------------------------------------------- -check_predator: - test [ flags ] , SHAPE_PREDATOR ; is predator effect on - jz check_partial - - mov eax , [ flags + edi ] ; pull the partial value - or [ jflags ] , FLAG_PREDATOR - shl eax , 1 - cmp eax , 0 - jge check_range - - neg eax - mov ebx , -1 - and eax , PRED_MASK ; keep entries within bounds - mov bl , al - mov eax , ebx ; will be ffffff00-ffffff07 - jmp pred_cont - -check_range: - and eax , PRED_MASK ; keep entries within bounds - -pred_cont: - add edi , 4 ; next argument - mov [ BFPredOffset ] , eax - mov [ BFPartialCount ] , 0 ; clear the partial count - mov [ BFPartialPred ] , 100h ; init partial to off - -pred_neg_init: - mov esi , [ dest ] ; get ptr to dest - mov ebx, 7 * 2 - -pred_loop: - movzx eax , [ WORD PTR BFPredNegTable + ebx ] - add eax , [esi].GraphicViewPort.GVPWidth ; add width - add eax , [esi].GraphicViewPort.GVPXAdd ; add x add - add eax , [esi].GraphicViewPort.GVPPitch ; extra pitch of DD surface ST - 9/29/95 1:08PM - mov [ WORD PTR BFPredNegTable + 16 + ebx ] , ax - dec ebx - dec ebx - jge pred_loop - - ;-------------------------------------------------------------------- - ; SHAPE_PARTIAL: DWORD partial_pred_value (0-255) - ;-------------------------------------------------------------------- -check_partial: - test [ flags ] , SHAPE_PARTIAL ; is this a partial pred? - jz setupfunc - - mov eax , [ flags + edi ] ; pull the partial value - add edi , 4 ; next argument - and eax , 0ffh ; make sure 0-255 - mov [ BFPartialPred ] , eax ; store it off - -setupfunc: - mov ebx , [ jflags ] ; load flags value - and ebx , FLAG_MASK ; clip high bits - add ebx , ebx ; mult by 4 to get DWORD offset - add ebx , ebx - mov ebx , dword ptr [ BufferFrameTable + ebx ] ; get table value - mov dword ptr [ BufferFrameRout ] , ebx ; store it in the function pointer - -; Clip dest Rectangle against source Window boundaries. - - mov [ scr_x ] , 0 - mov [ scr_y ] , 0 - mov esi , [ dest ] ; get ptr to dest - xor ecx , ecx - xor edx , edx - mov edi , [esi].GraphicViewPort.GVPWidth ; get width into register - mov ebx , [ x_pixel ] - mov eax , [ x_pixel ] - add ebx , [ pixel_width ] - shld ecx , eax , 1 - mov [ x1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi,[esi].GraphicViewPort.GVPHeight ; get height into register - mov ebx , [ y_pixel ] - mov eax , [ y_pixel ] - add ebx , [ pixel_height ] - shld ecx , eax , 1 - mov [ y1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz real_out - - or al , dl - jz do_blit - - mov [use_old_draw],1 - test cl , 1000b - jz dest_left_ok - - mov eax , [ x_pixel ] - neg eax - mov [ x_pixel ] , 0 - mov [ scr_x ] , eax - -dest_left_ok: - test cl , 0010b - jz dest_bottom_ok - - mov eax , [ y_pixel ] - neg eax - mov [ y_pixel ] , 0 - mov [ scr_y ] , eax - -dest_bottom_ok: - test dl , 0100b - jz dest_right_ok - - mov eax , [esi].GraphicViewPort.GVPWidth ; get width into register - mov [ x1_pixel ] , eax - -dest_right_ok: - test dl , 0001b - jz do_blit - - mov eax , [esi].GraphicViewPort.GVPHeight ; get width into register - mov [ y1_pixel ] , eax - -do_blit: - cld - mov eax , [esi].GraphicViewPort.GVPXAdd - add eax , [esi].GraphicViewPort.GVPPitch - add eax , [esi].GraphicViewPort.GVPWidth - mov edi , [esi].GraphicViewPort.GVPOffset - - mov ecx , eax - mul [ y_pixel ] - add edi , [ x_pixel ] - add edi , eax - - add ecx , [ x_pixel ] - sub ecx , [ x1_pixel ] - mov [ dest_adjust_width ] , ecx - - mov esi , [ src ] - mov eax , [ pixel_width ] - sub eax , [ x1_pixel ] - add eax , [ x_pixel ] - mov [ scr_adjust_width ] , eax - - mov eax , [ scr_y ] - mul [ pixel_width ] - add eax , [ scr_x ] - add esi , eax - -; -; If the shape needs to be clipped then we cant handle it with the new header systen -; so draw it with the old shape drawer -; - cmp [use_old_draw],0 - jnz use_old_stuff - - add [header_pointer],size ShapeHeaderType - mov edx,[pixel_height] - mov ecx,[pixel_width] - mov eax,[header_pointer] - mov al,[eax] - mov [save_ecx],ecx - inc [header_pointer] - and eax,BLIT_ALL - shl eax,2 - add eax,[ShapeJumpTableAddress] - jmp dword ptr [eax] - - -use_old_stuff: - mov edx , [ y1_pixel ] - mov eax , [ x1_pixel ] - - sub edx , [ y_pixel ] - jle real_out - - sub eax , [ x_pixel ] - jle real_out - - jmp [ BufferFrameRout ] ; buffer frame to viewport routine - -real_out: - - cmp [MMXAvailable],0 - jz no_mmx_cleanup - call MMX_Done - -no_mmx_cleanup: - epilogue - - ret - - -; ******************************************************************** -; Forward bitblit only -; the inner loop is so efficient that -; the optimal consept no longer apply because -; the optimal byte have to by a number greather than 9 bytes -; ******************************************************************** -;extern BF_Copy:near - -BF_Copy: - prologue - - cmp eax , 10 - jl forward_loop_bytes - -forward_loop_dword: - mov ecx , edi - mov ebx , eax - neg ecx - and ecx , 3 - sub ebx , ecx - rep movsb - mov ecx , ebx - shr ecx , 2 - rep movsd - mov ecx , ebx - and ecx , 3 - rep movsb - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz forward_loop_dword - - ret - -forward_loop_bytes: - mov ecx , eax - rep movsb - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx ; decrement the height - jnz forward_loop_bytes - - epilogue - - ret - - -;******************************************************************** -;******************************************************************** - -; segment code page public use32 'code' ; Need stricter segment alignment - ; for pentium optimisations - - -; -; Expand the 'next_line' macro so we can jump to it -; -; -; ST - 12/20/2018 3:48PM -Next_Line:: next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Trans:: - prologue - -Single_Line_Trans_Entry:: - -slt_mask_map_lp: ; Pentium pipeline usage - ;Pipe Cycles - mov al,[esi] ;U 1 - inc esi ;Vee 1 - - test al,al ;U 1 - jz slt_skip ;Vee 1/5 - -slt_not_trans:mov [edi],al ;u 1 - - inc edi ;vee 1 - dec ecx ;u 1 - - jnz slt_mask_map_lp ;vee (maybe) 1 - -slt_end_line: epilogue - next_line - - ;align 32 - -slt_skip: inc edi - dec ecx - jz slt_skip_end_line - - mov al,[esi] - inc esi - test al,al - jz slt_skip2 - mov [edi],al - inc edi - dec ecx - jnz slt_mask_map_lp - - epilogue - next_line - - ;align 32 - -slt_skip2: inc edi - dec ecx - jz slt_end_line - -; -; If we have hit two transparent pixels in a row then we go into -; the transparent optimised bit -; -slt_round_again: - rept 64 - mov al,[esi] ; ;pipe 1 - inc esi ;1 ;pipe 2 - test al,al ; ;pipe 1 - jnz slt_not_trans;pipe 2 (not pairable in 1) - ;2 - inc edi ; ;pipe 1 - dec ecx ;3 ;pipe 2 - jz slt_end_line ;4 ;pipe 1 (not pairable) - endm ; best case is 4 cycles per iteration - jmp slt_round_again - - - -slt_skip_end_line: - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with no transparent pixels -; -; 11/29/95 10:21AM - ST -; -; We have to align the destination for cards that dont bankswitch correctly -; when you write non-aligned data. -; - ;align 32 -Long_Single_Line_Copy: - prologue - - rept 3 - test edi,3 - jz LSLC_aligned - movsb - dec ecx - endm - -LSLC_aligned: - mov ebx,ecx - - shr ecx,2 - rep movsd - and ebx,3 - jz proc_out - movsb - dec bl - jz proc_out - movsb - dec bl - jz proc_out - movsb -proc_out: epilogue - next_line - - - -;***************************************************************************** -; Draw a single short line with no transparent pixels -; -; 11/29/95 10:21AM - ST -; - ;align 32 -Short_Single_Line_Copy: - prologue - cmp ecx,16 - jge Long_Single_Line_Copy - mov ebx,ecx - rep movsb - mov ecx,ebx - epilogue - next_line - - -;***************************************************************************** -; Skip a line of source that is all transparent -; -; 11/29/95 10:21AM - ST -; - - ;align 32 -Single_Line_Skip: - prologue - add esi,ecx - add edi,ecx - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 -Single_Line_Ghost: - - prologue - xor eax,eax -slg_loop: mov al,[esi] - mov ebx,[IsTranslucent] - inc esi - mov bh,[eax+ebx] - cmp bh,-1 - jz slg_store_pixel - - and ebx,0ff00h - mov al,[edi] - add ebx,[Translucent] - mov al,[eax+ebx] - -slg_store_pixel: - mov [edi],al - - inc edi - dec ecx - jnz slg_loop - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels and ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 -Single_Line_Ghost_Trans: - prologue - xor eax,eax -; cmp ecx,3 -; ja slgt4 - -slgt_loop: mov al,[esi] - inc esi - test al,al - jz slgt_transparent - -slgt_not_transparent: - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgt_store_pixel - - and ebx,0ff00h - mov al,[edi] - add ebx,[Translucent] - mov al,[eax+ebx] - -slgt_store_pixel: - mov [edi],al - inc edi - dec ecx - jnz slgt_loop - epilogue - next_line - - - ;align 32 - -slgt_transparent: - inc edi ;1 - dec ecx ;2 - jz slgt_out ;1 (not pairable) - -slgt_round_again: - rept 64 - mov al,[esi] ; ;pipe 1 - inc esi ;1 ;pipe 2 - test al,al ; ;pipe 1 - jnz slgt_not_transparent ;pipe 2 (not pairable in 1) - ;2 - inc edi ; ;pipe 1 - dec ecx ;3 ;pipe 2 - jz slgt_out ;4 ;pipe 1 (not pairable) - endm ; best case is 4 cycles per iteration - jmp slgt_round_again - -slgt_out: epilogue - next_line - - - -; -; Optimised video memory access version -; - ;align 32 - -slgt4: push edx - mov edx,[edi] - - rept 4 - local slgt4_store1 - local slgt4_trans1 - mov al,[esi] - inc esi - test al,al - jz slgt4_trans1 - - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgt4_store1 - - and ebx,0ff00h - mov al,dl - add ebx,[Translucent] - mov al,[eax+ebx] - -slgt4_store1: mov dl,al - -slgt4_trans1: ror edx,8 - endm - mov [edi],edx - pop edx - lea edi,[edi+4] - lea ecx,[ecx+0fffffffch] - cmp ecx,3 - ja slgt4 - test ecx,ecx - jnz slgt_loop - - epilogue - next_line - - - - - - - - - - -;***************************************************************************** -; Draw a single line with fading (colour remapping) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Fading: - prologue - xor eax,eax - mov ebx,[FadingTable] - push ebp - mov ebp,[FadingNum] - push ebp - -slf_loop: mov al,[esi] - inc esi - - mov ebp,[esp] - -slf_fade_loop:mov al,[ebx+eax] - dec ebp - jnz slf_fade_loop - - mov [edi],al - inc edi - - dec ecx - jnz slf_loop - add esp,4 - pop ebp - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with transparent pixels and fading (colour remapping) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Fading_Trans: - prologue - xor eax,eax - mov ebx,[FadingTable] - push ebp - mov ebp,[FadingNum] - push ebp - -slft_loop: mov al,[esi] - inc esi - test al,al - jz slft_transparent - - mov ebp,[esp] - -slft_fade_loop: - mov al,[ebx+eax] - dec ebp - jnz slft_fade_loop - - mov [edi],al -slft_transparent: - inc edi - - dec ecx - jnz slft_loop - add esp,4 - pop ebp - epilogue - next_line - - - - - -;***************************************************************************** -; Draw a single line with a single fade level (colour remap) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Single_Fade: - prologue - xor eax,eax - mov ebx,[FadingTable] - -slsf_loop: mov al,[esi] - mov al,[ebx+eax] - mov [edi],al - inc esi - inc edi - - dec ecx - jnz slsf_loop - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels and a single fade level (colour remap) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Single_Fade_Trans: - prologue - xor eax,eax - mov ebx,[FadingTable] - -slsft_loop: mov al,[esi] - inc esi - test al,al - jz slsft_transparent - mov al,[ebx+eax] - mov [edi],al - inc edi - dec ecx - jnz slsft_loop - epilogue - next_line - - ;align 32 - -slsft_transparent: - inc edi - - dec ecx - jz slsft_next_line - mov al,[esi] - inc esi - test al,al - jz slsft_transparent - mov al,[ebx+eax] - mov [edi],al - inc edi - dec ecx - jnz slsft_loop - -slsft_next_line: - epilogue - next_line - - - - - -;***************************************************************************** -; Draw a single line with ghosting and fading (colour remapping) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Ghost_Fading: - - prologue - mov [StashECX],ecx - -SLGF_loop: xor eax,eax - mov al,[esi] - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgf_do_fading - - and ebx,0ff00h - - mov al,[edi] - add ebx,[Translucent] - mov al,[ebx+eax] - -slgf_do_fading: - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slgf_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slgf_fade_loop - - mov [edi],al - inc esi - inc edi - - dec [StashECX] - jnz SLGF_loop - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with transparent pixels, ghosting and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Ghost_Fading_Trans: - prologue - mov [StashECX],ecx - xor eax,eax - -; cmp ecx,3 -; ja slgft4 - -SLGFT_loop: mov al,[esi] - inc esi - test al,al - jz slgft_trans_pixel - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgft_do_fading - - and ebx,0ff00h - - mov al,[edi] - add ebx,[Translucent] - mov al,[ebx+eax] - -slgft_do_fading: - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slgft_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slgft_fade_loop - - mov [edi],al -slgft_trans_pixel: - inc edi - - dec [StashECX] - jnz SLGFT_loop - epilogue - next_line - - - ;align 32 - -slgft4: push edx - mov edx,[edi] - - rept 4 - local slgft4_fade - local slgft4_fade_lp - local slgft4_trans - mov al,[esi] - inc esi - test al,al - jz slgft4_trans - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgft4_fade - - and ebx,0ff00h - - mov al,dl - add ebx,[Translucent] - mov al,[ebx+eax] - -slgft4_fade: mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slgft4_fade_lp: mov al,[eax+ebx] - dec ecx - jnz slgft4_fade_lp - - mov dl,al - -slgft4_trans: ror edx,8 - endm - mov [edi],edx - pop edx - lea edi,[edi+4] - sub [StashECX],4 - jz slgft4_out - cmp [StashECX],3 - ja slgft4 - jmp SLGFT_loop - -slgft4_out: epilogue - next_line - - -;***************************************************************************** -; Draw a single line with predator effect -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator: - - prologue - -slp_loop: mov al,[esi] - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - or bh,bh - jnz slp_get_pred - - mov [BFPartialCount] , ebx - jmp slp_skip_pixel - -slp_get_pred: xor bh , bh - mov eax,[BFPredOffset] - mov [BFPartialCount] , ebx - add byte ptr [BFPredOffset],2 - mov eax, dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - mov [edi],al - -slp_skip_pixel: - inc esi - inc edi - - dec ecx - jnz slp_loop - - epilogue - next_line - - - - -;***************************************************************************** -; Draw a single line with transparent pixels and predator effect -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Trans: - - prologue - -slpt_loop: mov al,[esi] - inc esi - test al,al - jz slpt_skip_pixel - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - or bh,bh - jnz slpt_get_pred - - mov [BFPartialCount] , ebx - jmp slpt_skip_pixel - -slpt_get_pred:xor bh , bh - mov eax,[BFPredOffset] - mov [BFPartialCount] , ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset ] , PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - mov [edi],al - -slpt_skip_pixel: - inc edi - - dec ecx - jnz slpt_loop - - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with predator and ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost: - - prologue - -slpg_loop: mov al,[esi] - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh,bh - jnz slpg_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpg_check_ghost - -slpg_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax ] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - mov al,[edi+eax] - -slpg_check_ghost: - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpg_store_pixel - - xor eax,eax - and ebx,0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpg_store_pixel: - mov [edi],al - inc esi - inc edi - - dec ecx - jnz slpg_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels, predator and ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost_Trans: - prologue - -slpgt_loop: mov al,[esi] - inc esi - test al,al - jz slpgt_transparent - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh,bh - jnz slpgt_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpgt_check_ghost - -slpgt_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax ] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - mov al,[edi+eax] - -slpgt_check_ghost: - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpgt_store_pixel - - xor eax,eax - and ebx,0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpgt_store_pixel: - mov [edi],al -slpgt_transparent: - inc edi - - dec ecx - jnz slpgt_loop - - pop ecx - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with predator and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Fading: - - prologue - mov [StashECX],ecx - -slpf_loop: mov al,[esi] - mov ebx,[BFPartialCount] - inc esi - add ebx,[BFPartialPred] - test bh,bh - jnz slpf_get_pred - - mov [BFPartialCount],ebx - jmp slpf_do_fading - -slpf_get_pred:xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - and byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - - and eax,0ffffh - mov al,[eax+edi] - -slpf_do_fading: - and eax,255 - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpf_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slpf_fade_loop - - mov [edi],al - inc edi - - dec [StashECX] - jnz slpf_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels, fading and predator -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Fading_Trans: - prologue - mov [StashECX],ecx - -slpft_loop: mov al,[esi] - inc esi - test al,al - jz slpft_transparent - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh,bh - jnz slpft_get_pred - - mov [BFPartialCount],ebx - jmp slpft_do_fading - -slpft_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - and byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - - and eax,0ffffh - mov al,[eax+edi] - -slpft_do_fading: - and eax,255 - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpft_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slpft_fade_loop - - mov [edi],al -slpft_transparent: - inc edi - - dec [StashECX] - jnz slpft_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with predator, ghosting and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost_Fading: - - prologue - mov [StashECX],ecx - -slpgf_loop: mov al,[esi] - mov ebx,[BFPartialCount] - inc esi - add ebx,[BFPartialPred] - test bh , bh - jnz slpgf_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpgf_check_ghost - -slpgf_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - -slpgf_check_ghost: - and eax,255 - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpgf_do_fading - - and ebx , 0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpgf_do_fading: - xor eax,eax - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpgf_fade_loop: - mov al,[ebx+eax] - dec ecx - jnz slpgf_fade_loop - -slpgf_store_pixel: - mov [edi],al - inc edi - - dec [StashECX] - jnz slpgf_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels, predator, ghosting and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost_Fading_Trans: - - prologue - mov [StashECX],ecx - -slpgft_loop: mov al,[esi] - inc esi - test al,al - jz slpgft_transparent - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh , bh - jnz slpgft_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpgft_check_ghost - -slpgft_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - -slpgft_check_ghost: - and eax,255 - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpgft_do_fading - - and ebx , 0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpgft_do_fading: - xor eax,eax - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpgft_fade_loop: - mov al,[ebx+eax] - dec ecx - jnz slpgft_fade_loop - -slpgft_store_pixel: - mov [edi],al -slpgft_transparent: - inc edi - - dec [StashECX] - jnz slpgft_loop - - epilogue - next_line - - - - -; ends ;end of strict alignment segment - -; codeseg - - - -;extern BF_Trans:near - -BF_Trans: - - prologue -; calc the code location to skip to 10 bytes per REPT below!!!! - mov ecx , eax - and ecx , 01fh - lea ecx , [ ecx + ecx * 4 ] ; quick multiply by 5 - neg ecx - shr eax , 5 - lea ecx , [ trans_reference + ecx * 2 ] ; next multiply by 2 - mov [ loop_cnt ] , eax - mov [ jmp_loc ] , ecx - -trans_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -; the following code should NOT be changed without changing the calculation -; above!!!!!! - -trans_line: - - REPT 32 - local trans_pixel - mov bl , [ esi ] - inc esi - test bl , bl - jz trans_pixel - - mov [ edi ] , bl - - trans_pixel: - inc edi - ENDM - -trans_reference: - dec ecx - jge trans_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz trans_loop - epilogue - - ret - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost:near -BF_Ghost: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx, [offset ghost_reference] - sub ecx, [offset ghost_line] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -ghost_line: - - REPT 32 - local store_pixel - mov al , [ esi ] - inc esi - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -ghost_reference: - dec ecx - jge ghost_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost_Trans:near -BF_Ghost_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset ghost_t_reference ] - sub ecx, [ offset ghost_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_t_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -ghost_t_line: - - REPT 32 - local transp_pixel - local store_pixel - mov al , [ esi ] - inc esi - test al , al - jz transp_pixel - - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - - transp_pixel: - inc edi - - ENDM - -ghost_t_reference: - dec ecx - jge ghost_t_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Fading:near -BF_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset fading_reference ] - sub ecx, [ offset fading_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ fading_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -fading_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - mov ebx , [ FadingTable ] ; run color through fading table - jmp [ jmp_loc ] - -fading_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -fading_line: - - REPT 32 - local fade_loop - mov al , [ esi ] - inc esi - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - inc edi - - ENDM - -fading_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge fading_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz fading_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Fading_Trans:near -BF_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset fading_t_reference ] - sub ecx, [ offset fading_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ fading_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -fading_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - mov ebx , [ FadingTable ] ; run color through fading table - jmp [ jmp_loc ] - -fading_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -fading_t_line: - - REPT 32 - local transp_pixel - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz transp_pixel - - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - - transp_pixel: - inc edi - - ENDM - -fading_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge fading_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz fading_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost_Fading:near -BF_Ghost_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset ghost_f_reference ] - sub ecx, [ offset ghost_f_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_f_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_f_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -ghost_f_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -ghost_f_line: - - REPT 32 - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - mov ebx , [ IsTranslucent ] ; is it a lucent color? - mov bh , byte ptr [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the lation table - ; ((_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (_color * 256) of the lation equ. - mov al , byte ptr [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -ghost_f_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge ghost_f_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_f_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost_Fading_Trans:near -BF_Ghost_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset ghost_f_t_reference ] - sub ecx, [ offset ghost_f_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_f_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_f_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -ghost_f_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -ghost_f_t_line: - - REPT 32 - local transp_pixel - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz transp_pixel - - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , byte ptr [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , byte ptr [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - - transp_pixel: - inc edi - - ENDM - -ghost_f_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge ghost_f_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_f_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator:near -BF_Predator: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_reference ] - sub ecx, [offset predator_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_line: - - REPT 32 - local get_pred - local skip_pixel - mov al , [ esi ] - inc esi - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp skip_pixel - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - -; xor bh , bh -; mov eax , [ BFPredValue ] ; pick up a color offset a pseudo- -; ; random amount from the current -; mov [ BFPartialCount ] , ebx -; mov al , [ edi + eax ] ; viewport address - - mov [ edi ] , al - - skip_pixel: - inc edi - - ENDM - -predator_reference: - dec ecx - jge predator_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Trans:near -BF_Predator_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_t_reference ] - sub ecx, [ offset predator_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_t_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_t_line: - - REPT 32 - local trans_pixel - local get_pred - local store_pixel - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp store_pixel - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - store_pixel: - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_t_reference: - dec ecx - jge predator_t_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost:near -BF_Predator_Ghost: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_reference ] - sub ecx, [ offset predator_g_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_g_line: - - REPT 32 - local get_pred - local check_ghost - local store_pixel - mov al , [ esi ] - mov ebx , [ BFPartialCount ] - inc esi - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -predator_g_reference: - dec ecx - jge predator_g_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost_Trans:near -BF_Predator_Ghost_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_t_reference ] - sub ecx, [ offset predator_g_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_t_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_g_t_line: - - REPT 32 - local trans_pixel - local get_pred - local check_ghost - local store_pixel - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_g_t_reference: - dec ecx - jge predator_g_t_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Fading:near -BF_Predator_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_f_reference ] - sub ecx, [ offset predator_f_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_f_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_f_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_f_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_f_line: - - REPT 32 - local get_pred - local do_fading - local fade_loop - mov al , [ esi ] - mov ebx , [ BFPartialCount ] - inc esi - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp do_fading - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - inc edi - - ENDM - -predator_f_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_f_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_f_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Fading_Trans:near -BF_Predator_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_f_t_reference ] - sub ecx, [ offset predator_f_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_f_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_f_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_f_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_f_t_line: - - REPT 32 - local trans_pixel - local get_pred - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp do_fading - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_f_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_f_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_f_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost_Fading:near -BF_Predator_Ghost_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_f_reference ] - sub ecx, [ offset predator_g_f_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_f_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_f_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_g_f_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_g_f_line: - - REPT 32 - local get_pred - local check_ghost - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - mov ebx , [ BFPartialCount ] - inc esi - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -predator_g_f_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_g_f_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_f_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost_Fading_Trans:near -BF_Predator_Ghost_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_f_t_reference ] - sub ecx, [ offset predator_g_f_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_f_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_f_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_g_f_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_g_f_t_line: - - REPT 32 - local trans_pixel - local get_pred - local check_ghost - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_g_f_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_g_f_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_f_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -Not_Supported: - ret - -Buffer_Frame_To_Page ENDP - - -end - diff --git a/code/TIBERIANDAWN/KEYFBUFF.INC b/code/TIBERIANDAWN/KEYFBUFF.INC deleted file mode 100644 index c05ed91..0000000 --- a/code/TIBERIANDAWN/KEYFBUFF.INC +++ /dev/null @@ -1,39 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - - - -;************************************************************** -; -; Macro to fetch the header of the next line and jump to the appropriate routine -; -next_line macro - - add edi,[dest_adjust_width] ;add in dest modulo - dec edx ;line counter - jz real_out ;return - mov ecx,[save_ecx] ;ecx is pixel count - mov eax,[header_pointer] ;ptr to next header byte - mov al,[eax] - inc [header_pointer] - and eax,BLIT_ALL ;Make sure we dont jump to some spurious address - ; if the header is wrong then its better to draw with the wrong - ; shape routine than to die - shl eax,2 - add eax,[ShapeJumpTableAddress] ;get the address to jump to - jmp [dword eax] ;do the jump - - endm - diff --git a/code/TIBERIANDAWN/KEYFRAME.CPP b/code/TIBERIANDAWN/KEYFRAME.CPP deleted file mode 100644 index 8c81d41..0000000 --- a/code/TIBERIANDAWN/KEYFRAME.CPP +++ /dev/null @@ -1,599 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\keyframe.cpv 2.14 16 Oct 1995 16:48:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : KEYFRAME.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 06/25/95 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Get_Build_Frame_Count -- Fetches the number of frames in data block. * - * Get_Build_Frame_Width -- Fetches the width of the shape image. * - * Get_Build_Frame_Height -- Fetches the height of the shape image. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" - -#define SUBFRAMEOFFS 7 // 3 1/2 frame offsets loaded (2 offsets/frame) - - -#define Apply_Delta(buffer, delta) Apply_XOR_Delta((char*)(buffer), (char*)(delta)) - -typedef struct { - unsigned short frames; - unsigned short x; - unsigned short y; - unsigned short width; - unsigned short height; - unsigned short largest_frame_size; - short flags; -} KeyFrameHeaderType; - -#define INITIAL_BIG_SHAPE_BUFFER_SIZE 12000*1024 -#define THEATER_BIG_SHAPE_BUFFER_SIZE 1000*1024 -#define UNCOMPRESS_MAGIC_NUMBER 56789 - -unsigned BigShapeBufferLength = INITIAL_BIG_SHAPE_BUFFER_SIZE; -unsigned TheaterShapeBufferLength = THEATER_BIG_SHAPE_BUFFER_SIZE; -extern "C"{ - char *BigShapeBufferStart = NULL; - char *TheaterShapeBufferStart = NULL; - BOOL UseBigShapeBuffer = FALSE; - bool IsTheaterShape = false; -} -char *BigShapeBufferPtr = NULL; -int TotalBigShapes=0; -BOOL ReallocShapeBufferFlag = FALSE; -bool OriginalUseBigShapeBuffer = false; - -char *TheaterShapeBufferPtr = NULL; -int TotalTheaterShapes = 0; - - - -#define MAX_SLOTS 1500 -#define THEATER_SLOT_START 1000 - -char **KeyFrameSlots [MAX_SLOTS]; -int TotalSlotsUsed=0; -int TheaterSlotsUsed = THEATER_SLOT_START; - - -typedef struct tShapeHeaderType{ - unsigned draw_flags; - char *shape_data; - int shape_buffer; //1 if shape is in theater buffer -} ShapeHeaderType; - -static int Length; - -void *Get_Shape_Header_Data(void *ptr) -{ - if (UseBigShapeBuffer){ - - ShapeHeaderType *header = (ShapeHeaderType*) ptr; - return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) ); - - }else{ - return (ptr); - } -} - -int Get_Last_Frame_Length(void) -{ - return(Length); -} - - - -void Reset_Theater_Shapes (void) -{ - /* - ** Delete any previously allocated slots - */ - for (int i=THEATER_SLOT_START ; i 16*1024*1024) ? TRUE : FALSE; - OriginalUseBigShapeBuffer = UseBigShapeBuffer; - - // UseBigShapeBuffer = false; -} - - - - -/*********************************************************************************************** - * Disable_Uncompressed_Shapes -- Temporarily turns off shape decompression * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/19/96 2:37PM ST : Created * - *=============================================================================================*/ -void Disable_Uncompressed_Shapes (void) -{ - UseBigShapeBuffer = false; -} - - - -/*********************************************************************************************** - * Enable_Uncompressed_Shapes -- Restores state of shape decompression before it was disabled * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/19/96 2:37PM ST : Created * - *=============================================================================================*/ -void Enable_Uncompressed_Shapes (void) -{ - UseBigShapeBuffer = OriginalUseBigShapeBuffer; -} - - -#define FIXIT_SCORE_CRASH - -unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr) -{ -#ifdef FIXIT_SCORE_CRASH - char * ptr; - unsigned long offcurr, offdiff; -#else - char * ptr, * lockptr; - unsigned long offcurr, off16, offdiff; -#endif - unsigned long offset[SUBFRAMEOFFS]; - KeyFrameHeaderType *keyfr; - unsigned short buffsize, currframe, subframe; - unsigned long length = 0; - char frameflags; - unsigned long return_value; - char *temp_shape_ptr; - - // - // valid pointer?? - // - Length = 0; - if ( !dataptr || !buffptr ) { - return(0); - } - - // - // look at header then check that frame to build is not greater - // than total frames - // - keyfr = (KeyFrameHeaderType *) dataptr; - - if ( framenumber >= keyfr->frames ) { - return(0); - } - - - if (UseBigShapeBuffer){ - /* - ** If we havnt yet allocated memory for uncompressed shapes then do so now. - ** - */ - if (!BigShapeBufferStart){ - BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL); - BigShapeBufferPtr = BigShapeBufferStart; - /* - ** Allocate memory for theater specific uncompressed shapes - */ - TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL); - TheaterShapeBufferPtr = TheaterShapeBufferStart; - } - - - /* - ** Track memory usage in uncompressed shape buffers. - */ - static bool show_info = true; - - if ((Frame & 0xff) == 0){ - - if (show_info){ - - char debugstr [128]; - sprintf (debugstr, "C&C95 - Big shape buffer is now %d Kb.\n", BigShapeBufferLength / 1024); - CCDebugString (debugstr); - - sprintf (debugstr, "C&C95 - %d Kb Used in big shape buffer.\n", (unsigned)((unsigned)BigShapeBufferPtr - (unsigned)BigShapeBufferStart)/1024); - CCDebugString (debugstr); - - sprintf (debugstr, "C&C95 - %d Kb Used in theater shape buffer.\n", (unsigned)((unsigned)TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart)/1024); - CCDebugString (debugstr); - show_info = false; - } - - }else{ - show_info = true; - - } - - - /* - ** If we are running out of memory (<128k left) for uncompressed shapes - ** then allocate some more. - */ - if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128*1024){ - ReallocShapeBufferFlag = TRUE; - } - - /* - ** If this animation was not previously uncompressed then - ** allocate memory to keep the pointers to the uncompressed data - ** for these animation frames - */ - if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER){ - keyfr->x = UNCOMPRESS_MAGIC_NUMBER; - if (IsTheaterShape){ - keyfr->y = TheaterSlotsUsed; - TheaterSlotsUsed++; - }else{ - keyfr->y = TotalSlotsUsed; - TotalSlotsUsed++; - } - /* - ** Allocate and clear the memory for the shape info - */ - KeyFrameSlots[keyfr->y]= new char *[keyfr->frames]; - memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4); - } - - /* - ** If this frame was previously uncompressed then just return - ** a pointer to the raw data - */ - if (*(KeyFrameSlots[keyfr->y]+framenumber)){ - if (IsTheaterShape){ - return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); - }else{ - return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); - } - } - } - - // calc buff size - buffsize = keyfr->width * keyfr->height; - - // get offset into data - ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) ); - Mem_Copy( ptr, &offset[0], 12L ); - frameflags = (char)(offset[0] >> 24); - - - if ( (frameflags & KF_KEYFRAME) ) { - - ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) ); - - if (keyfr->flags & 1 ) { - ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); - } - length = LCW_Uncompress( ptr, buffptr, buffsize ); - } else { // key delta or delta - - if ( (frameflags & KF_DELTA) ) { - currframe = (unsigned short)offset[1]; - - ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) ); - Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); - } - - // key frame - offcurr = offset[1] & 0x00FFFFFFL; - - // key delta - offdiff = (offset[0] & 0x00FFFFFFL) - offcurr; - - ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr ); - - if (keyfr->flags & 1 ) { - ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); - } - -#ifndef FIXIT_SCORE_CRASH - off16 = (unsigned long)lockptr & 0x00003FFFL; -#endif - length = LCW_Uncompress( ptr, buffptr, buffsize ); - - if (length > buffsize) { - return(0); - } - -#ifndef FIXIT_SCORE_CRASH - if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { - - ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); - off16 = (unsigned long)ptr & 0x00003FFFL; - - offcurr += offdiff; - offdiff = 0; - } -#endif - length = buffsize; - Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); - - if ( (frameflags & KF_DELTA) ) { - // adjust to delta after the keydelta - - currframe++; - subframe = 2; - - while (currframe <= framenumber) { - offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr; - -#ifndef FIXIT_SCORE_CRASH - if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { - - ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); - off16 = (unsigned long)lockptr & 0x00003FFFL; - - offcurr += offdiff; - offdiff = 0; - } -#endif - - length = buffsize; - Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); - - currframe++; - subframe += 2; - - if ( subframe >= (SUBFRAMEOFFS - 1) && - currframe <= framenumber ) { - Mem_Copy( Add_Long_To_Pointer( dataptr, - (((unsigned long)currframe << 3) + - sizeof(KeyFrameHeaderType)) ), - &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); - subframe = 0; - } - } - } - } - - if (UseBigShapeBuffer){ - /* - ** Save the uncompressed shape data so we dont have to uncompress it - ** again next time its drawn. - ** We keep a space free before the raw shape data so we can add line - ** header info before the shape is drawn for the first time - */ - - if (IsTheaterShape){ - /* - ** Shape is a theater specific shape - */ - return_value = (unsigned long) TheaterShapeBufferPtr; - temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); - /* - ** align the actual shape data - */ - if (3 & (unsigned)temp_shape_ptr){ - temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); - } - - memcpy (temp_shape_ptr , buffptr , length); - ((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated - ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data - ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer - *(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart; - TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); - /* - ** Align the next shape - */ - if (3 & (unsigned)TheaterShapeBufferPtr){ - TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc); - } - Length = length; - return (return_value); - - }else{ - - - return_value=(unsigned long)BigShapeBufferPtr; - temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); - /* - ** align the actual shape data - */ - if (3 & (unsigned)temp_shape_ptr){ - temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); - } - memcpy (temp_shape_ptr , buffptr , length); - ((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated - ((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data - ((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer - *(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart; - BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); - // Align the next shape - if (3 & (unsigned)BigShapeBufferPtr){ - BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc); - } - Length = length; - return (return_value); - } - - }else{ - return ((unsigned long)buffptr); - } -} - - -/*********************************************************************************************** - * Get_Build_Frame_Count -- Fetches the number of frames in data block. * - * * - * Use this routine to determine the number of shapes within the data block. * - * * - * INPUT: dataptr -- Pointer to the keyframe shape data block. * - * * - * OUTPUT: Returns with the number of shapes in the data block. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Commented. * - *=============================================================================================*/ -unsigned short Get_Build_Frame_Count(void const *dataptr) -{ - if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->frames); - } - return(0); -} - - -unsigned short Get_Build_Frame_X(void const *dataptr) -{ - if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->x); - } - return(0); -} - - -unsigned short Get_Build_Frame_Y(void const *dataptr) -{ - if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->y); - } - return(0); -} - - -/*********************************************************************************************** - * Get_Build_Frame_Width -- Fetches the width of the shape image. * - * * - * Use this routine to fetch the width of the shapes within the keyframe shape data block. * - * All shapes within the block have the same width. * - * * - * INPUT: dataptr -- Pointer to the keyframe shape data block. * - * * - * OUTPUT: Returns with the width of the shapes in the block -- expressed in pixels. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Commented * - *=============================================================================================*/ -unsigned short Get_Build_Frame_Width(void const *dataptr) -{ - if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->width); - } - return(0); -} - - -/*********************************************************************************************** - * Get_Build_Frame_Height -- Fetches the height of the shape image. * - * * - * Use this routine to fetch the height of the shapes within the keyframe shape data block. * - * All shapes within the block have the same height. * - * * - * INPUT: dataptr -- Pointer to the keyframe shape data block. * - * * - * OUTPUT: Returns with the height of the shapes in the block -- expressed in pixels. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Commented * - *=============================================================================================*/ -unsigned short Get_Build_Frame_Height(void const *dataptr) -{ - if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->height); - } - return(0); -} - - -bool Get_Build_Frame_Palette(void const * dataptr, void * palette) -{ - if (dataptr && (((KeyFrameHeaderType const *)dataptr)->flags & 1)) { - char const * ptr = (char const *)Add_Long_To_Pointer( dataptr, - ( (( (long)sizeof(unsigned long) << 1) * - ((KeyFrameHeaderType *) dataptr)->frames ) + - 16 + sizeof(KeyFrameHeaderType) ) ); - - memcpy(palette, ptr, 768L); - return(true); - } - return(false); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/LAYER.CPP b/code/TIBERIANDAWN/LAYER.CPP deleted file mode 100644 index 30427b6..0000000 --- a/code/TIBERIANDAWN/LAYER.CPP +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\layer.cpv 2.18 16 Oct 1995 16:50:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LAYER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 31, 1994 * - * * - * Last Update : March 10, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * LayerClass::Submit -- Adds an object to a layer list. * - * LayerClass::Sort -- Perform an incremental sort pass on the layer's objects. * - * LayerClass::Sorted_Add -- Adds object in sorted order to layer. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "layer.h" - - -/*********************************************************************************************** - * LayerClass::Submit -- Adds an object to a layer list. * - * * - * This routine is used to add an object to the layer list. If the list is full, then the * - * object is not added. * - * * - * INPUT: object -- Pointer to the object to add. * - * * - * OUTPUT: bool; Was the object added successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 05/31/1994 JLB : Allows sorted insert. * - * 01/02/1995 JLB : Fixed to work with EMSListOf template. * - *=============================================================================================*/ -bool LayerClass::Submit(ObjectClass const * object, bool sort) -{ - /* - ** Add the object to the layer. Either at the end (if "sort" is false) or at the - ** appropriately sorted position. - */ - if (sort) { - return(Sorted_Add(object)); - } - return(Add((ObjectClass *)object)); -} - - -/*********************************************************************************************** - * LayerClass::Sort -- Handles sorting the objects in the layer. * - * * - * This routine is used if the layer objects must be sorted and sorting is to occur now. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Don't call this routine too often since it does take a bit of time to * - * execute. It is a single pass binary sort and thus isn't horribly slow, * - * but it does take some time. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 03/10/1995 JLB : Uses comparison operator. * - *=============================================================================================*/ -void LayerClass::Sort(void) -{ - for (int index = 0; index < Count()-1; index++) { - if (*(*this)[index+1] < *(*this)[index]) { - ObjectClass * temp; - - temp = (*this)[index+1]; - (*this)[index+1] = (*this)[index]; - (*this)[index] = temp; - } - } -} - - -/*********************************************************************************************** - * DynamicVectorClass::Sorted_Add -- Adds object in sorted order to vector. * - * * - * Use this routine to add an object to the vector but it will be inserted in sorted * - * order. This depends on the ">" operator being defined for the vector object. * - * * - * INPUT: object -- Reference to the object that will be added to the vector. * - * * - * OUTPUT: bool; Was the object added to the vector successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -int LayerClass::Sorted_Add(ObjectClass const * const object) -{ - if (ActiveCount >= (int)Length()) { - if ((IsAllocated || !VectorMax) && GrowthStep > 0) { - if (!Resize(Length() + GrowthStep)) { - - /* - ** Failure to increase the size of the vector is an error condition. - ** Return with the error flag. - */ - return(false); - } - } else { - - /* - ** Increasing the size of this vector is not allowed! Bail this - ** routine with the error code. - */ - return(false); - } - } - - /* - ** There is room for the new object now. Add it to the right sorted position. - */ - int index; - for (index = 0; index < ActiveCount; index++) { - if ((*(*this)[index]) > (*object)) { - break; - } - } - - /* - ** Make room if the insertion spot is not at the end of the vector. - */ - for (int i = ActiveCount-1; i >= index; i--) { - (*this)[i+1] = (*this)[i]; - } - (*this)[index] = (ObjectClass *)object; - ActiveCount++; - return(true); -} - - diff --git a/code/TIBERIANDAWN/LAYER.H b/code/TIBERIANDAWN/LAYER.H deleted file mode 100644 index e25aed7..0000000 --- a/code/TIBERIANDAWN/LAYER.H +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\layer.h_v 2.19 16 Oct 1995 16:46:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LAYER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 31, 1994 * - * * - * Last Update : May 31, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef LAYER_H -#define LAYER_H - -#include "vector.h" - -class ObjectClass; - -class LayerClass : public DynamicVectorClass -{ - public: - - //----------------------------------------------------------------- - void Sort(void); - bool Submit(ObjectClass const * object, bool sort=false); - int Sorted_Add(ObjectClass const * const object); - - - virtual void Init(void) {Clear();}; - virtual void One_Time(void) {}; - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); -}; - -#endif diff --git a/code/TIBERIANDAWN/LED.H b/code/TIBERIANDAWN/LED.H deleted file mode 100644 index 3e379c1..0000000 --- a/code/TIBERIANDAWN/LED.H +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\led.h_v 2.17 16 Oct 1995 16:45:50 JOE_BOSTIC $ */ - -#ifndef LED_H -#define LED_H - -class LEDClass -{ - public: - typedef enum ControlType { - LED_NOCHANGE, // Do nothing (just query). - LED_OFF, // Turn LED off. - LED_ON, // Turn LED on. - LED_TOGGLE // Toggle LED state. - } ControlType; - - protected: - static int Shift_Control(ControlType control, char bit); - - public: - static int Scroll_Lock(ControlType control=LED_TOGGLE) {return Shift_Control(control, 0x01);}; - static int Caps_Lock(ControlType control=LED_TOGGLE) {return Shift_Control(control, 0x02);}; - static int Num_Lock(ControlType control=LED_TOGGLE) {return Shift_Control(control, 0x04);}; - - private: - static void Send_To_Keyboard(unsigned char val); -}; - -#endif diff --git a/code/TIBERIANDAWN/LINK.CPP b/code/TIBERIANDAWN/LINK.CPP deleted file mode 100644 index f8c24ee..0000000 --- a/code/TIBERIANDAWN/LINK.CPP +++ /dev/null @@ -1,413 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\link.cpv 2.18 16 Oct 1995 16:52:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LINK.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 19, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * LinkClass::LinkClass -- Default constructor for linked list object. * - * LinkClass::LinkClass -- Copy constructor for linked list object. * - * LinkClass::~LinkClass -- Default destructor for linked list object. * - * LinkClass::Zap -- Forces the link pointers to NULL. * - * LinkClass::operator= -- Assignment operator for linked list class object. * - * LinkClass::Get_Next -- Fetches the next object in list. * - * LinkClass::Get_Prev -- Fetches previous object in linked list. * - * LinkClass::Head_Of_List -- Finds the head of the list. * - * LinkClass::Tail_Of_List -- Scans for the object at the end of the list. * - * LinkClass::Add -- This object adds itself to the given list * - * LinkClass::Add_Head -- This gadget makes itself the head of the given list. * - * LinkClass::Add_Tail -- Add myself to the end of the given list. * - * LinkClass::Remove -- Removes the specified object from the list. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "link.h" - - -/*********************************************************************************************** - * LinkClass::LinkClass -- Default constructor for linked list object. * - * * - * This is the default constructor for a linked list object. It merely initializes the * - * next and previous pointers to NULL. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass::LinkClass(void) -{ - LinkClass::Zap(); -} - - -/*********************************************************************************************** - * LinkClass::LinkClass -- Copy constructor for linked list object. * - * * - * This copy constructor, unlike the assigment operator, doesn't have to deal with an * - * already initialized and legal link object to the left of the "=". It merely puts the * - * destination object into the same list as the source object. * - * * - * INPUT: link -- Reference to the object on the right of the "=". * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass::LinkClass(LinkClass & link) -{ - LinkClass::Zap(); - Add(link); -} - - -/*********************************************************************************************** - * LinkClass::~LinkClass -- Default destructor for linked list object. * - * * - * This default destructor will remove the object from any linked list it may be part of. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass::~LinkClass(void) -{ - Remove(); -} - - -/*********************************************************************************************** - * LinkClass::Zap -- Forces the link pointers to NULL. * - * * - * This routine will "zap" out the link pointers. This is usually necessary when the link * - * pointers start in an undefined state, but we KNOW that they aren't pointing to anything * - * valid. In such a case it becomes necessary to zap them so that when the object is added * - * to a list, it will be added corrrectly. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void LinkClass::Zap(void) -{ - Next = 0; - Prev = 0; -} - - -/*********************************************************************************************** - * LinkClass::operator= -- Assignment operator for linked list class object. * - * * - * The assignment operator makes sure that the previous and next pointers remain valid. * - * Because this class only consists of pointers, the assignment operator doesn't actually * - * transfer any data from the source object. It merely makes the destination object part * - * of the same list as the source object. In essence, this is transferring information * - * but not the actual values. * - * * - * If the destination object is already part of another list, it is removed from that list * - * before being added to the source object's list. This ensures that either list remains * - * in a valid condition. * - * * - * INPUT: link -- The object to the right of the "=" operator. * - * * - * OUTPUT: Returns a reference to the rightmost object -- per standard assigment rules. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & LinkClass::operator=(LinkClass & link) -{ - Remove(); - Add(link); - return(link); -} - - -/*********************************************************************************************** - * LinkClass::Get_Next -- Fetches the next object in list. * - * * - * This routine will return with a pointer to the next object in the list. If there are * - * no more objects, then NULL is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with pointer to next object in list or NULL if at end of list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass * LinkClass::Get_Next(void) const -{ - return(Next); -} - - -/*********************************************************************************************** - * LinkClass::Get_Prev -- Fetches previous object in linked list. * - * * - * Use this routine to get a pointer to the previous object in the linked list. If there * - * are no previous objects (such as at the head of the list), then NULL is returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the previous object in the list or NULL if none. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass * LinkClass::Get_Prev(void) const -{ - return(Prev); -} - - -/*********************************************************************************************** - * LinkClass::Head_Of_List -- Finds the head of the list. * - * * - * Use this routine to scan for and return a reference to the object at the head of the * - * list. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a reference to the object at the head of the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass const & LinkClass::Head_Of_List(void) const -{ - LinkClass const * link = this; - while (link->Prev) { - link = link->Prev; - if (link == this) break; // Safety check - } - return(*link); -} - - -/*********************************************************************************************** - * LinkClass::Tail_Of_List -- Scans for the object at the end of the list. * - * * - * Use this routine to scan for and return a reference to the object at the end of the * - * list. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a reference to the object at the end of the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass const & LinkClass::Tail_Of_List(void) const -{ - LinkClass const * link = this; - while (link->Next) { - link = link->Next; - if (link == this) break; // Safety check - } - return(*link); -} - - -/*********************************************************************************************** - * LinkClass::Add -- This object adds itself to the given list * - * * - * Use this routine to add a link object to the list, but to be added right after the * - * given link. This allows inserting a link in the middle of the chain. A quite necessary * - * ability if the chain is order dependant (e.g., the gadget system). * - * * - * INPUT: list -- gadget object to add this one to * - * * - * OUTPUT: Returns with a pointer to the head of the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & LinkClass::Add(LinkClass & list) -{ - LinkClass *ptr; - - /* - ** Save ptr to next gadget. - */ - ptr = list.Next; - - /* - ** Link myself in after 'list'. - */ - list.Next = this; - Prev = &list; - - /* - ** Link myself to next gadget, if there is one. - */ - Next = ptr; - if (ptr) { - ptr->Prev = this; - } - - return(Head_Of_List()); -} - - -/*********************************************************************************************** - * LinkClass::Add_Head -- This gadget makes itself the head of the given list. * - * * - * INPUT: list -- the list to make myself the head of * - * * - * OUTPUT: Returns with a reference to the object at the head of the list. This should be * - * the same object that is passed in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & LinkClass::Add_Head(LinkClass & list) -{ - LinkClass *ptr; - - /* - ** Get head of given list. - */ - ptr = &list.Head_Of_List(); - - /* - ** Link myself in front of it. - */ - ptr->Prev = this; - Next = ptr; - Prev = NULL; - - return(*this); -} - - -/*********************************************************************************************** - * LinkClass::Add_Tail -- Add myself to the end of the given list. * - * * - * INPUT: list -- list to add myself to * - * * - * OUTPUT: the head of the list * - * * - * WARNINGS: The previous and next pointers for the added object MUST have been properly * - * initialized for this routine to work correctly. * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & LinkClass::Add_Tail(LinkClass & list) -{ - LinkClass *ptr; - - /* - ** Get head of given list. - */ - ptr = &list.Tail_Of_List(); - - /* - ** Link myself in front of it. - */ - ptr->Next = this; - Prev = ptr; - Next = NULL; - - return(Head_Of_List()); -} - - -/*********************************************************************************************** - * LinkClass::Remove -- Removes the specified object from the list. * - * * - * This routine will remove the specified object from the list of objects. Because of the * - * previous and next pointers, it is possible to remove an object from the list without * - * knowing the head of the list. To do this, just call Remove() with the parameter of * - * "this". * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the new head of list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass * LinkClass::Remove(void) -{ - LinkClass * head = &Head_Of_List(); - LinkClass * tail = &Tail_Of_List(); - - if (Prev) { - Prev->Next = Next; - } - if (Next) { - Next->Prev = Prev; - } - Prev = 0; - Next = 0; - - if (head==this) { - if (tail==this) { - return(0); - } - return(&tail->Head_Of_List()); - } - return(head); -} - - diff --git a/code/TIBERIANDAWN/LINK.H b/code/TIBERIANDAWN/LINK.H deleted file mode 100644 index b781eac..0000000 --- a/code/TIBERIANDAWN/LINK.H +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\link.h_v 2.17 16 Oct 1995 16:45:52 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LINK.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef LINK_H -#define LINK_H - -/* -** This implements a simple linked list. It is possible to add, remove, and traverse the -** list. Since this is a doubly linked list, it is possible to remove an entry from the -** middle of an existing list. -*/ -class LinkClass -{ - public: - LinkClass(void); - virtual ~LinkClass(void); - - virtual LinkClass * Get_Next(void) const; - virtual LinkClass * Get_Prev(void) const; - virtual LinkClass & Add(LinkClass & object); - virtual LinkClass & Add_Tail(LinkClass & object); - virtual LinkClass & Add_Head(LinkClass & object); - virtual LinkClass const & Head_Of_List(void) const; - virtual LinkClass & Head_Of_List(void) - { - return (LinkClass &)(((LinkClass const *)this)->Head_Of_List()); - }; - virtual LinkClass const & Tail_Of_List(void) const; - virtual LinkClass & Tail_Of_List(void) - { - return (LinkClass &)(((LinkClass const *)this)->Tail_Of_List()); - }; - virtual void Zap(void); - virtual LinkClass * Remove(void); - - LinkClass & operator=(LinkClass & link); // Assignment operator. - LinkClass(LinkClass & link); // Copy constructor. - - private: - /* - ** Pointers to previous and next link objects in chain. - */ - LinkClass * Next; - LinkClass * Prev; -}; - -#endif diff --git a/code/TIBERIANDAWN/LIST.CPP b/code/TIBERIANDAWN/LIST.CPP deleted file mode 100644 index bf8cc17..0000000 --- a/code/TIBERIANDAWN/LIST.CPP +++ /dev/null @@ -1,894 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\list.cpv 2.17 16 Oct 1995 16:51:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LIST.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ListClass::Add -- This object adds itself to the given list * - * ListClass::Add_Head -- This gadget makes itself the head of the given list. * - * ListClass::Add_Item -- Adds a text item (as number) to the list box. * - * ListClass::Add_Item -- Adds an item to the list box. * - * ListClass::Add_Scroll_Bar -- Adds a scroll bar to the list box. * - * ListClass::Add_Tail -- Add myself to the end of the given list. * - * ListClass::Bump -- Bumps the list box up/down one "page". * - * ListClass::Current_Index -- Fetches the current selected index. * - * ListClass::Current_Item -- Fetches pointer to current item string. * - * ListClass::Draw_Entry -- Draws a list box text line as indicated. * - * ListClass::Draw_Me -- Draws the listbox. * - * ListClass::Get_Item -- Fetches an arbitrary item string. * - * ListClass::Peer_To_Peer -- A peer gadget was touched -- make adjustments. * - * ListClass::Remove -- Removes the specified object from the list. * - * ListClass::Remove_Item -- Remove specified text from list box. * - * ListClass::Remove_Scroll_Bar -- Removes the scroll bar if present * - * ListClass::Set_Selected_Index -- Set the top of the listbox to index specified. * - * ListClass::Set_Tabs -- Sets the tab stop list to be used for text printing. * - * ListClass::Set_View_Index -- Sets the top line for the current list view. * - * ListClass::Step -- Moves the list view one line in direction specified. * - * ListClass::Step_Selected_Index -- Change the listbox top line in direction specified. * - * ListClass::~ListClass -- Destructor for list class objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * ListClass::ListClass -- class constructor * - * * - * INPUT: id button ID * - * * - * x,y upper-left corner, in pixels * - * * - * w,h width, height, in pixels * - * * - * list ptr to array of char strings to list* - * * - * flags, style flags for mouse, style of listbox * - * * - * OUTPUT: none. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/05/1995 MML : Created. * - *=========================================================================*/ -ListClass::ListClass (int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down) : - ControlClass(id, x, y, w, h, LEFTPRESS | LEFTRELEASE | KEYBOARD, false), - UpGadget(0, up, x+w, y), - DownGadget(0, down, x+w, y+h), - ScrollGadget(0, x+w, y, 0, h, true) -{ - /* - ** Set preliminary values for the slider related gadgets. They don't automatically - ** appear at this time, but there are some values that can be pre-filled in. - */ - UpGadget.X -= UpGadget.Width; - DownGadget.X -= DownGadget.Width; - DownGadget.Y -= DownGadget.Height; - ScrollGadget.X -= MAX(UpGadget.Width, DownGadget.Width); - ScrollGadget.Y = Y+UpGadget.Height; - ScrollGadget.Height -= UpGadget.Height + DownGadget.Height; - ScrollGadget.Width = MAX(UpGadget.Width, DownGadget.Width); - - /* - ** Set the list box to a default state. - */ - TextFlags = flags; - IsScrollActive = false; - Tabs = 0; - SelectedIndex = 0; - CurrentTopIndex = 0; - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TextFlags); - LineHeight = FontHeight+FontYSpacing-1; - LineCount = (h-1) / LineHeight; -} - - -/*********************************************************************************************** - * ListClass::~ListClass -- Destructor for list class objects. * - * * - * This is the destructor for list objects. It handles removing anything it might have * - * allocated. This is typically the scroll bar. * - * * - * INPUT: none * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 01/16/1995 JLB : Created. * - *=============================================================================================*/ -ListClass::~ListClass(void) -{ - Remove_Scroll_Bar(); -} - - -/*********************************************************************************************** - * ListClass::Add_Item -- Adds an item to the list box. * - * * - * This will add the specified string to the list box. The string is added to the end * - * of the list. * - * * - * INPUT: text -- Pointer to the string to add to the list box. * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Add_Item(char const * text) -{ - if (text) { - List.Add(text); - Flag_To_Redraw(); - - /* - ** Add scroll gadget if the list gets too large to display all of the items - ** at the same time. - */ - if (List.Count() > LineCount) { - Add_Scroll_Bar(); - } - - /* - ** Tell the slider that there is one more entry in the list. - */ - if (IsScrollActive) { - ScrollGadget.Set_Maximum(List.Count()); - } - } - return(List.Count() - 1); -} - - -/*********************************************************************************************** - * ListClass::Add_Item -- Adds a text item (as number) to the list box. * - * * - * This will add the text as specified by the text number provided, to the list box. * - * The string is added to the end of the list. * - * * - * INPUT: text -- The text number for the string to add to the list box. * - * OUTPUT: none * - * WARNINGS: Once a string is added to the list box in this fashion, there is no method of * - * retrieving the text number as it relates to any particular index in the list. * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Add_Item(int text) -{ - if (text != TXT_NONE) { - Add_Item(Text_String(text)); - } - return(List.Count() - 1); -} - - -/*********************************************************************************************** - * ListClass::Remove_Item -- Remove specified text from list box. * - * * - * This routine will remove the specified text string from the list box. * - * * - * INPUT: text -- Pointer to the string to remove. * - * OUTPUT: none * - * WARNINGS: The text pointer passed into this routine MUST be the same text pointer that * - * was used to add the string to the list. * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Remove_Item(char const * text) -{ - if (text) { - List.Delete(text); - - /* - ** If the list is now small enough to display completely within the list box region, - ** then delete the slider gadget (if they are present). - */ - if (List.Count() <= LineCount) { - Remove_Scroll_Bar(); - } - - /* - ** Tell the slider that there is one less entry in the list. - */ - if (IsScrollActive) { - ScrollGadget.Set_Maximum(List.Count()); - } - - /* - ** If we just removed the selected entry, select the previous one - */ - if (SelectedIndex >= List.Count()) { - SelectedIndex--; - if (SelectedIndex < 0) - SelectedIndex = 0; - } - - /* - ** If we just removed the top-displayed entry, step up one item - */ - if (CurrentTopIndex >= List.Count()) { - CurrentTopIndex--; - if (CurrentTopIndex < 0) - CurrentTopIndex = 0; - if (IsScrollActive) - ScrollGadget.Step(1); - } - } -} - - -/*************************************************************************** - * ListClass::Action -- If clicked on, do this! * - * * - * INPUT: int flags -- combination of mouse flags indicating * - * what action to take. * - * * - * OUTPUT: bool result. * - * * - * WARNINGS: none. * - * * - * HISTORY: 01/05/1995 MML : Created. * - *=========================================================================*/ -int ListClass::Action(unsigned flags, KeyNumType & key) -{ - if (flags & LEFTRELEASE) { - key = KN_NONE; - flags &= (~LEFTRELEASE); - ControlClass::Action(flags, key); - return(true); - } else { - - /* -------------------------------------------------- - ** Handle keyboard events here. - */ - if (flags & KEYBOARD) { - - /* - ** Process the keyboard character. If indicated, consume this keyboard event - ** so that the edit gadget ID number is not returned. - */ - if (key == KN_UP) { - Step_Selected_Index(-1); - key = KN_NONE; - } else if (key == KN_DOWN) { - Step_Selected_Index(1); - key = KN_NONE; - } else { - flags &= ~KEYBOARD; - } - - } else { - - int index = Get_Mouse_Y() - (Y+1); - index = index / LineHeight; - SelectedIndex = CurrentTopIndex + index; - SelectedIndex = MIN(SelectedIndex, List.Count()-1); - } - } - return(ControlClass::Action(flags, key)); -} - - -/*********************************************************************************************** - * ListClass::Draw_Me -- Draws the listbox. * - * * - * This routine will render the listbox. * - * * - * INPUT: forced -- Should the listbox be redrawn even if it already thinks it doesn't * - * need to be? This is true when something outside of the gadget system * - * has trashed the screen. * - * * - * OUTPUT: Was the listbox redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Draw_Me(int forced) -{ - if (GadgetClass::Draw_Me(forced)) { - - /* - ** Turn off the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); - } - - Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_BOX, true); - - /* - ** Draw List. - */ - if (List.Count()) { - for (int index = 0; index < LineCount; index++) { - int line = CurrentTopIndex + index; - - if (List.Count() > line) { - - /* - ** Prints the text and handles right edge clipping and tabs. - */ - Draw_Entry(line, X+1, Y+(LineHeight*index)+1, Width-2, (line == SelectedIndex)); - } - } - } - - /* - ** Turn on the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * ListClass::Bump -- Bumps the list box up/down one "page". * - * * - * Use this routine to adjust the "page" that is being viewed in the list box. The view * - * will move up or down (as specified) one page (screen full) of text strings. * - * * - * INPUT: up -- Should the adjustment be up? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Bump(int up) -{ - if (IsScrollActive) { - if (ScrollGadget.Step(up)) { - CurrentTopIndex = ScrollGadget.Get_Value(); - Flag_To_Redraw(); - } - } -} - - -/*********************************************************************************************** - * ListClass::Step -- Moves the list view one line in direction specified. * - * * - * This routine will move the current view "page" one line in the direction specified. * - * * - * INPUT: up -- Should the view be moved upward? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Step(int up) -{ - if (IsScrollActive) { - if (ScrollGadget.Step(up)) { - CurrentTopIndex = ScrollGadget.Get_Value(); - Flag_To_Redraw(); - } - } -} - - -/*********************************************************************************************** - * ListClass::Get_Item -- Fetches an arbitrary item string. * - * * - * This routine will fetch an item string from the list box. The item fetched can be any * - * one of the ones in the list. * - * * - * INPUT: index -- The index to examine and return the text pointer from. * - * * - * OUTPUT: Returns with the text pointer to the string at the index position specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -char const * ListClass::Get_Item(int index) const -{ - if (List.Count() == 0) return (NULL); - - index = MIN(index, List.Count()-1 ); - return(List[index]); -} - - -/*********************************************************************************************** - * ListClass::Current_Item -- Fetches pointer to current item string. * - * * - * This routine will fetch a pointer to the currently selected item's text. * - * * - * INPUT: none * - * * - * OUTPUT: Return with pointer to currently selected text. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -char const * ListClass::Current_Item(void) -{ - return(List[SelectedIndex]); -} - - -/*********************************************************************************************** - * ListClass::Current_Index -- Fetches the current selected index. * - * * - * This routine will fetch the index number for the currently selected line. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the index of the currently selected line. This ranges from zero to * - * the number of items in the list minus one. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Current_Index(void) -{ - return(SelectedIndex); -} - - -/*********************************************************************************************** - * ListClass::Peer_To_Peer -- A peer gadget was touched -- make adjustments. * - * * - * This routine is called when one of the peer gadgets (the scroll arrows or the slider) * - * was touched in some fashion. This routine will sort out whom and why and then make * - * any necessary adjustments to the list box. * - * * - * INPUT: flags -- The event flags that affected the peer gadget. * - * * - * key -- The key value at the time of the event. * - * * - * whom -- Which gadget is being touched. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Peer_To_Peer(unsigned flags, KeyNumType &, ControlClass & whom) -{ - if (flags & LEFTRELEASE) { - if (&whom == &UpGadget) { - Step(true); - } - if (&whom == &DownGadget) { - Step(false); - } - } - - /* - ** The slider has changed, so reflect the current list position - ** according to the slider setting. - */ - if (&whom == &ScrollGadget) { - Set_View_Index(ScrollGadget.Get_Value()); - } -} - - -/*********************************************************************************************** - * ListClass::Set_View_Index -- Sets the top line for the current list view. * - * * - * This routine is used to set the line that will be at the top of the list view. This is * - * how the view can be scrolled up and down. This does not affect the currently selected * - * item. * - * * - * INPUT: index -- The line (index) to move to the top of the list view. * - * * - * OUTPUT: bool; Was the view actually changed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Set_View_Index(int index) -{ - index = Bound(index, 0, List.Count() - LineCount); - if (index != CurrentTopIndex) { - CurrentTopIndex = index; - Flag_To_Redraw(); - if (IsScrollActive) { - ScrollGadget.Set_Value(CurrentTopIndex); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * ListClass::Add_Scroll_Bar -- Adds a scroll bar to the list box. * - * * - * This routine will add a scroll bar (with matching arrows) to the list box. They are * - * added to the right edge and cause the interior of the list box to become narrower. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the scroll bar added? * - * * - * WARNINGS: The list box becomes narrower when the scroll bar is added. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Add_Scroll_Bar(void) -{ - if (!IsScrollActive) { - IsScrollActive = true; - - /* - ** Everything has been created successfully. Flag the list box to be - ** redrawn because it now must be made narrower to accomodate the new - ** slider gadgets. - */ - Flag_To_Redraw(); - Width -= ScrollGadget.Width; - - /* - ** Tell the newly created gadgets that they should inform this list box - ** whenever they get touched. In this way, the list box will automatically - ** be updated under control of the slider buttons. - */ - UpGadget.Make_Peer(*this); - DownGadget.Make_Peer(*this); - ScrollGadget.Make_Peer(*this); - - /* - ** Add these newly created gadgets to the same gadget list that the - ** list box is part of. - */ - UpGadget.Add(*this); - DownGadget.Add(*this); - ScrollGadget.Add(*this); - - /* - ** Make sure these added gadgets get redrawn at the next opportunity. - */ - UpGadget.Flag_To_Redraw(); - DownGadget.Flag_To_Redraw(); - ScrollGadget.Flag_To_Redraw(); - - /* - ** Inform the slider of the size of the window and the current view position. - */ - ScrollGadget.Set_Maximum(List.Count()); - ScrollGadget.Set_Thumb_Size(LineCount); - ScrollGadget.Set_Value(CurrentTopIndex); - - /* - ** Return with success flag. - */ - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * ListClass::Remove_Scroll_Bar -- Removes the scroll bar if present * - * * - * Use this routine to remove any attached scroll bar to this list box. If the scroll bar * - * is not present, then no action occurs. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the scroll bar removed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Remove_Scroll_Bar(void) -{ - if (IsScrollActive) { - IsScrollActive = false; - Width += ScrollGadget.Width; - ScrollGadget.Remove(); - UpGadget.Remove(); - DownGadget.Remove(); - Flag_To_Redraw(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * ListClass::Set_Tabs -- Sets the tab stop list to be used for text printing. * - * * - * This sets the tab stop list to be used for text printing. It specifies a series of * - * pixel offsets for each tab stop. The offsets are from the starting pixel position that * - * the text begins at. * - * * - * INPUT: tabs -- Pointer to a list of tab pixel offsets. * - * * - * OUTPUT: none * - * * - * WARNINGS: Only a pointer to the tabs is recorded by the ListClass object. Make sure that * - * the list remains intact for the duration of the existence of this object. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Set_Tabs(int const * tabs) -{ - Tabs = tabs; -} - - -/*********************************************************************************************** - * ListClass::Draw_Entry -- Draws a list box text line as indicated. * - * * - * This routine is called by the Draw_Me function when it desired to redraw a particular * - * text line in the list box. * - * * - * INPUT: index -- The index of the list entry to draw. This index is based on the * - * total list and NOT the current visible view page. * - * * - * x,y -- Pixel coordinates for the upper left corner of the text entry. * - * * - * width -- The maximum width that the text may draw over. It is expected that * - * this drawing routine entirely fills this length. * - * * - * selected -- bool; Is this a selected (highlighted) listbox entry? * - * * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Draw_Entry(int index, int x, int y, int width, int selected) -{ - if (TextFlags & TPF_6PT_GRAD) { - TextPrintType flags = TextFlags; - - if (selected) { - flags = flags | TPF_BRIGHT_COLOR; - LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, CC_GREEN_SHADOW); - } else { - if (!(flags & TPF_USE_GRAD_PAL)) { - flags = flags | TPF_MEDIUM_COLOR; - } - } - - Conquer_Clip_Text_Print(List[index], x, y, CC_GREEN, TBLACK, flags, width, Tabs); - - } else { - Conquer_Clip_Text_Print(List[index], x, y, (selected ? BLUE : WHITE), TBLACK, TextFlags, width, Tabs); - } -} - - -/*********************************************************************************************** - * ListClass::Add -- Adds myself to list immediately after given object * - * * - * Adds the list box to the chain, immemdiately after the given object. The order will be: * - * - Listbox * - * - Up arrow (if active) * - * - Down arrow (if active) * - * - Scroll gadget (if active) * - * * * - * INPUT: object -- Pointer to the object to be added right after this one. * - * * - * OUTPUT: Returns with a pointer to the head of the list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & ListClass::Add(LinkClass & list) -{ - /* - ** Add the scroll bar gadgets if they're active. - */ - if (IsScrollActive) { - ScrollGadget.Add(list); - DownGadget.Add(list); - UpGadget.Add(list); - } - - /* - ** Add myself to the list, then return. - */ - return(ControlClass::Add(list)); -} - - -/*********************************************************************************************** - * ListClass::Add_Head -- Adds myself to head of the given list * - * * - * INPUT: list -- list to add myself to * - * * - * OUTPUT: Returns with a reference to the object at the head of the list. This should be * - * the same object that is passed in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & ListClass::Add_Head(LinkClass & list) -{ - /* - ** Add the scroll bar gadgets if they're active. - */ - if (IsScrollActive) { - ScrollGadget.Add_Head(list); - DownGadget.Add_Head(list); - UpGadget.Add_Head(list); - } - - /* - ** Add myself to the list, then return. - */ - return(ControlClass::Add_Head(list)); -} - - -/*********************************************************************************************** - * ListClass::Add_Tail -- Adds myself to tail of given list * - * * - * Adds the list box to the tail of the give chain. The order will be: * - * - Listbox * - * - Up arrow (if active) * - * - Down arrow (if active) * - * - Scroll gadget (if active) * - * * - * INPUT: list -- list to add myself to * - * * - * OUTPUT: none * - * * - * WARNINGS: The previous and next pointers for the added object MUST have been properly * - * initialized for this routine to work correctly. * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -LinkClass & ListClass::Add_Tail(LinkClass & list) -{ - /* - ** Add myself to the list. - */ - ControlClass::Add_Tail(list); - - /* - ** Add the scroll bar gadgets if they're active. - */ - if (IsScrollActive) { - UpGadget.Add_Tail(list); - DownGadget.Add_Tail(list); - ScrollGadget.Add_Tail(list); - } - - return(Head_Of_List()); -} - - -/*********************************************************************************************** - * ListClass::Remove -- Removes the specified object from the list. * - * * - * This routine will remove the specified object from the list of objects. Because of the * - * previous and next pointers, it is possible to remove an object from the list without * - * knowing the head of the list. To do this, just call Remove() with the parameter of * - * "this". * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the new head of list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -GadgetClass * ListClass::Remove(void) -{ - /* - ** Remove the scroll bar if it's active - */ - if (IsScrollActive) { - ScrollGadget.Remove(); - DownGadget.Remove(); - UpGadget.Remove(); - } - - /* - ** Remove myself & return - */ - return(ControlClass::Remove()); -} - - -/*********************************************************************************************** - * ListClass::Set_Selected_Index -- Set the top of the listbox to index specified. * - * * - * This routine will set the top line of the listbox to the index value specified. * - * * - * INPUT: index -- The index to set the top of the listbox to. * - * * - * OUTPUT: none * - * * - * WARNINGS: The requested index may be adjusted to fit within legal parameters. * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -void ListClass::Set_Selected_Index(int index) -{ - if (index < List.Count()) { - SelectedIndex = index; - Flag_To_Redraw(); - if (SelectedIndex < CurrentTopIndex) { - Set_View_Index(SelectedIndex); - } - if (SelectedIndex >= CurrentTopIndex+LineCount) { - Set_View_Index(SelectedIndex-(LineCount-1)); - } - } -} - - -/*********************************************************************************************** - * ListClass::Step_Selected_Index -- Change the listbox top line in direction specified. * - * * - * This routine will scroll the top line of the listbox in the direction specified. * - * * - * INPUT: step -- The direction (and amount) to adjust the listbox. If negative value, then * - * the top line is scrolled upward. * - * * - * OUTPUT: Returns with the original top line index number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int ListClass::Step_Selected_Index(int step) -{ - int old = SelectedIndex; - - Set_Selected_Index(old + step); - return(old); -} diff --git a/code/TIBERIANDAWN/LIST.H b/code/TIBERIANDAWN/LIST.H deleted file mode 100644 index cb5fbf2..0000000 --- a/code/TIBERIANDAWN/LIST.H +++ /dev/null @@ -1,146 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\list.h_v 2.17 16 Oct 1995 16:46:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LIST.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef LIST_H -#define LIST_H - -#include "control.h" -#include "shapebtn.h" -#include "slider.h" - - -/*************************************************************************** - * ListClass -- Like a Windows ListBox structure * - * * - * INPUT: int x -- x position of gadget * - * int y -- y position of gadget * - * int w -- width of gadget * - * int h -- height of gadget * - * UWORD flags -- see enumeration choices * - * * - * OUTPUT: none. * - * WARNINGS: * - * HISTORY: 01/03/1995 MML : Created. * - *=========================================================================*/ -class ListClass : public ControlClass -{ - public: - ListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down); - virtual ~ListClass(void); - -// static ListClass * Create_One_Of(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down); - virtual int Add_Item(char const * text); - virtual int Add_Item(int text); - virtual int Add_Scroll_Bar(void); - virtual void Bump(int up); - virtual int Count(void) {return List.Count();}; - virtual int Current_Index(void); - virtual char const * Current_Item(void); - virtual int Draw_Me(int forced); - virtual char const * Get_Item(int index) const; - virtual int Step_Selected_Index(int forward); - - virtual void Peer_To_Peer(unsigned flags, KeyNumType & key, ControlClass & whom); - virtual void Remove_Item(char const * text); - virtual int Remove_Scroll_Bar(void); - virtual void Set_Selected_Index(int index); - virtual void Set_Tabs(int const * tabs); - virtual int Set_View_Index(int index); - virtual void Step(int up); - - /* - ** These overloaded list routines handle adding/removing the scroll bar - ** automatically when the list box is added or removed. - */ - virtual LinkClass & Add(LinkClass & object); - virtual LinkClass & Add_Tail(LinkClass & object); - virtual LinkClass & Add_Head(LinkClass & object); - virtual GadgetClass * Remove(void); - - protected: - virtual int Action(unsigned flags, KeyNumType &key); - virtual void Draw_Entry(int index, int x, int y, int width, int selected); - - /* - ** This controls what the text looks like. It uses the basic TPF_ flags that - ** are used to control Fancy_Text_Print(). - */ - TextPrintType TextFlags; - - /* - ** This is a series of tabstop pixel positions to use when processing any - ** characters found in a list box string. The tabs are a series of - ** pixel offsets from the starting pixel position of the text. - */ - int const *Tabs; - - /* - ** The actual list of text pointers is maintained by this list manager. The pointers - ** are stored in EMS. The text that is pointed to may also be in EMS. - */ - DynamicVectorClass List; - //EMSListOf List; - - /* - ** This is the total pixel height of a standar line of text. This is greatly - ** influenced by the TextFlags value. - */ - int LineHeight; - - /* - ** This is the number of text lines that can fit within the list box. - */ - int LineCount; - - /* - ** If the slider bar has been created, these point to the respective gadgets - ** that it is composed of. - */ - unsigned IsScrollActive:1; - ShapeButtonClass UpGadget; - ShapeButtonClass DownGadget; - SliderClass ScrollGadget; - - /* - ** This is the currently selected index. It is highlighted. - */ - int SelectedIndex; - - /* - ** This specifies the line (index) that is at the top of the list box. - */ - int CurrentTopIndex; -}; - -#endif diff --git a/code/TIBERIANDAWN/LOADDLG.CPP b/code/TIBERIANDAWN/LOADDLG.CPP deleted file mode 100644 index 9e2a10a..0000000 --- a/code/TIBERIANDAWN/LOADDLG.CPP +++ /dev/null @@ -1,735 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\loaddlg.cpv 2.18 16 Oct 1995 16:51:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LOADDLG.CPP * - * * - * Programmer : Maria Legg, Joe Bostic, Bill Randolph * - * * - * Start Date : March 19, 1995 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * LoadOptionsClass::Clear_List -- clears the list box & Files arrays * - * LoadOptionsClass::Compare -- for qsort * - * LoadOptionsClass::Fill_List -- fills the list box & GameNum arrays * - * LoadOptionsClass::LoadOptionsClass -- class constructor * - * LoadOptionsClass::Num_From_Ext -- clears the list box & GameNum arrays * - * LoadOptionsClass::Process -- main processing routine * - * LoadOptionsClass::~LoadOptionsClass -- class destructor * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include // for unlink - - -/*********************************************************************************************** - * LoadOptionsClass::LoadOptionsClass -- class constructor * - * * - * INPUT: * - * style style for this load/save dialog (LOAD/SAVE/DELETE) * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -LoadOptionsClass::LoadOptionsClass(LoadStyleType style) -{ - Style = style; - Files.Clear(); -} - - -/*********************************************************************************************** - * LoadOptionsClass::~LoadOptionsClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -LoadOptionsClass::~LoadOptionsClass() -{ - for (int i = 0; i < Files.Count(); i++) { - delete Files[i]; - } - Files.Clear(); -} - - -/*********************************************************************************************** - * LoadOptionsClass::Process -- main processing routine * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * false = User cancelled, true = operation completed * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -int LoadOptionsClass::Process(void) -{ - /* - ** Dialog & button dimensions - */ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - int d_dialog_w = 250 *factor; - int d_dialog_h = 156 * factor; - int d_dialog_x = (SeenBuff.Get_Width() - d_dialog_w) >> 1; - int d_dialog_y = (SeenBuff.Get_Height() - d_dialog_h) >> 1; - int d_dialog_cx = d_dialog_x + (d_dialog_w >> 1); - int d_txt8_h = 11 * factor; - int d_margin = 7 * factor; - - int d_list_w = d_dialog_w - (d_margin * 2); - int d_list_h = 104 * factor; - int d_list_x = d_dialog_x + d_margin; - int d_list_y = d_dialog_y + d_margin + d_txt8_h + d_margin; - - int d_edit_w = d_dialog_w - (d_margin * 2); - int d_edit_h = 13 * factor; - int d_edit_x = d_dialog_x + d_margin; - int d_edit_y = d_list_y + d_list_h - (30 * factor) + d_margin + d_txt8_h; - -#ifdef german - int d_button_w = 50 * factor; -#else - int d_button_w = 40 * factor; -#endif - int d_button_h = 13 * factor; - int d_button_x = d_dialog_cx - d_button_w - d_margin; - int d_button_y = d_dialog_y + d_dialog_h - d_button_h - d_margin; - -#ifdef german - int d_cancel_w = 50 * factor; -#else - int d_cancel_w = 40 * factor; -#endif - int d_cancel_h = 13 * factor; - int d_cancel_x = d_dialog_cx + d_margin; - int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin; -#if(0) - enum { - D_DIALOG_W = 250, // dialog width - D_DIALOG_H = 156, // dialog height - D_DIALOG_X = ((320 - D_DIALOG_W) / 2), // centered x-coord - D_DIALOG_Y = ((200 - D_DIALOG_H) / 2), // centered y-coord - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center - - D_TXT8_H = 11, // ht of 8-pt text - D_MARGIN = 7, // margin width/height - - D_LIST_W = D_DIALOG_W - (D_MARGIN * 2), - D_LIST_H = 104, - D_LIST_X = D_DIALOG_X + D_MARGIN, - D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN, - - D_EDIT_W = D_DIALOG_W - (D_MARGIN * 2), - D_EDIT_H = 13, - D_EDIT_X = D_DIALOG_X + D_MARGIN, - D_EDIT_Y = D_LIST_Y + D_LIST_H - 30 + D_MARGIN + D_TXT8_H, - -#if (GERMAN | FRENCH) - D_BUTTON_W = 50, -#else - D_BUTTON_W = 40, -#endif - D_BUTTON_H = 13, - D_BUTTON_X = D_DIALOG_CX - D_BUTTON_W - D_MARGIN, - D_BUTTON_Y = D_DIALOG_Y + D_DIALOG_H - D_BUTTON_H - D_MARGIN, - -#if (GERMAN | FRENCH) - D_CANCEL_W = 50,//BG:40 -#else - D_CANCEL_W = 40, -#endif - D_CANCEL_H = 13, - D_CANCEL_X = D_DIALOG_CX + D_MARGIN, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, - }; -#endif - /* - ** Button enumerations - */ - enum { - BUTTON_LOAD = 100, - BUTTON_SAVE, - BUTTON_DELETE, - BUTTON_CANCEL, - BUTTON_LIST, - BUTTON_EDIT, - }; - - /* - ** Redraw values: in order from "top" to "bottom" layer of the dialog - */ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /* - ** Dialog variables - */ - bool cancel = false; // true = user cancels - int list_ht = d_list_h; // adjusted list box height - - /* - ** Other Variables - */ - int btn_txt; // text on the 'OK' button - int btn_id; // ID of 'OK' button - int caption; // dialog caption - int game_idx = 0; // index of game to save/load/etc - int game_num = 0; // file number of game to load/save/etc - char game_descr[40] = {0}; // save-game description - char fname[13]; // for generating filename to delete - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - /* - ** Buttons - */ - ControlClass *commands = NULL; // the button list - - if (Style == LOAD) { - btn_txt = TXT_LOAD_BUTTON; - btn_id = BUTTON_LOAD; - caption = TXT_LOAD_MISSION; - } else { - if (Style == SAVE) { - btn_txt = TXT_SAVE_BUTTON; - btn_id = BUTTON_SAVE; - caption = TXT_SAVE_MISSION; - list_ht -= 30; - } else { - btn_txt = TXT_DELETE_BUTTON; - btn_id = BUTTON_DELETE; - caption = TXT_DELETE_MISSION; - } - } - - TextButtonClass button (btn_id, btn_txt, TPF_6PT_GRAD|TPF_CENTER|TPF_NOSHADOW, - d_button_x, d_button_y, d_button_w); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, TPF_6PT_GRAD|TPF_CENTER|TPF_NOSHADOW, - d_cancel_x, d_cancel_y, d_cancel_w); - - ListClass listbtn (BUTTON_LIST, d_list_x, d_list_y, d_list_w, list_ht, - TPF_6PT_GRAD | TPF_NOSHADOW, - up_button, - down_button); - - EditClass editbtn (BUTTON_EDIT, game_descr, 40, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - d_edit_x, d_edit_y, d_edit_w, -1, EditClass::ALPHANUMERIC); - - /* - ** Initialize. - */ - Set_Logic_Page(SeenBuff); - - Fill_List(&listbtn); - - /* - ** Do nothing if list is empty. - */ - if ((Style == LOAD || Style == WWDELETE) && listbtn.Count()==0) { - Clear_List(&listbtn); - CCMessageBox().Process(TXT_NO_SAVES); - return(false); - } - - /* - ** Create the button list. - */ - commands = &button; - cancelbtn.Add_Tail(*commands); - listbtn.Add_Tail(*commands); - if (Style == SAVE) { - editbtn.Add_Tail(*commands); - editbtn.Set_Focus(); - } - - /* - ** Main Processing Loop. - */ - bool firsttime = true; - bool display = true; - bool process = true; - while (process) { - - /* - ** Invoke game callback. - */ - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - cancel = true; - } - } - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Refresh display if needed. - */ - if (display) { - - Hide_Mouse(); - /* - ** Redraw the map. - */ - if (InMainLoop){ - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); - }else{ - HiddenPage.Clear(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - } - - - /* - ** Display the dialog box. - */ - if (display) { - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - Draw_Caption(caption, d_dialog_x, d_dialog_y, d_dialog_w); - - if (Style == SAVE) { - Fancy_Text_Print(TXT_MISSION_DESCRIPTION, d_dialog_cx, - d_edit_y - d_txt8_h, CC_GREEN, TBLACK, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_CENTER | TPF_NOSHADOW); - } - } - - /* - ** Redraw the buttons. - */ - if (display) { - commands->Flag_List_To_Redraw(); - } - Show_Mouse(); - display = false; - } - - /* - ** Get user input. - */ - KeyNumType input = commands->Input(); - - /* - ** The first time through the processing loop, set the edit - ** gadget to have the focus if this is the save dialog. The - ** focus must be set here since the gadget list has changed - ** and this change will cause any previous focus setting to be - ** cleared by the input processing routine. - */ - if (firsttime && Style == SAVE) { - firsttime = false; - editbtn.Set_Focus(); - editbtn.Flag_To_Redraw(); - } - - /* - ** If the key was pressed, then default to the appropriate - ** action button according to the style of this dialog box. - */ - if (input == KN_RETURN) { - switch (Style) { - case SAVE: - input = (KeyNumType)(BUTTON_SAVE|KN_BUTTON); - break; - - case LOAD: - input = (KeyNumType)(BUTTON_LOAD|KN_BUTTON); - break; - - case WWDELETE: - input = (KeyNumType)(BUTTON_DELETE|KN_BUTTON); - break; - } - } - - /* - ** Process input. - */ - switch (input) { - /* - ** Load: if load fails, present a message, and stay in the dialog - ** to allow the user to try another game - */ - case (BUTTON_LOAD | KN_BUTTON): - game_idx = listbtn.Current_Index(); - game_num = Files[game_idx]->Num; - if (Files[game_idx]->Valid) { - CCMessageBox().Process(TXT_LOADING, TXT_NONE); - if (!Load_Game(game_num)) { - CCMessageBox().Process(TXT_ERROR_LOADING_GAME); - } else { - Hide_Mouse(); - VisiblePage.Clear(); - Set_Palette(GamePalette); - Show_Mouse(); - process = false; - } - } else { - CCMessageBox().Process(TXT_OBSOLETE_SAVEGAME); - } - break; - - /* - ** Save: Save the game & exit the dialog - */ - case (BUTTON_SAVE | KN_BUTTON): - if (!strlen(game_descr)) { - CCMessageBox().Process(TXT_MUSTENTER_DESCRIPTION); - firsttime = true; - display = true; - break; - } - game_idx = listbtn.Current_Index(); - if (Disk_Space_Available() < SAVE_GAME_DISK_SPACE && game_idx == 0) { -// CCMessageBox().Process("Insuficent disk space to save a game. Please delete a previous save to free up some disk space and try again."); - CCMessageBox().Process(TXT_SPACE_CANT_SAVE); - firsttime = true; - display = true; - break; - } - - game_num = Files[game_idx]->Num; - if (!Save_Game(game_num,game_descr)) { - CCMessageBox().Process(TXT_ERROR_SAVING_GAME); - } else { - CCMessageBox().Process(TXT_GAME_WAS_SAVED, TXT_NONE, TXT_NONE); - } - process = false; - break; - - /* - ** Delete: delete the file & stay in the dialog, to allow the user - ** to delete multiple files. - */ - case (BUTTON_DELETE | KN_BUTTON): - game_idx = listbtn.Current_Index(); - game_num = Files[game_idx]->Num; - if (CCMessageBox().Process(TXT_DELETE_FILE_QUERY,TXT_YES,TXT_NO)==0) { - sprintf(fname,"SAVEGAME.%03d",game_num); - unlink(fname); - Clear_List(&listbtn); - Fill_List(&listbtn); - if (listbtn.Count() == 0) { - process = false; - } - } - display = true; - break; - - /* - ** If the user clicks on the list, see if the there is a new current - ** item; if so, and if we're in SAVE mode, copy the list item into - ** the save-game description field. - */ - case (BUTTON_LIST | KN_BUTTON): - if (Style != SAVE) { - break; - } - - if (listbtn.Count() && listbtn.Current_Index() != game_idx) { - game_idx = listbtn.Current_Index(); - /* - ** Copy the game's description, UNLESS it's the empty slot; if - ** it is, set the edit buffer to empty. - */ - if (game_idx != 0) { - strcpy(game_descr,listbtn.Get_Item(game_idx)); - } else { - game_descr[0] = 0; - } - editbtn.Set_Text(game_descr,40); - } - break; - - /* - ** ESC/Cancel: break - */ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - default: - break; - } - } - - Clear_List(&listbtn); - - if (cancel) return(false); - - return(true); -} - - -/*********************************************************************************************** - * LoadOptionsClass::Clear_List -- clears the list box & Files arrays * - * * - * This step is essential, because it frees all the strings allocated for list items. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void LoadOptionsClass::Clear_List(ListClass *list) -{ - /* - ** For every item in the list, free its buffer & remove it from the list. - */ - int j = list->Count(); - int i; - for (i = 0; i < j; i++) { - list->Remove_Item(list->Get_Item(0)); - } - - /* - ** Clear the array of game numbers - */ - for (i = 0; i < Files.Count(); i++) { - delete Files[i]; - } - Files.Clear(); -} - - -/*********************************************************************************************** - * LoadOptionsClass::Fill_List -- fills the list box & GameNum arrays * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - * 06/25/1995 JLB : Shows which saved games are "(old)". * - *=============================================================================================*/ -void LoadOptionsClass::Fill_List(ListClass *list) -{ -//PG_TO_FIX -#if (0) - FileEntryClass *fdata; // for adding entries to 'Files' - char descr[DESCRIP_MAX]; - unsigned scenario; // scenario # - HousesType house; // house - struct find_t ff; // for _dos_findfirst - int id; - - /* - ** Make sure the list is empty - */ - Clear_List(list); - - /* - ** Add the Empty Slot entry - */ - if (Style == SAVE) { - fdata = new FileEntryClass; - strcpy(fdata->Descr,Text_String(TXT_EMPTY_SLOT)); - fdata->DateTime = 0xffffffff; // will always be first - Files.Add(fdata); - } - - /* - ** Find all savegame files - */ - int rc = _dos_findfirst("SAVEGAME.*", _A_NORMAL, &ff); - - while (!rc) { - /* - ** Extract the game ID from the filename - */ - id = Num_From_Ext(ff.name); - - /* - ** get the game's info; if success, add it to the list - */ - bool ok = Get_Savefile_Info(id, descr, &scenario, &house); - - fdata = new FileEntryClass; - - fdata->Descr[0] = '\0'; - if (!ok) strcpy(fdata->Descr, Text_String(TXT_OLD_GAME)); - strncat(fdata->Descr, descr, (sizeof(fdata->Descr)-strlen(fdata->Descr))-1); - fdata->Valid = ok; - fdata->Scenario = scenario; - fdata->House = house; - fdata->Num = id; - fdata->DateTime = (((unsigned long)ff.wr_date) << 16) | (unsigned long)ff.wr_time; - Files.Add(fdata); - - /* - ** Find the next file - */ - rc = _dos_findnext(&ff); - } - - /* - ** If saving a game, determine a unique file ID for the empty slot - */ - if (Style == SAVE) { - /* - ** Find an un-used number to associate with the Empty Slot by looking in - ** GameNum for each number from 0 to 'N', where 'N' is the # of entries - ** in the list; if any number isn't found, use that number; otherwise, - ** use 'N + 1'. - */ - for (int i = 0; i < Files.Count(); i++) { // i = the # we're searching for - id = -1; // mark as 'not found' - for (int j = 0; j < Files.Count(); j++) { // loop through all game ID's - if (Files[j]->Num==i) { // if found, mark as found - id = j; - break; - } - } - if (id == -1) break; // if ID not found, use this one - } - - Files[0]->Num = i; // set the empty slot's ID - } - - /* - ** Now sort the list in order of Date/Time (newest first, oldest last) - */ - qsort((void *)(&Files[0]), Files.Count(), sizeof(class FileEntryClass *), LoadOptionsClass::Compare); - - /* - ** Now add every file's name to the list box - */ - for (int i = 0; i < Files.Count(); i++) { - list->Add_Item(Files[i]->Descr); - } -#endif -} - - -/*********************************************************************************************** - * LoadOptionsClass::Num_From_Ext -- clears the list box & GameNum arrays * - * * - * INPUT: * - * fname filename to parse * - * * - * OUTPUT: * - * File number for this name. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -int LoadOptionsClass::Num_From_Ext(char *fname) -{ - char ext[_MAX_EXT]; - - _splitpath(fname, NULL, NULL, NULL, ext); - int num = atoi(ext + 1); // skip the '.' - return(num); -} - - -/*********************************************************************************************** - * LoadOptionsClass::Compare -- for qsort * - * * - * INPUT: * - * p1,p2 ptrs to elements to compare * - * * - * OUTPUT: * - * 0 = same, -1 = (*p1) goes BEFORE (*p2), 1 = (*p1) goes AFTER (*p2) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -int LoadOptionsClass::Compare(const void *p1, const void *p2) -{ - class FileEntryClass *fe1,*fe2; - - fe1 = *((class FileEntryClass **)p1); - fe2 = *((class FileEntryClass **)p2); - - if (fe1->DateTime > fe2->DateTime) return(-1); - if (fe1->DateTime < fe2->DateTime) return(1); - return(0); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/LOADDLG.H b/code/TIBERIANDAWN/LOADDLG.H deleted file mode 100644 index fb3b5f2..0000000 --- a/code/TIBERIANDAWN/LOADDLG.H +++ /dev/null @@ -1,89 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\loaddlg.h_v 2.17 16 Oct 1995 16:48:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LOADDLG.H * - * * - * Programmer : Maria Legg, Joe Bostic, Bill Randolph * - * * - * Start Date : March 19, 1995 * - * * - * Last Update : March 19, 1995 * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef LOADDLG_H -#define LOADDLG_H - -class FileEntryClass { - public: - char Descr[40]; // save-game description - unsigned Scenario; // scenario # - HousesType House; // house - int Num; // save file number (from the extension) - unsigned long DateTime; // date/time stamp of file - bool Valid; // Is the scenario valid? -}; - -class LoadOptionsClass -{ - public: - /* - ** This defines the style of the dialog - */ - typedef enum OperationModeEnum { - NONE = 0, - LOAD, - SAVE, - WWDELETE, - } LoadStyleType; - - LoadOptionsClass (LoadStyleType style = LoadOptionsClass::NONE); - ~LoadOptionsClass (); - int Process (void); - - - protected: - /* - ** Internal routines - */ - void Clear_List (ListClass *list); // clears the list & game # array - void Fill_List (ListClass *list); // fills the list & game # array - int Num_From_Ext (char *fname); // translates filename to file # - static int Compare(const void *p1, const void *p2); // for qsort() - - /* - ** This is the requested style of the dialog - */ - LoadStyleType Style; - - /* - ** This is an array of pointers to FileEntryClass objects. These objects - ** are allocated on the fly as files are found, and pointers to them are - ** added to the vector list. Thus, all the objects must be free'd before - ** the vector list is cleared. This list is used for sorting the files - ** by date/time. - */ - DynamicVectorClass Files; -}; - - -#endif diff --git a/code/TIBERIANDAWN/LOGIC.CPP b/code/TIBERIANDAWN/LOGIC.CPP deleted file mode 100644 index f6298f6..0000000 --- a/code/TIBERIANDAWN/LOGIC.CPP +++ /dev/null @@ -1,342 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\logic.cpv 2.17 16 Oct 1995 16:50:52 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LOGIC.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 27, 1993 * - * * - * Last Update : December 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * LogicClass::AI -- Handles AI logic processing for game objects. * - * LogicClass::Debug_Dump -- Displays logic class status to the mono screen. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "logic.h" - -static unsigned FramesPerSecond=0; - -#ifdef CHEAT_KEYS - -static unsigned TotalFrames; -static unsigned FPSDivider = 1; -static unsigned AverageFramesPerSecond; - -/*********************************************************************************************** - * LogicClass::Debug_Dump -- Displays logic class status to the mono screen. * - * * - * This is a debugging support routine. It displays the current state of the logic class * - * to the monochrome monitor. It assumes that it is being called once per second. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Call this routine only once per second. * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void LogicClass::Debug_Dump(MonoClass *mono) const -{ - #define RECORDCOUNT 40 - #define RECORDHEIGHT 21 - static struct { - int Graphic; - } _record[RECORDCOUNT]; - static int _framecounter = 0; - - TotalFrames+= FramesPerSecond; - AverageFramesPerSecond = TotalFrames/FPSDivider++; - - mono->Set_Cursor(21, 9); - mono->Print( - "ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r" - "³Units.....³ ³Frame Rate: Avg: Frame: ³\r" - "³Infantry..³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\r" - "³Aircraft..³ ³ ³\r" - "³Buildings.³ ³ ³\r" - "³Terrain...³ à ´\r" - "³Bullets...³ ³ ³\r" - "³Anims.....³ ³ ³\r" - "³Teams.....³ à Ĵ\r" - "³Triggers..³ ³ ³\r" - "³Factories.³ ³ ³\r" - "³ ³ à ´\r" - "³ ³ ³ ³\r" - "ÀÄÄÄÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄ´Spare CPU TimeÃÄÄÄÄÄÄÄÄÄÄÄÄÙ\r"); - - _framecounter++; - mono->Set_Cursor(70, 10);mono->Printf("%ld", Frame); - if (ScenarioInit) { - mono->Set_Cursor(21, 9);mono->Printf("%d", ScenarioInit); - } - - mono->Set_Cursor(33, 10);mono->Printf("%3d", Units.Count()); - mono->Set_Cursor(33, 11);mono->Printf("%3d", Infantry.Count()); - mono->Set_Cursor(33, 12);mono->Printf("%3d", Aircraft.Count()); - mono->Set_Cursor(33, 13);mono->Printf("%3d", Buildings.Count()); - mono->Set_Cursor(33, 14);mono->Printf("%3d", Terrains.Count()); - mono->Set_Cursor(33, 15);mono->Printf("%3d", Bullets.Count()); - mono->Set_Cursor(33, 16);mono->Printf("%3d", Anims.Count()); - mono->Set_Cursor(33, 17);mono->Printf("%3d", Teams.Count()); - mono->Set_Cursor(33, 18);mono->Printf("%3d", Triggers.Count()); - mono->Set_Cursor(33, 19);mono->Printf("%3d", Factories.Count()); - - mono->Set_Cursor(48, 10);mono->Printf("%d", FramesPerSecond); - mono->Set_Cursor(58, 10);mono->Printf("%d", AverageFramesPerSecond); - - /* - ** Advance to the next recorded performance record. If the record buffer - ** is full then throw out the oldest record. - */ - memcpy(&_record[0], &_record[1], sizeof(_record[0])*(RECORDCOUNT-1)); - - /* - ** Fill in the data for the current frame's performance record. - */ - SpareTicks = MIN((long)SpareTicks, (long)TIMER_SECOND); - _record[RECORDCOUNT-1].Graphic = Fixed_To_Cardinal(RECORDHEIGHT, Cardinal_To_Fixed(TIMER_SECOND, SpareTicks)); - - /* - ** Draw the bars across the performance record screen. - */ - for (int column = 0; column < RECORDCOUNT; column++) { - for (int row = 1; row < RECORDHEIGHT; row += 2) { - static unsigned char _barchar[4] = {' ', 220, 0, 219}; - char str[2]; - int index = 0; - - index |= (_record[column].Graphic >= row) ? 0x01 : 0x00; - index |= (_record[column].Graphic >= row+1) ? 0x02: 0x00; - - str[1] = '\0'; - str[0] = _barchar[index]; - mono->Text_Print(str, 37+column, 21-(row/2)); - } - } - - SpareTicks = 0; - FramesPerSecond = 0; -} -#endif - - -/*********************************************************************************************** - * LogicClass::AI -- Handles AI logic processing for game objects. * - * * - * This routine is used to perform the AI processing for all game objects. This includes * - * all houses, factories, objects, and teams. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/29/1994 JLB : Created. * - * 12/17/1994 JLB : Must perform one complete pass rather than bailing early. * - * 12/23/1994 JLB : Esures that no object gets skipped if it was deleted. * - *=============================================================================================*/ -void LogicClass::AI(void) -{ - int index; - - FramesPerSecond++; - - /* - ** Crate regeneration is handled here. - */ - if (GameToPlay != GAME_NORMAL && CrateMaker && CrateTimer.Expired()) { - Map.Place_Random_Crate(); - CrateTimer = TICKS_PER_MINUTE * Random_Pick(7, 15); - } - - /* - ** Team AI is processed. - */ - for (index = 0; index < Teams.Count(); index++) { - Teams.Ptr(index)->AI(); - } - -// Heap_Dump_Check( "After Team AI" ); - - /* - ** AI for all sentient objects is processed. - */ - for (index = 0; index < Count(); index++) { - ObjectClass * obj = (*this)[index]; - - obj->AI(); - - /* - ** If the object was destroyed in the process of performing its AI, then - ** adjust the index so that no object gets skipped. - */ - if (obj != (*this)[index]) { -// if (!obj->IsActive) { - index--; - } - } - -// Heap_Dump_Check( "After Object AI" ); - - /* - ** A second pass through the sentient objects is required so that the appropriate scan - ** bits will be set for the owner house. - */ - for (index = 0; index < Units.Count(); index++) { - UnitClass const * unit = Units.Ptr(index); - if (unit->IsLocked && (GameToPlay != GAME_NORMAL || !unit->House->IsHuman || unit->IsDiscoveredByPlayer)) { - unit->House->NewUScan |= (1L << unit->Class->Type); - if (!unit->IsInLimbo) unit->House->NewActiveUScan |= (1L << unit->Class->Type); - } - } - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass const * infantry = Infantry.Ptr(index); - if (infantry->IsLocked && (GameToPlay != GAME_NORMAL || !infantry->House->IsHuman || infantry->IsDiscoveredByPlayer)) { - infantry->House->NewIScan |= (1L << infantry->Class->Type); - if (!infantry->IsInLimbo) infantry->House->NewActiveIScan |= (1L << infantry->Class->Type); - } - } - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass const * aircraft = Aircraft.Ptr(index); - if (aircraft->IsLocked && (GameToPlay != GAME_NORMAL || !aircraft->House->IsHuman || aircraft->IsDiscoveredByPlayer)) { - aircraft->House->NewAScan |= (1L << aircraft->Class->Type); - if (!aircraft->IsInLimbo) aircraft->House->NewActiveAScan |= (1L << aircraft->Class->Type); - } - } - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass const * building = Buildings.Ptr(index); - if (building->IsLocked && (GameToPlay != GAME_NORMAL || !building->House->IsHuman || building->IsDiscoveredByPlayer)) { - building->House->NewBScan |= (1L << building->Class->Type); - if (!building->IsInLimbo) building->House->NewActiveBScan |= (1L << building->Class->Type); - } - } - -// Heap_Dump_Check( "After Object AI 2" ); - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 10:56AM - // - HouseClass::Recalc_Attributes(); -#endif // USE_RA_AI - - /* - ** Map related logic is performed. - */ - Map.Logic(); - -// Heap_Dump_Check( "After Map.Logic" ); - - /* - ** Factory processing is performed. - */ - for (index = 0; index < Factories.Count(); index++) { - Factories.Ptr(index)->AI(); - } - -// Heap_Dump_Check( "After Factory AI" ); - -#if (1) - /* - ** Changed integrated from RA to only call AI on the houses that need it. Without this change, AI houses immediately - ** become paranoid at the start of a multiplayer match - ** ST - 10/30/2019 11:15AM - */ - if (GameToPlay != GAME_NORMAL) { - for (HousesType house = HOUSE_MULTI1; house < HOUSE_COUNT; house++) { - HouseClass * hptr = HouseClass::As_Pointer(house); - if (hptr && hptr->IsActive) { - hptr->AI(); - } - } - - HouseClass* neutral_house = HouseClass::As_Pointer(HOUSE_NEUTRAL); - if (neutral_house && neutral_house->IsActive) { - neutral_house->AI(); - } - - HouseClass* jp_house = HouseClass::As_Pointer(HOUSE_JP); - if (jp_house && jp_house->IsActive) { - jp_house->AI(); - } - - } else { - - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - HouseClass * hptr = HouseClass::As_Pointer(house); - if (hptr && hptr->IsActive) { - hptr->AI(); - } - } - } - - -#else - /* - ** House processing is performed. - */ - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - HouseClass * hptr = HouseClass::As_Pointer(house); - if (hptr && hptr->IsActive) { - hptr->AI(); - } - } -#endif - -// Heap_Dump_Check( "After House AI" ); -} - - - - - - -/*********************************************************************************************** - * LogicClass::Clear_Recently_Created_Bits -- Clear out the indicators that objects were * - * recently created * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 8/19/2019 5:47PM ST : Created. * - *=============================================================================================*/ -void LogicClass::Clear_Recently_Created_Bits(void) -{ - for (int index = 0; index < Count(); index++) { - ObjectClass * obj = (*this)[index]; - obj->IsRecentlyCreated = false; - } -} - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/LOGIC.H b/code/TIBERIANDAWN/LOGIC.H deleted file mode 100644 index a60f991..0000000 --- a/code/TIBERIANDAWN/LOGIC.H +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\logic.h_v 2.17 16 Oct 1995 16:45:52 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : LOGIC.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 29, 1994 * - * * - * Last Update : May 29, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef LOGIC_H -#define LOGIC_H - -#include "layer.h" - -/*********************************************************************************************** -** Game logic processing is controlled by this class. The graphic and AI logic is handled -** separately so that on slower machines, the graphic display is least affected. -*/ -class LogicClass : public LayerClass -{ - public: - void AI(void); - #ifdef CHEAT_KEYS - void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** Added. ST - 8/19/2019 5:46PM - */ - void Clear_Recently_Created_Bits(void); -}; -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/License.txt b/code/TIBERIANDAWN/License.txt deleted file mode 100644 index a4adf6d..0000000 --- a/code/TIBERIANDAWN/License.txt +++ /dev/null @@ -1,712 +0,0 @@ -Electronic Arts Inc. released only TiberianDawn.dll and RedAlert.dll and their corresponding source code under the GPL V3 below, with additional terms at the bottom. - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - -ADDITIONAL TERMS per GNU GPL Section 7 -No trademark or publicity rights are granted. This license does NOT give you -any right, title or interest in "Command & Conquer" or any other Electronic Arts trademark. You may not distribute any -modification of this program using any Electronic Arts trademark or claim any affiliation or association with Electronic Arts Inc. -or its affiliates or their employees. - -Any propagation or conveyance of this program must include this copyright -notice and these terms. - -If you convey this program (or any modifications of it) and assume -contractual liability for the program to recipients of it, you agree to -indemnify Electronic Arts for any liability that those contractual -assumptions impose on Electronic Arts. - -You may not misrepresent the origins of this program; modified versions of -the program must be marked as such and not identified as the original program. - -This disclaimer supplements the one included in the General Public License. -TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS PROGRAM IS -PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY OF ANY KIND, AND -YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF SATISFACTORY QUALITY AND -PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS DISCLAIMS ANY AND ALL EXPRESS, -IMPLIED OR STATUTORY WARRANTIES, INCLUDING IMPLIED WARRANTIES OF -MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, -NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A -COURSE OF DEALING, USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT -AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL -MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR -ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE WITH THIRD PARTY SOFTWARE -OR THAT ANY ERRORS IN THE PROGRAM WILL BE CORRECTED. NO ORAL OR WRITTEN ADVICE -PROVIDED BY ELECTRONIC ARTS OR ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A -WARRANTY. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON -IMPLIED WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A -CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY NOT APPLY -TO YOU. \ No newline at end of file diff --git a/code/TIBERIANDAWN/MAP.CPP b/code/TIBERIANDAWN/MAP.CPP deleted file mode 100644 index bb789a5..0000000 --- a/code/TIBERIANDAWN/MAP.CPP +++ /dev/null @@ -1,1577 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\map.cpv 2.17 16 Oct 1995 16:52:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAP.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : August 20, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * MapClass::Cell_Distance -- Determines the distance between two cells. * - * MapClass::Cell_Region -- Determines the region from a specified cell number. * - * MapClass::Cell_Threat -- Gets a houses threat value for a cell * - * MapClass::Close_Object -- Finds a clickable close object to the specified coordinate. * - * MapClass::In_Radar -- Is specified cell in the radar map? * - * MapClass::Init -- clears all cells * - * MapClass::Logic -- Handles map related logic functions. * - * MapClass::One_Time -- Performs special one time initializations for the map. * - * MapClass::Overlap_Down -- computes & marks object's overlap cells * - * MapClass::Overlap_Up -- Computes & clears object's overlap cells * - * MapClass::Overpass -- Performs any final cleanup to a freshly constructed map. * - * MapClass::Pick_Up -- Removes specified object from the map. * - * MapClass::Place_Down -- Places the specified object onto the map. * - * MapClass::Place_Random_Crate -- Places a crate at random location on map. * - * MapClass::Read_Binary -- reads the map's binary image file * - * MapClass::Set_Map_Dimensions -- Initialize the map. * - * MapClass::Sight_From -- Mark as visible the cells within a specified radius. * - * MapClass::Validate -- validates every cell on the map * - * MapClass::Write_Binary -- writes the map's binary image file * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#define MCW MAP_CELL_W -int const MapClass::RadiusOffset[] = { - /* 0 */ 0, - /* 1 */ (-MCW*1)-1,(-MCW*1)+0,(-MCW*1)+1,-1,1,(MCW*1)-1,(MCW*1)+0,(MCW*1)+1, - /* 2 */ (-MCW*2)-1,(-MCW*2)+0,(-MCW*2)+1,(-MCW*1)-2,(-MCW*1)+2,-2,2,(MCW*1)-2,(MCW*1)+2,(MCW*2)-1,(MCW*2)+0,(MCW*2)+1, - /* 3 */ (-MCW*3)-1,(-MCW*3)+0,(-MCW*3)+1,(-MCW*2)-2,(-MCW*2)+2,(-MCW*1)-3,(-MCW*1)+3,-3,3,(MCW*1)-3,(MCW*1)+3,(MCW*2)-2,(MCW*2)+2,(MCW*3)-1,(MCW*3)+0,(MCW*3)+1, - /* 4 */ (-MCW*4)-1,(-MCW*4)+0,(-MCW*4)+1,(-MCW*3)-3,(-MCW*3)-2,(-MCW*3)+2,(-MCW*3)+3,(-MCW*2)-3,(-MCW*2)+3,(-MCW*1)-4,(-MCW*1)+4,-4,4,(MCW*1)-4,(MCW*1)+4,(MCW*2)-3,(MCW*2)+3,(MCW*3)-3,(MCW*3)-2,(MCW*3)+2,(MCW*3)+3,(MCW*4)-1,(MCW*4)+0,(MCW*4)+1, - /* 5 */ (-MCW*5)-1,(-MCW*5)+0,(-MCW*5)+1,(-MCW*4)-3,(-MCW*4)-2,(-MCW*4)+2,(-MCW*4)+3,(-MCW*3)-4,(-MCW*3)+4,(-MCW*2)-4,(-MCW*2)+4,(-MCW*1)-5,(-MCW*1)+5,-5,5,(MCW*1)-5,(MCW*1)+5,(MCW*2)-4,(MCW*2)+4,(MCW*3)-4,(MCW*3)+4,(MCW*4)-3,(MCW*4)-2,(MCW*4)+2,(MCW*4)+3,(MCW*5)-1,(MCW*5)+0,(MCW*5)+1, - /* 6 */ (-MCW*6)-1,(-MCW*6)+0,(-MCW*6)+1,(-MCW*5)-3,(-MCW*5)-2,(-MCW*5)+2,(-MCW*5)+3,(-MCW*4)-4,(-MCW*4)+4,(-MCW*3)-5,(-MCW*3)+5,(-MCW*2)-5,(-MCW*2)+5,(-MCW*1)-6,(-MCW*1)+6,-6,6,(MCW*1)-6,(MCW*1)+6,(MCW*2)-5,(MCW*2)+5,(MCW*3)-5,(MCW*3)+5,(MCW*4)-4,(MCW*4)+4,(MCW*5)-3,(MCW*5)-2,(MCW*5)+2,(MCW*5)+3,(MCW*6)-1,(MCW*6)+0,(MCW*6)+1, - /* 7 */ (-MCW*7)-1,(-MCW*7)+0,(-MCW*7)+1,(-MCW*6)-3,(-MCW*6)-2,(-MCW*6)+2,(-MCW*6)+3,(-MCW*5)-5,(-MCW*5)-4,(-MCW*5)+4,(-MCW*5)+5,(-MCW*4)-5,(-MCW*4)+5,(-MCW*3)-6,(-MCW*3)+6,(-MCW*2)-6,(-MCW*2)+6,(-MCW*1)-7,(-MCW*1)+7,-7,7,(MCW*1)-7,(MCW*1)+7,(MCW*2)-6,(MCW*2)+6,(MCW*3)-6,(MCW*3)+6,(MCW*4)-5,(MCW*4)+5,(MCW*5)-5,(MCW*5)-4,(MCW*5)+4,(MCW*5)+5,(MCW*6)-3,(MCW*6)-2,(MCW*6)+2,(MCW*6)+3,(MCW*7)-1,(MCW*7)+0,(MCW*7)+1, - /* 8 */ (-MCW*8)-1,(-MCW*8)+0,(-MCW*8)+1,(-MCW*7)-3,(-MCW*7)-2,(-MCW*7)+2,(-MCW*7)+3,(-MCW*6)-5,(-MCW*6)-4,(-MCW*6)+4,(-MCW*6)+5,(-MCW*5)-6,(-MCW*5)+6,(-MCW*4)-6,(-MCW*4)+6,(-MCW*3)-7,(-MCW*3)+7,(-MCW*2)-7,(-MCW*2)+7,(-MCW*1)-8,(-MCW*1)+8,-8,8,(MCW*1)-8,(MCW*1)+8,(MCW*2)-7,(MCW*2)+7,(MCW*3)-7,(MCW*3)+7,(MCW*4)-6,(MCW*4)+6,(MCW*5)-6,(MCW*5)+6,(MCW*6)-5,(MCW*6)-4,(MCW*6)+4,(MCW*6)+5,(MCW*7)-3,(MCW*7)-2,(MCW*7)+2,(MCW*7)+3,(MCW*8)-1,(MCW*8)+0,(MCW*8)+1, - /* 9 */ (-MCW*9)-1,(-MCW*9)+0,(-MCW*9)+1,(-MCW*8)-3,(-MCW*8)-2,(-MCW*8)+2,(-MCW*8)+3,(-MCW*7)-5,(-MCW*7)-4,(-MCW*7)+4,(-MCW*7)+5,(-MCW*6)-6,(-MCW*6)+6,(-MCW*5)-7,(-MCW*5)+7,(-MCW*4)-7,(-MCW*4)+7,(-MCW*3)-8,(-MCW*3)+8,(-MCW*2)-8,(-MCW*2)+8,(-MCW*1)-9,(-MCW*1)+9,-9,9,(MCW*1)-9,(MCW*1)+9,(MCW*2)-8,(MCW*2)+8,(MCW*3)-8,(MCW*3)+8,(MCW*4)-7,(MCW*4)+7,(MCW*5)-7,(MCW*5)+7,(MCW*6)-6,(MCW*6)+6,(MCW*7)-5,(MCW*7)-4,(MCW*7)+4,(MCW*7)+5,(MCW*8)-3,(MCW*8)-2,(MCW*8)+2,(MCW*8)+3,(MCW*9)-1,(MCW*9)+0,(MCW*9)+1, - /* 10 */ (-MCW*10)-1,(-MCW*10)+0,(-MCW*10)+1,(-MCW*9)-3,(-MCW*9)-2,(-MCW*9)+2,(-MCW*9)+3,(-MCW*8)-5,(-MCW*8)-4,(-MCW*8)+4,(-MCW*8)+5,(-MCW*7)-7,(-MCW*7)-6,(-MCW*7)+6,(-MCW*7)+7,(-MCW*6)-7,(-MCW*6)+7,(-MCW*5)-8,(-MCW*5)+8,(-MCW*4)-8,(-MCW*4)+8,(-MCW*3)-9,(-MCW*3)+9,(-MCW*2)-9,(-MCW*2)+9,(-MCW*1)-10,(-MCW*1)+10,-10,10,(MCW*1)-10,(MCW*1)+10,(MCW*2)-9,(MCW*2)+9,(MCW*3)-9,(MCW*3)+9,(MCW*4)-8,(MCW*4)+8,(MCW*5)-8,(MCW*5)+8,(MCW*6)-7,(MCW*6)+7,(MCW*7)-7,(MCW*7)-6,(MCW*7)+6,(MCW*7)+7,(MCW*8)-5,(MCW*8)-4, - (MCW*8)+4,(MCW*8)+5,(MCW*9)-3,(MCW*9)-2,(MCW*9)+2,(MCW*9)+3,(MCW*10)-1,(MCW*10)+0,(MCW*10)+1, -}; - -int const MapClass::RadiusCount[11] = {1,9,21,37,61,89,121,161,205,253,309}; - - -CellClass *BlubCell; - -/*********************************************************************************************** - * MapClass::One_Time -- Performs special one time initializations for the map. * - * * - * This routine is used by the game initialization function in order to perform any one * - * time initializations required for the map. This includes allocation of the map and * - * setting up its default dimensions. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine MUST be called once and only once. * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 12/01/1994 BR : Added CellTriggers initialization * - *=============================================================================================*/ -void MapClass::One_Time(void) -{ - GScreenClass::One_Time(); - - XSize = MAP_CELL_W; - YSize = MAP_CELL_H; - Size = XSize * YSize; - - /* - ** Allocate the cell array. - */ - Alloc_Cells(); - - /* - ** Init the CellTriggers array to the required size. - */ - CellTriggers.Resize(MAP_CELL_TOTAL); -} - -//////////////////////////////////////////////////// -// Added this function to allow the editor to setup the map without setting up the entire system. - 06/18/2019 JAS -void MapClass::One_Time_Editor(void) -{ - XSize = MAP_CELL_W; - YSize = MAP_CELL_H; - Size = XSize * YSize; - - /* - ** Allocate the cell array. - */ - Alloc_Cells(); - - /* - ** Init the CellTriggers array to the required size. - */ - CellTriggers.Resize(MAP_CELL_TOTAL); -} -// End of change. - 06/15/2019 JAS -//////////////////////////////////////////////////// - -/*********************************************************************************************** - * MapClass::Init_Clear -- clears the map & buffers to a known state * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void MapClass::Init_Clear(void) -{ - GScreenClass::Init_Clear(); - Init_Cells(); - TiberiumScan = 0; - IsForwardScan = true; - TiberiumGrowthCount = 0; - TiberiumSpreadCount = 0; -} - - -/*********************************************************************************************** - * MapClass::Alloc_Cells -- allocates the cell array * - * * - * This routine should be called at One_Time, and after loading the Map object from a save * - * game, but prior to loading the cell objects. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void MapClass::Alloc_Cells(void) -{ - /* - ** Assume that whatever the contents of the VectorClass are is garbage - ** (it may have been loaded from a save-game file), so zero it out first. - */ - Vector = 0; - VectorMax = 0; - IsAllocated = 0; - Resize(Size); -} - - -/*********************************************************************************************** - * MapClass::Free_Cells -- frees the cell array * - * * - * This routine is used by the Load_Game routine to free the map's cell array before loading * - * the map object from disk; the array is then re-allocated & cleared before the cell objects * - * are loaded. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void MapClass::Free_Cells(void) -{ - Clear(); -} - - -/*********************************************************************************************** - * MapClass::Init_Cells -- Initializes the cell array to a fresh state. * - * * - * This routine is used by Init_Clear to set the cells to a known state; it's also used by * - * the Load_Game routine to init all cells before loading a set of cells from disk, so it * - * needs to be called separately from the other Init_xxx() routines. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/17/1995 BRR : Created. * - *=============================================================================================*/ -void MapClass::Init_Cells(void) -{ - TotalValue = 0; -#ifdef NEVER - Free_Cells(); - Alloc_Cells(); -#else - for (int index = 0; index < MAP_CELL_TOTAL; index++) { - Map[index] = CellClass(); - } -#endif -} - - -/*********************************************************************************************** - * MapClass::Set_Map_Dimensions -- Set map dimensions. * - * * - * This routine is used to set the legal limits and position of the * - * map as it relates to the overall map array. Typically, this is * - * called by the scenario loading code. * - * * - * INPUT: x,y -- The X and Y coordinate of the "upper left" corner * - * of the map. * - * * - * w,h -- The width and height of the legal map. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - *=============================================================================================*/ -void MapClass::Set_Map_Dimensions(int x, int y, int w, int h) -{ - MapCellX = x; - MapCellY = y; - MapCellWidth = w; - MapCellHeight = h; -} - - -/*********************************************************************************************** - * MapClass::Sight_From -- Mark as visible the cells within a specified radius. * - * * - * This routine is used to reveal the cells around a specific location. * - * Typically, as a unit moves or is deployed, this routine will be * - * called. Since it deals with MANY cells, it needs to be extremely * - * fast. * - * * - * INPUT: house -- Player to perform the visibility update for * - * * - * cell -- The coordinate that the sighting originates from. * - * * - * sightrange-- The distance in cells that sighting extends. * - * * - * incremental-- Is this an incremental sighting. In other * - * words, has this function been called before where * - * the center coordinate is no more than one cell * - * distant from the last time? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/19/1992 JLB : Created. * - * 03/08/1994 JLB : Updated to use sight table and incremental flag. * - * 05/18/1994 JLB : Converted to member function. * - * 03/06/2019 ST : Added HouseClass pointer parameter for new multiplayer code * - *=============================================================================================*/ -void MapClass::Sight_From(HouseClass *house, CELL cell, int sightrange, bool incremental) -{ - int xx; // Center cell X coordinate (bounds checking). - int const *ptr; // Offset pointer. - int count; // Counter for number of offsets to process. - - // Added. ST - 3/6/2019 1:50PM - if ((house == NULL || house->IsHuman == false) && !ShareAllyVisibility) { - return; - } - - /* - ** Units that are off-map cannot sight. - */ - if (!In_Radar(cell)) return; - if (!sightrange || sightrange > 10) return; - - /* - ** Determine logical cell coordinate for center scan point. - */ - xx = Cell_X(cell); - - /* - ** Incremental scans only scan the outer rings. Full scans - ** scan all internal cells as well. - */ - count = RadiusCount[sightrange]; - ptr = &RadiusOffset[0]; - if (incremental) { - if (sightrange > 1) { - ptr += RadiusCount[sightrange-2]; - count -= RadiusCount[sightrange-2]; - } - } - - /* - ** Process all offsets required for the desired scan. - */ - while (count--) { - CELL newcell; // New cell with offset. - int xdiff; // New cell's X coordinate distance from center. - - newcell = cell + *ptr++; - - /* - ** Determine if the map edge has been wrapped. If so, - ** then don't process the cell. - */ - if ((unsigned)newcell >= MAP_CELL_TOTAL) continue; - xdiff = Cell_X(newcell) - xx; - xdiff = ABS(xdiff); - if (xdiff > sightrange) continue; - if (Distance(newcell, cell) > sightrange) continue; - - /* - ** Map the cell. For incremental scans, then update - ** adjacent cells as well. For full scans, just update - ** the cell itself. - */ - if (!(*this)[newcell].Is_Mapped(house)) { - // Pass the house through, instead of assuming it's the local player. ST - 3/6/2019 10:26AM - //Map.Map_Cell(newcell, PlayerPtr); - Map.Map_Cell(newcell, house, true); - } - } -} - - -/*********************************************************************************************** - * MapClass::Cell_Distance -- Determines the distance between two cells. * - * * - * This routine will return with the calculated "straight line" * - * distance between the two cells specified. It uses the dragon strike * - * method of distance calculation. * - * * - * INPUT: cell1 -- First cell. * - * * - * cell2 -- Second cell. * - * * - * OUTPUT: Returns with the "cell" distance between the two cells * - * specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/29/1994 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - *=============================================================================================*/ -int MapClass::Cell_Distance(CELL cell1, CELL cell2) -{ - register int x,y; // Difference on X and Y axis. - - x = Cell_X(cell1) - Cell_X(cell2); - y = Cell_Y(cell1) - Cell_Y(cell2); - - if (x < 0) x = -x; - if (y < 0) y = -y; - - if (x > y) { - return(x + (y>>1)); - } - return(y + (x>>1)); -} - - -/*********************************************************************************************** - * MapClass::In_Radar -- Is specified cell in the radar map? * - * * - * This determines if the specified cell can be within the navigable * - * bounds of the map. Technically, this means, any cell that can be * - * scanned by radar. If a cell returns false from this function, then * - * the player could never move to or pass over this cell. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: bool; Is this cell possible to be displayed on radar? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 04/30/1994 JLB : Converted to member function. * - * 05/01/1994 JLB : Speeded up. * - *=============================================================================================*/ -bool MapClass::In_Radar(CELL cell) const -{ - if (cell & 0xF000) return(false); - return((unsigned)(Cell_X(cell) - MapCellX) < (unsigned)MapCellWidth && (unsigned)(Cell_Y(cell) - MapCellY) < (unsigned)MapCellHeight); -} - - -/*********************************************************************************************** - * MapClass::Place_Down -- Places the specified object onto the map. * - * * - * This routine is used to place an object onto the map. It updates the "occupier" of the * - * cells that this object covers. The cells are determined from the Occupy_List function * - * provided by the object. Only one cell can have an occupier and this routine is the only * - * place that sets this condition. * - * * - * INPUT: cell -- The cell to base object occupation around. * - * * - * object -- The object to place onto the map. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/31/1994 JLB : Created. * - *=============================================================================================*/ -void MapClass::Place_Down(CELL cell, ObjectClass * object) -{ - if (!object) return; - - short const *list = object->Occupy_List(); - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if ((unsigned)newcell < MAP_CELL_TOTAL) { - (*this)[newcell].Occupy_Down(object); - (*this)[newcell].Recalc_Attributes(); - (*this)[newcell].Redraw_Objects(); - } - } - - list = object->Overlap_List(); - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if ((unsigned)newcell < MAP_CELL_TOTAL) { - (*this)[newcell].Overlap_Down(object); - (*this)[newcell].Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * MapClass::Pick_Up -- Removes specified object from the map. * - * * - * The object specified is removed from the map by this routine. This will remove the * - * occupation flag for all the cells that the object covers. The cells that are covered * - * are determined from the Occupy_List function. * - * * - * INPUT: cell -- The cell that the object is centered about. * - * * - * object -- Pointer to the object that will be removed. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/31/1994 JLB : Created. * - *=============================================================================================*/ -void MapClass::Pick_Up(CELL cell, ObjectClass * object) -{ - if (!object) return; - - short const *list = object->Occupy_List(); - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if ((unsigned)newcell < MAP_CELL_TOTAL) { - (*this)[newcell].Occupy_Up(object); - (*this)[newcell].Recalc_Attributes(); - (*this)[newcell].Redraw_Objects(); - } - } - - list = object->Overlap_List(); - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if ((unsigned)newcell < MAP_CELL_TOTAL) { - (*this)[newcell].Overlap_Up(object); - (*this)[newcell].Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * MapClass::Overlap_Down -- computes & marks object's overlap cells * - * * - * This routine is just like Place_Down, but it doesn't mark the cell's Occupier. * - * This routine is used to implement MARK_OVERLAP_DOWN, which is useful for changing * - * an object's render size, but not its logical size (ie when it's selected or an * - * animation is attached to it). * - * * - * INPUT: * - * cell -- The cell to base object overlap around. * - * object -- The object to place onto the map. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/12/1995 BRR : Created. * - *=============================================================================================*/ -void MapClass::Overlap_Down(CELL cell, ObjectClass * object) -{ - if (!object) return; - - short const *list = object->Overlap_List(); - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if ((unsigned)newcell < MAP_CELL_TOTAL) { - (*this)[newcell].Overlap_Down(object); - (*this)[newcell].Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * MapClass::Overlap_Up -- Computes & clears object's overlap cells * - * * - * This routine is just like Pick_Up, but it doesn't mark the cell's Occupier. * - * This routine is used to implement MARK_OVERLAP_UP, which is useful for changing * - * an object's render size, but not its logical size (ie when it's selected or an * - * animation is attached to it). * - * * - * INPUT: * - * cell -- The cell to base object overlap around. * - * object -- The object to place onto the map. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/12/1995 BRR : Created. * - *=============================================================================================*/ -void MapClass::Overlap_Up(CELL cell, ObjectClass * object) -{ - if (!object) return; - - short const *list = object->Overlap_List(); - while (*list != REFRESH_EOL) { - CELL newcell = cell + *list++; - if ((unsigned)newcell < MAP_CELL_TOTAL) { - (*this)[newcell].Overlap_Up(object); - (*this)[newcell].Redraw_Objects(); - } - } -} - - -/*********************************************************************************************** - * MapClass::Overpass -- Performs any final cleanup to a freshly constructed map. * - * * - * This routine will clean up anything necessary with the presumption that the map has * - * been freshly created. Such things to clean up include various tiberium concentrations. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the total credit value of the tiberium on the map. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - * 02/13/1995 JLB : Returns total tiberium worth. * - * 02/15/1995 JLB : Optimal scan. * - *=============================================================================================*/ -long MapClass::Overpass(void) -{ - long value = 0; - - /* - ** Smooth out Tiberium. Cells that are not surrounded by other tiberium - ** will be reduced in density. - */ - for (int y = 0; y < MapCellHeight-1; y++) { - for (int x = 0; x < MapCellWidth; x++) { - value += (*this)[(MapCellY+y) * MAP_CELL_W + (MapCellX+x)].Tiberium_Adjust(true); - } - } - return(value); -} - - -/*********************************************************************************************** - * MapClass::Read_Binary -- reads the map's binary image file * - * * - * INPUT: * - * root root filename for scenario * - * crc ptr to CRC value to update * - * * - * OUTPUT: * - * 1 = success, 0 = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/14/1994 BR : Created. * - * 01/08/1995 JLB : Fixup any obsolete icons detected. * - *=============================================================================================*/ -#ifdef DEMO -bool MapClass::Read_Binary(char const * root, unsigned long *) -#else -bool MapClass::Read_Binary(char const * root, unsigned long *crc) -#endif -{ - CCFileClass file; - char fname[_MAX_FNAME+_MAX_EXT]; - int i; - char *map; - void *rawmap; - void const * shape; - - /* - ** Filename = INI name with BIN extension. - */ - sprintf(fname,"%s.BIN",root); - - /* - ** Create object & open file. - */ - file.Set_Name(fname); - if (!file.Is_Available()) { - return(false); - } - file.Open(READ); - - /* - ** Loop through all cells. - */ - CellClass * cellptr = &Map[0]; - for (i = 0; i < MAP_CELL_TOTAL; i++) { - struct { - TemplateType TType; // Template type. - unsigned char TIcon; // Template icon number. - } temp; - - if (file.Read(&temp, sizeof(temp)) != sizeof(temp)) break; - if (temp.TType == (TemplateType)255) { - temp.TType = TEMPLATE_NONE; - } - - /* - ** Verify that the template type actually contains the template number specified. If - ** an illegal icon was specified, then replace it with clear terrain. - */ - if (temp.TType != TEMPLATE_CLEAR1 && temp.TType != TEMPLATE_NONE) { - TemplateTypeClass const &ttype = TemplateTypeClass::As_Reference(temp.TType); - shape = ttype.Get_Image_Data(); - if (shape) { - rawmap = Get_Icon_Set_Map(shape); - if (rawmap) { - map = (char*)rawmap; - if ((temp.TIcon >= (ttype.Width * ttype.Height)) || (map[temp.TIcon] == -1)) { - temp.TIcon = 0; - temp.TType = TEMPLATE_NONE; - } - } - } - } - - cellptr->TType = temp.TType; - cellptr->TIcon = temp.TIcon; - cellptr->Recalc_Attributes(); - -#ifndef DEMO - Add_CRC(crc, (unsigned long)cellptr->TType); - Add_CRC(crc, (unsigned long)cellptr->TIcon); -#endif - - cellptr++; - } - - /* - ** Close the file. - */ - file.Close(); - - return(i == MAP_CELL_TOTAL); -} - - -/*********************************************************************************************** - * MapClass::Read_BinaryRead_Binary_File -- reads the map's binary image file * - * * - * INPUT: * - * fname file path for scenario * - * crc ptr to CRC value to update * - * * - * OUTPUT: * - * 1 = success, 0 = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/28/2019 JAS : Created. * - *=============================================================================================*/ -bool MapClass::Read_Binary_File(char const * fname, unsigned long *crc) -{ - CCFileClass file; - - int i; - char *map; - void *rawmap; - void const * shape; - - /* - ** Create object & open file. - */ - file.Set_Name(fname); - if (!file.Is_Available()) { - return(false); - } - file.Open(READ); - - /* - ** Loop through all cells. - */ - CellClass * cellptr = &Map[0]; - for (i = 0; i < MAP_CELL_TOTAL; i++) { - struct { - TemplateType TType; // Template type. - unsigned char TIcon; // Template icon number. - } temp; - - if (file.Read(&temp, sizeof(temp)) != sizeof(temp)) break; - if (temp.TType == (TemplateType)255) { - temp.TType = TEMPLATE_NONE; - } - - /* - ** Verify that the template type actually contains the template number specified. If - ** an illegal icon was specified, then replace it with clear terrain. - */ - if (temp.TType != TEMPLATE_CLEAR1 && temp.TType != TEMPLATE_NONE) { - shape = TemplateTypeClass::As_Reference(temp.TType).Get_Image_Data(); - if (shape) { - rawmap = Get_Icon_Set_Map(shape); - if (rawmap) { - map = (char*)rawmap; - if (map[temp.TIcon] == -1) { - temp.TIcon = 0; - temp.TType = TEMPLATE_NONE; - } - } - } - } - - cellptr->TType = temp.TType; - cellptr->TIcon = temp.TIcon; - cellptr->Recalc_Attributes(); - -#ifndef DEMO - Add_CRC(crc, (unsigned long)cellptr->TType); - Add_CRC(crc, (unsigned long)cellptr->TIcon); -#endif - - cellptr++; - } - - /* - ** Close the file. - */ - file.Close(); - - return(i == MAP_CELL_TOTAL); -} - - - -/*********************************************************************************************** - * MapClass::Write_Binary -- writes the map's binary image file * - * * - * INPUT: * - * root root filename for scenario * - * * - * OUTPUT: * - * 1 = success, 0 = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/14/1994 BR : Created. * - *=============================================================================================*/ -bool MapClass::Write_Binary(char const * root) -{ - CCFileClass *file; - char fname[_MAX_FNAME+_MAX_EXT]; - int i; - - /* - ** Filename = INI name with BIN extension. - */ - sprintf(fname,"%s.BIN",root); - - /* - ** Create object & open file. - */ - file = new CCFileClass(fname); - file->Open(WRITE); - - /* - ** Loop through all cells. - */ - for (i = 0; i < MAP_CELL_TOTAL; i++) { - /* - ** Save TType. - */ - if (file->Write (&(Map[i].TType), sizeof(TemplateType)) != sizeof(TemplateType)) { - file->Close(); - delete file; - return(false); - } - - /* - ** Save TIcon. - */ - if (file->Write (&(Map[i].TIcon), sizeof(unsigned char)) != sizeof(unsigned char)) { - file->Close(); - delete file; - return(false); - } - } - - /* - ** Close the file. - */ - file->Close(); - delete file; - - return(true); -} - - -/*********************************************************************************************** - * MapClass::Logic -- Handles map related logic functions. * - * * - * Manages tiberium growth and spread. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/11/1995 JLB : Created. * - * 07/09/1995 JLB : Handles two directional scan. * - * 08/01/1995 JLB : Gives stronger weight to blossom trees. * - *=============================================================================================*/ -void MapClass::Logic(void) -{ - if (Debug_Force_Crash) { *((int *)0) = 1; } - - /* - ** Bail early if there is no allowed growth or spread of Tiberium. - */ - if (!Special.IsTGrowth && !Special.IsTSpread) return; - - /* - ** Scan another block of the map in order to accumulate the potential - ** Tiberium cells that can grow or spread. - */ - int subcount = 30; - int index; - for (index = TiberiumScan; index < MAP_CELL_TOTAL; index++) { - CELL cell = index; - if (!IsForwardScan) cell = (MAP_CELL_TOTAL-1) - index; - CellClass *ptr = &(*this)[cell]; - - if (Special.IsTGrowth && ptr->Land_Type() == LAND_TIBERIUM && ptr->OverlayData < 11) { - if (TiberiumGrowthCount < sizeof(TiberiumGrowth)/sizeof(TiberiumGrowth[0])) { - TiberiumGrowth[TiberiumGrowthCount++] = cell; - } else { - TiberiumGrowth[Random_Pick(0, TiberiumGrowthCount-1)] = cell; - } - } - - /* - ** Heavy Tiberium growth can spread. - */ - TerrainClass * terrain = ptr->Cell_Terrain(); - if (Special.IsTSpread && - (ptr->Land_Type() == LAND_TIBERIUM && ptr->OverlayData > 6) || - (terrain && terrain->Class->IsTiberiumSpawn)) { - - int tries = 1; - if (terrain) tries = 3; - for (int i = 0; i < tries; i++) { - if (TiberiumSpreadCount < sizeof(TiberiumSpread)/sizeof(TiberiumSpread[0])) { - TiberiumSpread[TiberiumSpreadCount++] = cell; - } else { - TiberiumSpread[Random_Pick(0, TiberiumSpreadCount-1)] = cell; - } - } - } - subcount--; - if (!subcount) break; - } - TiberiumScan = index; - - if (TiberiumScan >= MAP_CELL_TOTAL) { - int tries = 1; - if (Special.IsTFast || GameToPlay != GAME_NORMAL) tries = 2; - TiberiumScan = 0; - IsForwardScan = (IsForwardScan == false); - - /* - ** Growth logic. - */ - if (TiberiumGrowthCount) { - for (int i = 0; i < tries; i++) { - CELL cell = TiberiumGrowth[Random_Pick(0, TiberiumGrowthCount-1)]; - CellClass * newcell = &(*this)[cell]; - if (newcell->Land_Type() == LAND_TIBERIUM && newcell->OverlayData < 12-1) { - newcell->OverlayData++; - } - } - } - TiberiumGrowthCount = 0; - - /* - ** Spread logic. - */ - if (TiberiumSpreadCount) { - for (int i = 0; i < tries; i++) { - CELL cell = TiberiumSpread[Random_Pick(0, TiberiumSpreadCount-1)]; - - /* - ** Find a pseudo-random adjacent cell that doesn't contain any tiberium. - */ - if (Map.In_Radar(cell)) { - FacingType offset = Random_Pick(FACING_N, FACING_NW); - for (FacingType index = FACING_N; index < FACING_COUNT; index++) { - CellClass *newcell = (*this)[cell].Adjacent_Cell(index+offset); - - if (newcell && newcell->Cell_Object() == NULL && newcell->Land_Type() == LAND_CLEAR && newcell->Overlay == OVERLAY_NONE) { - bool found = false; - - switch (newcell->TType) { - case TEMPLATE_BRIDGE1: - case TEMPLATE_BRIDGE2: - case TEMPLATE_BRIDGE3: - case TEMPLATE_BRIDGE4: - break; - - default: - found = true; - new OverlayClass(Random_Pick(OVERLAY_TIBERIUM1, OVERLAY_TIBERIUM12), newcell->Cell_Number()); - newcell->OverlayData = 1; - break; - - } - if (found) break; - } - } - } - } - } - TiberiumSpreadCount = 0; - } -} - - -/*********************************************************************************************** - * MapClass::Cell_Region -- Determines the region from a specified cell number. * - * * - * Use this routine to determine what region a particular cell lies in. * - * * - * INPUT: cell -- The cell number to examine. * - * * - * OUTPUT: Returns with the region that the specified cell occupies. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/15/1995 JLB : Created. * - *=============================================================================================*/ -int MapClass::Cell_Region(CELL cell) -{ - return((Cell_X(cell) / REGION_WIDTH) + 1) + (((Cell_Y(cell) / REGION_HEIGHT) + 1) * MAP_REGION_WIDTH); -} - - -/*************************************************************************** - * MapClass::Cell_Threat -- Gets a houses threat value for a cell * - * * - * INPUT: CELL cell - the cell number to check * - * HouseType house - the house to check * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/25/1995 PWG : Created. * - *=========================================================================*/ -int MapClass::Cell_Threat(CELL cell, HousesType house) -{ - int threat = HouseClass::As_Pointer(house)->Regions[Map.Cell_Region(Map[cell].Cell_Number())].Threat_Value(); - //using function for IsVisible so we have different results for different players - JAS 2019/09/30 - if (!threat && Map[cell].Is_Visible(house)) { - threat = 1; - } - return(threat); -} - - -/*********************************************************************************************** - * MapClass::Place_Random_Crate -- Places a crate at random location on map. * - * * - * This routine will place a crate at a random location on the map. This routine will only * - * make a limited number of attempts to place and if unsuccessful, it will not place any. * - * * - * INPUT: none * - * * - * OUTPUT: Was a crate successfully placed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -bool MapClass::Place_Random_Crate(void) -{ - int old = ScenarioInit; - ScenarioInit = 0; - for (int index = 0; index < 100; index++) { - int x = Random_Pick(0, MapCellWidth-1); - int y = Random_Pick(0, MapCellHeight-1); - CELL cell = XY_Cell(MapCellX+x, MapCellY+y); - - CellClass * ptr = &(*this)[cell]; - if (ptr->Is_Generally_Clear() && ptr->Overlay == OVERLAY_NONE) { - ptr->Overlay = OVERLAY_WOOD_CRATE; - ptr->OverlayData = 0; - ptr->Redraw_Objects(); - ScenarioInit = old; - return(true); - } - } - ScenarioInit = old; - return(false); -} - - -/*************************************************************************** - * MapClass::Validate -- validates every cell on the map * - * * - * This is a debugging routine, designed to detect memory trashers that * - * alter the map. This routine is slow, but thorough. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = map is OK, false = an error was found * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/08/1995 BRR : Created. * - *=========================================================================*/ -int MapClass::Validate(void) -{ - CELL cell; - TemplateType ttype; - unsigned char ticon; - //TemplateTypeClass const *tclass; - //unsigned char map[13*8]; - OverlayType overlay; - SmudgeType smudge; - ObjectClass *obj; - LandType land; - int i; - -BlubCell = &((*this)[797]); - -if (BlubCell->Overlapper[1]) { - obj = BlubCell->Overlapper[1]; - if (obj) { - if (obj->IsInLimbo) - obj = obj; - } -} - - /*------------------------------------------------------------------------ - Check every cell on the map, even those that aren't displayed, - in the hopes of detecting a memory trasher. - ------------------------------------------------------------------------*/ - for (cell = 0; cell < MAP_CELL_TOTAL; cell++) { - /*..................................................................... - Validate Template & Icon data - .....................................................................*/ - ttype = (*this)[cell].TType; - ticon = (*this)[cell].TIcon; - if (ttype >= TEMPLATE_COUNT && ttype != TEMPLATE_NONE) - return(false); - - /*..................................................................... - To validate the icon value, we have to get a copy of the template's - "icon map"; this map will have 0xff's in spots where there is no - icon. If the icon value is out of range or points to an invalide spot, - return an error. - .....................................................................*/ -#if (0) - if (ttype != TEMPLATE_NONE) { - tclass = &TemplateTypeClass::As_Reference(ttype); - ticon = (*this)[cell].TIcon; - Mem_Copy(Get_Icon_Set_Map(tclass->Get_Image_Data()), map, - tclass->Width * tclass->Height); - if (ticon < 0 || - ticon >= (tclass->Width * tclass->Height) || - map[ticon]==0xff) - return (false); - } -#endif - /*..................................................................... - Validate Overlay - .....................................................................*/ - overlay = (*this)[cell].Overlay; - if (overlay < OVERLAY_NONE || overlay >= OVERLAY_COUNT) - return(false); - - /*..................................................................... - Validate Smudge - .....................................................................*/ - smudge = (*this)[cell].Smudge; - if (smudge < SMUDGE_NONE || smudge >= SMUDGE_COUNT) - return(false); - - /*..................................................................... - Validate LandType - .....................................................................*/ - land = (*this)[cell].Land_Type(); - if (land < LAND_CLEAR || land >= LAND_COUNT) - return(false); - - /*..................................................................... - Validate Occupier - .....................................................................*/ - obj = (*this)[cell].Cell_Occupier(); - if (obj) { - - volatile TARGET target = obj->As_Target(); // This will do some internal verification - - if (!obj->IsActive) { - return false; - } - - if (obj->IsInLimbo) { - return false; - } - - if (((unsigned int)Coord_Cell(obj->Coord) > 4095)) { - return (false); - } - } - - /*..................................................................... - Validate Overlappers - .....................................................................*/ - for (i = 0; i < 3; i++) { - obj = (*this)[cell].Overlapper[i]; - if (obj) { - - volatile TARGET target = obj->As_Target(); // This will do some internal verification - - if (!obj->IsActive) { - return false; - } - - if (obj->IsInLimbo) { - return false; - } - - if (((unsigned int)Coord_Cell(obj->Coord) > 4095)) { - return (false); - } - } - } - } - - return (true); -} - - - -/*********************************************************************************************** - * MapClass::Clean -- Clean up dangling pointers caused by bugs in the originl code. * - * * - * Ideally, we'd fix the underlying cause of the overlappers not being cleared * - * but we can afford the CPU time now * - * * - * INPUT: none * - * * - * OUTPUT: * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 4/14/2020 11:48AM ST : Created. * - *=============================================================================================*/ -void MapClass::Clean(void) -{ - CELL cell; - ObjectClass *obj; - int i; -#ifndef NDEBUG - char debug_message[256]; -#endif - bool active_fail = false; - bool limbo_fail = false; - const char *type_text = NULL; - const char *ini_name = NULL; - AbstractClass abstract_object; - unsigned long abstract_vtable = *(unsigned long*)&abstract_object; - - /*------------------------------------------------------------------------ - Check every cell on the map, even those that aren't displayed. - ------------------------------------------------------------------------*/ - for (cell = 0; cell < MAP_CELL_TOTAL; cell++) { - - /*..................................................................... - Validate Occupier - .....................................................................*/ - (*this)[cell].Cell_Occupier(); - - /*..................................................................... - Validate Overlappers - .....................................................................*/ - for (i = 0; i < 3; i++) { - obj = (*this)[cell].Overlapper[i]; - if (obj) { - - if (!obj->IsActive) { - (*this)[cell].Overlapper[i] = NULL; - active_fail = true; - } - - if (!active_fail && obj->IsInLimbo) { - (*this)[cell].Overlapper[i] = NULL; - limbo_fail = true; - } - - if (active_fail || limbo_fail) { -#ifndef NDEBUG - /* - ** This object is likely deleted. - */ - if (abstract_vtable == *(unsigned long*)obj) { - type_text = "Abstract"; - ini_name = "UNKNOWN"; - } else { - - RTTIType type = obj->What_Am_I(); - - switch (type) { - default: - type_text = "Unknown"; - break; - - case RTTI_INFANTRY: - type_text = "Infantry"; - break; - - case RTTI_UNIT: - type_text = "Unit"; - break; - - case RTTI_AIRCRAFT: - type_text = "Aircraft"; - break; - - case RTTI_BUILDING: - type_text = "Building"; - break; - - case RTTI_BULLET: - type_text = "Bullet"; - break; - - case RTTI_ANIM: - type_text = "Anim"; - break; - - case RTTI_SMUDGE: - type_text = "Smudge"; - break; - - case RTTI_TERRAIN: - type_text = "Terrain"; - break; - } - - ini_name = obj->Class_Of().IniName; - } - - sprintf_s(debug_message, sizeof(debug_message) - 1, "Cleaned %s overlapper in cell %08X. Type=%s, IniName=%s", active_fail ? "inactive" : "limbo", cell, type_text, ini_name); - GlyphX_Debug_Print(debug_message); -#endif //NDEBUG - } - } - } - } -} - - -/*********************************************************************************************** - * MapClass::Close_Object -- Finds a clickable close object to the specified coordinate. * - * * - * This routine is used by the mouse input processing code to find a clickable object * - * close to coordinate specified. This is for targeting as well as selection determination. * - * * - * INPUT: coord -- The coordinate to scan for close object from. * - * * - * OUTPUT: Returns with a pointer to an object that is nearby the specified coordinate. * - * * - * WARNINGS: There could be a cloaked object at the location, but it won't be considered * - * if it is not owned by the player. * - * * - * HISTORY: * - * 08/20/1995 JLB : Created. * - *=============================================================================================*/ -ObjectClass * MapClass::Close_Object(COORDINATE coord) const -{ - ObjectClass * object = 0; - int distance = 0; - CELL cell = Coord_Cell(coord); - - /* - ** Scan through current and adjacent cells, looking for the - ** closest object (within reason) to the specified coordinate. - */ - static int _offsets[] = {0, -1, 1, -MAP_CELL_W, MAP_CELL_W, MAP_CELL_W-1, MAP_CELL_W+1, -(MAP_CELL_W-1), -(MAP_CELL_W+1)}; - for (int index = 0; index < (sizeof(_offsets) / sizeof(_offsets[0])); index++) { - - /* - ** Examine the cell for close object. Make sure that the cell actually is a - ** legal one. - */ - CELL newcell = cell + _offsets[index]; - if (In_Radar(newcell)) { - - /* - ** Search through all objects that occupy this cell and then - ** find the closest object. Check against any previously found object - ** to ensure that it is actually closer. - */ - ObjectClass * o = (*this)[newcell].Cell_Occupier(); - while (o) { - - /* - ** Special case check to ignore cloaked object if not owned by the player. - */ - // Changed for multiplayer. ST - 3/13/2019 5:38PM - if (!o->Is_Techno() || ((TechnoClass *)o)->Is_Owned_By_Player() || ((TechnoClass *)o)->Cloak != CLOAKED) { - //if (!o->Is_Techno() || ((TechnoClass *)o)->IsOwnedByPlayer || ((TechnoClass *)o)->Cloak != CLOAKED) { - int d=-1; - if (o->What_Am_I() == RTTI_BUILDING) { - d = Distance(coord, Cell_Coord(newcell)); - if (d > 0x00C0) d = -1; - } else { - d = Distance(coord, o->Center_Coord()); - } - if (d >= 0 && (!object || d < distance)) { - distance = d; - object = o; - } - } - o = o->Next; - } - } - } - - /* - ** Handle aircraft selection separately, since they aren't tracked in cells while flying - */ - for (int index = 0; index < Aircraft.Count(); index++) { - AircraftClass * aircraft = Aircraft.Ptr(index); - - if (aircraft->In_Which_Layer() != LAYER_GROUND) { - if (aircraft->Is_Owned_By_Player() || (aircraft->Cloak != CLOAKED)) { - int d = Distance(coord, Coord_Add(aircraft->Center_Coord(), XY_Coord(0, -Pixel_To_Lepton(aircraft->Altitude)))); - if (d >= 0 && (!object || d < distance)) { - distance = d; - object = aircraft; - } - } - } - } - - /* - ** Only return the object if it is within 1/4 cell distance from the specified - ** coordinate. - */ - if (object && distance > 0xC0) { - object = 0; - } - return(object); -} - - - - -#ifdef USE_RA_AI - -/* -** Nearby_Location pulled in from RA for AI. ST - 7/24/2019 5:54PM -*/ -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - -/*********************************************************************************************** - * MapClass::Nearby_Location -- Finds a generally clear location near a specified cell. * - * * - * This routine is used to find a location that probably will be ok to move to that is * - * located as close as possible to the specified cell. The computer uses this when it has * - * determined the ideal location for an object, but then needs to give a valid movement * - * destination to a unit. * - * * - * INPUT: cell -- The cell that scanning should radiate out from. * - * * - * zone -- The zone that must be matched to find a legal location (value of -1 means * - * any zone will do). * - * * - * * - * check -- The type of zone to check against. Only valid if a zone value is given. * - * * - * OUTPUT: Returns with the cell that is generally clear (legal to move to) that is close * - * to the specified cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/05/1995 JLB : Created. * - *=============================================================================================*/ -CELL MapClass::Nearby_Location(CELL cell) const //, SpeedType speed, int zone, MZoneType check) const -{ - CELL topten[10]; - int count = 0; - int xx = Cell_X(cell); - int yy = Cell_Y(cell); - - /* - ** Determine the limits of the scanning in the four directions so that - ** it won't scan past the edge of the world. - */ - int left = MapCellX; - int right = MapCellX + MapCellWidth - 1; - int top = MapCellY; - int bottom = MapCellY + MapCellHeight - 1; - - /* - ** Radiate outward from the specified location, looking for the closest - ** location that is generally clear. - */ - for (int radius = 0; radius < MAP_CELL_W; radius++) { - CELL newcell; - CellClass const * cellptr; - - /* - ** Scan the top and bottom rows of the "box". - */ - for (int x = xx-radius; x <= xx+radius; x++) { - if (x >= left && x <= right) { - int y = yy-radius; - if (y >= top) { - newcell = XY_Cell(x, y); - cellptr = &Map[newcell]; - if (Map.In_Radar(newcell) && cellptr->Is_Clear_To_Move(false, false)) { - topten[count++] = newcell; - } - } - if (count == ARRAY_SIZE(topten)) break; - - y = yy+radius; - if (y <= bottom) { - newcell = XY_Cell(x, y); - cellptr = &Map[newcell]; - if (Map.In_Radar(newcell) && cellptr->Is_Clear_To_Move(false, false)) { - topten[count++] = newcell; - } - } - if (count == ARRAY_SIZE(topten)) break; - } - } - - if (count == ARRAY_SIZE(topten)) break; - - /* - ** Scan the left and right columns of the "box". - */ - for (int y = yy-radius; y <= yy+radius; y++) { - if (y >= top && y <= bottom) { - int x = xx-radius; - if (x >= left) { - newcell = XY_Cell(x, y); - cellptr = &Map[newcell]; - if (Map.In_Radar(newcell) && cellptr->Is_Clear_To_Move(false, false)) { - topten[count++] = newcell; - } - } - if (count == ARRAY_SIZE(topten)) break; - - x = xx+radius; - if (x <= right) { - newcell = XY_Cell(x, y); - cellptr = &Map[newcell]; - if (Map.In_Radar(newcell) && cellptr->Is_Clear_To_Move(false, false)) { - topten[count++] = newcell; - } - } - if (count == ARRAY_SIZE(topten)) break; - } - } - - if (count > 0) break; - } - - if (count > 0) { - return(topten[Frame % count]); - } - return(0); -} - -#endif // USE_RA_AI \ No newline at end of file diff --git a/code/TIBERIANDAWN/MAP.H b/code/TIBERIANDAWN/MAP.H deleted file mode 100644 index 6af2a76..0000000 --- a/code/TIBERIANDAWN/MAP.H +++ /dev/null @@ -1,174 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\map.h_v 2.19 16 Oct 1995 16:46:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAP.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : April 29, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MAP_H -#define MAP_H - -#include "gscreen.h" - -#define BIGMAP 0 - - -class MapClass: public GScreenClass -{ - public: - - /* - ** Initialization - */ - virtual void One_Time(void); // Theater-specific inits - virtual void Init_Clear(void); // Clears all to known state - virtual void Alloc_Cells(void); // Allocates buffers - virtual void Free_Cells(void); // Frees buffers - virtual void Init_Cells(void); // Frees buffers - - // Added this function to allow the editor to setup the map without setting up the entire system. - 06/18/2019 JAS - void One_Time_Editor(void); - - /*-------------------------------------------------------- - ** Main functions that deal with groupings of cells within the map or deals with the cell - ** as it relates to the map - not what the cell contains. - */ - ObjectClass * Close_Object(COORDINATE coord) const; - virtual void Detach(ObjectClass * ) {}; - int Cell_Region(CELL cell); - int Cell_Threat(CELL cell, HousesType house); - int Cell_Distance(CELL cell1, CELL cell2); - bool In_Radar(CELL cell) const; - void Sight_From(HouseClass *house, CELL cell, int sightrange, bool incremental=false); // Added house pointer parameter. ST - 3/6/2019 10:23AM - void Place_Down(CELL cell, ObjectClass * object); - void Pick_Up(CELL cell, ObjectClass * object); - void Overlap_Down(CELL cell, ObjectClass * object); - void Overlap_Up(CELL cell, ObjectClass * object); - bool Read_Binary(char const *root, unsigned long *crc); - bool Write_Binary(char const *root); - bool Place_Random_Crate(void); - - //Added for loading custom maps - 2019/10/28 JAS - bool Read_Binary_File(char const *fname, unsigned long *crc); - - long Overpass(void); - - virtual void Logic(void); - virtual void Set_Map_Dimensions(int x, int y, int w, int h); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Debug routine - */ - int Validate(void); - - /* - ** Catch-all for bad overlappers - */ - void Clean(void); - -#ifdef USE_RA_AI - /* - ** Pulled in from RA for AI. ST - 7/24/2019 5:53PM - */ - CELL Nearby_Location(CELL cell) const; //, SpeedType speed, int zone, MZoneType check) const -#endif //USE_RA_AI - - /* - ** This is the dimensions and position of the sub section of the global map. - ** It is this region that appears on the radar map and constrains normal - ** movement. - */ - int MapCellX; - int MapCellY; - int MapCellWidth; - int MapCellHeight; - - /* - ** This is the total value of all harvestable Tiberium on the map. - */ - long TotalValue; - - protected: - - /* - ** These are the size dimensions of the underlying array of cell objects. - ** This is the dimensions of the "map" that the tactical view is - ** restricted to. - */ - int XSize; - int YSize; - int Size; - - static int const RadiusCount[11]; - static int const RadiusOffset[]; - - private: - friend class CellClass; - - /* - ** Tiberium growth potiential cells are recorded here. - */ - CELL TiberiumGrowth[50]; - int TiberiumGrowthCount; - - /* - ** List of cells that are full enough strength that they could spread - ** Tiberium to adjacent cells. - */ - CELL TiberiumSpread[50]; - int TiberiumSpreadCount; - - /* - ** This is the current cell number in the incremental map scan process. - */ - CELL TiberiumScan; - - /* - ** If the Tiberium map scan is processing forward, then this flag - ** will be true. It alternates between forward and backward scanning - ** in order to avoid the "Tiberium Creep". - */ - unsigned IsForwardScan:1; - - enum MapEnum {SCAN_AMOUNT=MAP_CELL_TOTAL}; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[1024]; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/MAPEDDLG.CPP b/code/TIBERIANDAWN/MAPEDDLG.CPP deleted file mode 100644 index b57de36..0000000 --- a/code/TIBERIANDAWN/MAPEDDLG.CPP +++ /dev/null @@ -1,3847 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapeddlg.cpv 2.18 16 Oct 1995 16:49:00 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPEDDLG.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : November 18, 1994 * - * * - * Last Update : December 12, 1994 [BR] * - * * - *-------------------------------------------------------------------------* - * Map Editor dialogs & main menu options * - *-------------------------------------------------------------------------* - * Functions: * - * MapEditClass::New_Scenario -- creates a new scenario * - * MapEditClass::Load_Scenario -- loads a scenario INI file * - * MapEditClass::Save_Scenario -- saves current scenario to an INI file * - * MapEditClass::Pick_Scenario -- dialog for choosing scenario * - * MapEditClass::Size_Map -- lets user set size & location of map * - * MapEditClass::Scenario_Dialog -- scenario global parameters dialog * - * MapEditClass::Handle_Triggers -- processes the trigger dialogs * - * MapEditClass::Select_Trigger -- lets user select a trigger * - * MapEditClass::Edit_Trigger -- lets user edit a [new] trigger * - * MapEditClass::Import_Triggers -- lets user import triggers * - * MapEditClass::Import_Teams -- lets user import teams * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef SCENARIO_EDITOR - - -/*************************************************************************** - * MapEditClass::New_Scenario -- creates a new scenario * - * * - * - Prompts user for scenario data (house, scenario #); sets globals * - * PlayerPtr (for house) & Scenario (for scenario #) * - * - Prompts user for map size * - * - Initializes the scenario by calling Clear_Scenario(), which calls * - * everybody's Init() routine * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = new scenario created, -1 = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/21/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::New_Scenario(void) -{ - int scen_num = Scenario; - ScenarioPlayerType player = ScenPlayer; - ScenarioDirType dir = ScenDir; - ScenarioVarType var = ScenVar; - int rc; - HousesType house; - - /* - ------------------------ Prompt for scenario info ------------------------ - */ - rc = Pick_Scenario("New Scenario", &scen_num, &player, &dir, &var, 1); - if (rc != 0) { - return(-1); - } - - /* - -------------------------- Blow away everything -------------------------- - */ - Clear_Scenario(); - - /* - ----------------------------- Set parameters ----------------------------- - */ - Scenario = scen_num; - ScenPlayer = player; - ScenDir = dir; - ScenVar = var; - Set_Scenario_Name(ScenarioName,scen_num,player,dir,var); - - /* - ----------------------------- Create houses ------------------------------ - */ - for (house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - new HouseClass(house); - } - - if (ScenPlayer == SCEN_PLAYER_MPLAYER) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI1); - PlayerPtr->IsHuman = true; - LastHouse = HOUSE_MULTI1; - } else { - if (player == SCEN_PLAYER_GDI) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_GOOD); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_BAD; - } else { - if (player == SCEN_PLAYER_NOD) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_BAD); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_GOOD; - } else { - PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_MULTI4; - } - } - LastHouse = HOUSE_GOOD; - } - - /* - -------------------------- Init the entire map --------------------------- - */ - Init_Clear(); - Fill_In_Data(); - - /* - -------------------------- Prompt for map size --------------------------- - */ - Size_Map(-1,-1,20,20); - - /* - ------ Set the Home & Reinforcement Cells to the center of the map ------- - */ - Waypoint[WAYPT_REINF] = XY_Cell(MapCellX + MapCellWidth / 2, MapCellY + MapCellHeight / 2); - Waypoint[WAYPT_HOME] = XY_Cell(MapCellX + MapCellWidth / 2, MapCellY + MapCellHeight / 2); - (*this)[Coord_Cell(TacticalCoord)].IsWaypoint = 1; - Flag_Cell(Coord_Cell(TacticalCoord)); - - ScenarioInit++; - Set_Tactical_Position(Cell_Coord(Waypoint[WAYPT_HOME])); - ScenarioInit--; - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Load_Scenario -- loads a scenario INI file * - * * - * - Prompts user for scenario data (house, scenario #); sets globals * - * PlayerPtr (for house) & Scenario (for scenario #) * - * - Loads the INI file for that scenario * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/21/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Load_Scenario(void) -{ - int scen_num = Scenario; - ScenarioPlayerType player = ScenPlayer; - ScenarioDirType dir = ScenDir; - ScenarioVarType var = ScenVar; - int rc; - - /* - ------------------------ Prompt for scenario info ------------------------ - */ - rc = Pick_Scenario("Load Scenario", &scen_num, &player, &dir, &var, 1); - if (rc != 0) { - return(-1); - } - - /* - ----------------------------- Set parameters ----------------------------- - */ - Scenario = scen_num; - ScenPlayer = player; - ScenDir = dir; - ScenVar = var; - Set_Scenario_Name(ScenarioName,scen_num,player,dir,var); - - /*------------------------------------------------------------------------ - Read_Scenario_Ini() must be able to set PlayerPtr to the right house: - - Reading the INI will create the house objects - - PlayerPtr must be set before any Techno objects are created - - For GDI or NOD scenarios, PlayerPtr is set by reading the INI; - but for multiplayer, it's set via the MPlayerLocalID; so, here we have - to set various multiplayer variables to fool the Assign_Houses() routine - into working properly. - ------------------------------------------------------------------------*/ - if (ScenPlayer == SCEN_PLAYER_MPLAYER) { - MPlayerLocalID = Build_MPlayerID(2,HOUSE_GOOD); - MPlayerCount = 1; - LastHouse = HOUSE_MULTI1; - } - else if (ScenPlayer==SCEN_PLAYER_JP) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_MULTI4; - } - else { - LastHouse = HOUSE_GOOD; - } - - /* - -------------------------- Blow away everything -------------------------- - */ - Clear_Scenario(); - - /* - ------------------------------ Read the INI ------------------------------ - */ - if (Read_Scenario_Ini(ScenarioName) == 0) { - CCMessageBox().Process("Unable to read scenario!"); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - } else { - Fill_In_Data(); - Set_Palette(GamePalette); - } - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Save_Scenario -- saves current scenario to an INI file * - * * - * - Prompts user for scenario data (house, scenario #); sets globals * - * PlayerPtr (for house) & Scenario (for scenario #) * - * - Saves the INI file for this scenario * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = error/cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/21/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Save_Scenario(void) -{ - int scen_num = Scenario; - ScenarioPlayerType player = ScenPlayer; - ScenarioDirType dir = ScenDir; - ScenarioVarType var = ScenVar; - int rc; - FILE *fp; - char fname[13]; - - /* - ------------------------ Prompt for scenario info ------------------------ - */ - rc = Pick_Scenario("Save Scenario", &scen_num, &player, &dir, &var, 0); - if (rc != 0) { - return(-1); - } - - /* - ------------------- Warning if scenario already exists ------------------- - */ - Set_Scenario_Name(fname, scen_num, player, dir, var); - fp = fopen(fname,"rb"); - if (fp) { - fclose(fp); - rc = CCMessageBox().Process("File exists. Replace?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - if (rc==1) - return(-1); - } - - /* - ----------------------------- Set parameters ----------------------------- - */ - Scenario = scen_num; - ScenPlayer = player; - ScenDir = dir; - ScenVar = var; - Set_Scenario_Name(ScenarioName,scen_num,player,dir,var); - - /*------------------------------------------------------------------------ - Player may have changed from GDI to NOD, so change playerptr accordingly - ------------------------------------------------------------------------*/ - if (ScenPlayer == SCEN_PLAYER_GDI || ScenPlayer==SCEN_PLAYER_NOD) { - if (ScenPlayer==SCEN_PLAYER_GDI) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_GOOD); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_BAD; - } else { - if (ScenPlayer == SCEN_PLAYER_NOD) { - PlayerPtr = HouseClass::As_Pointer(HOUSE_BAD); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_GOOD; - } else { - PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4); - PlayerPtr->IsHuman = true; - Base.House = HOUSE_MULTI4; - } - } - LastHouse = HOUSE_GOOD; - } - - /* - ----------------------------- Write the INI ------------------------------ - */ - Write_Scenario_Ini(ScenarioName); - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Pick_Scenario -- dialog for choosing scenario * - * * - * Prompts user for: * - * - House (GDI, NOD) * - * - Scenario # * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Caption ³ * - * ³ ³ * - * ³ Scenario ___ ³ * - * ³ Version ___ ³ * - * ³ ³ * - * ³ [East] [West] ³ * - * ³ ³ * - * ³ [ GDI ] ³ * - * ³ [ NOD ] ³ * - * ³ [Multi-Player] ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * caption string to use as a title * - * scen_nump output: ptr to scenario # * - * playerp output: ptr to player type * - * dirp output: ptr to direction * - * varp output: ptr to variation * - * multi 1 = allow to change single/multiplayer; 0 = not * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/21/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Pick_Scenario(char const * caption, int *scen_nump, - ScenarioPlayerType *playerp, ScenarioDirType *dirp, ScenarioVarType *varp, - int multi) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 400, // dialog width - D_DIALOG_H = 328, // dialog height - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), // centered x-coord - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), // centered y-coord - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center - - D_TXT8_H = 22, // ht of 8-pt text - D_MARGIN = 14, // margin width/height - - D_SCEN_W = 90, // Scenario # width - D_SCEN_H = 18, // Scenario # height - D_SCEN_X = D_DIALOG_CX + 5, // Scenario # x - D_SCEN_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN, // Scenario # y - - D_VARA_W = 26, // Version A width - D_VARA_H = 18, // Version A height - D_VARA_X = D_DIALOG_CX - (D_VARA_W * 5) / 2, // Version A x - D_VARA_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version A y - - D_VARB_W = 26, // Version B width - D_VARB_H = 18, // Version B height - D_VARB_X = D_VARA_X + D_VARA_W, // Version B x - D_VARB_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version B y - - D_VARC_W = 26, // Version C width - D_VARC_H = 18, // Version C height - D_VARC_X = D_VARB_X + D_VARB_W, // Version C x - D_VARC_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version C y - - D_VARD_W = 26, // Version D width - D_VARD_H = 18, // Version D height - D_VARD_X = D_VARC_X + D_VARC_W, // Version D x - D_VARD_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version D y - - D_VARLOSE_W = 26, // Version Lose width - D_VARLOSE_H = 18, // Version Lose height - D_VARLOSE_X = D_VARD_X + D_VARD_W, // Version Lose x - D_VARLOSE_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version Lose y - - D_EAST_W = 100, // EAST width - D_EAST_H = 18, // EAST height - D_EAST_X = D_DIALOG_CX - D_EAST_W - 5, // EAST x - D_EAST_Y = D_VARLOSE_Y + D_VARLOSE_H + D_MARGIN,// EAST y - - D_WEST_W = 100, // WEST width - D_WEST_H = 18, // WEST height - D_WEST_X = D_DIALOG_CX + 5, // WEST x - D_WEST_Y = D_VARLOSE_Y + D_VARLOSE_H + D_MARGIN,// EAST y - - D_GDI_W = 140, // GDI width - D_GDI_H = 18, // GDI height - D_GDI_X = D_DIALOG_CX - (D_GDI_W / 2), // GDI x - D_GDI_Y = D_EAST_Y + D_EAST_H + D_MARGIN, // GDI y - - D_NOD_W = 140, // NOD width - D_NOD_H = 18, // NOD height - D_NOD_X = D_DIALOG_CX - (D_NOD_W / 2), // NOD x - D_NOD_Y = D_GDI_Y + D_GDI_H, // NOD y - - D_NEU_W = 140, // Neutral width - D_NEU_H = 18, // Neutral height - D_NEU_X = D_DIALOG_CX - (D_NOD_W / 2), // Neutral x - D_NEU_Y = D_NOD_Y + D_NOD_H, // Neutral y - - D_MPLAYER_W = 140, // Multi-Player width - D_MPLAYER_H = 18, // Multi-Player height - D_MPLAYER_X = D_DIALOG_CX - (D_MPLAYER_W / 2), // Multi-Player x - D_MPLAYER_Y = D_NEU_Y + D_NEU_H, // Multi-Player y - - D_OK_W = 90, // OK width - D_OK_H = 18, // OK height - D_OK_X = D_DIALOG_CX - D_OK_W - 5, // OK x - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN, // OK y - - D_CANCEL_W = 90, // Cancel width - D_CANCEL_H = 18, // Cancel height - D_CANCEL_X = D_DIALOG_CX + 5, // Cancel x - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, // Cancel y - - }; - /*........................................................................ - Button enumerations - ........................................................................*/ - enum { - BUTTON_GDI=100, - BUTTON_NOD, - BUTTON_NEUTRAL, - BUTTON_MPLAYER, - BUTTON_EAST, - BUTTON_WEST, - BUTTON_OK, - BUTTON_CANCEL, - BUTTON_SCENARIO, - BUTTON_VAR_A, - BUTTON_VAR_B, - BUTTON_VAR_C, - BUTTON_VAR_D, - BUTTON_VAR_L, - }; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - KeyNumType input; - bool cancel = false; // true = user cancels - /*........................................................................ - Other Variables - ........................................................................*/ - char scen_buf[10]={0}; // buffer for editing scenario # - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - EditClass editbtn (BUTTON_SCENARIO, - scen_buf, 5, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_SCEN_X, D_SCEN_Y, D_SCEN_W, D_SCEN_H, EditClass::NUMERIC); - - TextButtonClass varabtn (BUTTON_VAR_A, "A", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_VARA_X, D_VARA_Y, D_VARA_W, D_VARA_H); - - TextButtonClass varbbtn (BUTTON_VAR_B, "B", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_VARB_X, D_VARB_Y, D_VARB_W, D_VARB_H); - - TextButtonClass varcbtn (BUTTON_VAR_C, "C", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_VARC_X, D_VARC_Y, D_VARC_W, D_VARC_H); - - TextButtonClass vardbtn (BUTTON_VAR_D, "D", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_VARD_X, D_VARD_Y, D_VARD_W, D_VARD_H); - - TextButtonClass varlbtn (BUTTON_VAR_L, "L", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_VARLOSE_X, D_VARLOSE_Y, D_VARLOSE_W, D_VARLOSE_H); - - TextButtonClass gdibtn (BUTTON_GDI, "GDI", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H); - - TextButtonClass nodbtn (BUTTON_NOD, "NOD", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H); - - TextButtonClass playermbtn (BUTTON_MPLAYER, "Multi Player", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MPLAYER_X, D_MPLAYER_Y, D_MPLAYER_W, D_MPLAYER_H); - - TextButtonClass eastbtn (BUTTON_EAST, "East", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_EAST_X, D_EAST_Y, D_EAST_W, D_EAST_H); - - TextButtonClass westbtn (BUTTON_WEST, "West", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_WEST_X, D_WEST_Y, D_WEST_W, D_WEST_H); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - sprintf(scen_buf,"%d",(*scen_nump)); // init edit buffer - editbtn.Set_Text(scen_buf,5); - - varabtn.Turn_Off(); - varbbtn.Turn_Off(); - varcbtn.Turn_Off(); - vardbtn.Turn_Off(); - varlbtn.Turn_Off(); - switch (*varp) { - case SCEN_VAR_A: - varabtn.Turn_On(); - break; - - case SCEN_VAR_B: - varbbtn.Turn_On(); - break; - - case SCEN_VAR_C: - varcbtn.Turn_On(); - break; - - case SCEN_VAR_D: - vardbtn.Turn_On(); - break; - - case SCEN_VAR_LOSE: - varlbtn.Turn_On(); - break; - } - - /* - ......................... Create the button list ......................... - */ - commands = &editbtn; - varabtn.Add_Tail(*commands); - varbbtn.Add_Tail(*commands); - varcbtn.Add_Tail(*commands); - vardbtn.Add_Tail(*commands); - varlbtn.Add_Tail(*commands); - if (multi) { - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - playermbtn.Add_Tail(*commands); - } else { - if ((*playerp) == SCEN_PLAYER_MPLAYER) { - playermbtn.Add_Tail(*commands); - } else { - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - } - } - eastbtn.Add_Tail(*commands); - westbtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - /* - ......................... Init the button states ......................... - */ - if ((*playerp) == SCEN_PLAYER_GDI) { - gdibtn.Turn_On(); - nodbtn.Turn_Off(); - playermbtn.Turn_Off(); - } else { - if ((*playerp) == SCEN_PLAYER_NOD) { - gdibtn.Turn_Off(); - nodbtn.Turn_On(); - playermbtn.Turn_Off(); - } else { - gdibtn.Turn_Off(); - nodbtn.Turn_Off(); - playermbtn.Turn_On(); - } - } - - if ((*dirp)==SCEN_DIR_EAST) { - eastbtn.Turn_On(); - westbtn.Turn_Off(); - } else { - eastbtn.Turn_Off(); - westbtn.Turn_On(); - } - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print(caption, D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Scenario", D_DIALOG_CX - 5, - D_SCEN_Y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (BUTTON_VAR_A | KN_BUTTON): - (*varp) = SCEN_VAR_A; - varabtn.Turn_On(); - varbbtn.Turn_Off(); - varcbtn.Turn_Off(); - vardbtn.Turn_Off(); - varlbtn.Turn_Off(); - break; - - case (BUTTON_VAR_B | KN_BUTTON): - (*varp) = SCEN_VAR_B; - varabtn.Turn_Off(); - varbbtn.Turn_On(); - varcbtn.Turn_Off(); - vardbtn.Turn_Off(); - varlbtn.Turn_Off(); - break; - - case (BUTTON_VAR_C | KN_BUTTON): - (*varp) = SCEN_VAR_C; - varabtn.Turn_Off(); - varbbtn.Turn_Off(); - varcbtn.Turn_On(); - vardbtn.Turn_Off(); - varlbtn.Turn_Off(); - break; - - case (BUTTON_VAR_D | KN_BUTTON): - (*varp) = SCEN_VAR_D; - varabtn.Turn_Off(); - varbbtn.Turn_Off(); - varcbtn.Turn_Off(); - vardbtn.Turn_On(); - varlbtn.Turn_Off(); - break; - - case (BUTTON_VAR_L | KN_BUTTON): - (*varp) = SCEN_VAR_LOSE; - varabtn.Turn_Off(); - varbbtn.Turn_Off(); - varcbtn.Turn_Off(); - vardbtn.Turn_Off(); - varlbtn.Turn_On(); - break; - - case (BUTTON_EAST | KN_BUTTON): - (*dirp) = SCEN_DIR_EAST; - eastbtn.Turn_On(); - westbtn.Turn_Off(); - break; - - case (BUTTON_WEST | KN_BUTTON): - (*dirp) = SCEN_DIR_WEST; - eastbtn.Turn_Off(); - westbtn.Turn_On(); - break; - - case (BUTTON_GDI | KN_BUTTON): - (*playerp) = SCEN_PLAYER_GDI; - gdibtn.Turn_On(); - nodbtn.Turn_Off(); - playermbtn.Turn_Off(); - break; - - case (BUTTON_NOD | KN_BUTTON): - (*playerp) = SCEN_PLAYER_NOD; - gdibtn.Turn_Off(); - nodbtn.Turn_On(); - playermbtn.Turn_Off(); - break; - - case (BUTTON_MPLAYER | KN_BUTTON): - (*playerp) = SCEN_PLAYER_MPLAYER; - gdibtn.Turn_Off(); - nodbtn.Turn_Off(); - playermbtn.Turn_On(); - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - cancel = false; - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - case (BUTTON_SCENARIO | KN_BUTTON): - break; - - default: - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /* - ------------------------- If cancel, just return ------------------------- - */ - if (cancel) - return(-1); - - /* - ------------------------ Save selections & return ------------------------ - */ - (*scen_nump) = atoi(scen_buf); - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Size_Map -- lets user set size & location of map * - * * - * Lets the user select a side of the map and expand/shrink it to the * - * desired size, or move the whole map around the available map area. * - * * - * The entire available map area is displayed, but the map is limited such * - * that there's always one blank cell around the map; this lets objects * - * properly exit the screen, since they have a blank undisplayed cell to * - * exit onto. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Clear Terrain ³ * - * ³ ³ ³ Water ³ * - * ³ ³ ³ Tiberium ³ * - * ³ ³ ³ Rock/Wall/Road ³ * - * ³ ³ (Map Area) ³ GDI Unit ³ * - * ³ ³ ³ NOD Unit ³ * - * ³ ³ ³ Neutral Unit ³ * - * ³ ³ ³ Terrain Object ³ * - * ³ ³ ³ Starting Cell ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ ³ * - * ³ X Y Width Height ³ * - * ³ ## ## ## ## ³ * - * ³ ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * x,y,w,h: initial size parameters (-1 = center the thing) * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/21/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Size_Map(int x, int y, int w, int h) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 480, // dialog width - D_DIALOG_H = 280, // dialog height - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), // centered x-coord - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), // centered y-coord - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center - - D_TXT8_H = 22, // ht of 8-pt text - D_MARGIN = 14, // margin width/height - - D_BORD_X1 = D_DIALOG_X + (D_DIALOG_W / 2 - MAP_CELL_W) / 2, - D_BORD_Y1 = D_DIALOG_Y + 10, - D_BORD_X2 = D_BORD_X1 + MAP_CELL_W + 1, - D_BORD_Y2 = D_BORD_Y1 + MAP_CELL_H + 1, - - D_OK_W = 90, // OK width - D_OK_H = 18, // OK height - D_OK_X = D_DIALOG_CX - D_OK_W - 5, // OK x - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN, // OK y - - D_CANCEL_W = 90, // Cancel width - D_CANCEL_H = 18, // Cancel height - D_CANCEL_X = D_DIALOG_CX + 5, // Cancel x - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, // Cancel y - - }; - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - BUTTON_OK=100, - BUTTON_CANCEL, - }; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_MAP, // includes map interior & coord values - REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables: - ........................................................................*/ - bool process; // Loop while true - RedrawType display; // requested redraw level - bool cancel = false; // true = user cancels - KeyNumType input; // user input - int grabbed = 0; // 1=TLeft,2=TRight,3=BRight,4=BLeft - int map_x1; // map coords x1, pixel coords - int map_x2; // map coords x2, pixel coords - int map_y1; // map coords y1, pixel coords - int map_y2; // map coords y2, pixel coords - int delta1, delta2; // mouse-click proximity - int mx,my; // last-saved mouse coords - char txt[40]; - int txt_x,txt_y; // for displaying text - unsigned index; // for drawing map symbology - CELL cell; // for drawing map symbology - int color; // for drawing map symbology - ObjectClass * occupier; // cell's occupier - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /*........................................................................ - Set up the actual map area relative to the map's border coords - ........................................................................*/ - if (x==-1) { - map_x1 = D_BORD_X1 + (MAP_CELL_W - w) / 2 + 1; - } else { - map_x1 = D_BORD_X1 + x + 1; - } - - if (y==-1) { - map_y1 = D_BORD_Y1 + (MAP_CELL_H - h) / 2 + 1; - } else { - map_y1 = D_BORD_Y1 + y + 1; - } - - map_x2 = map_x1 + w - 1; - map_y2 = map_y1 + h - 1; - - /* - ------------------------- Build the button list -------------------------- - */ - commands = &okbtn; - cancelbtn.Add_Tail(*commands); - - /*------------------------------------------------------------------------ - Main processing loop - ------------------------------------------------------------------------*/ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ------------------------ Invoke game callback ------------------------- - */ - Call_Back(); - - /* - ---------------------- Refresh display if needed ---------------------- - */ - if (display) { - Hide_Mouse(); - /*------------------------------------------------------------------ - Redraw the background, map border, key, and coord labels - ------------------------------------------------------------------*/ - if (display >= REDRAW_BACKGROUND) { - /* - .......................... Background ........................... - */ - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - - /* - ..................... Draw the map border ....................... - */ - LogicPage->Lock(); - LogicPage->Draw_Rect(D_BORD_X1, D_BORD_Y1, D_BORD_X2, D_BORD_Y2, CC_GREEN_SHADOW); - for (index = D_BORD_X1; index < D_BORD_X2; - index += (320/ICON_PIXEL_W)) { - LogicPage->Put_Pixel(index, D_BORD_Y1-1, CC_GREEN_SHADOW); - LogicPage->Put_Pixel(index, D_BORD_Y2+1, CC_GREEN_SHADOW); - } - for (index = D_BORD_Y1; index < D_BORD_Y2-8; - index += (200/ICON_PIXEL_H)) { - LogicPage->Put_Pixel(D_BORD_X1-1, index, CC_GREEN_SHADOW); - LogicPage->Put_Pixel(D_BORD_X2+1, index, CC_GREEN_SHADOW); - } - - /*............................................................... - Draw the map "key" - ...............................................................*/ - txt_x = D_DIALOG_CX; - txt_y = D_DIALOG_Y + 8; - Fancy_Text_Print("Clear Terrain", txt_x, txt_y, LTGREY, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Water", txt_x, txt_y, BLUE, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Tiberium", txt_x, txt_y, GREY, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Rock/Wall/Road", txt_x, txt_y, BROWN, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("GDI Unit", txt_x, txt_y, YELLOW, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Nod Unit", txt_x, txt_y, RED, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Neutral Unit", txt_x, txt_y, PURPLE, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Terrain Object", txt_x, txt_y, DKGREEN, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - txt_y += 16; - Fancy_Text_Print("Starting Cell", txt_x, txt_y, WHITE, TBLACK, TPF_DROPSHADOW | TPF_6POINT); - /* - .................. Draw the coordinate labels ................... - */ - txt_x = D_DIALOG_X + D_DIALOG_W / 8; - txt_y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 33; - Fancy_Text_Print("X", txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - txt_x += (D_DIALOG_W - 20) / 4; - Fancy_Text_Print("Y", txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - txt_x += (D_DIALOG_W - 20) / 4; - Fancy_Text_Print("Width", txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - txt_x += (D_DIALOG_W - 20) / 4; - Fancy_Text_Print("Height", txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - LogicPage->Unlock(); - - /* - ...................... Redraw the buttons ....................... - */ - commands->Flag_List_To_Redraw(); - - } - - /*------------------------------------------------------------------ - Redraw the map symbology & location - ------------------------------------------------------------------*/ - if (display >= REDRAW_MAP) { - - LogicPage->Lock(); - - /* - .................... Erase the map interior ..................... - */ - LogicPage->Fill_Rect(D_BORD_X1 + 1, D_BORD_Y1 + 1, D_BORD_X2 - 1, D_BORD_Y2 - 1, BLACK); - - /*............................................................... - Draw Land map symbols (use color according to Ground[] array). - ...............................................................*/ - for (cell=0; cell < MAP_CELL_TOTAL; cell++) { - occupier = (*this)[cell].Cell_Occupier(); - if (occupier == NULL) { - color = Ground[(*this)[cell].Land_Type()].Color; - LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(cell) + 1, D_BORD_Y1 + Cell_Y(cell) + 1, color); - } - } - - LogicPage->Unlock(); - - /* - ................. Draw the actual map location .................. - */ - LogicPage->Draw_Rect(map_x1, map_y1, map_x2, map_y2, WHITE); - switch (grabbed) { - case 1: - LogicPage->Draw_Line(map_x1, map_y1, map_x1 + 5, map_y1, BLUE); - LogicPage->Draw_Line(map_x1, map_y1, map_x1, map_y1 + 5, BLUE); - break; - - case 2: - LogicPage->Draw_Line(map_x2, map_y1, map_x2 - 5, map_y1, BLUE); - LogicPage->Draw_Line(map_x2, map_y1, map_x2, map_y1 + 5, BLUE); - break; - - case 3: - LogicPage->Draw_Line(map_x2, map_y2, map_x2 - 5, map_y2, BLUE); - LogicPage->Draw_Line(map_x2, map_y2, map_x2, map_y2 - 5, BLUE); - break; - - case 4: - LogicPage->Draw_Line(map_x1, map_y2, map_x1 + 5, map_y2, BLUE); - LogicPage->Draw_Line(map_x1, map_y2, map_x1, map_y2 - 5, BLUE); - break; - - case 5: - LogicPage->Draw_Rect(map_x1, map_y1, map_x2, map_y2, BLUE); - break; - - default: - break; - } - - /*............................................................... - Draw Unit map symbols (Use the radar map color according to - that specified in the house type class object. - DKGREEN = terrain object - ...............................................................*/ - for (cell=0; cell < MAP_CELL_TOTAL; cell++) { - occupier = (*this)[cell].Cell_Occupier(); - if (occupier) { - color = DKGREEN; - if (occupier && occupier->Owner() != HOUSE_NONE) { - color = HouseClass::As_Pointer(occupier->Owner())->Class->Color; - } - LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(cell) + 1, D_BORD_Y1 + Cell_Y(cell) + 1, color); - } - } - - /* - ...................... Draw Home location ....................... - */ - LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(Waypoint[WAYPT_HOME]) + 1, D_BORD_Y1 + Cell_Y(Waypoint[WAYPT_HOME]) + 1, WHITE); - - /* - ..................... Erase old coordinates ..................... - */ - LogicPage->Fill_Rect( D_DIALOG_X + 7, - D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 22, - D_DIALOG_X + D_DIALOG_W - 7, - D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 22 + 10, BLACK); - - /* - ..................... Draw the coordinates ...................... - */ - txt_x = D_DIALOG_X + D_DIALOG_W / 8; - txt_y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 22; - sprintf(txt,"%d",map_x1 - D_BORD_X1 - 1); - Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - txt_x += (D_DIALOG_W - 20) / 4; - sprintf(txt,"%d",map_y1 - D_BORD_Y1 - 1); - Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - txt_x += (D_DIALOG_W - 20) / 4; - sprintf(txt,"%d",map_x2 - map_x1 + 1); - Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - txt_x += (D_DIALOG_W - 20) / 4; - sprintf(txt,"%d",map_y2 - map_y1 + 1); - Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ------------------------- Process user input -------------------------- - */ - input = commands->Input(); - /*..................................................................... - Normal button processing: This is done when the mouse button is NOT - being held down ('grabbed' is 0). - .....................................................................*/ - if (grabbed == 0) { - switch (input) { - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - cancel = false; - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - case KN_LMOUSE: - /* - ....................... Grab top left ........................ - */ - delta1 = abs(_Kbd->MouseQX - map_x1); - delta2 = abs(_Kbd->MouseQY - map_y1); - if (delta1 < 3 && delta2 < 3) { - grabbed = 1; - mx = _Kbd->MouseQX; - my = _Kbd->MouseQY; - display = REDRAW_MAP; - break; - } - /* - ...................... Grab top right ........................ - */ - delta1 = abs(_Kbd->MouseQX - map_x2); - delta2 = abs(_Kbd->MouseQY - map_y1); - if (delta1 < 3 && delta2 < 3) { - grabbed = 2; - mx = _Kbd->MouseQX; - my = _Kbd->MouseQY; - display = REDRAW_MAP; - break; - } - /* - ..................... Grab bottom right ...................... - */ - delta1 = abs(_Kbd->MouseQX - map_x2); - delta2 = abs(_Kbd->MouseQY - map_y2); - if (delta1 < 3 && delta2 < 3) { - grabbed = 3; - mx = _Kbd->MouseQX; - my = _Kbd->MouseQY; - display = REDRAW_MAP; - break; - } - /* - ..................... Grab bottom left ....................... - */ - delta1 = abs(_Kbd->MouseQX - map_x1); - delta2 = abs(_Kbd->MouseQY - map_y2); - if (delta1 < 3 && delta2 < 3) { - grabbed = 4; - mx = _Kbd->MouseQX; - my = _Kbd->MouseQY; - display = REDRAW_MAP; - break; - } - /* - ..................... Grab the whole map ..................... - */ - delta1 = abs(_Kbd->MouseQX - ((map_x1 + map_x2) / 2)); - delta2 = abs(_Kbd->MouseQY - ((map_y1 + map_y2) / 2)); - if (delta1 < (map_x2 - map_x1) / 4 && - delta2 < (map_y2 - map_y1) / 4) { - grabbed = 5; - mx = _Kbd->MouseQX; - my = _Kbd->MouseQY; - display = REDRAW_MAP; - } - break; - - default: - break; - } - } else { - /*..................................................................... - Mouse motion processing: This is done while the left mouse button IS - being held down. - - First, check for the button release; if detected, un-grab - - Then, handle mouse motion. WWLIB doesn't pass through a KN_MOUSE_MOVE - value while the button is being held down, so this case must be - trapped as a default. - .....................................................................*/ - switch (input) { - case ((int)KN_LMOUSE | (int)KN_RLSE_BIT): - grabbed = 0; - display = REDRAW_MAP; - break; - - default: - delta1 = Get_Mouse_X() - mx; - delta2 = Get_Mouse_Y() - my; - if (delta1==0 && delta2==0) { - break; - } - - /* - ....................... Move top left ........................ - */ - if (grabbed==1) { - map_x1 += delta1; - if (map_x1 > map_x2 - 2) { - map_x1 = map_x2 - 2; - } else { - if (map_x1 < D_BORD_X1 + 2) { - map_x1 = D_BORD_X1 + 2; - } - } - - map_y1 += delta2; - if (map_y1 > map_y2 - 2) { - map_y1 = map_y2 - 2; - } else { - if (map_y1 < D_BORD_Y1 + 2) { - map_y1 = D_BORD_Y1 + 2; - } - } - display = REDRAW_MAP; - mx = Get_Mouse_X(); - my = Get_Mouse_Y(); - } - - /* - ....................... Move top right ....................... - */ - if (grabbed==2) { - map_x2 += delta1; - if (map_x2 < map_x1 + 2) { - map_x2 = map_x1 + 2; - } else { - if (map_x2 > D_BORD_X2 - 2) { - map_x2 = D_BORD_X2 - 2; - } - } - - map_y1 += delta2; - if (map_y1 > map_y2 - 2) { - map_y1 = map_y2 - 2; - } else { - if (map_y1 < D_BORD_Y1 + 2) { - map_y1 = D_BORD_Y1 + 2; - } - } - display = REDRAW_MAP; - mx = Get_Mouse_X(); - my = Get_Mouse_Y(); - } - - /* - ..................... Move bottom right ...................... - */ - if (grabbed==3) { - map_x2 += delta1; - if (map_x2 < map_x1 + 2) { - map_x2 = map_x1 + 2; - } else { - if (map_x2 > D_BORD_X2 - 2) { - map_x2 = D_BORD_X2 - 2; - } - } - - map_y2 += delta2; - if (map_y2 < map_y1 + 2) { - map_y2 = map_y1 + 2; - } else { - if (map_y2 > D_BORD_Y2 - 2) { - map_y2 = D_BORD_Y2 - 2; - } - } - display = REDRAW_MAP; - mx = Get_Mouse_X(); - my = Get_Mouse_Y(); - } - - /* - ...................... Move bottom left ...................... - */ - if (grabbed==4) { - map_x1 += delta1; - if (map_x1 > map_x2 - 2) { - map_x1 = map_x2 - 2; - } else { - if (map_x1 < D_BORD_X1 + 2) { - map_x1 = D_BORD_X1 + 2; - } - } - - map_y2 += delta2; - if (map_y2 < map_y1 + 2) { - map_y2 = map_y1 + 2; - } else { - if (map_y2 > D_BORD_Y2 - 2) { - map_y2 = D_BORD_Y2 - 2; - } - } - display = REDRAW_MAP; - mx = Get_Mouse_X(); - my = Get_Mouse_Y(); - } - - /* - ....................... Move whole map ....................... - */ - if (grabbed==5) { - if (map_x1 + delta1 > D_BORD_X1 + 1 && map_x2 + delta1 < D_BORD_X2 - 1) { - map_x1 += delta1; - map_x2 += delta1; - } - - if (map_y1 + delta2 > D_BORD_Y1 + 1 && map_y2 + delta2 < D_BORD_Y2 - 1) { - map_y1 += delta2; - map_y2 += delta2; - } - display = REDRAW_MAP; - mx = Get_Mouse_X(); - my = Get_Mouse_Y(); - } - break; - } - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /* - ------------------------- If cancel, just return ------------------------- - */ - if (cancel) { - return(-1); - } - - /* - ---------------------------- Save selections ----------------------------- - */ - MapCellX = map_x1 - D_BORD_X1 - 1; - MapCellY = map_y1 - D_BORD_Y1 - 1; - MapCellWidth = map_x2 - map_x1 + 1; - MapCellHeight = map_y2 - map_y1 + 1; - - /* - --------------------- Clip Home Cell to new map size --------------------- - */ - if (Cell_X(Waypoint[WAYPT_HOME]) < MapCellX) { - Waypoint[WAYPT_HOME] = XY_Cell(MapCellX, Cell_Y(Waypoint[WAYPT_HOME])); - } - - if (Cell_X(Waypoint[WAYPT_HOME]) > MapCellX + MapCellWidth - 1) { - Waypoint[WAYPT_HOME] = XY_Cell(MapCellX + MapCellWidth - 1, Cell_Y(Waypoint[WAYPT_HOME])); - } - - if (Cell_Y(Waypoint[WAYPT_HOME]) < MapCellY) { - Waypoint[WAYPT_HOME] = XY_Cell(Cell_X(Waypoint[WAYPT_HOME]), MapCellY); - } - - if (Cell_Y(Waypoint[WAYPT_HOME]) > MapCellY + MapCellHeight - 1) { - Waypoint[WAYPT_HOME] = XY_Cell(Cell_X(Waypoint[WAYPT_HOME]), MapCellY + MapCellHeight - 1); - } - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Scenario_Dialog -- scenario global parameters dialog * - * * - * Lets the user edit the Theater, starting credits for houses, and the * - * Edge for HOUSE_GOOD & HOUSE_BAD. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Theater Credits / 1000 ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ Temperate ³ GDI: _____ ³ * - * ³ ³ Desert ³ NOD: _____ ³ * - * ³ ³ Jungle ³ Neutral: _____ ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ Build Level:___ ³ * - * ³ ³ * - * ³ Reinforcements ³ * - * ³ ³ * - * ³ GDI NOD ³ * - * ³ ³ * - * ³   ³ * - * ³ <- -> <- -> ³ * - * ³   ³ * - * ³ ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * Uses HIDBUFF. * - * * - * HISTORY: * - * 11/14/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Scenario_Dialog(void) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 544, - D_DIALOG_H = 320, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_THEATER_W = 200, - D_THEATER_H = 68, - D_THEATER_X = D_DIALOG_X + D_MARGIN, - D_THEATER_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_LEVEL_W = 80, - D_LEVEL_H = 18, - D_LEVEL_X = D_THEATER_X + D_THEATER_W - D_LEVEL_W, - D_LEVEL_Y = D_THEATER_Y + D_THEATER_H + D_MARGIN, - - D_GDICRED_W = 120, - D_GDICRED_H = 18, - D_GDICRED_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_GDICRED_W, - D_GDICRED_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_NODCRED_W = 120, - D_NODCRED_H = 18, - D_NODCRED_X = D_GDICRED_X, - D_NODCRED_Y = D_GDICRED_Y + D_GDICRED_H, - - D_NEUTCRED_W = 120, - D_NEUTCRED_H = 18, - D_NEUTCRED_X = D_GDICRED_X, - D_NEUTCRED_Y = D_NODCRED_Y + D_NODCRED_H, - - D_GDIN_W = 26, - D_GDIN_H = 18, - D_GDIN_X = D_DIALOG_CX - 5 - D_GDIN_W * 2, - D_GDIN_Y = D_LEVEL_Y + D_LEVEL_H + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H, - - D_GDIS_W = 26, - D_GDIS_H = 18, - D_GDIS_X = D_GDIN_X, - D_GDIS_Y = D_GDIN_Y + D_GDIN_H * 2, - - D_GDIW_W = 26, - D_GDIW_H = 18, - D_GDIW_X = D_DIALOG_CX - 5 - D_GDIN_W * 3, - D_GDIW_Y = D_GDIN_Y + D_GDIN_H, - - D_GDIE_W = 26, - D_GDIE_H = 18, - D_GDIE_X = D_DIALOG_CX - 5 - D_GDIN_W, - D_GDIE_Y = D_GDIN_Y + D_GDIN_H, - - D_NODN_W = 26, - D_NODN_H = 18, - D_NODN_X = D_DIALOG_CX + 5 + D_NODN_W, - D_NODN_Y = D_LEVEL_Y + D_LEVEL_H + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H, - - D_NODS_W = 26, - D_NODS_H = 18, - D_NODS_X = D_NODN_X, - D_NODS_Y = D_NODN_Y + D_NODN_H * 2, - - D_NODW_W = 26, - D_NODW_H = 18, - D_NODW_X = D_DIALOG_CX + 5, - D_NODW_Y = D_NODN_Y + D_NODN_H, - - D_NODE_W = 26, - D_NODE_H = 18, - D_NODE_X = D_DIALOG_CX + 5 + D_NODN_W * 2, - D_NODE_Y = D_NODN_Y + D_NODN_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_DIALOG_CX - D_OK_W - 5, - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN, - - D_CANCEL_W = 90, - D_CANCEL_H = 18, - D_CANCEL_X = D_DIALOG_CX + 5, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, - }; - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - LIST_THEATER=100, - TEDIT_LEVEL, - TEDIT_GDICRED, - TEDIT_NODCRED, - TEDIT_NEUTCRED, - BUTTON_GDI_N, - BUTTON_GDI_E, - BUTTON_GDI_S, - BUTTON_GDI_W, - BUTTON_NOD_N, - BUTTON_NOD_E, - BUTTON_NOD_S, - BUTTON_NOD_W, - BUTTON_OK, - BUTTON_CANCEL, - }; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, // includes map interior & coord values - REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables: - ........................................................................*/ - KeyNumType input; // input from user - bool process; // loop while true - RedrawType display; // true = re-draw everything - bool cancel = false; // true = user cancels - /* - .......................... Scenario parameters ........................... - */ - TheaterType theater; // DisplayClass::Theater - TheaterType orig_theater; // original theater - long gdi_credits; // HouseClass::As_Pointer(HouseType)->Credits - long nod_credits; // HouseClass::As_Pointer(HouseType)->Credits - long neut_credits; // HouseClass::As_Pointer(HouseType)->Credits - SourceType gdi_edge; // HouseClass::As_Pointer(HouseType)->Edge - SourceType nod_edge; // HouseClass::As_Pointer(HouseType)->Edge - char level_buf[10] = {0}; - char gdicred_buf[10] = {0}; - char nodcred_buf[10] = {0}; - char neutcred_buf[10] = {0}; - /* - ....................... Theater-changing variables ....................... - */ - unsigned char theater_mask; // template/terrain mask - TerrainClass * terrain; // cell's terrain pointer - CELL i; // loop counter - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - ListClass theaterbtn (LIST_THEATER, - D_THEATER_X, D_THEATER_Y, D_THEATER_W, D_THEATER_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - EditClass leveledt (TEDIT_GDICRED, level_buf, 4, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_LEVEL_X, D_LEVEL_Y, D_LEVEL_W, D_LEVEL_H, EditClass::NUMERIC); - - EditClass gdicred (TEDIT_GDICRED, gdicred_buf, 8, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDICRED_X, D_GDICRED_Y, D_GDICRED_W, D_GDICRED_H, EditClass::NUMERIC); - - EditClass nodcred (TEDIT_NODCRED, nodcred_buf, 8, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NODCRED_X, D_NODCRED_Y, D_NODCRED_W, D_NODCRED_H, EditClass::NUMERIC); - - EditClass neutcred (TEDIT_NEUTCRED, neutcred_buf, 8, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NEUTCRED_X, D_NEUTCRED_Y, D_NEUTCRED_W, D_NEUTCRED_H, EditClass::NUMERIC); - - TextButtonClass gdinbtn (BUTTON_GDI_N, TXT_UP, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDIN_X, D_GDIN_Y, D_GDIN_W, D_GDIN_H); - - TextButtonClass gdiebtn (BUTTON_GDI_E, TXT_RIGHT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDIE_X, D_GDIE_Y, D_GDIE_W, D_GDIE_H); - - TextButtonClass gdisbtn (BUTTON_GDI_S, TXT_DOWN, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDIS_X, D_GDIS_Y, D_GDIS_W, D_GDIS_H); - - TextButtonClass gdiwbtn (BUTTON_GDI_W, TXT_LEFT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDIW_X, D_GDIW_Y, D_GDIW_W, D_GDIW_H); - - TextButtonClass nodnbtn (BUTTON_NOD_N, TXT_UP, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NODN_X, D_NODN_Y, D_NODN_W, D_NODN_H); - - TextButtonClass nodebtn (BUTTON_NOD_E, TXT_RIGHT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NODE_X, D_NODE_Y, D_NODE_W, D_NODE_H); - - TextButtonClass nodsbtn (BUTTON_NOD_S, TXT_DOWN, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NODS_X, D_NODS_Y, D_NODS_W, D_NODS_H); - - TextButtonClass nodwbtn (BUTTON_NOD_W, TXT_LEFT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NODW_X, D_NODW_Y, D_NODW_W, D_NODW_H); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - .......................... Fill in theater items ......................... - */ - theaterbtn.Add_Item("Desert"); - theaterbtn.Add_Item("Jungle"); - theaterbtn.Add_Item("Temperate"); - theaterbtn.Add_Item("Winter"); - - /* - ............................ Init parameters ............................. - */ - orig_theater = theater = Theater; - if (ScenPlayer != SCEN_PLAYER_MPLAYER) { - gdi_credits = HouseClass::As_Pointer(HOUSE_GOOD)->Credits / 1000L; - nod_credits = HouseClass::As_Pointer(HOUSE_BAD)->Credits / 1000L; - neut_credits = HouseClass::As_Pointer(HOUSE_NEUTRAL)->Credits / 1000L; - gdi_edge = HouseClass::As_Pointer(HOUSE_GOOD)->Edge; - nod_edge = HouseClass::As_Pointer(HOUSE_BAD)->Edge; - } else { - gdi_credits = 0; - nod_credits = 0; - neut_credits = 0; - gdi_edge = SOURCE_NONE; - nod_edge = SOURCE_NONE; - } - - /* - ............................ Create the list ............................. - */ - commands = &theaterbtn; - leveledt.Add_Tail(*commands); - gdicred.Add_Tail(*commands); - nodcred.Add_Tail(*commands); - neutcred.Add_Tail(*commands); - gdinbtn.Add_Tail(*commands); - gdiebtn.Add_Tail(*commands); - gdisbtn.Add_Tail(*commands); - gdiwbtn.Add_Tail(*commands); - nodnbtn.Add_Tail(*commands); - nodebtn.Add_Tail(*commands); - nodsbtn.Add_Tail(*commands); - nodwbtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - - /* - ...................... Init GDI Edge button states ....................... - */ - if (gdi_edge==SOURCE_NORTH) gdinbtn.Turn_On(); - if (gdi_edge==SOURCE_EAST) gdiebtn.Turn_On(); - if (gdi_edge==SOURCE_SOUTH) gdisbtn.Turn_On(); - if (gdi_edge==SOURCE_WEST) gdiwbtn.Turn_On(); - - /* - ...................... Init NOD Edge button states ....................... - */ - if (nod_edge==SOURCE_NORTH) nodnbtn.Turn_On(); - if (nod_edge==SOURCE_EAST) nodebtn.Turn_On(); - if (nod_edge==SOURCE_SOUTH) nodsbtn.Turn_On(); - if (nod_edge==SOURCE_WEST) nodwbtn.Turn_On(); - - /* - .......................... Init credits buffers .......................... - */ - sprintf(level_buf,"%ld",BuildLevel); - leveledt.Set_Text(level_buf,4); - - sprintf(gdicred_buf,"%ld",gdi_credits); - gdicred.Set_Text(gdicred_buf,8); - - sprintf(nodcred_buf,"%ld",nod_credits); - nodcred.Set_Text(nodcred_buf,8); - - sprintf(neutcred_buf,"%ld",neut_credits); - neutcred.Set_Text(neutcred_buf,8); - - theaterbtn.Set_Selected_Index(orig_theater - THEATER_NONE - 1); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - - /* - ..................... Draw the background ....................... - */ - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - - /* - ....................... Draw the labels ......................... - */ - Fancy_Text_Print("Theater", D_THEATER_X + D_THEATER_W / 2, - D_THEATER_Y - D_TXT8_H, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Build Level", D_LEVEL_X, D_LEVEL_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Credits/1000", D_GDICRED_X + D_GDICRED_W / 2, - D_GDICRED_Y - D_TXT8_H, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print ("GDI", D_GDICRED_X - 5, D_GDICRED_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print ("NOD", D_NODCRED_X - 5, D_NODCRED_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print ("Neutral", D_NEUTCRED_X - 5, D_NEUTCRED_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print ("Reinforcements", D_DIALOG_CX, - D_LEVEL_Y + D_LEVEL_H + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print ("GDI", D_GDIN_X + D_GDIN_W / 2, - D_GDIN_Y - D_TXT8_H, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print ("NOD", D_NODN_X + D_NODN_W / 2, - D_NODN_Y - D_TXT8_H, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - - /*.................................................................. - Credit edit boxes: no need for any action - ..................................................................*/ - case (TEDIT_GDICRED | KN_BUTTON): - break; - - case (TEDIT_NODCRED | KN_BUTTON): - break; - - case (TEDIT_NEUTCRED | KN_BUTTON): - break; - - /*.................................................................. - GDI Edge buttons: turn this one on, others off, save the edge value - ..................................................................*/ - case (BUTTON_GDI_N | KN_BUTTON): - gdi_edge = SOURCE_NORTH; - gdinbtn.Turn_On(); - gdiebtn.Turn_Off(); - gdisbtn.Turn_Off(); - gdiwbtn.Turn_Off(); - break; - - case (BUTTON_GDI_E | KN_BUTTON): - gdi_edge = SOURCE_EAST; - gdinbtn.Turn_Off(); - gdiebtn.Turn_On(); - gdisbtn.Turn_Off(); - gdiwbtn.Turn_Off(); - break; - - case (BUTTON_GDI_S | KN_BUTTON): - gdi_edge = SOURCE_SOUTH; - gdinbtn.Turn_Off(); - gdiebtn.Turn_Off(); - gdisbtn.Turn_On(); - gdiwbtn.Turn_Off(); - break; - - case (BUTTON_GDI_W | KN_BUTTON): - gdi_edge = SOURCE_WEST; - gdinbtn.Turn_Off(); - gdiebtn.Turn_Off(); - gdisbtn.Turn_Off(); - gdiwbtn.Turn_On(); - break; - - /*.................................................................. - NOD Edge buttons: turn this one on, others off, save the edge value - ..................................................................*/ - case (BUTTON_NOD_N | KN_BUTTON): - nod_edge = SOURCE_NORTH; - nodnbtn.Turn_On(); - nodebtn.Turn_Off(); - nodsbtn.Turn_Off(); - nodwbtn.Turn_Off(); - break; - - case (BUTTON_NOD_E | KN_BUTTON): - nod_edge = SOURCE_EAST; - nodnbtn.Turn_Off(); - nodebtn.Turn_On(); - nodsbtn.Turn_Off(); - nodwbtn.Turn_Off(); - break; - - case (BUTTON_NOD_S | KN_BUTTON): - nod_edge = SOURCE_SOUTH; - nodnbtn.Turn_Off(); - nodebtn.Turn_Off(); - nodsbtn.Turn_On(); - nodwbtn.Turn_Off(); - break; - - case (BUTTON_NOD_W | KN_BUTTON): - nod_edge = SOURCE_WEST; - nodnbtn.Turn_Off(); - nodebtn.Turn_Off(); - nodsbtn.Turn_Off(); - nodwbtn.Turn_On(); - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - cancel = false; - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - default: - break; - } - } - - /* - ----------------------------- Redraw the map ----------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /* - ------------------------- If cancel, just return ------------------------- - */ - if (cancel) { - return(-1); - } - - /* - ------------------------ Save selections & return ------------------------ - */ - if (ScenPlayer != SCEN_PLAYER_MPLAYER) { - /* - .............................. Credits ................................ - */ - gdi_credits = atol(gdicred_buf); - nod_credits = atol(nodcred_buf); - neut_credits = atol(neutcred_buf); - HouseClass::As_Pointer(HOUSE_GOOD)->Credits = gdi_credits * 1000L; - HouseClass::As_Pointer(HOUSE_BAD)->Credits = nod_credits * 1000L; - HouseClass::As_Pointer(HOUSE_NEUTRAL)->Credits = neut_credits * 1000L; - /* - ............................... Edges ................................. - */ - HouseClass::As_Pointer(HOUSE_GOOD)->Edge = gdi_edge; - HouseClass::As_Pointer(HOUSE_BAD)->Edge = nod_edge; - } - - /* - ........................... Sidebar build level .......................... - */ - BuildLevel = atoi(level_buf); - - /*........................................................................ - Change the theater: - - 1st set the Theater global - - scan all cells to check their TType for compatibility with the new - theater; if not compatible, set TType to TEMPLATE_NONE & TIcon to 0 - - Then, re-initialize the TypeClasses for the new Theater - ........................................................................*/ - theater = (TheaterType)(THEATER_NONE + 1 + theaterbtn.Current_Index()); - if (theater != orig_theater) { - /* - ....................... Loop through all cells ........................ - */ - for (i =0;iClass->Theater; - if ( (theater_mask & (1<Remove(); - CurTrigger = NULL; - Changed = 1; - } - } - } - - /*------------------------------------------------------------------------ - Don't allow trigger placement if the trigger is house-specific; such - triggers cannot be "placed". - ------------------------------------------------------------------------*/ - if (CurTrigger) { - if (!TriggerClass::Event_Need_Object(CurTrigger->Event)) { - CurTrigger = NULL; - } - } -} - - -/*************************************************************************** - * MapEditClass::Select_Trigger -- lets user select a trigger * - * * - * CurTrigger can be NULL when this function is called. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Triggers ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ Name Event Action House Team ³³ ³ * - * ³ ³ Name Event Action House Team ÃÄ´ ³ * - * ³ ³ Name Event Action House Team ³ ³ ³ * - * ³ ³ Name Event Action House Team ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ ³ * - * ³ [Edit] [New] [Delete] [OK] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, 1 = Edit, 2 = New, 3 = Delete * - * * - * WARNINGS: * - * Uses HIDBUFF. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Select_Trigger(void) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 640, - D_DIALOG_H = 290, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_LIST_W = 612, - D_LIST_H = 208, - D_LIST_X = D_DIALOG_X + D_MARGIN, - D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_EDIT_W = 90, - D_EDIT_H = 18, - D_EDIT_X = D_DIALOG_X + (D_DIALOG_W / 8) - (D_EDIT_W / 2), - D_EDIT_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_EDIT_H, - - D_NEW_W = 90, - D_NEW_H = 18, - D_NEW_X = D_DIALOG_X + (D_DIALOG_W / 8) * 3 - (D_NEW_W / 2), - D_NEW_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_NEW_H, - - D_DELETE_W = 90, - D_DELETE_H = 18, - D_DELETE_X = D_DIALOG_X + (D_DIALOG_W / 8) * 5 - (D_DELETE_W / 2), - D_DELETE_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_DELETE_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_DIALOG_X + (D_DIALOG_W / 8) * 7 - (D_OK_W / 2), - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - }; - - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - TRIGGER_LIST=100, - BUTTON_EDIT, - BUTTON_NEW, - BUTTON_DELETE, - BUTTON_OK, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables: - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - char *trigtext[TRIGGER_MAX + 1]; // text for defined triggers - KeyNumType input; // user input - bool edit_trig = false; // true = user wants to edit - bool new_trig = false; // true = user wants to new - bool del_trig = false; // true = user wants to new - int i; // loop counter - int def_idx; // default list index - static int tabs[] = {70, 240, 390, 440}; // list box tab stops - - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - ListClass triggerlist (TRIGGER_LIST, D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - TextButtonClass editbtn (BUTTON_EDIT, "Edit", TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - D_EDIT_X, D_EDIT_Y, D_EDIT_W, D_EDIT_H); - - TextButtonClass newbtn (BUTTON_NEW, "New", TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - D_NEW_X, D_NEW_Y, D_NEW_W, D_NEW_H); - - TextButtonClass deletebtn (BUTTON_DELETE, "Delete", TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - D_DELETE_X, D_DELETE_Y, D_DELETE_W, D_DELETE_H); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ......................... Fill in trigger names .......................... - */ - def_idx = 0; - for (i = 0; i < Triggers.Count(); i++) { - /*..................................................................... - Generate string for this trigger - - Name can be up to 4 characters - - Event can be up to 15 characters - - Action can be up to 15 characters - - House is 3 characters - - Team name is up to 11 characters - .....................................................................*/ - //trigtext[i] = (char *)HidPage.Get_Graphic_Buffer()->Get_Buffer() + 60 * i; - trigtext[i] = new char[255]; - sprintf(trigtext[i],"%s\t%s\t%s\t", - Triggers.Ptr(i)->Get_Name(), - TriggerClass::Name_From_Event(Triggers.Ptr(i)->Event), - TriggerClass::Name_From_Action(Triggers.Ptr(i)->Action)); - - /* - ......................... Add on the house ID ......................... - */ - if (TriggerClass::Event_Need_House(Triggers.Ptr(i)->Event)) { - if (Triggers.Ptr(i)->House != HOUSE_NONE) { - strcat(trigtext[i], HouseTypeClass::As_Reference(Triggers.Ptr(i)->House).Suffix); - } else { - strcat(trigtext[i], "!!!"); - } - } else { - strcat(trigtext[i]," "); - } - - /* - .......................... Add the team name .......................... - */ - strcat(trigtext[i],"\t"); - if (TriggerClass::Action_Need_Team(Triggers.Ptr(i)->Action)) { - if (Triggers.Ptr(i)->Team) { - strcat(trigtext[i],Triggers.Ptr(i)->Team->IniName); - } else { - strcat(trigtext[i], "!!!"); - } - } - - /* - ................. Set def_idx if this is CurTrigger ................... - */ - if (Triggers.Ptr(i) == CurTrigger) { - def_idx = i; - } - } - - /* - .......................... Fill in the list box .......................... - */ - for (i = 0; i < Triggers.Count(); i++) { - triggerlist.Add_Item(trigtext[i]); - } - triggerlist.Set_Selected_Index(def_idx); - - /* - ....................... Set CurTrigger if it isn't ....................... - */ - if (Triggers.Count()==0) { - CurTrigger = NULL; - } else { - if (!CurTrigger) { - CurTrigger = Triggers.Ptr(def_idx); - } - } - - /* - ............................ Create the list ............................. - */ - commands = &triggerlist; - editbtn.Add_Tail(*commands); - newbtn.Add_Tail(*commands); - deletebtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - - /* - ------------------------ Init tab stops for list ------------------------- - */ - triggerlist.Set_Tabs(tabs); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print("Triggers", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, CC_GREEN, TBLACK, - TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - } - - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (TRIGGER_LIST | KN_BUTTON): - def_idx = triggerlist.Current_Index(); - if (def_idx < Triggers.Count()) { - CurTrigger = Triggers.Ptr(def_idx); - } - break; - - case (BUTTON_EDIT | KN_BUTTON): - if (CurTrigger) { // only allow if there's one selected - process = false; - edit_trig = true; - } - break; - - case (BUTTON_NEW | KN_BUTTON): - process = false; - new_trig = true; - break; - - case (BUTTON_DELETE | KN_BUTTON): - process = false; - del_trig = true; - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - for (i = 0; i < Triggers.Count(); i++) { - delete [] trigtext[i]; - } - - if (edit_trig) return(1); - if (new_trig) return(2); - if (del_trig) return(3); - return(0); -} - - -/*************************************************************************** - * MapEditClass::Edit_Trigger -- lets user edit a [new] trigger * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Trigger Editor ³ * - * ³ ³ * - * ³ Events Actions ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ ³³ ³ ³³ ³ * - * ³ ³ ÃÄ´ ³ ÃÄ´ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ³ ÃÄ´ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ ³ * - * ³ Name: _______ [ Volatile ] ³ * - * ³ [GDI] [ Persistent ] ³ * - * ³ Time / Credits: _______ [NOD] [SemiPersistent] ³ * - * ³ ³ * - * ³ [Team] Team_Name ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * CurTrigger must NOT be NULL when this function is called. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Edit_Trigger(void) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 528, - D_DIALOG_H = 376, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_EVENT_W = 240, - D_EVENT_H = 88, - D_EVENT_X = D_DIALOG_X + D_MARGIN, - D_EVENT_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H, - - D_ACTION_W = 240, - D_ACTION_H = 88, - D_ACTION_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_ACTION_W, - D_ACTION_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H, - - D_NAME_W = 80, - D_NAME_H = 18, - D_NAME_X = D_EVENT_X + (D_EVENT_W / 2) - 10, - D_NAME_Y = D_EVENT_Y + D_EVENT_H + D_MARGIN, - - D_DATA_W = 80, - D_DATA_H = 18, - D_DATA_X = D_NAME_X, - D_DATA_Y = D_NAME_Y + D_NAME_H + D_MARGIN, - - D_TEAM_W = 80, - D_TEAM_H = 18, - D_TEAM_X = D_NAME_X - D_TEAM_W - 5, - D_TEAM_Y = D_DATA_Y + D_DATA_H + D_MARGIN, - - D_GDI_W = 90, - D_GDI_H = 18, - D_GDI_X = D_DIALOG_CX - (D_GDI_W / 2), - D_GDI_Y = D_NAME_Y, - - D_NOD_W = 90, - D_NOD_H = 18, - D_NOD_X = D_GDI_X, - D_NOD_Y = D_GDI_Y + D_GDI_H, - - D_NEU_W = 90, - D_NEU_H = 18, - D_NEU_X = D_NOD_X, - D_NEU_Y = D_NOD_Y + D_NOD_H, - - D_MULTI1_W = 44, - D_MULTI1_H = 18, - D_MULTI1_X = D_GDI_X, - D_MULTI1_Y = D_GDI_Y, - - D_MULTI2_W = 44, - D_MULTI2_H = 18, - D_MULTI2_X = D_GDI_X + D_MULTI1_W, - D_MULTI2_Y = D_GDI_Y, - - D_MULTI3_W = 44, - D_MULTI3_H = 18, - D_MULTI3_X = D_NOD_X, - D_MULTI3_Y = D_NOD_Y, - - D_MULTI4_W = 44, - D_MULTI4_H = 18, - D_MULTI4_X = D_NOD_X + D_MULTI1_W, - D_MULTI4_Y = D_NOD_Y, - - D_VOLATILE_W = 100, - D_VOLATILE_H = 18, - D_VOLATILE_X = D_ACTION_X + (D_ACTION_W / 2) - (D_VOLATILE_W / 2) + 10, - D_VOLATILE_Y = D_NAME_Y, - - D_PERSIST_W = 100, - D_PERSIST_H = 18, - D_PERSIST_X = D_ACTION_X + (D_ACTION_W / 2) - (D_PERSIST_W / 2) + 10, - D_PERSIST_Y = D_VOLATILE_Y + D_VOLATILE_H, - - D_SEMIPERSIST_W = 100, - D_SEMIPERSIST_H = 18, - D_SEMIPERSIST_X = D_ACTION_X + (D_ACTION_W / 2) - (D_SEMIPERSIST_W / 2) + 10, - D_SEMIPERSIST_Y = D_PERSIST_Y + D_PERSIST_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_DIALOG_CX - 5 - D_OK_W, - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - D_CANCEL_W = 90, - D_CANCEL_H = 18, - D_CANCEL_X = D_DIALOG_CX + 5, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_CANCEL_H, - - }; - - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - EVENT_LIST=100, - ACTION_LIST, - NAME_EDIT, - DATA_EDIT, - BUTTON_TEAM, - BUTTON_GDI, - BUTTON_NOD, - BUTTON_NEUTRAL, - BUTTON_JP, // placeholder - BUTTON_MULTI1, - BUTTON_MULTI2, - BUTTON_MULTI3, - BUTTON_MULTI4, - BUTTON_MULTI5, - BUTTON_MULTI6, - BUTTON_VOLATILE, - BUTTON_PERSIST, - BUTTON_SEMIPERSIST, - BUTTON_OK, - BUTTON_CANCEL, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables: - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - KeyNumType input; // user input - bool cancel = false; // true = user cancels - int i; // loop counter - EventType event_idx; // index for event list - TriggerClass::ActionType action_idx; // index for action list - char namebuf[5]; // name of this trigger - char databuf[10]; // for credit/time-based triggers - HousesType house; // house for this trigger - const char *eventnames[EVENT_COUNT + 1]; // names of events - const char *actionnames[TriggerClass::ACTION_COUNT + 1]; // names of actions - TriggerClass::PersistantType persistant; // trigger's persistence level - - /*........................................................................ - These flags enable various controls for each EventType. - ........................................................................*/ -// static char data_enabled[EVENT_COUNT] = {0,0,0,0,0,0,0,0,0,1,1,1,1,0,0}; -// static char house_enabled[EVENT_COUNT] = {1,0,0,0,0,1,1,1,1,1,1,1,1,1,1}; -// static char team_enabled[TriggerClass::ACTION_COUNT] = {0,0,0,1,1,0,1,0,0,0,0,0,0,0}; - - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - ListClass eventlist(EVENT_LIST, - D_EVENT_X, D_EVENT_Y, D_EVENT_W, D_EVENT_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - ListClass actionlist(ACTION_LIST, - D_ACTION_X, D_ACTION_Y, D_ACTION_W, D_ACTION_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - EditClass name_edt(NAME_EDIT, namebuf, 5, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NAME_X, D_NAME_Y, D_NAME_W, D_NAME_H, EditClass::ALPHANUMERIC); - - EditClass data_edt(DATA_EDIT, databuf, 8, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_DATA_X, D_DATA_Y, D_DATA_W, D_DATA_H, EditClass::ALPHANUMERIC); - - TextButtonClass teambtn(BUTTON_TEAM, "Team", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_TEAM_X, D_TEAM_Y, D_TEAM_W, D_TEAM_H); - - TextButtonClass gdibtn(BUTTON_GDI, "GDI", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H); - - TextButtonClass nodbtn(BUTTON_NOD, "NOD", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H); - - TextButtonClass neutralbtn(BUTTON_NEUTRAL, "Neutral", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NEU_X, D_NEU_Y, D_NEU_W, D_NEU_H); - - TextButtonClass multi1btn(BUTTON_MULTI1, "M1", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI1_X, D_MULTI1_Y, D_MULTI1_W, D_MULTI1_H); - - TextButtonClass multi2btn(BUTTON_MULTI2, "M2", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI2_X, D_MULTI2_Y, D_MULTI2_W, D_MULTI2_H); - - TextButtonClass multi3btn(BUTTON_MULTI3, "M3", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI3_X, D_MULTI3_Y, D_MULTI3_W, D_MULTI3_H); - - TextButtonClass multi4btn(BUTTON_MULTI4, "M4", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI4_X, D_MULTI4_Y, D_MULTI4_W, D_MULTI4_H); - - TextButtonClass volatilebtn(BUTTON_VOLATILE, "Volatile", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_VOLATILE_X, D_VOLATILE_Y, D_VOLATILE_W, D_VOLATILE_H); - - TextButtonClass persistbtn(BUTTON_PERSIST, "Persistant", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_PERSIST_X, D_PERSIST_Y, D_PERSIST_W, D_PERSIST_H); - - TextButtonClass semipersistbtn(BUTTON_SEMIPERSIST, "SemiPersistant", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_SEMIPERSIST_X, D_SEMIPERSIST_Y, D_SEMIPERSIST_W, D_SEMIPERSIST_H); - - TextButtonClass okbtn(BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ....................... Set default button states ........................ - */ - event_idx = CurTrigger->Event; // event list - if (event_idx == EVENT_NONE) event_idx = EVENT_FIRST; - - action_idx = CurTrigger->Action; // action list - if (action_idx == TriggerClass::ACTION_NONE) action_idx = TriggerClass::ACTION_FIRST; - - strcpy(namebuf,CurTrigger->Get_Name()); // Name - name_edt.Set_Text(namebuf,5); - - if (TriggerClass::Event_Need_Data(event_idx)) { - sprintf(databuf,"%ld",CurTrigger->Data); // Credits/Time - data_edt.Set_Text(databuf,8); - } - - house = CurTrigger->House; // House - - persistant = CurTrigger->IsPersistant; - - volatilebtn.Turn_Off(); - persistbtn.Turn_Off(); - semipersistbtn.Turn_Off(); - switch (CurTrigger->IsPersistant) { - case TriggerClass::VOLATILE: - volatilebtn.Turn_On(); - break; - - case TriggerClass::SEMIPERSISTANT: - semipersistbtn.Turn_On(); - break; - - case TriggerClass::PERSISTANT: - persistbtn.Turn_On(); - break; - } - - /* - ......................... Fill in the list boxes ......................... - */ - for (i = 0; i < EVENT_COUNT; i++) { - eventnames[i] = TriggerClass::Name_From_Event( (EventType)i); - eventlist.Add_Item(eventnames[i]); - } - eventlist.Set_Selected_Index(event_idx); - - for (i = 0; i < TriggerClass::ACTION_COUNT; i++) { - actionnames[i] = TriggerClass::Name_From_Action( (TriggerClass::ActionType)i); - actionlist.Add_Item(actionnames[i]); - } - actionlist.Set_Selected_Index(action_idx); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print("Trigger Editor", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Events", D_EVENT_X + D_EVENT_W / 2, - D_EVENT_Y - D_TXT8_H, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Actions", D_ACTION_X + D_ACTION_W / 2, - D_ACTION_Y - D_TXT8_H, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Name", D_NAME_X - 5, D_NAME_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if ((EventType)event_idx==EVENT_CREDITS) { // use 'Data' for Credits - Fancy_Text_Print("Credits", D_DATA_X - 5, D_DATA_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - } else { - if ((EventType)event_idx==EVENT_TIME) { // use 'Data' for Time - Fancy_Text_Print("1/10 Min", D_DATA_X - 5, D_DATA_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - } - - if (TriggerClass::Action_Need_Team(action_idx)) { - if (CurTrigger->Team) { - Fancy_Text_Print(CurTrigger->Team->IniName, - D_TEAM_X + D_TEAM_W + 5, D_TEAM_Y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } else { - Fancy_Text_Print( "!!!", - D_TEAM_X + D_TEAM_W + 5, D_TEAM_Y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - } - } - - /* - ..................... Rebuild the button list ...................... - */ - eventlist.Zap(); - actionlist.Zap(); - name_edt.Zap(); - data_edt.Zap(); - teambtn.Zap(); - gdibtn.Zap(); - nodbtn.Zap(); - neutralbtn.Zap(); - volatilebtn.Zap(); - persistbtn.Zap(); - semipersistbtn.Zap(); - okbtn.Zap(); - cancelbtn.Zap(); - - commands = &okbtn; - cancelbtn.Add_Tail(*commands); - eventlist.Add_Tail(*commands); - actionlist.Add_Tail(*commands); - name_edt.Add_Tail(*commands); - volatilebtn.Add_Tail(*commands); - persistbtn.Add_Tail(*commands); - semipersistbtn.Add_Tail(*commands); - if (TriggerClass::Event_Need_Data(event_idx)) { - data_edt.Add_Tail(*commands); - sprintf(databuf,"%ld",CurTrigger->Data); - data_edt.Set_Text(databuf,8); - } - if (TriggerClass::Event_Need_House(event_idx)) { - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - neutralbtn.Add_Tail(*commands); - Set_House_Buttons(house, commands, BUTTON_GDI); - } - if (TriggerClass::Action_Need_Team(action_idx)) teambtn.Add_Tail(*commands); - - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) { - commands->Flag_List_To_Redraw(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (EVENT_LIST | KN_BUTTON): - if (eventlist.Current_Index() != event_idx) { - event_idx = EventType(eventlist.Current_Index()); - databuf[0] = 0; - CurTrigger->Data = 0; - if (!TriggerClass::Event_Need_House(event_idx)) { - CurTrigger->House = HOUSE_NONE; - } - display = REDRAW_ALL; - } - break; - - case (ACTION_LIST | KN_BUTTON): - if (actionlist.Current_Index() != action_idx) { - action_idx = TriggerClass::ActionType(actionlist.Current_Index()); - display = REDRAW_ALL; - } - break; - - case (NAME_EDIT | KN_BUTTON): - break; - - case (DATA_EDIT | KN_BUTTON): - break; - - case (BUTTON_GDI | KN_BUTTON): - case (BUTTON_NOD | KN_BUTTON): - case (BUTTON_NEUTRAL | KN_BUTTON): - case (BUTTON_MULTI1 | KN_BUTTON): - case (BUTTON_MULTI2 | KN_BUTTON): - case (BUTTON_MULTI3 | KN_BUTTON): - case (BUTTON_MULTI4 | KN_BUTTON): - case (BUTTON_MULTI5 | KN_BUTTON): - case (BUTTON_MULTI6 | KN_BUTTON): - house = (HousesType)( (input & (~KN_BUTTON)) - BUTTON_GDI); - Set_House_Buttons(house, commands, BUTTON_GDI); - break; - - case (BUTTON_TEAM | KN_BUTTON): - Handle_Teams("Select a Team"); - if (CurTeam) { - CurTrigger->Team = CurTeam; - } - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - display = REDRAW_ALL; - break; - - case (BUTTON_VOLATILE | KN_BUTTON): - persistant = TriggerClass::VOLATILE; - volatilebtn.Turn_On(); - persistbtn.Turn_Off(); - semipersistbtn.Turn_Off(); - break; - - case (BUTTON_PERSIST | KN_BUTTON): - persistant = TriggerClass::PERSISTANT; - volatilebtn.Turn_Off(); - persistbtn.Turn_On(); - semipersistbtn.Turn_Off(); - break; - - case (BUTTON_SEMIPERSIST | KN_BUTTON): - persistant = TriggerClass::SEMIPERSISTANT; - volatilebtn.Turn_Off(); - persistbtn.Turn_Off(); - semipersistbtn.Turn_On(); - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - default: - break; - } - } - - /* - ------------------------------ Save values ------------------------------- - */ - if (!cancel) { - - /* - .......................... Get list indices ........................... - */ - event_idx = EventType(eventlist.Current_Index()); - action_idx = TriggerClass::ActionType(actionlist.Current_Index()); - - /* - ......................... Set Event & Action .......................... - */ - CurTrigger->Event = EventType(event_idx); - CurTrigger->Action = TriggerClass::ActionType(action_idx); - - /* - .............................. Set name ............................... - */ - if (strlen(namebuf)==0) { - CurTrigger->Set_Name("____"); - } else { - CurTrigger->Set_Name(namebuf); - } - - /* - .............................. Set Data ............................... - */ - if (TriggerClass::Event_Need_Data(event_idx)) { - CurTrigger->Data = atol(databuf); - } - - /* - .............................. Set House .............................. - */ - if (TriggerClass::Event_Need_House(event_idx)) { - CurTrigger->House = house; - } else { - CurTrigger->House = HOUSE_NONE; - } - - /* - ........................... Set Persistence .......................... - */ - CurTrigger->IsPersistant = persistant; - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - if (cancel) { - return(-1); - } else { - return(0); - } -} - - -/*************************************************************************** - * MapEditClass::Import_Triggers -- lets user import triggers * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Triggers ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³x Name Event Action House ³³ ³ * - * ³ ³ Name Event Action House ÃÄ´ ³ * - * ³ ³x Name Event Action House ³ ³ ³ * - * ³ ³ Name Event Action House ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = user cancelled * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/29/1995 BRR : Created. * - *=========================================================================*/ -int MapEditClass::Import_Triggers(void) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 480, - D_DIALOG_H = 290, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_LIST_W = 452, - D_LIST_H = 208, - D_LIST_X = D_DIALOG_X + D_MARGIN, - D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_DIALOG_CX - D_OK_W - 5, - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - D_CANCEL_W = 90, - D_CANCEL_H = 18, - D_CANCEL_X = D_DIALOG_CX + 5, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - }; - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - TRIGGER_LIST=100, - BUTTON_OK, - BUTTON_CANCEL, - }; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables: - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - KeyNumType input; // user input - bool cancel = false; - static int tabs[] = - {70, 220, 370, 420}; // list box tab stops - DynamicVectorClass trignames; // list of INI trigger names - char *inibuf; // working INI buffer - CCFileClass file; // file for reading the INI file - char buf[128]; // for reading an INI entry - char *tbuffer; // Accumulation buffer of trigger IDs. - int len; // Length of data in buffer. - TriggerClass *trigger; // Working trigger pointer. - char *item; // for adding to list box - char *eventptr; - char *actionptr; - char *houseptr; - int i; - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - CheckListClass triggerlist (TRIGGER_LIST, - D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - Set_Logic_Page(SeenBuff); - - /*------------------------------------------------------------------------ - Read the MASTER.INI file - ------------------------------------------------------------------------*/ - /*........................................................................ - Read the file into the staging buffer - ........................................................................*/ - inibuf = new char [30000]; - memset(inibuf, '\0', 30000); - file.Set_Name("MASTER.INI"); - if (!file.Is_Available()) { - file.Close(); - delete [] inibuf; - return(-1); - } else { - file.Read(inibuf, 30000 - 1); - } - file.Close(); - - /*........................................................................ - Read all entry names in the Triggers section into a temp buffer - ........................................................................*/ - len = strlen(inibuf) + 2; - tbuffer = inibuf + len; - WWGetPrivateProfileString(TriggerClass::INI_Name(), NULL, NULL, tbuffer, - 30000 - len, inibuf); - - /*........................................................................ - For each entry in the INI section: - - Get the entry - - Generate a string describing the trigger - - Add that string to the list box - - Add a ptr to the INI entry name to our 'trignames' list - ........................................................................*/ - while (*tbuffer != '\0') { - WWGetPrivateProfileString(TriggerClass::INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, inibuf); - item = new char [60]; - - /* - ** Parse the INI entry - */ - eventptr = strtok(buf,","); - actionptr = strtok(NULL,","); - strtok(NULL,","); - houseptr = strtok(NULL,","); - - /* - ** Generate the descriptive string - */ - sprintf(item, " %s\t%s\t%s\t", tbuffer, eventptr, actionptr); - - /* - ** Add house name if needed - */ - if (TriggerClass::Event_Need_House(TriggerClass::Event_From_Name(eventptr))) { - HousesType house = HouseTypeClass::From_Name(houseptr); - if (house != HOUSE_NONE) { - strcat(item, HouseTypeClass::As_Reference(house).Suffix); - } else { - strcat(item, "!!!"); - } - } else { - strcat(item," "); - } - - /* - ** Add the item to the list box - */ - triggerlist.Add_Item(item); - - /* - ** Add the name to our internal name list - */ - trignames.Add(tbuffer); - - tbuffer += strlen(tbuffer)+1; - } - - /* - ............................ Create the list ............................. - */ - commands = &triggerlist; - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - - /* - ------------------------ Init tab stops for list ------------------------- - */ - triggerlist.Set_Tabs(tabs); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print("Import Triggers", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) - commands->Flag_List_To_Redraw(); - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (TRIGGER_LIST | KN_BUTTON): - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /*........................................................................ - Re-parse the INI section; if any item is checked in the list box, create - that trigger for this scenario. - ........................................................................*/ - if (!cancel) { - tbuffer = inibuf + len; - i = 0; - while (*tbuffer != '\0') { - - /* - ** If this item is checked on the list, create a new trigger - ** and fill it in. - */ - if (triggerlist.Is_Checked(i)) { - WWGetPrivateProfileString(TriggerClass::INI_Name(), tbuffer, NULL, - buf, sizeof(buf)-1, inibuf); - - trigger = new TriggerClass(); - trigger->Fill_In(tbuffer, buf); - - if (trigger->House != HOUSE_NONE) - HouseTriggers[trigger->House].Add(trigger); - } - - tbuffer += strlen(tbuffer)+1; - i++; - } - } - - - /*........................................................................ - Clean up memory - ........................................................................*/ - trignames.Clear(); - while (triggerlist.Count()) { - item = (char *)triggerlist.Get_Item(0); - triggerlist.Remove_Item(item); - delete [] item; - } - delete [] inibuf; - - if (cancel) { - return(-1); - } else { - return(0); - } -} - - -/*************************************************************************** - * MapEditClass::Import_Teams -- lets the user import teams * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Teams ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ Name House Class:Count,Class:Count ³³ ³ * - * ³ ³ Name House Class:Count,Class:Count ÃÄ´ ³ * - * ³ ³ Name House Class:Count,Class:Count ³ ³ ³ * - * ³ ³ Name House Class:Count,Class:Count ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = user cancelled * - * * - * WARNINGS: * - * Uses HIDBUFF. * - * * - * HISTORY: * - * 12/08/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Import_Teams(void) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 528, - D_DIALOG_H = 290, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_LIST_W = 500, - D_LIST_H = 208, - D_LIST_X = D_DIALOG_X + D_MARGIN, - D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_DIALOG_CX - D_OK_W - 5, - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - D_CANCEL_W = 90, - D_CANCEL_H = 18, - D_CANCEL_X = D_DIALOG_CX + 5, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - TEAMTXT_LEN = 43, // max length of a team entry - }; - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - TEAM_LIST=100, - BUTTON_OK, - BUTTON_CANCEL, - }; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables: - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - KeyNumType input; // user input - bool cancel = false; - static int tabs[] = {120, 180}; // list box tab stops - DynamicVectorClass teamnames; // list of INI team names - char *inibuf; // working INI buffer - CCFileClass file; // file for reading the INI file - char buf[128]; // for reading an INI entry - char *tbuffer; // Accumulation buffer of team IDs. - int len; // Length of data in buffer. - TeamTypeClass *team; // Working team pointer. - char *item; // for adding to list box - char *houseptr; - char *classptr; - int numclasses; - int i; - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - CheckListClass teamlist (TEAM_LIST, - D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - Set_Logic_Page(SeenBuff); - - /*------------------------------------------------------------------------ - Read the MASTER.INI file - ------------------------------------------------------------------------*/ - /*........................................................................ - Read the file into the staging buffer - ........................................................................*/ - inibuf = new char [30000]; - memset(inibuf, '\0', 30000); - file.Set_Name("MASTER.INI"); - if (!file.Is_Available()) { - file.Close(); - delete [] inibuf; - return(-1); - } else { - file.Read(inibuf, 30000 - 1); - } - - file.Close(); - /*........................................................................ - Read all entry names in the TeamTypes section into a temp buffer - ........................................................................*/ - len = strlen(inibuf) + 2; - tbuffer = inibuf + len; - WWGetPrivateProfileString(TeamTypeClass::INI_Name(), NULL, NULL, tbuffer, - 30000 - len, inibuf); - - /*........................................................................ - For each entry in the INI section: - - Get the entry - - Generate a string describing the team - - Add that string to the list box - - Add a ptr to the INI entry name to our 'teamnames' list - ........................................................................*/ - while (*tbuffer != '\0') { - WWGetPrivateProfileString(TeamTypeClass::INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, inibuf); - item = new char [60]; - - /* - ** Parse the INI entry - */ - houseptr = strtok(buf,","); - for (i = 0; i < 9; i++) { - strtok(NULL,","); - } - numclasses = atoi(strtok(NULL,",")); - - /* - ** Generate the descriptive string - */ - sprintf(item," %s\t",tbuffer); - HousesType house = HouseTypeClass::From_Name(houseptr); - if (house != HOUSE_NONE) { - strcat(item, HouseTypeClass::As_Reference(house).Suffix); - } else { - strcat(item, "!!!"); - } - strcat(item, "\t"); - - classptr = strtok(NULL,","); - for (i = 0; i < numclasses; i++) { - if (strlen(item) + strlen(classptr) < 60) { - strcat(item,classptr); - classptr = strtok(NULL,","); - } else { - break; - } - } - - /* - ** Add the item to the list box - */ - teamlist.Add_Item(item); - /* - ** Add the name to our internal name list - */ - teamnames.Add(tbuffer); - - tbuffer += strlen(tbuffer)+1; - } - - /* - ............................ Create the list ............................. - */ - commands = &teamlist; - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - - /* - ------------------------ Init tab stops for list ------------------------- - */ - teamlist.Set_Tabs(tabs); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print("Import Teams", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) - commands->Flag_List_To_Redraw(); - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (TEAM_LIST | KN_BUTTON): - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /*........................................................................ - Re-parse the INI section; if any item is checked in the list box, create - that team for this scenario. - ........................................................................*/ - if (!cancel) { - tbuffer = inibuf + len; - i = 0; - while (*tbuffer != '\0') { - /* - ** If this item is checked on the list, create a new team - ** and fill it in. - */ - if (teamlist.Is_Checked(i)) { - WWGetPrivateProfileString(TeamTypeClass::INI_Name(), tbuffer, NULL, - buf, sizeof(buf)-1, inibuf); - - team = new TeamTypeClass(); - team->Fill_In(tbuffer,buf); - } - - tbuffer += strlen(tbuffer)+1; - i++; - } - } - - /*........................................................................ - Clean up memory - ........................................................................*/ - teamnames.Clear(); - while (teamlist.Count()) { - item = (char *)teamlist.Get_Item(0); - teamlist.Remove_Item(item); - delete [] item; - } - delete [] inibuf; - - if (cancel) { - return(-1); - } else { - return(0); - } -} - -#endif diff --git a/code/TIBERIANDAWN/MAPEDIT.CPP b/code/TIBERIANDAWN/MAPEDIT.CPP deleted file mode 100644 index 265187a..0000000 --- a/code/TIBERIANDAWN/MAPEDIT.CPP +++ /dev/null @@ -1,1923 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapedit.cpv 2.18 16 Oct 1995 16:48:40 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPEDIT.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : October 20, 1994 * - * * - * Last Update : February 2, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * Map Editor overloaded routines & utility routines * - *-------------------------------------------------------------------------* - * Map Editor modules: * - * (Yes, they're all one huge class.) * - * mapedit.cpp: overloaded routines, utility routines * - * mapeddlg.cpp: map editor dialogs, most of the main menu options * - * mapedplc.cpp: object-placing routines * - * mapedsel.cpp: object-selection & manipulation routines * - * mapedtm.cpp: team-editing routines * - *-------------------------------------------------------------------------* - * Functions: * - * MapEditClass::MapEditClass -- class constructor * - * MapEditClass::One_Time -- one-time initialization * - * MapEditClass::Read_INI -- overloaded Read_INI function * - * MapEditClass::Clear_List -- clears the internal choosable object list * - * MapEditClass::Add_To_List -- adds a TypeClass to the choosable list * - * MapEditClass::AI -- The map editor's main logic * - * MapEditClass::Draw_It -- overloaded Redraw routine * - * MapEditClass::Main_Menu -- main menu processor for map editor * - * MapEditClass::AI_Menu -- menu of AI options * - * MapEditClass::Mouse_Moved -- checks for mouse motion * - * MapEditClass::Verify_House -- sees if given house can own given obj * - * MapEditClass::Cycle_House -- finds next valid house for object type * - * MapEditClass::Trigger_Needs_Team -- tells if a trigger needs a team * - * MapEditClass::Fatal -- exits with error message * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef SCENARIO_EDITOR - -/* -****************************** Globals/Externs ****************************** -*/ -/*........................................................................... -Array of all missions supported by the map editor -...........................................................................*/ -MissionType MapEditClass::MapEditMissions[] = { - MISSION_GUARD, - MISSION_STICKY, - MISSION_HARVEST, - MISSION_GUARD_AREA, - MISSION_RETURN, - MISSION_AMBUSH, - MISSION_HUNT, - MISSION_SLEEP, -}; -#define NUM_EDIT_MISSIONS (sizeof(MapEditClass::MapEditMissions) / sizeof(MapEditClass::MapEditMissions[0])) - - -/*........................................................................... -For menu processing -...........................................................................*/ -extern int UnknownKey; // in menus.cpp - -char MapEditClass::HealthBuf[20]; - - -/*************************************************************************** - * MapEditClass::MapEditClass -- class constructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/20/1994 BR : Created. * - *=========================================================================*/ -MapEditClass::MapEditClass(void) -{ - /* - ** Init data members. - */ - ScenVar = SCEN_VAR_A; - ObjCount = 0; - LastChoice = 0; - LastHouse = HOUSE_GOOD; - GrabbedObject = 0; - for (int i=0; i < NUM_EDIT_CLASSES; i++) { - NumType[i] = 0; - TypeOffset[i] = 0; - } - Waypoint[WAYPT_HOME] = 0; - CurrentCell = 0; - CurTrigger = NULL; - Changed = 0; - LMouseDown = 0; - BaseBuilding = 0; - BasePercent = 100; -} - - -/*************************************************************************** - * MapEditClass::One_Time -- one-time initialization * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/02/1995 BR : Created. * - *=========================================================================*/ -void MapEditClass::One_Time(void) -{ - MouseClass::One_Time(); - - /*------------------------------------------------------------------------ - Create the pop-up controls - ------------------------------------------------------------------------*/ - /*........................................................................ - The map: a single large "button" - ........................................................................*/ - //MapArea = new ControlClass(MAP_AREA,0,8,312,192, GadgetClass::LEFTPRESS | - //GadgetClass::LEFTRELEASE, false); - MapArea = new ControlClass(MAP_AREA,0,16,624,384, GadgetClass::LEFTPRESS | - GadgetClass::LEFTRELEASE, false); - - /*........................................................................ - House buttons - ........................................................................*/ - GDIButton = new TextButtonClass (POPUP_GDI, "GDI", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_GDI_X, POPUP_GDI_Y, POPUP_GDI_W, POPUP_GDI_H); - - NODButton = new TextButtonClass (POPUP_NOD, "NOD", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_NOD_X, POPUP_NOD_Y, POPUP_NOD_W, POPUP_NOD_H); - - NeutralButton = new TextButtonClass (POPUP_NEUTRAL, "Neutral", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_NEUTRAL_X, POPUP_NEUTRAL_Y, POPUP_NEUTRAL_W, POPUP_NEUTRAL_H); - - Multi1Button = new TextButtonClass (POPUP_MULTI1, "M1", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_MULTI1_X, POPUP_MULTI1_Y, POPUP_MULTI1_W, POPUP_MULTI1_H); - - Multi2Button = new TextButtonClass (POPUP_MULTI2, "M2", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_MULTI2_X, POPUP_MULTI2_Y, POPUP_MULTI2_W, POPUP_MULTI2_H); - - Multi3Button = new TextButtonClass (POPUP_MULTI3, "M3", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_MULTI3_X, POPUP_MULTI3_Y, POPUP_MULTI3_W, POPUP_MULTI3_H); - - Multi4Button = new TextButtonClass (POPUP_MULTI4, "M4", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - POPUP_MULTI4_X, POPUP_MULTI4_Y, POPUP_MULTI4_W, POPUP_MULTI4_H); - - /*........................................................................ - The mission list box - ........................................................................*/ - MissionList = new ListClass (POPUP_MISSIONLIST, - POPUP_MISSION_X, POPUP_MISSION_Y, POPUP_MISSION_W, POPUP_MISSION_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - for (int i = 0; i < NUM_EDIT_MISSIONS; i++) { - MissionList->Add_Item (MissionClass::Mission_Name(MapEditMissions[i])); - } - - /*........................................................................ - The health bar - ........................................................................*/ - HealthGauge = new TriColorGaugeClass (POPUP_HEALTHGAUGE, - POPUP_HEALTH_X, POPUP_HEALTH_Y, POPUP_HEALTH_W, POPUP_HEALTH_H); - HealthGauge->Use_Thumb(true); - HealthGauge->Set_Maximum(0x100); - HealthGauge->Set_Red_Limit(0x3f - 1); - HealthGauge->Set_Yellow_Limit(0x7f - 1); - - /*........................................................................ - The health text label - ........................................................................*/ - HealthBuf[0] = 0; - HealthText = new TextLabelClass (HealthBuf, - POPUP_HEALTH_X + POPUP_HEALTH_W / 2, - POPUP_HEALTH_Y + POPUP_HEALTH_H + 1, - CC_GREEN, TPF_CENTER | TPF_FULLSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - - /*........................................................................ - The facing dial - ........................................................................*/ - FacingDial = new Dial8Class (POPUP_FACINGDIAL, POPUP_FACEBOX_X, - POPUP_FACEBOX_Y, POPUP_FACEBOX_W, POPUP_FACEBOX_H, (DirType)0); - - /*........................................................................ - The base percent-built slider & its label - ........................................................................*/ - BaseGauge = new GaugeClass (POPUP_BASEPERCENT, - POPUP_BASE_X, POPUP_BASE_Y, POPUP_BASE_W, POPUP_BASE_H); - BaseLabel = new TextLabelClass ("Base:", POPUP_BASE_X - 3, POPUP_BASE_Y, - CC_GREEN, TPF_RIGHT | TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - BaseGauge->Set_Maximum(100); - BaseGauge->Set_Value(BasePercent); -} - - -/*********************************************************************************************** - * MapeditClass::Init_IO -- Reinitializes the radar map at scenario start. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -void MapEditClass::Init_IO(void) -{ - /*------------------------------------------------------------------------ - For normal game mode, jump to the parent's Init routine. - ------------------------------------------------------------------------*/ - if (!Debug_Map) { - - MouseClass::Init_IO(); - - } else { - - /*------------------------------------------------------------------------ - For editor mode, add the map area to the button input list - ------------------------------------------------------------------------*/ - Buttons = 0; - Add_A_Button(*BaseGauge); - Add_A_Button(*BaseLabel); - Add_A_Button(*MapArea); - } -} - - -/*************************************************************************** - * MapEditClass::Read_INI -- overloaded Read_INI function * - * * - * Overloading this function gives the map editor a chance to initialize * - * certain values every time a new INI is read. * - * * - * INPUT: * - * buffer INI staging area * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/16/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Read_INI(char *buffer) -{ - /* - ------------------------ Invoke parent's Read_INI ------------------------ - */ - MouseClass::Read_INI(buffer); - - BasePercent = WWGetPrivateProfileInt("Basic","Percent",0,buffer); - BaseGauge->Set_Value(BasePercent); -} - - -/*************************************************************************** - * MapEditClass::Write_INI -- overloaded Read_INI function * - * * - * INPUT: * - * buffer INI staging area * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/16/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Write_INI(char *buffer) -{ - /* - ----------------------- Invoke parent's Write_INI ------------------------ - */ - MouseClass::Write_INI(buffer); - - /* - ** Save the base's percent-built value; this must be saved into the BASIC - ** section of the INI, since the Base section will be entirely erased - ** by the Base's Write_INI routine. - */ - WWWritePrivateProfileInt("Basic", "Percent", BasePercent, buffer); -} - - -/*************************************************************************** - * MapEditClass::Clear_List -- clears the internal choosable object list * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/20/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Clear_List(void) -{ - /*------------------------------------------------------------------------ - Set # object type ptrs to 0, set NumType for each type to 0 - ------------------------------------------------------------------------*/ - ObjCount = 0; - for (int i = 0; i < NUM_EDIT_CLASSES; i++) { - NumType[i] = 0; - } -} - - -/*************************************************************************** - * MapEditClass::Add_To_List -- adds a TypeClass to the choosable list * - * * - * Use this routine to add an object to the game object selection list. * - * This list is used by the Add_Object function. All items located in the * - * list will appear and be chooseable by that function. Make sure to * - * clear the list before adding a sequence of items to it. Clearing * - * the list is accomplished by the Clear_List() function. * - * * - * INPUT: * - * object ptr to ObjectTypeClass to add * - * * - * OUTPUT: * - * bool: was the object added to the list? A failure could occur if * - * NULL were passed in or the list is full. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/04/1994 JLB : Created. * - *=========================================================================*/ -bool MapEditClass::Add_To_List(ObjectTypeClass const *object) -{ - /* - ** Add the object if there's room. - */ - if (object && ObjCount < MAX_EDIT_OBJECTS) { - Objects[ObjCount++] = object; - - /* - ** Update type counters. - */ - switch (object->What_Am_I()) { - case RTTI_TEMPLATETYPE: - NumType[0]++; - break; - - case RTTI_OVERLAYTYPE: - NumType[1]++; - break; - - case RTTI_SMUDGETYPE: - NumType[2]++; - break; - - case RTTI_TERRAINTYPE: - NumType[3]++; - break; - - case RTTI_UNITTYPE: - NumType[4]++; - break; - - case RTTI_INFANTRYTYPE: - NumType[5]++; - break; - - case RTTI_AIRCRAFTTYPE: - NumType[6]++; - break; - - case RTTI_BUILDINGTYPE: - NumType[7]++; - break; - } - return(true); - } - - return(false); -} - - -/*************************************************************************** - * MapEditClass::AI -- The map editor's main logic * - * * - * This routine overloads the parent's (DisplayClass) AI function. * - * It checks for any input specific to map editing, and calls the parent * - * AI routine to handle scrolling and other mainstream map stuff. * - * * - * If this detects one of its special input keys, it sets 'input' to 0 * - * before calling the parent AI routine; this prevents input conflict. * - * * - * SUPPORTED INPUT: * - * General: * - * F2/RMOUSE: main menu * - * F6: toggles show-passable mode * - * HOME: go to the Home Cell (scenario's start position)* - * SHIFT-HOME: set the Home Cell to the current TacticalCell* - * ESC: exits to DOS * - * Object Placement: * - * INSERT: go into placement mode * - * ESC: exit placement mode * - * LEFT/RIGHT: prev/next placement object * - * PGUP/PGDN: prev/next placement category * - * HOME: 1st placement object (clear template) * - * h/H: toggle house of placement object * - * LMOUSE: place the placement object * - * MOUSE MOTION: "paint" with the placement object * - * Object selection: * - * LMOUSE: select & "grab" current object * - * If no object is present where the mouse is * - * clicked, the current object is de-selected * - * If the same object is clicked on, it stays * - * selected. Also displays the object-editing * - * gadgets. * - * LMOUSE RLSE: release currently-grabbed object * - * MOUSE MOTION: if an object is grabbed, moves the object * - * SHIFT|ALT|ARROW: moves object in that direction * - * DELETE deletes currently-selected object * - * Object-editing controls: * - * POPUP_GDI: makes GDI the owner of this object * - * POPUP_NOD: makes NOD the owner of this object * - * POPUP_MISSIONLIST: sets that mission for this object * - * POPUP_HEALTHGAUGE: sets that health value for this object * - * POPUP_FACINGDIAL: sets the object's facing * - * * - * Changed is set when you: * - * - place an object * - * - move a grabbed object * - * - delete an object * - * - size the map * - * - create a new scenario * - * Changed is cleared when you: * - * - Save the scenario * - * - Load a scenario * - * - Play the scenario * - * * - * INPUT: * - * input KN_ value, 0 if none * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/20/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::AI(KeyNumType &input, int x, int y) -{ - int rc; - MissionType mission; - int strength; - CELL cell; - int i; - int found; // for removing a waypoint label - int waypt_idx; // for labelling a waypoint - BaseNodeClass *node; // for removing from an AI Base - HousesType house; - - /*------------------------------------------------------------------------ - Trap 'F2' regardless of whether we're in game or editor mode - ------------------------------------------------------------------------*/ - if (Debug_Flag) { - if (/*(input == KN_F2 && Session == GAME_SOLO) ||*/ input == (KN_F2 | KN_CTRL_BIT)) { - ScenarioInit = 0; - - /* - ** If we're in editor mode & Changed is set, prompt for saving changes - */ - if (Debug_Map && Changed) { - rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - /* - ........................ User wants to save ........................ - */ - if (rc == 0) { - - /* - ................ If save cancelled, abort game .................. - */ - if (Save_Scenario()!=0) { - input = KN_NONE; - } else { - Changed = 0; - Go_Editor(!Debug_Map); - } - } else { - - /* - .................... User doesn't want to save ..................... - */ - Go_Editor(!Debug_Map); - } - } else { - /* - ** If we're in game mode, set Changed to 0 (so if we didn't save our - ** changes above, they won't keep coming back to haunt us with continual - ** Save Changes? prompts!) - */ - if (!Debug_Map) { - Changed = 0; - } - Go_Editor(!Debug_Map); - } - } - } - - /*------------------------------------------------------------------------ - For normal game mode, jump to the parent's AI routine. - ------------------------------------------------------------------------*/ - if (!Debug_Map) { - MouseClass::AI(input, x, y); - return; - } - - ::Frame++; - - /*------------------------------------------------------------------------ - Do special mouse processing if the mouse is over the map - ------------------------------------------------------------------------*/ - if (Get_Mouse_X() > TacPixelX && Get_Mouse_X() < - TacPixelX + Lepton_To_Pixel(TacLeptonWidth) && - Get_Mouse_Y() > TacPixelY && Get_Mouse_Y() < - TacPixelY + Lepton_To_Pixel(TacLeptonHeight)) { - /*..................................................................... - When the mouse moves over a scrolling edge, ScrollClass changes its - shape to the appropriate arrow or NO symbol; it's our job to change it - back to normal (or whatever the shape is set to by Set_Default_Mouse()) - when it re-enters the map area. - .....................................................................*/ - if (CurTrigger) { - Override_Mouse_Shape(MOUSE_CAN_MOVE); - } else { - Override_Mouse_Shape(MOUSE_NORMAL); - } - } - - /*..................................................................... - Set 'ZoneCell' to track the mouse cursor around over the map. Do this - even if the map is scrolling. - .....................................................................*/ - if (Get_Mouse_X() >= TacPixelX && Get_Mouse_X() <= - TacPixelX + Lepton_To_Pixel(TacLeptonWidth) && - Get_Mouse_Y() >= TacPixelY && Get_Mouse_Y() <= - TacPixelY + Lepton_To_Pixel(TacLeptonHeight)) { - - cell = Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y()); - if (cell != -1) { - Set_Cursor_Pos(cell); - if (PendingObject) { - Flag_To_Redraw(true); - } - } - } - - /*------------------------------------------------------------------------ - Check for mouse motion while left button is down. - ------------------------------------------------------------------------*/ - rc = Mouse_Moved(); - if (LMouseDown && rc) { - /*..................................................................... - "Paint" mode: place current object, and restart placement - .....................................................................*/ - if (PendingObject) { - Flag_To_Redraw(true); - if (Place_Object() == 0) { - Changed = 1; - Start_Placement(); - } - } else { - /*..................................................................... - Move the currently-grabbed object - .....................................................................*/ - if (GrabbedObject) { - GrabbedObject->Mark(MARK_CHANGE); - if (Move_Grabbed_Object() == 0) { - Changed = 1; - } - } - } - } - - /*------------------------------------------------------------------------ - Trap special editing keys; if one is detected, set 'input' to 0 to - prevent a conflict with parent's AI(). - ------------------------------------------------------------------------*/ - switch (input) { - /*--------------------------------------------------------------------- - F2/RMOUSE = pop up main menu - ---------------------------------------------------------------------*/ - case KN_RMOUSE: - /* - ..................... Turn off placement mode ...................... - */ - if (PendingObject) { - if (BaseBuilding) { - Cancel_Base_Building(); - } else { - Cancel_Placement(); - } - } - - /* - ................. Turn off trigger placement mode .................. - */ - if (CurTrigger) { - Stop_Trigger_Placement(); - } - - /* - .............. Unselect object & hide popup controls ............... - */ - if (CurrentObject.Count()) { - CurrentObject[0]->Unselect(); - Popup_Controls(); - } - Main_Menu(); - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - F6 = toggle passable/impassable display - ---------------------------------------------------------------------*/ - case KN_F6: - Debug_Passable = (Debug_Passable == false); - HiddenPage.Clear(); - Flag_To_Redraw(true); - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - INSERT = go into object-placement mode - ---------------------------------------------------------------------*/ - case KN_INSERT: - if (!PendingObject) { - /* - ......... Unselect current object, hide popup controls .......... - */ - if (CurrentObject.Count()) { - CurrentObject[0]->Unselect(); - Popup_Controls(); - } - /* - .................... Go into placement mode ..................... - */ - Start_Placement(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - ESC = exit placement mode, or exit to DOS - ---------------------------------------------------------------------*/ - case KN_ESC: - - /* - .................... Exit object placement mode .................... - */ - if (PendingObject) { - if (BaseBuilding) { - Cancel_Base_Building(); - } else { - Cancel_Placement(); - } - input = KN_NONE; - break; - } else { - - /* - ................... Exit trigger placement mode .................... - */ - if (CurTrigger) { - Stop_Trigger_Placement(); - input = KN_NONE; - break; - } else { - rc = CCMessageBox().Process("Exit Scenario Editor?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /* - .......... User doesn't want to exit; return to editor .......... - */ - if (rc==1) { - input = KN_NONE; - break; - } - - /* - ................. If changed, prompt for saving ................. - */ - if (Changed) { - rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /* - ..................... User wants to save ..................... - */ - if (rc == 0) { - - /* - .............. If save cancelled, abort exit .............. - */ - if (Save_Scenario()!=0) { - input = KN_NONE; - break; - } else { - Changed = 0; - } - } - } - } - } - Prog_End(); - exit (0); - break; - - /*--------------------------------------------------------------------- - LEFT = go to previous placement object - ---------------------------------------------------------------------*/ - case KN_LEFT: - if (PendingObject) { - Place_Prev(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - RIGHT = go to next placement object - ---------------------------------------------------------------------*/ - case KN_RIGHT: - if (PendingObject) { - Place_Next(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - PGUP = go to previous placement category - ---------------------------------------------------------------------*/ - case KN_PGUP: - if (PendingObject) { - Place_Prev_Category(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - PGDN = go to next placement category - ---------------------------------------------------------------------*/ - case KN_PGDN: - if (PendingObject) { - Place_Next_Category(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - HOME = jump to first placement object, or go to Home Cell - ---------------------------------------------------------------------*/ - case KN_HOME: - if (PendingObject) { - Place_Home(); - } else { - - /* - ....................... Set map position ........................ - */ - ScenarioInit++; - Set_Tactical_Position(Waypoint[WAYPT_HOME]); - ScenarioInit--; - - /* - ...................... Force map to redraw ...................... - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - SHIFT-HOME: set new Home Cell position - ---------------------------------------------------------------------*/ - case ((int)KN_HOME | (int)KN_SHIFT_BIT): - /* - ** Unflag the old Home Cell, if there are no other waypoints - ** pointing to it - */ - cell = Waypoint[WAYPT_HOME]; - - if (cell != -1) { - found = 0; - for (i = 0; i < WAYPT_COUNT; i++) { - if (i != WAYPT_HOME && Waypoint[i]==cell) { - found = 1; - } - } - - if (found==0) { - (*this)[cell].IsWaypoint = 0; - Flag_Cell(cell); - } - - } - - /* - ** Now set the new Home cell - */ - Waypoint[WAYPT_HOME] = Coord_Cell(TacticalCoord); - (*this)[Coord_Cell(TacticalCoord)].IsWaypoint = 1; - Flag_Cell(Coord_Cell(TacticalCoord)); - Changed = 1; - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - SHIFT-R: set new Reinforcement Cell position. Don't allow setting - the Reinf. Cell to the same as the Home Cell (for display purposes.) - ---------------------------------------------------------------------*/ - case ((int)KN_R | (int)KN_SHIFT_BIT): - if (CurrentCell==0 || CurrentCell==Waypoint[WAYPT_HOME]) { - break; - } - - /* - ** Unflag the old Reinforcement Cell, if there are no other waypoints - ** pointing to it - */ - cell = Waypoint[WAYPT_REINF]; - - if (cell != -1) { - found = 0; - for (i = 0; i < WAYPT_COUNT; i++) { - if (i != WAYPT_REINF && Waypoint[i]==cell) { - found = 1; - } - } - - if (found==0) { - (*this)[cell].IsWaypoint = 0; - Flag_Cell(cell); - } - - } - /* - ** Now set the new Reinforcement cell - */ - Waypoint[WAYPT_REINF] = CurrentCell; - (*this)[CurrentCell].IsWaypoint = 1; - Flag_Cell(CurrentCell); - Changed = 1; - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - ALT-Letter: Label a waypoint cell - ---------------------------------------------------------------------*/ - case ((int)KN_A | (int)KN_ALT_BIT): - case ((int)KN_B | (int)KN_ALT_BIT): - case ((int)KN_C | (int)KN_ALT_BIT): - case ((int)KN_D | (int)KN_ALT_BIT): - case ((int)KN_E | (int)KN_ALT_BIT): - case ((int)KN_F | (int)KN_ALT_BIT): - case ((int)KN_G | (int)KN_ALT_BIT): - case ((int)KN_H | (int)KN_ALT_BIT): - case ((int)KN_I | (int)KN_ALT_BIT): - case ((int)KN_J | (int)KN_ALT_BIT): - case ((int)KN_K | (int)KN_ALT_BIT): - case ((int)KN_L | (int)KN_ALT_BIT): - case ((int)KN_M | (int)KN_ALT_BIT): - case ((int)KN_N | (int)KN_ALT_BIT): - case ((int)KN_O | (int)KN_ALT_BIT): - case ((int)KN_P | (int)KN_ALT_BIT): - case ((int)KN_Q | (int)KN_ALT_BIT): - case ((int)KN_R | (int)KN_ALT_BIT): - case ((int)KN_S | (int)KN_ALT_BIT): - case ((int)KN_T | (int)KN_ALT_BIT): - case ((int)KN_U | (int)KN_ALT_BIT): - case ((int)KN_V | (int)KN_ALT_BIT): - case ((int)KN_W | (int)KN_ALT_BIT): - case ((int)KN_X | (int)KN_ALT_BIT): - case ((int)KN_Y | (int)KN_ALT_BIT): - case ((int)KN_Z | (int)KN_ALT_BIT): - if (CurrentCell != 0) { - waypt_idx = KN_To_KA(input & 0xff) - KA_a; - /*............................................................... - Unflag cell for this waypoint if there is one - ...............................................................*/ - cell = Waypoint[waypt_idx]; - if (cell != -1) { - if (Waypoint[WAYPT_HOME] != cell && - Waypoint[WAYPT_REINF] != cell) - (*this)[cell].IsWaypoint = 0; - Flag_Cell(cell); - } - Waypoint[waypt_idx] = CurrentCell; - (*this)[CurrentCell].IsWaypoint = 1; - Changed = 1; - Flag_Cell(CurrentCell); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - ALT-1-4: Designate a cell as a capture-the-flag cell. - ---------------------------------------------------------------------*/ - case ((int)KN_1 | (int)KN_ALT_BIT): - case ((int)KN_2 | (int)KN_ALT_BIT): - case ((int)KN_3 | (int)KN_ALT_BIT): - case ((int)KN_4 | (int)KN_ALT_BIT): - /*------------------------------------------------------------------ - If there's a current cell, place the flag & waypoint there. - ------------------------------------------------------------------*/ - if (CurrentCell != 0) { - waypt_idx = (KN_To_KA(input & 0xff) - KA_1); - house = (HousesType)(HOUSE_MULTI1 + waypt_idx); - if (HouseClass::As_Pointer(house)) { - HouseClass::As_Pointer(house)->Flag_Attach(CurrentCell,true); - } - } else { - /*------------------------------------------------------------------ - If there's a current object, attach the flag to it and clear the - waypoint. - ------------------------------------------------------------------*/ - if (CurrentObject[0] != 0) { - waypt_idx = (KN_To_KA(input & 0xff) - KA_1); - house = (HousesType)(HOUSE_MULTI1 + waypt_idx); - if (HouseClass::As_Pointer(house) && CurrentObject[0]->What_Am_I() == RTTI_UNIT) { - HouseClass::As_Pointer(house)->Flag_Attach((UnitClass *)CurrentObject[0], true); - } - } - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - ALT-Space: Remove a waypoint designation - ---------------------------------------------------------------------*/ - case ((int)KN_SPACE | (int)KN_ALT_BIT): - if (CurrentCell != 0) { - /*............................................................... - Loop through letter waypoints; if this cell is one of them, - clear that waypoint. - ...............................................................*/ - for (i = 0 ; i < 26; i++) { - if (Waypoint[i]==CurrentCell) - Waypoint[i] = -1; - } - - /*............................................................... - Loop through flag home values; if this cell is one of them, clear - that waypoint. - ...............................................................*/ - for (i = 0; i < MAX_PLAYERS; i++) { - house = (HousesType)(HOUSE_MULTI1 + i); - if (HouseClass::As_Pointer(house) && - CurrentCell == HouseClass::As_Pointer(house)->FlagHome) - HouseClass::As_Pointer(house)->Flag_Remove(As_Target(CurrentCell),true); - } - - /*............................................................... - If there are no more waypoints on this cell, clear the cell's - waypoint designation. - ...............................................................*/ - if (Waypoint[WAYPT_HOME]!=CurrentCell && - Waypoint[WAYPT_REINF]!=CurrentCell) - (*this)[CurrentCell].IsWaypoint = 0; - Changed = 1; - Flag_Cell(CurrentCell); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - 'H' = toggle current placement object's house - ---------------------------------------------------------------------*/ - case KN_H: - case ((int)KN_H | (int)KN_SHIFT_BIT): - if (PendingObject) { - Toggle_House(); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - Left-mouse click: - Button DOWN: - - Toggle LMouseDown - - If we're in placement mode, try to place the current object - - If success, re-enter placement mode - - Otherwise, try to select an object, and "grab" it if there is one - - If no object, then select that cell as the "current" cell - Button UP: - - Toggle LMouseDown - - release any grabbed object - ---------------------------------------------------------------------*/ - case ((int)MAP_AREA | (int)KN_BUTTON): - /* - ------------------------- Left Button DOWN ------------------------- - */ - if (Keyboard::Down(KN_LMOUSE)) { - LMouseDown = 1; - /* - ............... Placement mode: place an object ................. - */ - if (PendingObject) { - if (Place_Object()==0) { - Changed = 1; - Start_Placement(); - } - } else { - /* - ....................... Place a trigger ......................... - */ - if (CurTrigger) { - Place_Trigger(); - Changed = 1; - } else { - /* - ................. Select an object or a cell ................. - .................. Check for double-click .................... - */ - if (CurrentObject.Count() && - ( (TickCount.Time() - LastClickTime) < 15)) { - ; // stub - - } else { - /* - ................ Single-click: select object ................. - */ - if (Select_Object()==0) { - CurrentCell = 0; - Grab_Object(); - } else { - /* - ................ No object: select the cell .................. - */ - CurrentCell = Click_Cell_Calc(_Kbd->MouseQX,_Kbd->MouseQY); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - } - } - } - } - LastClickTime = TickCount.Time(); - input = KN_NONE; - } else { - - /* - -------------------------- Left Button UP -------------------------- - */ - LMouseDown = 0; - GrabbedObject = 0; - input = KN_NONE; - } - break; - - /*--------------------------------------------------------------------- - SHIFT-ALT-Arrow: move the current object - ---------------------------------------------------------------------*/ - case (int)KN_UP | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT: - case (int)KN_DOWN | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT: - case (int)KN_LEFT | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT: - case (int)KN_RIGHT | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT: - if (CurrentObject.Count()) { - CurrentObject[0]->Move(KN_To_Facing(input)); - Changed = 1; - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - DELETE: delete currently-selected object - ---------------------------------------------------------------------*/ - case KN_DELETE: - /*.................................................................. - Delete currently-selected object's trigger, or the object - ..................................................................*/ - if (CurrentObject.Count()) { - - /* - ........................ Delete trigger ......................... - */ - if (CurrentObject[0]->Trigger) { - CurrentObject[0]->Trigger = NULL; - } else { - /* - ** If the current object is part of the AI's Base, remove it - ** from the Base's Node list. - */ - if (CurrentObject[0]->What_Am_I()==RTTI_BUILDING && - Base.Is_Node((BuildingClass *)CurrentObject[0])) { - node = Base.Get_Node((BuildingClass *)CurrentObject[0]); - Base.Nodes.Delete(*node); - } - - /* - ................... Delete current object .................... - */ - delete CurrentObject[0]; - - /* - .................. Hide the popup controls ................... - */ - Popup_Controls(); - } - - /* - ........................ Force a redraw ......................... - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Changed = 1; - } else { - /* - ................. Remove trigger from current cell ................. - */ - if (CurrentCell) { - if ((*this)[CurrentCell].IsTrigger) { - (*this)[CurrentCell].IsTrigger = 0; - CellTriggers[CurrentCell] = NULL; - /* - ...................... Force a redraw ........................ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Changed = 1; - } - } - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - TAB: select next object on the map - ---------------------------------------------------------------------*/ - case KN_TAB: - Select_Next(); - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - Object-Editing button: House Button - ---------------------------------------------------------------------*/ - case (POPUP_GDI | KN_BUTTON): - case (POPUP_NOD | KN_BUTTON): - case (POPUP_NEUTRAL | KN_BUTTON): - case (POPUP_MULTI1 | KN_BUTTON): - case (POPUP_MULTI2 | KN_BUTTON): - case (POPUP_MULTI3 | KN_BUTTON): - case (POPUP_MULTI4 | KN_BUTTON): - /*.................................................................. - Convert input value into a house value; assume HOUSE_GOOD is 0 - ..................................................................*/ - house = (HousesType)( (input & (~KN_BUTTON)) - POPUP_GDI); - /*.................................................................. - If that house doesn't own this object, try to transfer it - ..................................................................*/ - if (CurrentObject[0]->Owner()!=house) { - if (Change_House(house)) { - Changed = 1; - } - } - Set_House_Buttons(CurrentObject[0]->Owner(), Buttons, POPUP_GDI); - HiddenPage.Clear(); - Flag_To_Redraw(true); - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - Object-Editing button: Mission - ---------------------------------------------------------------------*/ - case (POPUP_MISSIONLIST | KN_BUTTON): - if (CurrentObject[0]->Is_Techno()) { - /* - ........................ Set new mission ........................ - */ - mission = MapEditMissions[MissionList->Current_Index()]; - if (CurrentObject[0]->Get_Mission() != mission) { - ((TechnoClass *)CurrentObject[0])->Set_Mission(mission); - Changed = 1; - } - } - Flag_To_Redraw(true); - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - Object-Editing button: Health - ---------------------------------------------------------------------*/ - case (POPUP_HEALTHGAUGE | KN_BUTTON): - if (CurrentObject[0]->Is_Techno()) { - /* - .......... Derive strength from current gauge reading ........... - */ - strength = Fixed_To_Cardinal( - (unsigned)CurrentObject[0]->Class_Of().MaxStrength, - (unsigned)HealthGauge->Get_Value()); - - /* - ........................... Clip to 1 ........................... - */ - if (strength <= 0) { - strength = 1; - } - - /* - ....................... Set new strength ........................ - */ - if (strength != CurrentObject[0]->Strength) { - CurrentObject[0]->Strength = strength; - HiddenPage.Clear(); - Flag_To_Redraw(true); - Changed = 1; - } - - /* - ....................... Update text label ....................... - */ - sprintf(HealthBuf,"%d",strength); - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - Object-Editing button: Facing - ---------------------------------------------------------------------*/ - case (POPUP_FACINGDIAL | KN_BUTTON): - if (CurrentObject[0]->Is_Techno()) { - /* - ........................ Set new facing ......................... - */ - if (FacingDial->Get_Direction() != - ((TechnoClass *)CurrentObject[0])->PrimaryFacing.Get()) { - /* - ..................... Set body's facing ...................... - */ - ((TechnoClass *)CurrentObject[0])->PrimaryFacing.Set(FacingDial->Get_Direction()); - - /* - ............. Set turret facing, if there is one ............. - */ - if (CurrentObject[0]->What_Am_I()==RTTI_UNIT) { - ((UnitClass *)CurrentObject[0])->SecondaryFacing.Set(FacingDial->Get_Direction()); - } - - HiddenPage.Clear(); - Flag_To_Redraw(true); - Changed = 1; - } - } - input = KN_NONE; - break; - - /*--------------------------------------------------------------------- - Object-Editing button: Facing - ---------------------------------------------------------------------*/ - case (POPUP_BASEPERCENT | KN_BUTTON): - if (BaseGauge->Get_Value() != BasePercent) { - BasePercent = BaseGauge->Get_Value(); - Build_Base_To(BasePercent); - HiddenPage.Clear(); - Flag_To_Redraw(true); - } - input = KN_NONE; - break; - - case (KN_LMOUSE): - input = KN_NONE; - break; - - default: - break; - } - - /* - ------------------------ Call parent's AI routine ------------------------ - */ - MouseClass::AI(input, x, y); -} - - -/*************************************************************************** - * MapEditClass::Draw_It -- overloaded Redraw routine * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/17/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Draw_It(bool forced) -{ - char const *label; - char buf[40]; - char const *tptr; - - MouseClass::Draw_It(forced); - - if (!Debug_Map) { - return; - } - - // - // Erase scrags at top of screen - // - LogicPage->Fill_Rect(0, 0, 640, 16, BLACK); - - /* - ** Display the total value of all Tiberium on the map. - */ - Fancy_Text_Print("Tiberium=%ld ", 0, 0, CC_GREEN, BLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, TotalValue); - - /*------------------------------------------------------------------------ - If there are no object controls displayed, just invoke parent's Redraw - and return. - ------------------------------------------------------------------------*/ - if (!Buttons) { - return; - } - - /*------------------------------------------------------------------------ - Otherwise, if 'display' is set, invoke the parent's Redraw to refresh - the HIDPAGE; then, update the buttons & text labels onto HIDPAGE; - then invoke the parent's Redraw to blit the HIDPAGE to SEENPAGE. - ------------------------------------------------------------------------*/ - if (forced) { - - /* - ....................... Update the text labels ........................ - */ - if (CurrentObject.Count()) { - /* - ------------------ Display the object's name & ID ------------------ - */ - label = Text_String(CurrentObject[0]->Full_Name()); - tptr = label; - sprintf(buf,"%s (%d)",tptr,CurrentObject[0]->As_Target()); - - /* - ......................... print the label .......................... - */ - Fancy_Text_Print (buf, 320, 0, CC_TAN, TBLACK, - TPF_CENTER | TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - } - } -} - - -/*************************************************************************** - * MapEditClass::Mouse_Moved -- checks for mouse motion * - * * - * Reports whether the mouse has moved or not. This varies based on the * - * type of object currently selected. If there's an infantry object * - * selected, mouse motion counts even within a cell; for all other types,* - * mouse motion counts only if the mouse changes cells. * - * * - * The reason this routine is needed is to prevent Paint-Mode from putting* - * gobs of trees and such into the same cell if the mouse moves just * - * a little bit. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/08/1994 BR : Created. * - *=========================================================================*/ -bool MapEditClass::Mouse_Moved(void) -{ - static int old_mx = 0; - static int old_my = 0; - static CELL old_zonecell = 0; - const ObjectTypeClass * objtype = NULL; - bool retcode = false; - - /* - -------------------------- Return if no motion --------------------------- - */ - if (old_mx == Get_Mouse_X() && old_my == Get_Mouse_Y()) { - return(false); - } - - /* - ---------------------- Get a ptr to ObjectTypeClass ---------------------- - */ - if (PendingObject) { - objtype = PendingObject; - } else { - if (GrabbedObject) { - objtype = &GrabbedObject->Class_Of(); - } else { - old_mx = Get_Mouse_X(); - old_my = Get_Mouse_Y(); - old_zonecell = ZoneCell; - return(false); - } - } - - /* - --------------------- Check for motion based on type --------------------- - */ - /* - ............... Infantry: mouse moved if any motion at all ............... - */ - if (objtype->What_Am_I() == RTTI_INFANTRYTYPE) { - retcode = true; - } else { - /* - ................ Others: mouse moved only if cell changed ................ - */ - if (old_zonecell!=ZoneCell) { - retcode = true; - } else { - retcode = false; - } - } - - old_mx = Get_Mouse_X(); - old_my = Get_Mouse_Y(); - old_zonecell = ZoneCell; - return(retcode); -} - - -/*************************************************************************** - * MapEditClass::Main_Menu -- main menu processor for map editor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/20/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Main_Menu(void) -{ - char const *_menus[MAX_MAIN_MENU_NUM + 1]; - int selection; // option the user picks - bool process; // menu stays up while true - int rc; - - /* - --------------------------- Fill in menu items --------------------------- - */ - _menus[0] = "New Scenario"; - _menus[1] = "Load Scenario"; - _menus[2] = "Save Scenario"; - _menus[3] = "Size Map"; - _menus[4] = "Add Game Object"; - _menus[5] = "Scenario Options"; - _menus[6] = "AI Options"; - _menus[7] = "Play Scenario"; - _menus[8] = NULL; - - /* - ----------------------------- Main Menu loop ----------------------------- - */ - Override_Mouse_Shape(MOUSE_NORMAL); // display default mouse cursor - process = true; - while (process) { - - /* - ................ Invoke game callback, to update music ................ - */ - Call_Back(); - - /* - ............................. Invoke menu ............................. - */ - Hide_Mouse(); // Do_Menu assumes the mouse is already hidden - selection = Do_Menu(&_menus[0], true); - Show_Mouse(); - if (UnknownKey==KN_ESC || UnknownKey==KN_LMOUSE || UnknownKey==KN_RMOUSE) { - break; - } - - /* - .......................... Process selection .......................... - */ - switch (selection) { - /* - ........................... New scenario ........................... - */ - case 0: - if (Changed) { - rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - if (rc==0) { - if (Save_Scenario()!=0) { - break; - } else { - Changed = 0; - } - } - } - if (New_Scenario()==0) { - CarryOverMoney = 0; - Changed = 1; - } - process = false; - break; - - /* - .......................... Load scenario ........................... - */ - case 1: - if (Changed) { - rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - if (rc==0) { - if (Save_Scenario()!=0) { - break; - } else { - Changed = 0; - } - } - } - if (Load_Scenario()==0) { - CarryOverMoney = 0; - Changed = 0; - } - process = false; - break; - - /* - .......................... Save scenario ........................... - */ - case 2: - if (Save_Scenario() == 0) { - Changed = 0; - } - process = false; - break; - - /* - .......................... Edit map size ........................... - */ - case 3: - if (Size_Map(MapCellX, MapCellY, MapCellWidth, MapCellHeight)==0) { - process = false; - Changed = 1; - } - break; - - /* - .......................... Add an object ........................... - */ - case 4: - if (Placement_Dialog() == 0) { - Start_Placement(); - process = false; - } - break; - - /* - ......................... Scenario options ......................... - */ - case 5: - if (Scenario_Dialog() == 0) { - Changed = 1; - process = false; - } - break; - - /* - .......................... Other options ........................... - */ - case 6: - AI_Menu(); - process = false; - break; - - /* - ...................... Test-drive this scenario .................... - */ - case 7: - if (Changed) { - rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - if (rc==0) { - if (Save_Scenario()!=0) { - break; - } else { - Changed = 0; - } - } - } - Changed = 0; - Debug_Map = false; - Start_Scenario(ScenarioName); - return; - } - } - - /*------------------------------------------------------------------------ - Restore the display: - - Clear HIDPAGE to erase any spurious drawing done by the menu system - - Invoke Flag_To_Redraw to tell DisplayClass to re-render the whole screen - - Invoke Redraw() to update the display - ------------------------------------------------------------------------*/ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::AI_Menu -- menu of AI options * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::AI_Menu(void) -{ - int selection; // option the user picks - bool process; // menu stays up while true - char const *_menus[MAX_AI_MENU_NUM + 1]; - - /* - -------------------------- Fill in menu strings -------------------------- - */ - _menus[0] = "Pre-Build a Base"; - _menus[1] = "Import Triggers"; - _menus[2] = "Edit Triggers"; - _menus[3] = "Import Teams"; - _menus[4] = "Edit Teams"; - _menus[5] = NULL; - - /* - ----------------------------- Main Menu loop ----------------------------- - */ - Override_Mouse_Shape(MOUSE_NORMAL); // display default mouse cursor - process = true; - while (process) { - - /* - ................ Invoke game callback, to update music ................ - */ - Call_Back(); - - /* - ............................. Invoke menu ............................. - */ - Hide_Mouse(); // Do_Menu assumes the mouse is already hidden - selection = Do_Menu(&_menus[0], true); - Show_Mouse(); - if (UnknownKey==KN_ESC || UnknownKey==KN_LMOUSE || UnknownKey==KN_RMOUSE) { - break; - } - - /* - .......................... Process selection .......................... - */ - switch (selection) { - /* - ......................... Pre-Build a Base ......................... - */ - case 0: - Start_Base_Building(); - process = false; - break; - - /* - ......................... Import Triggers .......................... - */ - case 1: - if (Import_Triggers()==0) - process = false; - break; - - /* - ......................... Trigger Editing .......................... - */ - case 2: - Handle_Triggers(); - /* - ................ Go into trigger placement mode ................. - */ - if (CurTrigger) { - Start_Trigger_Placement(); - } - process = false; - break; - - /* - ........................... Import Teams ........................... - */ - case 3: - if (Import_Teams()==0) - process = false; - break; - - /* - ........................... Team Editing ........................... - */ - case 4: - Handle_Teams("Teams"); - process = false; - break; - } - } -} - - -/*************************************************************************** - * MapEditClass::Verify_House -- is this objtype ownable by this house? * - * * - * INPUT: * - * house house to check * - * objtype ObjectTypeClass to check * - * * - * OUTPUT: * - * 0 = isn't ownable, 1 = it is * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/16/1994 BR : Created. * - *=========================================================================*/ -bool MapEditClass::Verify_House(HousesType house, ObjectTypeClass const *objtype) -{ - /* - --------------- Verify that new house can own this object ---------------- - */ - return((objtype->Get_Ownable() & (1 << house)) != 0); -} - - -/*************************************************************************** - * MapEditClass::Cycle_House -- finds next valid house for object type * - * * - * INPUT: * - * objtype ObjectTypeClass ptr to get house for * - * curhouse current house value to start with * - * * - * OUTPUT: * - * HousesType that's valid for this object type * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/23/1994 BR : Created. * - *=========================================================================*/ -HousesType MapEditClass::Cycle_House(HousesType curhouse, - ObjectTypeClass const *objtype) -{ - HousesType count; // prevents an infinite loop - - /*------------------------------------------------------------------------ - Loop through all house types, starting with the one after 'curhouse'; - return the first one that's valid - ------------------------------------------------------------------------*/ - count = HOUSE_NONE; - while (1) { - - /* - .......................... Go to next house ........................... - */ - curhouse++; - if (curhouse == HOUSE_COUNT) { - curhouse = HOUSE_FIRST; - } - - /* - ................ Count # iterations; don't go forever ................. - */ - count++; - if (count == HOUSE_COUNT) { - curhouse = HOUSE_NONE; - break; - } - - /* - ................... Break if this is a valid house .................... - */ - if (HouseClass::As_Pointer(curhouse) && Verify_House(curhouse,objtype)) { - break; - } - } - - return(curhouse); -} - - -/*************************************************************************** - * MapEditClass::Fatal -- exits with error message * - * * - * INPUT: * - * code tells which message to display; this minimizes the * - * use of character strings in the code. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/12/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Fatal(int txt) -{ - Prog_End(); - printf("%s\n",txt); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } -} - - -bool MapEditClass::Scroll_Map(DirType facing, int & distance, bool really) -{ - if (Debug_Map) { - /* - ** The popup gadgets require the entire map to be redrawn if we scroll. - */ - if (really) { - Flag_To_Redraw(true); - } - } - return(MouseClass::Scroll_Map(facing, distance, really)); -} - - -void MapEditClass::Detach(ObjectClass * object) -{ - if (GrabbedObject == object) { - GrabbedObject = 0; - } -} - - -#endif - -#include "mapedsel.cpp" \ No newline at end of file diff --git a/code/TIBERIANDAWN/MAPEDIT.H b/code/TIBERIANDAWN/MAPEDIT.H deleted file mode 100644 index 598c3c3..0000000 --- a/code/TIBERIANDAWN/MAPEDIT.H +++ /dev/null @@ -1,352 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapedit.h_v 2.19 16 Oct 1995 16:46:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPEDIT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 14, 1994 * - * * - * Last Update : May 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * This class is derived from the normal display map class. It exists * - * only to allow editing and adding items to the map. * - *---------------------------------------------------------------------------------------------* - * House-setting functions: The editor contains several house maintenance routines: * - * Verify_House: tells if the given ObjectType can be owned by the given HousesType * - * Cycle_House: Finds the next valid house for the given ObjectType; used when a new object * - * can't be owned by the current editor HousesType. * - * Change_House: attempts to change the owner of the currently-selected object * - * Toggle_House: cycles the HousesType of a pending placement object * - * Set_House_Buttons: sets house buttons in accordance with the given HousesType * - *---------------------------------------------------------------------------------------------* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MAPEDIT_H -#define MAPEDIT_H - -/* -********************************* Includes ********************************** -*/ -#include "function.h" - -/* -********************************** Defines ********************************** -*/ -/*........................................................................... -This is the maximum # of ObjectTypeClasses the editor has to deal with. -...........................................................................*/ -enum MapEdit1Enum { - MAX_EDIT_OBJECTS = // max # of ObjectTypeClasses allowed - (int)TEMPLATE_COUNT + - (int)OVERLAY_COUNT + - (int)SMUDGE_COUNT + - (int)TERRAIN_COUNT + - (int)UNIT_COUNT + - (int)INFANTRY_COUNT + - (int)AIRCRAFT_COUNT + - (int)STRUCT_COUNT, - - MAX_TEAM_CLASSES = // max # ObjectTypeClasses for a team - (int)UNIT_COUNT + - (int)INFANTRY_COUNT + - (int)AIRCRAFT_COUNT, - -// NUM_EDIT_MISSIONS = 6, // # missions that can be assigned an object - - NUM_EDIT_CLASSES = 8, // # different classes (templates, terrain, etc) - - MAX_MAIN_MENU_NUM = 8, - MAX_MAIN_MENU_LEN = 20, - - MAX_AI_MENU_NUM = 6, - MAX_AI_MENU_LEN = 20, - - POPUP_GDI_W = 100, - POPUP_GDI_H = 18, - POPUP_GDI_X = 20, - POPUP_GDI_Y = 320, - - POPUP_NOD_W = 100, - POPUP_NOD_H = 18, - POPUP_NOD_X = 20, - POPUP_NOD_Y = 338, - - POPUP_NEUTRAL_W = 100, - POPUP_NEUTRAL_H = 18, - POPUP_NEUTRAL_X = 20, - POPUP_NEUTRAL_Y = 356, - - POPUP_MULTI1_W = 50, - POPUP_MULTI1_H = 18, - POPUP_MULTI1_X = 20, - POPUP_MULTI1_Y = 320, - - POPUP_MULTI2_W = 50, - POPUP_MULTI2_H = 18, - POPUP_MULTI2_X = 70, - POPUP_MULTI2_Y = 320, - - POPUP_MULTI3_W = 50, - POPUP_MULTI3_H = 18, - POPUP_MULTI3_X = 20, - POPUP_MULTI3_Y = 330, - - POPUP_MULTI4_W = 50, - POPUP_MULTI4_H = 18, - POPUP_MULTI4_X = 70, - POPUP_MULTI4_Y = 338, - - POPUP_MISSION_W = 160, - POPUP_MISSION_H = 80, - POPUP_MISSION_X = 140, - POPUP_MISSION_Y = 300, - - POPUP_FACEBOX_W = 60, - POPUP_FACEBOX_H = 60, - POPUP_FACEBOX_X = 320, - POPUP_FACEBOX_Y = 320, - - POPUP_HEALTH_W = 100, - POPUP_HEALTH_H = 20, - POPUP_HEALTH_X = 400, - POPUP_HEALTH_Y = 340, - - POPUP_BASE_W = 100, - POPUP_BASE_H = 16, - POPUP_BASE_X = 600 - POPUP_BASE_W, - POPUP_BASE_Y = 0, -}; - -/*........................................................................... -These are the button ID's for the pop-up object-editing gizmos. -The house button ID's must be sequential, with a 1-to-1 correspondence to -the HousesType values. -...........................................................................*/ -enum MapEditButtonIDEnum{ - POPUP_GDI=500, // GDI house button - POPUP_NOD, // NOD house button - POPUP_NEUTRAL, // Neutral house button - POPUP_HOUSE_JP, // not used - POPUP_MULTI1, // Multiplayer 1 house button - POPUP_MULTI2, // Multiplayer 2 house button - POPUP_MULTI3, // Multiplayer 3 house button - POPUP_MULTI4, // Multiplayer 4 house button - POPUP_MULTI5, // Multiplayer 4 house button - POPUP_MULTI6, // Multiplayer 4 house button - POPUP_MISSIONLIST, // list box for missions - POPUP_HEALTHGAUGE, // health of object - POPUP_FACINGDIAL, // object's facing - POPUP_BASEPERCENT, // Base's percent-built slider - MAP_AREA, // map as a click-able thingy - BUTTON_FLAG=0x8000 -}; - - -/* -******************************* Declarations ******************************** -*/ -class TeamTypeClass; - -/* -***************************** Class Declaration ***************************** -*/ -class MapEditClass : public MouseClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /* - ............................. mapedit.cpp ............................. - */ - MapEditClass(void); - virtual void One_Time(void); // One-time init - virtual void Init_IO(void); // Inits button list - virtual void AI(KeyNumType &input, int x, int y); - virtual void Draw_It(bool forced = true); - virtual bool Scroll_Map(DirType facing, int & distance, bool really=true); -// virtual void Flag_To_Redraw(bool complete); - virtual void Read_INI(char *buffer); - virtual void Write_INI(char *buffer); - virtual void Detach(ObjectClass * object); - void Clear_List(void); - bool Add_To_List(ObjectTypeClass const *object); - void Main_Menu(void); - void AI_Menu(void); - bool Mouse_Moved(void); - bool Verify_House(HousesType house, ObjectTypeClass const * objtype); - HousesType Cycle_House(HousesType curhouse, ObjectTypeClass const * objtype); -// int Trigger_Needs_Team(TriggerClass *trigger); - void Fatal(int txt); - - /* - ............................ mapeddlg.cpp ............................. - */ - int New_Scenario(void); - int Load_Scenario(void); - int Save_Scenario(void); - int Pick_Scenario(char const * caption, int *scen_nump, - ScenarioPlayerType *playerp, ScenarioDirType *dirp, - ScenarioVarType *varp, int multi); - int Size_Map(int x, int y, int w, int h); - int Scenario_Dialog(void); - void Handle_Triggers(void); - int Select_Trigger(void); - int Edit_Trigger(void); - int Import_Triggers(void); - int Import_Teams(void); - /* - ............................ mapedplc.cpp ............................. - */ - int Placement_Dialog(void); - void Start_Placement(void); - int Place_Object(void); - void Cancel_Placement(void); - void Place_Next(void); - void Place_Prev(void); - void Place_Next_Category(void); - void Place_Prev_Category(void); - void Place_Home(void); - void Toggle_House(void); - void Set_House_Buttons(HousesType house, GadgetClass *btnlist, int base_id); - void Start_Trigger_Placement(void); - void Stop_Trigger_Placement(void); - void Place_Trigger(void); - void Start_Base_Building(void); - void Cancel_Base_Building(void); - void Build_Base_To(int percent); - - /* - ............................ mapedsel.cpp ............................. - */ - int Select_Object(void); - void Select_Next(void); - void Popup_Controls(void); - void Grab_Object(void); - int Move_Grabbed_Object(void); - bool Change_House(HousesType newhouse); - - /* - ............................. mapedtm.cpp ............................. - */ - void Draw_Member(TechnoTypeClass const * ptr, int index, - int quant, HousesType house, int pic_x, int pic_y); - void Handle_Teams(char const * caption); - int Select_Team(char const * caption); - int Edit_Team(void); - int Team_Members(HousesType house); - void Build_Mission_List(int missioncount, TeamMissionStruct *missions, - char missionbuf[TeamTypeClass::MAX_TEAM_MISSIONS][20], ListClass *list); - - /* - --------------------------- Private Interface ---------------------------- - */ - private: - /*..................................................................... - This is the last-requested variation of a loaded/saved/new scenario. - .....................................................................*/ - ScenarioVarType ScenVar; - - /*..................................................................... - Array of all TypeClasses the user can add to the map; cleared by - Clear_List(), added to by Add_To_List() - .....................................................................*/ - ObjectTypeClass const * Objects[MAX_EDIT_OBJECTS]; - int ObjCount; // # of objects in the Objects array - - /*..................................................................... - Last-selected object to place, and last-selected house of object - .....................................................................*/ - int LastChoice; // index of item user picked last - HousesType LastHouse; // house of last item picked - - /*..................................................................... - Variables for grabbing/moving objects - .....................................................................*/ - ObjectClass * GrabbedObject; // object "grabbed" with mouse - CELL GrabOffset; // offset to grabbed obj's upper-left - unsigned long LastClickTime; // time of last LMOUSE click - - /*..................................................................... - Number of each type of object in Objects, so we can switch categories - .....................................................................*/ - int NumType[NUM_EDIT_CLASSES]; // # of each type of class: - // 0 = Template - // 1 = Overlay - // 2 = Smudge - // 3 = Terrain - // 4 = Unit - // 5 = Infantry - // 6 = Aircraft - // 7 = Building - - /*..................................................................... - The offset of each type of object within the Objects[] array - .....................................................................*/ - int TypeOffset[NUM_EDIT_CLASSES]; // offsets within Objects[] - - /*..................................................................... - The "current" trigger for point-and-click trigger setting - .....................................................................*/ - TriggerClass * CurTrigger; // current trigger - - /*..................................................................... - The "current" team type for editing & associating with a trigger - .....................................................................*/ - TeamTypeClass * CurTeam; // current team - - /*..................................................................... - Bitfields for flags & such - .....................................................................*/ - int Changed : 1; // 1 = changes are unsaved - int LMouseDown : 1; // 1 = left mouse is held down - int BaseBuilding : 1; // 1 = we're in base-building mode - - /*..................................................................... - Variables for pre-building a base - .....................................................................*/ - int BasePercent; // Percentage the base will be built - - /*..................................................................... - Variables for supporting the object-editing controls at screen bottom - .....................................................................*/ - TextButtonClass *GDIButton; - TextButtonClass *NODButton; - TextButtonClass *NeutralButton; - TextButtonClass *Multi1Button; - TextButtonClass *Multi2Button; - TextButtonClass *Multi3Button; - TextButtonClass *Multi4Button; - ListClass *MissionList; - TriColorGaugeClass *HealthGauge; - Dial8Class *FacingDial; - ControlClass *MapArea; - TextLabelClass *HealthText; - static char HealthBuf[20]; - GaugeClass *BaseGauge; - TextLabelClass *BaseLabel; - static MissionType MapEditMissions[]; -}; - -#endif diff --git a/code/TIBERIANDAWN/MAPEDPLC.CPP b/code/TIBERIANDAWN/MAPEDPLC.CPP deleted file mode 100644 index b8d74a0..0000000 --- a/code/TIBERIANDAWN/MAPEDPLC.CPP +++ /dev/null @@ -1,1996 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapedplc.cpv 2.16 16 Oct 1995 16:51:00 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPEDPLC.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : November 18, 1994 * - * * - * Last Update : July 4, 1995 [JLB] * - * * - *-------------------------------------------------------------------------* - * Object-placement routines * - *-------------------------------------------------------------------------* - * Functions: * - * MapEditClass::Placement_Dialog -- adds an object to the scenario * - * MapEditClass::Start_Placement -- enters placement mode * - * MapEditClass::Place_Object -- attempts to place the current object * - * MapEditClass::Cancel_Placement -- cancels placement mode * - * MapEditClass::Place_Next -- while placing object, goes to next * - * MapEditClass::Place_Prev -- while placing object, goes to previous * - * MapEditClass::Place_Next_Category -- places next object category * - * MapEditClass::Place_Prev_Category -- places previous object category * - * MapEditClass::Place_Home -- homes the placement object * - * MapEditClass::Toggle_House -- toggles current placement object's house* - * MapEditClass::Set_House_Buttons -- toggles house buttons for btn list * - * MapEditClass::Start_Trigger_Placement -- enters trigger placement mode* - * MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode * - * MapEditClass::Place_Trigger -- assigns trigger to object or cell * - * MapEditClass::Start_Base_Building -- starts base-building mode * - * MapEditClass::Cancel_Base_Building -- stops base-building mode * - * MapEditClass::Build_Base_To -- builds the AI base to the given percent* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef SCENARIO_EDITOR - - -/*************************************************************************** - * MapEditClass::Placement_Dialog -- adds an object to the scenario * - * * - * This function sets LastChoice & LastHouse to the values chosen * - * by the user. It's up to the caller to call Start_Placement to enter * - * placement mode. * - * This routine does not modify PendingObject or PendingHouse. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ [GDI] [NOD] [Neutral] ³ * - * ³ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ [Template] ³ * - * ³ ³ ³ [Overlay ] ³ * - * ³ ³ ³ [Smudge ] ³ * - * ³ ³ ³ [Terrain ] ³ * - * ³ ³ (Object picture) ³ [Unit ] ³ * - * ³ ³ ³ [Infantry] ³ * - * ³ ³ ³ [Aircraft] ³ * - * ³ ³ ³ [Building] ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÚÄÄÄÄÄÄ¿ ³ * - * ³ [<-] [->] ³(Grid)³ ³ * - * ³ ³ ³ ³ * - * ³ [OK] [Cancel] ÀÄÄÄÄÄÄÙ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/21/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Placement_Dialog(void) -{ - HousesType house; - - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 480, - D_DIALOG_H = 360, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_PICTURE_W = 304, // must be divisible by 8! - D_PICTURE_H = 210, - D_PICTURE_X = D_DIALOG_X + 16, // must start on a byte boundary! - D_PICTURE_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN, - D_PICTURE_CX = D_PICTURE_X + D_PICTURE_W / 2, - - D_GDI_W = 90, - D_GDI_H = 18, - D_GDI_X = D_DIALOG_X + D_MARGIN, - D_GDI_Y = D_DIALOG_Y + D_MARGIN, - - D_NOD_W = 90, - D_NOD_H = 18, - D_NOD_X = D_GDI_X + D_GDI_W, - D_NOD_Y = D_DIALOG_Y + D_MARGIN, - - D_NEUTRAL_W = 90, - D_NEUTRAL_H = 18, - D_NEUTRAL_X = D_NOD_X + D_NOD_W, - D_NEUTRAL_Y = D_DIALOG_Y + D_MARGIN, - - D_MULTI1_W = 44, - D_MULTI1_H = 18, - D_MULTI1_X = D_GDI_X, - D_MULTI1_Y = D_GDI_Y, - - D_MULTI2_W = 44, - D_MULTI2_H = 18, - D_MULTI2_X = D_MULTI1_X + D_MULTI1_W, - D_MULTI2_Y = D_GDI_Y, - - D_MULTI3_W = 44, - D_MULTI3_H = 18, - D_MULTI3_X = D_MULTI2_X + D_MULTI2_W, - D_MULTI3_Y = D_GDI_Y, - - D_MULTI4_W = 44, - D_MULTI4_H = 18, - D_MULTI4_X = D_MULTI3_X + D_MULTI3_W, - D_MULTI4_Y = D_GDI_Y, - - D_LEFT_W = 90, - D_LEFT_H = 18, - D_LEFT_X = D_PICTURE_CX - 5 - D_LEFT_W, - D_LEFT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN, - - D_RIGHT_W = 90, - D_RIGHT_H = 18, - D_RIGHT_X = D_PICTURE_CX + 5, - D_RIGHT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN, - - D_TEMPLATE_W = 140, - D_TEMPLATE_H = 18, - D_TEMPLATE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TEMPLATE_W, - D_TEMPLATE_Y = D_PICTURE_Y, - - D_OVERLAY_W = 140, - D_OVERLAY_H = 18, - D_OVERLAY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_OVERLAY_W, - D_OVERLAY_Y = D_TEMPLATE_Y + D_TEMPLATE_H, - - D_SMUDGE_W = 140, - D_SMUDGE_H = 18, - D_SMUDGE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_SMUDGE_W, - D_SMUDGE_Y = D_OVERLAY_Y + D_OVERLAY_H, - - D_TERRAIN_W = 140, - D_TERRAIN_H = 18, - D_TERRAIN_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TERRAIN_W, - D_TERRAIN_Y = D_SMUDGE_Y + D_SMUDGE_H, - - D_UNIT_W = 140, - D_UNIT_H = 18, - D_UNIT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_UNIT_W, - D_UNIT_Y = D_TERRAIN_Y + D_TERRAIN_H, - - D_INFANTRY_W = 140, - D_INFANTRY_H = 18, - D_INFANTRY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_INFANTRY_W, - D_INFANTRY_Y = D_UNIT_Y + D_UNIT_H, - - D_AIRCRAFT_W = 140, - D_AIRCRAFT_H = 18, - D_AIRCRAFT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_AIRCRAFT_W, - D_AIRCRAFT_Y = D_INFANTRY_Y + D_INFANTRY_H, - - D_BUILDING_W = 140, - D_BUILDING_H = 18, - D_BUILDING_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_BUILDING_W, - D_BUILDING_Y = D_AIRCRAFT_Y + D_AIRCRAFT_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_PICTURE_CX - D_OK_W - 5, - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN, - - D_CANCEL_W = 90, - D_CANCEL_H = 18, - D_CANCEL_X = D_PICTURE_CX + 5, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, - - }; - /*........................................................................ - Grid Dimensions - ........................................................................*/ - enum { - GRIDSIZE = 10, - GRIDBLOCK_W = 6, - GRIDBLOCK_H = 6, - D_GRID_X = D_DIALOG_X + D_DIALOG_W - (GRIDSIZE * GRIDBLOCK_W) - D_MARGIN, - D_GRID_Y = D_DIALOG_Y + D_DIALOG_H - (GRIDSIZE * GRIDBLOCK_H) - D_MARGIN, - }; - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - BUTTON_GDI=100, - BUTTON_NOD, - BUTTON_NEUTRAL, - BUTTON_JP, // placeholder - BUTTON_MULTI1, - BUTTON_MULTI2, - BUTTON_MULTI3, - BUTTON_MULTI4, - BUTTON_NEXT, - BUTTON_PREV, - BUTTON_OK, - BUTTON_CANCEL, - BUTTON_TEMPLATE, - BUTTON_OVERLAY, - BUTTON_SMUDGE, - BUTTON_TERRAIN, - BUTTON_UNIT, - BUTTON_INFANTRY, - BUTTON_AIRCRAFT, - BUTTON_BUILDING, - }; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_OBJECT, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display; // display level - bool process; // loop while true - bool cancel = false; // true = user cancels - const ObjectTypeClass * curobj; // Working object pointer. - int x,y; // for drawing the grid - KeyNumType input; // user input - short const *occupy; // ptr into object's OccupyList - int cell; // cell index for parsing OccupyList - int i; - int typeindex; // index of class type - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands; - - TextButtonClass gdibtn (BUTTON_GDI, "GDI", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H); - - TextButtonClass nodbtn (BUTTON_NOD, "NOD", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H); - - TextButtonClass neutbtn (BUTTON_NEUTRAL, "Neutral", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NEUTRAL_X, D_NEUTRAL_Y, D_NEUTRAL_W, D_NEUTRAL_H); - - TextButtonClass multi1btn (BUTTON_MULTI1, "M1", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI1_X, D_MULTI1_Y, D_MULTI1_W, D_MULTI1_H); - - TextButtonClass multi2btn (BUTTON_MULTI2, "M2", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI2_X, D_MULTI2_Y, D_MULTI2_W, D_MULTI2_H); - - TextButtonClass multi3btn (BUTTON_MULTI3, "M3", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI3_X, D_MULTI3_Y, D_MULTI3_W, D_MULTI3_H); - - TextButtonClass multi4btn (BUTTON_MULTI4, "M4", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI4_X, D_MULTI4_Y, D_MULTI4_W, D_MULTI4_H); - - TextButtonClass nextbtn (BUTTON_NEXT, TXT_RIGHT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_RIGHT_X, D_RIGHT_Y, D_RIGHT_W, D_RIGHT_H); - - TextButtonClass prevbtn (BUTTON_PREV, TXT_LEFT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_LEFT_X, D_LEFT_Y, D_LEFT_W, D_LEFT_H); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - TextButtonClass templatebtn (BUTTON_TEMPLATE, "Template", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_TEMPLATE_X, D_TEMPLATE_Y, D_TEMPLATE_W, D_TEMPLATE_H); - - TextButtonClass overlaybtn (BUTTON_OVERLAY, "Overlay", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OVERLAY_X, D_OVERLAY_Y, D_OVERLAY_W, D_OVERLAY_H); - - TextButtonClass smudgebtn (BUTTON_SMUDGE, "Smudge", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_SMUDGE_X, D_SMUDGE_Y, D_SMUDGE_W, D_SMUDGE_H); - - TextButtonClass terrainbtn (BUTTON_TERRAIN, "Terrain", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_TERRAIN_X, D_TERRAIN_Y, D_TERRAIN_W, D_TERRAIN_H); - - TextButtonClass unitbtn (BUTTON_UNIT, "Unit", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_UNIT_X, D_UNIT_Y, D_UNIT_W, D_UNIT_H); - - TextButtonClass infantrybtn (BUTTON_INFANTRY, "Infantry", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_INFANTRY_X, D_INFANTRY_Y, D_INFANTRY_W, D_INFANTRY_H); - - TextButtonClass aircraftbtn (BUTTON_AIRCRAFT, "Aircraft", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_AIRCRAFT_X, D_AIRCRAFT_Y, D_AIRCRAFT_W, D_AIRCRAFT_H); - - TextButtonClass buildingbtn (BUTTON_BUILDING, "Building", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_BUILDING_X, D_BUILDING_Y, D_BUILDING_W, D_BUILDING_H); - - /*------------------------------------------------------------------------ - Initialize addable objects list; we must do this every time in case one - of the object pools has become exhausted; that object won't be available - for adding. (Skip aircraft, since they won't be used in the editor.) - ------------------------------------------------------------------------*/ - Clear_List(); - TemplateTypeClass::Prep_For_Add(); - OverlayTypeClass::Prep_For_Add(); - SmudgeTypeClass::Prep_For_Add(); - TerrainTypeClass::Prep_For_Add(); - UnitTypeClass::Prep_For_Add(); - InfantryTypeClass::Prep_For_Add(); - BuildingTypeClass::Prep_For_Add(); - - /*........................................................................ - Compute offset of each class type in the Objects array - ........................................................................*/ - TypeOffset[0] = 0; - for (i=1; i= ObjCount) { - LastChoice = 0; - } - curobj = Objects[LastChoice]; // current object to choose - - commands = &neutbtn; - if (ScenPlayer == SCEN_PLAYER_MPLAYER) { - multi1btn.Add_Tail(*commands); - multi2btn.Add_Tail(*commands); - multi3btn.Add_Tail(*commands); - multi4btn.Add_Tail(*commands); - } else { - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - } - nextbtn.Add_Tail(*commands); - prevbtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - templatebtn.Add_Tail(*commands); - overlaybtn.Add_Tail(*commands); - smudgebtn.Add_Tail(*commands); - terrainbtn.Add_Tail(*commands); - unitbtn.Add_Tail(*commands); - infantrybtn.Add_Tail(*commands); - aircraftbtn.Add_Tail(*commands); - buildingbtn.Add_Tail(*commands); - - /*........................................................................ - If the current house isn't valid for the current object type, cycle to - the next house. - ........................................................................*/ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - } - - /* - ..................... Set the buttons for this house ..................... - */ - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - - /* - -------------------------- Main processing loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - /* - ---------------------- Refresh display if needed ---------------------- - */ - if (display > REDRAW_NONE) { - /* - ---------------------- Display the dialog box ---------------------- - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - } - - /*------------------------------------------------------------------ - Display the current object: - - save the current window dimensions - - adjust the window size to the actual drawable area - - draw the shape - - reset the window dimensions - ------------------------------------------------------------------*/ - if (display >= REDRAW_OBJECT) { - WindowList[WINDOW_EDITOR][WINDOWX] = D_PICTURE_X >> 3; - WindowList[WINDOW_EDITOR][WINDOWY] = D_PICTURE_Y; - WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W >> 3; - WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H; - Change_Window((int)WINDOW_EDITOR); - Draw_Box(D_PICTURE_X, D_PICTURE_Y, D_PICTURE_W, D_PICTURE_H, - BOXSTYLE_GREEN_DOWN, true); - curobj->Display(WinW<<2, WinH>>1, WINDOW_EDITOR, LastHouse); - - /* - ........................ Erase the grid ......................... - */ - LogicPage->Fill_Rect(D_GRID_X - GRIDBLOCK_W * 2, D_GRID_Y, - D_GRID_X + GRIDSIZE * GRIDBLOCK_W, - D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, BLACK); - - /* - .............. Draw a box for every cell occupied ............... - */ - occupy = curobj->Occupy_List(); - while ( (*occupy) != REFRESH_EOL) { - cell = (*occupy); - occupy++; - x = D_GRID_X + ((cell % MAP_CELL_W) * GRIDBLOCK_W); - y = D_GRID_Y + ((cell / MAP_CELL_W) * GRIDBLOCK_H); - LogicPage->Fill_Rect(x, y, x + GRIDBLOCK_W - 1, y + GRIDBLOCK_H - 1, - CC_BRIGHT_GREEN); - } - - /* - ..................... Draw the grid itself ...................... - */ - for (y = 0; y <= GRIDSIZE; y++) { - for (x = 0; x <= GRIDSIZE; x++) { - LogicPage->Draw_Line(D_GRID_X + x * GRIDBLOCK_W, D_GRID_Y, - D_GRID_X + x * GRIDBLOCK_W, - D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, CC_GREEN_SHADOW); - } - LogicPage->Draw_Line(D_GRID_X, D_GRID_Y + y * GRIDBLOCK_H, - D_GRID_X + GRIDSIZE * GRIDBLOCK_W, D_GRID_Y + y * GRIDBLOCK_H, - CC_GREEN_SHADOW); - } - - /*............................................................... - Print the object's label from the class's Full_Name(). - Warning: Text_String returns an EMS pointer, so standard string - functions won't work! - ...............................................................*/ - Fancy_Text_Print (curobj->Full_Name(), - D_PICTURE_CX, D_PICTURE_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /* - -------------------------- Redraw buttons -------------------------- - */ - if (display >= REDRAW_BUTTONS) { - /*............................................................... - Figure out which class category we're in & highlight that button - This updates 'typeindex', which is used below, and it also updates - the category button states. - ...............................................................*/ - i = 0; - for (typeindex = 0; typeindex < NUM_EDIT_CLASSES; typeindex++) { - i += NumType[typeindex]; - if (LastChoice < i) break; - } - templatebtn.Turn_Off(); - overlaybtn.Turn_Off(); - smudgebtn.Turn_Off(); - terrainbtn.Turn_Off(); - unitbtn.Turn_Off(); - infantrybtn.Turn_Off(); - aircraftbtn.Turn_Off(); - buildingbtn.Turn_Off(); - switch (typeindex + BUTTON_TEMPLATE) { - case BUTTON_TEMPLATE: - templatebtn.Turn_On(); - break; - - case BUTTON_OVERLAY: - overlaybtn.Turn_On(); - break; - - case BUTTON_SMUDGE: - smudgebtn.Turn_On(); - break; - - case BUTTON_TERRAIN: - terrainbtn.Turn_On(); - break; - - case BUTTON_UNIT: - unitbtn.Turn_On(); - break; - - case BUTTON_INFANTRY: - infantrybtn.Turn_On(); - break; - - case BUTTON_AIRCRAFT: - aircraftbtn.Turn_On(); - break; - - case BUTTON_BUILDING: - buildingbtn.Turn_On(); - break; - } - } - - /* - .......................... Redraw buttons .......................... - */ - commands->Draw_All(); - Show_Mouse(); - display = REDRAW_NONE; - - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ------------------------- Process user input -------------------------- - */ - switch (input) { - /* - ---------------------------- GDI House ----------------------------- - */ - case (BUTTON_GDI | KN_BUTTON): - case (BUTTON_NOD | KN_BUTTON): - case (BUTTON_NEUTRAL | KN_BUTTON): - case (BUTTON_MULTI1 | KN_BUTTON): - case (BUTTON_MULTI2 | KN_BUTTON): - case (BUTTON_MULTI3 | KN_BUTTON): - case (BUTTON_MULTI4 | KN_BUTTON): - house = (HousesType)( (input & (~KN_BUTTON)) - BUTTON_GDI); - /* - ............... ignore if invalid for this object ............... - */ - if (!Verify_House(house,curobj)) { - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - break; - } - - /* - ...................... Set flags & buttons ...................... - */ - LastHouse = house; - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - display = REDRAW_OBJECT; - break; - - /* - --------------------------- Next in list --------------------------- - */ - case (KN_RIGHT): - case (BUTTON_NEXT | KN_BUTTON): - /* - ..................... Increment to next obj ..................... - */ - LastChoice++; - if (LastChoice == ObjCount) { - LastChoice = 0; - } - curobj = Objects[LastChoice]; - - /* - .................... Get valid house for obj .................... - */ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - } - - nextbtn.Turn_Off(); - display = REDRAW_OBJECT; - break; - - /* - ------------------------- Previous in list ------------------------- - */ - case (KN_LEFT): - case (BUTTON_PREV | KN_BUTTON): - /* - ..................... Decrement to prev obj ..................... - */ - LastChoice--; - if (LastChoice < 0) { - LastChoice = ObjCount-1; - } - curobj = Objects[LastChoice]; - - /* - .................... Get valid house for obj .................... - */ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - } - - prevbtn.Turn_Off(); - display = REDRAW_OBJECT; - break; - - /* - ----------------------- Select a class type ------------------------ - */ - case (BUTTON_TEMPLATE | KN_BUTTON): - case (BUTTON_OVERLAY | KN_BUTTON): - case (BUTTON_SMUDGE | KN_BUTTON): - case (BUTTON_TERRAIN | KN_BUTTON): - case (BUTTON_UNIT | KN_BUTTON): - case (BUTTON_INFANTRY | KN_BUTTON): - case (BUTTON_AIRCRAFT | KN_BUTTON): - case (BUTTON_BUILDING | KN_BUTTON): - /* - ...................... Find index of class ...................... - */ - typeindex = input - (BUTTON_TEMPLATE | KN_BUTTON); - - /* - ............ If no objects of that type, do nothing ............. - */ - if (NumType[typeindex]==0) { - display = REDRAW_BUTTONS; // force to reset button states - break; - } - - /* - ...................... Set current object ....................... - */ - LastChoice = TypeOffset[typeindex]; - curobj = Objects[LastChoice]; - - /* - .................... Get valid house for obj .................... - */ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - } - - display = REDRAW_OBJECT; - break; - - /* - -------------------------- Next category --------------------------- - */ - case KN_PGDN: - typeindex++; - if (typeindex==NUM_EDIT_CLASSES) { - typeindex = 0; - } - - /* - ...................... Set current object ....................... - */ - LastChoice = TypeOffset[typeindex]; - curobj = Objects[LastChoice]; - - /* - .................... Get valid house for obj .................... - */ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - } - - display = REDRAW_OBJECT; - break; - - /* - ------------------------ Previous category ------------------------- - */ - case KN_PGUP: - typeindex--; - if (typeindex < 0) { - typeindex = NUM_EDIT_CLASSES - 1; - } - - /* - ...................... Set current object ....................... - */ - LastChoice = TypeOffset[typeindex]; - curobj = Objects[LastChoice]; - - /* - .................... Get valid house for obj .................... - */ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - } - - display = REDRAW_OBJECT; - break; - - /* - ------------------------ Jump to 1st choice ------------------------ - */ - case KN_HOME: - LastChoice = 0; - /* - ...................... Set current object ....................... - */ - curobj = Objects[LastChoice]; - /* - .................... Get valid house for obj .................... - */ - if (!Verify_House(LastHouse,curobj)) { - LastHouse = Cycle_House(LastHouse,curobj); - Set_House_Buttons(LastHouse, commands, BUTTON_GDI); - } - display = REDRAW_OBJECT; - break; - - /* - -------------------------------- OK -------------------------------- - */ - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - cancel = false; - process = false; - break; - - /* - ------------------------------ Cancel ------------------------------ - */ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - default: - break; - } - - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - if (cancel) { - return(-1); - } - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Start_Placement -- enters placement mode * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/04/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Start_Placement(void) -{ - int i; - - /*------------------------------------------------------------------------ - Initialize addable objects list; we must do this every time in case one - of the object pools has become exhausted; that object won't be available - for adding. - ------------------------------------------------------------------------*/ - Clear_List(); - TemplateTypeClass::Prep_For_Add(); - OverlayTypeClass::Prep_For_Add(); - SmudgeTypeClass::Prep_For_Add(); - TerrainTypeClass::Prep_For_Add(); - UnitTypeClass::Prep_For_Add(); - InfantryTypeClass::Prep_For_Add(); - //AircraftTypeClass::Prep_For_Add(); - BuildingTypeClass::Prep_For_Add(); - /*........................................................................ - Compute offset of each class type in the Objects array - ........................................................................*/ - TypeOffset[0] = 0; - for (i=1; i= ObjCount) - LastChoice = ObjCount - 1; - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse)); - } else { - if (LastChoice < TypeOffset[7]) - LastChoice = TypeOffset[7]; - if (LastChoice >= ObjCount) - LastChoice = ObjCount - 1; - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse = Base.House; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse)); - } - - - /* - ------------------- Error if no more objects available ------------------- - */ - if (!PendingObjectPtr) { - CCMessageBox().Process("No more objects of this type available."); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - PendingObject = NULL; - if (BaseBuilding) - Cancel_Base_Building(); - return; - } - - /* - ------------------------ Set the placement cursor ------------------------ - */ - Set_Cursor_Pos(); - Set_Cursor_Shape(PendingObject->Occupy_List()); -} - - -/*************************************************************************** - * MapEditClass::Place_Object -- attempts to place the current object * - * * - * Placement of "real" objects is simply checked via their Unlimbo routine.* - * Placement of templates is more complex: * - * - for every cell in the template's OccupyList, check for objects * - * already in that cell by looking at the cell's OccupyList & * - * OverlapList * - * - "lift" all the objects in the cell by Mark'ing them * - * - temporarily place the template in that cell * - * - try to Unlimbo all the objects that were in the cell. If any * - * objects fail to Unlimbo onto that template, the template cannot * - * be placed here * - * * - * It is assumed that the object being placed is a "new" object; the * - * object's strength & mission are not set during Unlimbo. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = unable to place * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/04/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Place_Object(void) -{ - CELL template_cell; // cell being checked for template - COORDINATE obj_coord; // coord of occupier object - int okflag; // OK to place a template? - short const *occupy; // ptr into template's OccupyList - ObjectClass *occupier; // occupying object - TemplateType save_ttype; // for saving cell's TType - unsigned char save_ticon; // for saving cell's TIcon - BaseNodeClass node; // for adding to an AI Base - - /*------------------------------------------------------------------------ - Placing a template: - - first lift up any objects in the cell - - place the template, and try to replace the objects; if they won't go - back, the template can't go there - ------------------------------------------------------------------------*/ - //ScenarioInit++; - if (PendingObject->What_Am_I() == RTTI_TEMPLATETYPE) { - - /* - .......... Loop through all cells this template will occupy ........... - */ - okflag = true; - occupy = PendingObject->Occupy_List(); - while ((*occupy) != REFRESH_EOL) { - - /* - ................. Check this cell for an occupier .................. - */ - template_cell = (ZoneCell+ZoneOffset) + (*occupy); - if ((*this)[template_cell].Cell_Occupier()) { - occupier = (*this)[template_cell].Cell_Occupier(); - - /* - .................. Save object's coordinates .................... - */ - obj_coord = occupier->Coord; - - /* - ................... Place the object in limbo ................... - */ - occupier->Mark(MARK_UP); - - /* - ................ Set the cell's template values ................. - */ - save_ttype = (*this)[template_cell].TType; - save_ticon = (*this)[template_cell].TIcon; - (*this)[template_cell].TType = - ((TemplateTypeClass *)PendingObject)->Type; - (*this)[template_cell].TIcon = Cell_X(*occupy) + Cell_Y(*occupy) * - ((TemplateTypeClass *)PendingObject)->Width; - (*this)[template_cell].Recalc_Attributes(); - /* - ................ Try to put the object back down ................ - */ - if (occupier->Can_Enter_Cell(Coord_Cell(obj_coord)) != MOVE_OK) { - okflag = false; - } - - /* - .............. Put everything back the way it was ............... - */ - (*this)[template_cell].TType = save_ttype; - (*this)[template_cell].TIcon = save_ticon; - (*this)[template_cell].Recalc_Attributes(); - - /* - .......... Major error if can't replace the object now .......... - */ - occupier->Mark(MARK_DOWN); - } - occupy++; - } - - /* - ......... If it's still OK after ALL THAT, place the template ......... - */ - if (okflag) { - if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) { - /*............................................................... - Loop through all cells occupied by this template, and clear the - smudge & overlay. - ...............................................................*/ - occupy = PendingObject->Occupy_List(); - while ((*occupy) != REFRESH_EOL) { - /* - ............... Get cell for this occupy item ................ - */ - template_cell = (ZoneCell+ZoneOffset) + (*occupy); - - /* - ................... Clear smudge & overlay ................... - */ - (*this)[template_cell].Overlay = OVERLAY_NONE; - (*this)[template_cell].OverlayData = 0; - (*this)[template_cell].Smudge = SMUDGE_NONE; - - /* - ............ make adjacent cells recalc attrib's ............. - */ - (*this)[template_cell].Recalc_Attributes(); - (*this)[template_cell].Wall_Update(); - (*this)[template_cell].Concrete_Calc(); - - occupy++; - } - - /* - ......................... Set flags etc ......................... - */ - PendingObjectPtr = 0; - PendingObject = 0; - PendingHouse = HOUSE_NONE; - Set_Cursor_Shape(0); - //ScenarioInit--; - TotalValue = Overpass(); - Flag_To_Redraw(false); - return(0); - } - - /* - ** Failure to deploy results in a returned failure code. - */ - //ScenarioInit--; - return(-1); - } - - /* - ........................ Not OK; return error ......................... - */ - //ScenarioInit--; - return(-1); - } - - /*------------------------------------------------------------------------ - Placing infantry: Infantry can go into cell sub-positions, so find the - sub-position closest to the mouse & put him there - ------------------------------------------------------------------------*/ - if (PendingObject->What_Am_I() == RTTI_INFANTRYTYPE) { - /* - ....................... Find cell sub-position ........................ - */ - if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(),Get_Mouse_Y()))) { - obj_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(), - Get_Mouse_Y())); - } else { - obj_coord = NULL; - } - - /* - ................ No free spots; don't place the object ................ - */ - if (obj_coord == NULL) { - //ScenarioInit--; - return(-1); - } - - /* - ......................... Unlimbo the object .......................... - */ - if (PendingObjectPtr->Unlimbo(obj_coord)) { - ((InfantryClass *)PendingObjectPtr)->Set_Occupy_Bit(obj_coord); -// Map[Coord_Cell(obj_coord)].Flag.Composite |= -// (1 << CellClass::Spot_Index(obj_coord)); - PendingObjectPtr = 0; - PendingObject = 0; - PendingHouse = HOUSE_NONE; - Set_Cursor_Shape(0); - //ScenarioInit--; - return(0); - } - - //ScenarioInit--; - return(-1); - } - - /*------------------------------------------------------------------------ - Placing an object - ------------------------------------------------------------------------*/ - if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) { - - /* - ** Update the Tiberium computation if we're placing an overlay - */ - if (PendingObject->What_Am_I() == RTTI_OVERLAYTYPE && - ((OverlayTypeClass *)PendingObject)->IsTiberium) { - - TotalValue = Overpass(); - Flag_To_Redraw(false); - } - - /* - ** If we're building a base, add this building to the base's Node list. - */ - if (BaseBuilding && PendingObject->What_Am_I() == RTTI_BUILDINGTYPE) { - node.Type = ((BuildingTypeClass *)PendingObject)->Type; - node.Coord = PendingObjectPtr->Coord; - Base.Nodes.Add(node); - } - - PendingObjectPtr = 0; - PendingObject = 0; - PendingHouse = HOUSE_NONE; - Set_Cursor_Shape(0); - //ScenarioInit--; - return(0); - } - - return(-1); -} - - -/*************************************************************************** - * MapEditClass::Cancel_Placement -- cancels placement mode * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/04/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Cancel_Placement(void) -{ - /* - ---------------------- Delete the placement object ----------------------- - */ - delete PendingObjectPtr; - PendingObject = 0; - PendingObjectPtr = 0; - PendingHouse = HOUSE_NONE; - - /* - -------------------------- Restore cursor shape -------------------------- - */ - Set_Cursor_Shape(0); - - /* - ----------------- Redraw the map to erase old leftovers ------------------ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::Place_Next -- while placing object, goes to next * - * * - * - Deletes the current 'PendingObjectPtr' * - * - Increments LastChoice * - * - Tries to create a new 'PendingObjectPtr'; if fails, keeps * - * incrementing until it gets it * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/03/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Place_Next(void) -{ - delete PendingObjectPtr; - PendingObjectPtr = NULL; - PendingObject = NULL; - - /* - ------------------ Loop until we create a valid object ------------------- - */ - while (!PendingObjectPtr) { - /* - ................. Go to next object in Objects list ................... - */ - LastChoice++; - if (LastChoice == ObjCount) { - /* - ** If we're in normal placement mode, wrap to the 1st object; - ** if we're in base-building mode, wrap to the 1st building - */ - if (!BaseBuilding) { - LastChoice = 0; - } else { - LastChoice = TypeOffset[7]; - } - } - - /* - ................... Get house for this object type .................... - */ - if (!Verify_House(LastHouse,Objects[LastChoice])) { - /* - ** If we're in normal placement mode, change the current - ** placement house to the one that can own this object. - ** If we're building a base, skip ahead to the next object if the - ** base's house can't own this one. - */ - if (!BaseBuilding) { - LastHouse = Cycle_House(LastHouse,Objects[LastChoice]); - } else { - continue; - } - } - - /* - ....................... Create placement object ....................... - */ - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse)); - if (!PendingObjectPtr) { - PendingObject = NULL; - } - } - - /* - ------------------------ Set the new cursor shape ------------------------ - */ - Set_Cursor_Pos(); - Set_Cursor_Shape(0); - Set_Cursor_Shape(PendingObject->Occupy_List()); - - /* - ----------------- Redraw the map to erase old leftovers ------------------ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::Place_Prev -- while placing object, goes to previous * - * * - * - Deletes the current 'PendingObjectPtr' * - * - Decrements LastChoice * - * - Tries to create a new 'PendingObjectPtr'; if fails, keeps * - * decrementing until it gets it * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/03/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Place_Prev(void) -{ - delete PendingObjectPtr; - PendingObjectPtr = NULL; - PendingObject = NULL; - - /* - ------------------ Loop until we create a valid object ------------------- - */ - while (!PendingObjectPtr) { - - /* - ................. Go to prev object in Objects list .................. - */ - LastChoice--; - /* - ** If we're in normal placement mode, wrap at the 1st object. - ** If we're building a base, wrap at the 1st building. - */ - if (!BaseBuilding) { - if (LastChoice < 0) - LastChoice = ObjCount - 1; - } else { - if (LastChoice < TypeOffset[7]) - LastChoice = ObjCount - 1; - } - - /* - ................... Get house for this object type .................... - */ - if (!Verify_House(LastHouse,Objects[LastChoice])) { - /* - ** If we're in normal placement mode, change the current - ** placement house to the one that can own this object. - ** If we're building a base, skip ahead to the next object if the - ** base's house can't own this one. - */ - if (!BaseBuilding) { - LastHouse = Cycle_House(LastHouse,Objects[LastChoice]); - } else { - continue; - } - } - - /* - ....................... Create placement object ....................... - */ - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse)); - if (!PendingObjectPtr) { - PendingObject = NULL; - } - } - - /* - ------------------------ Set the new cursor shape ------------------------ - */ - Set_Cursor_Pos(); - Set_Cursor_Shape(0); - Set_Cursor_Shape(PendingObject->Occupy_List()); - - /* - ----------------- Redraw the map to erase old leftovers ------------------ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::Place_Next_Category -- places next category of object * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/03/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Place_Next_Category(void) -{ - int i; - - /* - ** Don't allow this command if we're building a base; the only valid - ** category for base-building is buildings. - */ - if (BaseBuilding) { - return; - } - - delete PendingObjectPtr; - PendingObjectPtr = NULL; - PendingObject = NULL; - - /* - ------------------ Go to next category in Objects list ------------------- - */ - i = LastChoice; - while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) { - i++; - if (i == ObjCount) { - i = 0; - } - } - LastChoice = i; - - /* - ------------------ Loop until we create a valid object ------------------- - */ - while (!PendingObjectPtr) { - - /* - ................... Get house for this object type .................... - */ - if (!Verify_House(LastHouse,Objects[LastChoice])) { - LastHouse = Cycle_House(LastHouse,Objects[LastChoice]); - } - - /* - ....................... Create placement object ....................... - */ - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse)); - - /* - .................. If this one failed, try the next ................... - */ - if (!PendingObjectPtr) { - PendingObject = NULL; - LastChoice++; - if (LastChoice == ObjCount) { - LastChoice = 0; - } - } - } - - /* - ------------------------ Set the new cursor shape ------------------------ - */ - Set_Cursor_Pos(); - Set_Cursor_Shape(0); - Set_Cursor_Shape(PendingObject->Occupy_List()); - - /* - ----------------- Redraw the map to erase old leftovers ------------------ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::Place_Prev_Category -- places previous category of object * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/03/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Place_Prev_Category(void) -{ - int i; - - /* - ** Don't allow this command if we're building a base; the only valid - ** category for base-building is buildings. - */ - if (BaseBuilding) { - return; - } - - delete PendingObjectPtr; - PendingObjectPtr = NULL; - PendingObject = NULL; - - /* - ------------------ Go to prev category in Objects list ------------------- - */ - i = LastChoice; - /* - ..................... Scan for the previous category ..................... - */ - while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) { - i--; - if (i < 0) { - i = ObjCount - 1; - } - } - /* - .................... Scan for start of this category ..................... - */ - LastChoice = i; - while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) { - LastChoice = i; - i--; - if (i < 0) { - i = ObjCount - 1; - } - } - - /* - ------------------ Loop until we create a valid object ------------------- - */ - while (!PendingObjectPtr) { - /* - ................... Get house for this object type .................... - */ - if (!Verify_House(LastHouse,Objects[LastChoice])) { - LastHouse = Cycle_House(LastHouse,Objects[LastChoice]); - } - - /* - ....................... Create placement object ....................... - */ - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse)); - - /* - .................. If this one failed, try the next ................... - */ - if (!PendingObjectPtr) { - PendingObject = NULL; - LastChoice--; - if (LastChoice < 0) { - LastChoice = ObjCount - 1; - } - } - } - - /* - ------------------------ Set the new cursor shape ------------------------ - */ - Set_Cursor_Pos(); - Set_Cursor_Shape(0); - Set_Cursor_Shape(PendingObject->Occupy_List()); - - /* - ----------------- Redraw the map to erase old leftovers ------------------ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::Place_Home -- homes the placement object * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/03/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Place_Home(void) -{ - delete PendingObjectPtr; - PendingObjectPtr = NULL; - PendingObject = NULL; - - /* - ** Don't allow this command if we're building a base; the only valid - ** category for base-building is buildings. - */ - if (BaseBuilding) { - return; - } - - /* - ------------------ Loop until we create a valid object ------------------- - */ - LastChoice = 0; - while (!PendingObjectPtr) { - /* - ................... Get house for this object type .................... - */ - if (!Verify_House(LastHouse,Objects[LastChoice])) { - LastHouse = Cycle_House(LastHouse,Objects[LastChoice]); - } - - /* - ....................... Create placement object ....................... - */ - PendingObject = Objects[LastChoice]; - PendingHouse = LastHouse; - PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse)); - - /* - .................. If this one failed, try the next ................... - */ - if (!PendingObjectPtr) { - PendingObject = NULL; - LastChoice++; - if (LastChoice == ObjCount) { - LastChoice = 0; - } - } - } - - /* - ------------------------ Set the new cursor shape ------------------------ - */ - Set_Cursor_Pos(); - Set_Cursor_Shape(0); - Set_Cursor_Shape(PendingObject->Occupy_List()); - - /* - ----------------- Redraw the map to erase old leftovers ------------------ - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); -} - - -/*************************************************************************** - * MapEditClass::Toggle_House -- toggles current placement object's house * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/04/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Toggle_House(void) -{ - TechnoClass *tp; - - /* - ** Don't allow this command if we're building a base; the only valid - ** house for base-building is the one assigned to the base. - */ - if (BaseBuilding) { - return; - } - - /*------------------------------------------------------------------------ - Only techno objects can be owned by a house; return if not a techno - ------------------------------------------------------------------------*/ - if (!PendingObjectPtr->Is_Techno()) { - return; - } - - /*------------------------------------------------------------------------ - Select the house that will own this object - ------------------------------------------------------------------------*/ - LastHouse = Cycle_House(PendingObjectPtr->Owner(), PendingObject); - - /*------------------------------------------------------------------------ - Change the house - ------------------------------------------------------------------------*/ - tp = (TechnoClass *)PendingObjectPtr; - tp->House = HouseClass::As_Pointer(LastHouse); - - /*------------------------------------------------------------------------ - Set house variables to new house - ------------------------------------------------------------------------*/ - PendingHouse = LastHouse; -} - - -/*************************************************************************** - * MapEditClass::Set_House_Buttons -- toggles house buttons for btn list * - * * - * Looks in the given button list for the given GDI, NOD & Neutral button * - * id's. Sets the On/Off state of the buttons based on the given house, * - * only if that button is found in the list. * - * * - * INPUT: * - * house house to set buttons to * - * btnlist ptr to button list to search * - * base_id button ID for GDI; assumes other id's are sequential* - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/23/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Set_House_Buttons(HousesType house, GadgetClass *btnlist, int base_id) -{ - HousesType h; - int id; - TextButtonClass *btn; - - /* - ** Loop through all houses, searching the button list for each one. - */ - for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { - - /* - ** Compute the desired button ID; get a pointer to the button - */ - id = (int)h + base_id; - btn = (TextButtonClass *)btnlist->Extract_Gadget(id); - if (btn) { - - /* - ** If this house value is the desired one, turn the button on; - ** otherwise, turn it off. - */ - if (h == house) { - btn->Turn_On(); - } else { - btn->Turn_Off(); - } - } - } -} - - -/*************************************************************************** - * MapEditClass::Start_Trigger_Placement -- enters trigger placement mode * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Start_Trigger_Placement(void) -{ - Set_Default_Mouse(MOUSE_CAN_MOVE); - Override_Mouse_Shape(MOUSE_CAN_MOVE); -} - - -/*************************************************************************** - * MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Stop_Trigger_Placement(void) -{ - CurTrigger = NULL; - Set_Default_Mouse(MOUSE_NORMAL); - Override_Mouse_Shape(MOUSE_NORMAL); -} - - -/*************************************************************************** - * MapEditClass::Place_Trigger -- assigns trigger to object or cell * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Place_Trigger(void) -{ - ObjectClass * object=NULL; // Generic object clicked on. - int x,y; - CELL cell; // Cell that was selected. - - /* - -------------------- See if an object was clicked on --------------------- - */ - x = _Kbd->MouseQX; - y = _Kbd->MouseQY; - - /* - ............................ Get cell for x,y ............................ - */ - cell = Click_Cell_Calc(x, y); - - /* - ............... Convert x,y to offset from cell upper-left ............... - */ - x = (x-TacPixelX) % ICON_PIXEL_W; - y = (y-TacPixelY) % ICON_PIXEL_H; - - /* - ......................... Get object at that x,y ......................... - */ - object = Cell_Object(cell, x, y); - - /* - ---------------------- Assign trigger to an object ----------------------- - */ - if (object && TriggerClass::Event_Need_Object(CurTrigger->Event)) { - object->Trigger = CurTrigger; - } else { - - /* - ------------------------ Assign trigger to a cell ------------------------ - */ - if (CurTrigger->Event <= EVENT_OBJECTFIRST) { - Map[cell].IsTrigger = 1; - CellTriggers[cell] = CurTrigger; - } - } - - /* - -------------------------- Force map to redraw --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); -} - - -/*************************************************************************** - * MapEditClass::Start_Base_Building -- starts base-building mode * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Start_Base_Building(void) -{ - /* - ** Fully build the base so the user can edit it - */ - Build_Base_To(100); - - /* - ** Start placement mode - */ - BaseBuilding = 1; - Start_Placement(); - - /* - ** Force map to redraw - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); -} - - -/*************************************************************************** - * MapEditClass::Cancel_Base_Building -- stops base-building mode * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Cancel_Base_Building(void) -{ - /* - ** Build the base to the proper amount - */ - Build_Base_To(BasePercent); - - /* - ** Cancel placement mode - */ - Cancel_Placement(); - BaseBuilding = 0; - - /* - ** Force map to redraw - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); -} - - -/*************************************************************************** - * MapEditClass::Build_Base_To -- builds the AI base to the given percent * - * * - * INPUT: * - * percent percentage to build base to * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/01/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Build_Base_To(int percent) -{ - int i; - int num_buildings; - BuildingTypeClass const *objtype; - BuildingClass *obj; - - //ScenarioInit++; - - /* - ** Completely dismantle the base, so we start at a known point - */ - for (i = 0; i < Base.Nodes.Count(); i++) { - if (Base.Is_Built(i)) { - obj = Base.Get_Building(i); - delete obj; - } - } - - /* - ** Compute number of buildings to build - */ - num_buildings = (Base.Nodes.Count() * percent) / 100; - - /* - ** Build the base to the desired amount - */ - for (i = 0; i < num_buildings; i++) { - /* - ** Get a ptr to the type of building to build, create one, and unlimbo it. - */ - objtype = &BuildingTypeClass::As_Reference(Base.Nodes[i].Type); - obj = (BuildingClass *)objtype->Create_One_Of(HouseClass::As_Pointer(Base.House)); - /* - ** If unlimbo fails, error out - */ - if (!obj->Unlimbo(Base.Nodes[i].Coord)) { - delete obj; - CCMessageBox().Process("Unable to build base!"); - return; - } - } - - //ScenarioInit--; -} - - -#endif diff --git a/code/TIBERIANDAWN/MAPEDSEL.CPP b/code/TIBERIANDAWN/MAPEDSEL.CPP deleted file mode 100644 index c2f35fa..0000000 --- a/code/TIBERIANDAWN/MAPEDSEL.CPP +++ /dev/null @@ -1,604 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapedsel.cpv 2.18 16 Oct 1995 16:49:58 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPEDSEL.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : November 18, 1994 * - * * - * Last Update : February 2, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * Object-selection & manipulation routines * - *-------------------------------------------------------------------------* - * Functions: * - * MapEditClass::Select_Object -- selects an object for processing * - * MapEditClass::Select_Next -- selects next object on the map * - * MapEditClass::Popup_Controls -- shows/hides the pop-up object controls* - * MapEditClass::Grab_Object -- grabs the current object * - * MapEditClass::Move_Grabbed_Object -- moves the grabbed object * - * MapEditClass::Change_House -- changes CurrentObject's house * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef SCENARIO_EDITOR - - -/*************************************************************************** - * Select_Object -- selects an object for processing * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = object selected, -1 = none * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/04/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Select_Object(void) -{ - ObjectClass *object=NULL; // Generic object clicked on. - int x,y; - CELL cell; // Cell that was selected. - int rc=0; - - /* - -------------------- See if an object was clicked on --------------------- - */ - x = _Kbd->MouseQX; - y = _Kbd->MouseQY; - - /* - ............................ Get cell for x,y ............................ - */ - cell = Click_Cell_Calc(x, y); - - /* - ............... Convert x,y to offset from cell upper-left ............... - */ - x = (x-TacPixelX) % ICON_PIXEL_W; - y = (y-TacPixelY) % ICON_PIXEL_H; - - /* - ......................... Get object at that x,y ......................... - */ - object = Cell_Object(cell, x, y); - - /* - ----------------- If no object, unselect the current one ----------------- - */ - if (!object) { - if (CurrentObject.Count()) { - /* - ................... Unselect all current objects ................... - */ - Unselect_All(); - - /* - ..................... Turn off object controls ..................... - */ - Popup_Controls(); - } - rc = -1; - } else { - - /* - ------------------ Select object only if it's different ------------------ - */ - if (!CurrentObject.Count() || (CurrentObject.Count() && object != CurrentObject[0])) { - /* - ..................... Unselect all current objects .................... - */ - Unselect_All(); - object->Select(); - - /* - ................... Set mouse shape back to normal .................... - */ - Set_Default_Mouse(MOUSE_NORMAL); - Override_Mouse_Shape(MOUSE_NORMAL); - - /* - ....................... Show the popup controls ....................... - */ - Popup_Controls(); - } - } - - /* - -------------------------- Force map to redraw --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - - return(rc); -} - - -/*************************************************************************** - * MapEditClass::Select_Next -- selects next object on the map * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/22/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Select_Next(void) -{ - ObjectClass * obj; - CELL obj_cell; - int smap_w; // screen map width in icons - int smap_h; // screen map height in icons - int cell_x; // cell-x of next object - int cell_y; // cell-y of next object - int tcell_x; // cell-x of TacticalCell - int tcell_y; // cell-y of TacticalCell - - /* - ----------------------- Get next object on the map ----------------------- - */ - obj = Map.Next_Object(CurrentObject[0]); - - if (obj) { - /* - ............... Unselect current object if there is one ............... - */ - Unselect_All(); - - /* - ......................... Select this object .......................... - */ - obj->Select(); - } - - /* - --------------------- Restore mouse shape to normal ---------------------- - */ - Set_Default_Mouse(MOUSE_NORMAL); - Override_Mouse_Shape(MOUSE_NORMAL); - - /* - -------------------------- Show pop-up controls -------------------------- - */ - Popup_Controls(); - - /* - ---------------- Make sure object is shown on the screen ----------------- - */ - /* - ..................... compute screen map dimensions ...................... - */ - smap_w = Lepton_To_Cell(TacLeptonWidth); - smap_h = Lepton_To_Cell(TacLeptonHeight); - - /* - ...................... compute x,y of object's cell ...................... - */ - obj_cell = Coord_Cell(CurrentObject[0]->Coord); - cell_x = Cell_X(obj_cell); - cell_y = Cell_Y(obj_cell); - tcell_x = Coord_XCell(TacticalCoord); - tcell_y = Coord_YCell(TacticalCoord); - - /* - ................... If object is off-screen, move map .................... - */ - if (cell_x < tcell_x) { - tcell_x = cell_x; - } else { - if (cell_x >= tcell_x + smap_w) { - tcell_x = cell_x - smap_w + 1; - } - } - - if (cell_y < tcell_y) { - tcell_y = cell_y; - } else { - if (cell_y >= tcell_y + smap_h) { - tcell_y = cell_y - smap_h + 1; - } - } - - ScenarioInit++; - Set_Tactical_Position(XY_Coord(Cell_To_Lepton(tcell_x), Cell_To_Lepton(tcell_y))); - ScenarioInit--; - - /* - -------------------------- Force map to redraw --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); -} - - -/*************************************************************************** - * MapEditClass::Popup_Controls -- shows/hides the pop-up object controls * - * * - * Call this routine whenever the CurrentObject changes. The routine will * - * selectively enable or disable the popup controls based on whether * - * CurrentObject is NULL, or if it's a Techno object, or what type of * - * Techno object it is. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/22/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Popup_Controls(void) -{ - const TechnoTypeClass * objtype = NULL; - HousesType owner; // object's current owner - int mission_index; // object's current mission - int strength; // object's 0-255 strength value - int i; - - /*------------------------------------------------------------------------ - Remove all buttons from GScreen's button list (so none of them provide - input any more); then, destroy the list by Zapping each button. Then, - we'll have to add at least the MapArea button back to the Input button - list before we return, plus any other buttons to process input for. We - always must add MapArea LAST in the list, so it doesn't intercept the - other buttons' input. - ------------------------------------------------------------------------*/ - Remove_A_Button(*GDIButton); - Remove_A_Button(*NODButton); - Remove_A_Button(*NeutralButton); - Remove_A_Button(*Multi1Button); - Remove_A_Button(*Multi2Button); - Remove_A_Button(*Multi3Button); - Remove_A_Button(*Multi4Button); - Remove_A_Button(*MissionList); - Remove_A_Button(*HealthGauge); - Remove_A_Button(*HealthText); - Remove_A_Button(*FacingDial); - Remove_A_Button(*BaseGauge); - Remove_A_Button(*BaseLabel); - Remove_A_Button(*MapArea); - - /* - ------------------ If no current object, hide the list ------------------- - */ - if (!CurrentObject.Count()) { - Add_A_Button(*BaseGauge); - Add_A_Button(*BaseLabel); - Add_A_Button(*MapArea); - return; - } - - /* - --------------- If not Techno, no need for editing buttons --------------- - */ - if (!CurrentObject[0]->Is_Techno()) { - Add_A_Button(*BaseGauge); - Add_A_Button(*BaseLabel); - Add_A_Button(*MapArea); - return; - } - - objtype = (TechnoTypeClass const *)&CurrentObject[0]->Class_Of(); - - /* - ---------------------- Get object's current values ----------------------- - */ - owner = CurrentObject[0]->Owner(); - mission_index = 0; - for (i = 0; i < NUM_EDIT_MISSIONS; i++) { - if (CurrentObject[0]->Get_Mission() == MapEditMissions[i]) { - mission_index = i; - } - } - strength = CurrentObject[0]->Health_Ratio(); - - - /* - ----------------------------- House buttons ------------------------------ - */ - if (ScenPlayer == SCEN_PLAYER_MPLAYER) { - if (Verify_House(HOUSE_NEUTRAL, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*NeutralButton); - } - if (Verify_House(HOUSE_MULTI1, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*Multi1Button); - } - if (Verify_House(HOUSE_MULTI2, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*Multi2Button); - } - if (Verify_House(HOUSE_MULTI3, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*Multi3Button); - } - if (Verify_House(HOUSE_MULTI4, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*Multi4Button); - } - } else { - if (Verify_House(HOUSE_NEUTRAL, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*NeutralButton); - } - if (Verify_House(HOUSE_BAD, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*NODButton); - } - if (Verify_House(HOUSE_GOOD, &CurrentObject[0]->Class_Of())) { - Add_A_Button(*GDIButton); - } - } - - /* - ........................ Set house button states ......................... - */ - if (Buttons) { - Set_House_Buttons(owner, Buttons, POPUP_GDI); - } - - switch (objtype->What_Am_I()) { - case RTTI_UNITTYPE: - case RTTI_INFANTRYTYPE: - case RTTI_AIRCRAFTTYPE: - MissionList->Set_Selected_Index(mission_index); - HealthGauge->Set_Value(strength); - sprintf(HealthBuf, "%d", CurrentObject[0]->Strength); - FacingDial->Set_Direction(((TechnoClass *)CurrentObject[0])->PrimaryFacing); - - /* - ** Make the list. - */ - Add_A_Button(*MissionList); - Add_A_Button(*HealthGauge); - Add_A_Button(*HealthText); - Add_A_Button(*FacingDial); - break; - - case RTTI_BUILDINGTYPE: - HealthGauge->Set_Value(strength); - sprintf(HealthBuf, "%d", CurrentObject[0]->Strength); - Add_A_Button(*HealthGauge); - Add_A_Button(*HealthText); - - if (objtype->IsTurretEquipped) { - FacingDial->Set_Direction(((TechnoClass *) CurrentObject[0])->PrimaryFacing); - Add_A_Button(*FacingDial); - } - break; - } - - /*------------------------------------------------------------------------ - Add the map area last, so it's "underneath" the other buttons, and won't - intercept input for those buttons. - ------------------------------------------------------------------------*/ - Add_A_Button(*BaseGauge); - Add_A_Button(*BaseLabel); - Add_A_Button(*MapArea); -} - - -/*************************************************************************** - * MapEditClass::Grab_Object -- grabs the current object * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/07/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Grab_Object(void) -{ - CELL cell; - - if (CurrentObject.Count()) { - GrabbedObject = CurrentObject[0]; - - /*------------------------------------------------------------------------ - Find out which cell 'ZoneCell' is in relation to the object's current cell - ------------------------------------------------------------------------*/ - cell = Coord_Cell(GrabbedObject->Coord); - GrabOffset = cell - ZoneCell; - } -} - - -/*************************************************************************** - * MapEditClass::Move_Grabbed_Object -- moves the grabbed object * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = object moved, -1 = it didn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/07/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Move_Grabbed_Object(void) -{ - COORDINATE new_coord = 0; - int retval = -1; - - /* - --------------------------- Lift up the object --------------------------- - */ - GrabbedObject->Mark(MARK_UP); - - /*------------------------------------------------------------------------ - If infantry, use a free spot in this cell - ------------------------------------------------------------------------*/ - if (GrabbedObject->Is_Infantry()) { - - if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()))) { - new_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(), - Get_Mouse_Y())); - /*.................................................................. - Clear the occupied bit in this infantry's cell. - ..................................................................*/ - ((InfantryClass *)GrabbedObject)->Clear_Occupy_Bit(GrabbedObject->Coord); -// Map[Coord_Cell(GrabbedObject->Coord)].Flag.Composite &= -// ~(1 << CellClass::Spot_Index(GrabbedObject->Coord)); - } else { - new_coord = NULL; - } - - } else { - - /*------------------------------------------------------------------------ - Non-infantry: use cell's center coordinate - ------------------------------------------------------------------------*/ - new_coord = Cell_Coord(ZoneCell + GrabOffset); - - if (GrabbedObject->What_Am_I() == RTTI_BUILDING || - GrabbedObject->What_Am_I() == RTTI_TERRAIN) { - - new_coord &= 0xFF00FF00L; - } - - /* - ................ Try to place object at new coordinate ................ - */ - if (GrabbedObject->Can_Enter_Cell(Coord_Cell(new_coord)) != MOVE_OK) { - new_coord = NULL; - } - } - if (new_coord != NULL) { - /* - ** If this object is part of the AI's Base list, change the coordinate - ** in the Base's Node list. - */ - if (GrabbedObject->What_Am_I()==RTTI_BUILDING && - Base.Get_Node((BuildingClass *)GrabbedObject)) - Base.Get_Node((BuildingClass *)GrabbedObject)->Coord = new_coord; - - GrabbedObject->Coord = new_coord; - retval = 0; - } - GrabbedObject->Mark(MARK_DOWN); - - /*------------------------------------------------------------------------ - For infantry, set the bit in its new cell marking that spot as occupied. - ------------------------------------------------------------------------*/ - if (GrabbedObject->Is_Infantry()) { - ((InfantryClass *)GrabbedObject)->Set_Occupy_Bit(new_coord); -// Map[Coord_Cell(new_coord)].Flag.Composite |= -// (1 << CellClass::Spot_Index(new_coord)); - } - - /*------------------------------------------------------------------------ - Re-select the object, and reset the mouse pointer - ------------------------------------------------------------------------*/ - Set_Default_Mouse(MOUSE_NORMAL); - Override_Mouse_Shape(MOUSE_NORMAL); - - Flag_To_Redraw(true); - - return(retval); -} - - -/*************************************************************************** - * MapEditClass::Change_House -- changes CurrentObject's house * - * * - * INPUT: * - * newhouse house to change to * - * * - * OUTPUT: * - * 1 = house was changed, 0 = it wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/17/1994 BR : Created. * - *=========================================================================*/ -bool MapEditClass::Change_House(HousesType newhouse) -{ - TechnoClass *tp; - - /*------------------------------------------------------------------------ - Return if no current object - ------------------------------------------------------------------------*/ - if (!CurrentObject.Count()) { - return(false); - } - - /*------------------------------------------------------------------------ - Only techno objects can be owned by a house; return if not a techno - ------------------------------------------------------------------------*/ - if (!CurrentObject[0]->Is_Techno()) { - return(false); - } - - /*------------------------------------------------------------------------ - You can't change the house if the object is part of the AI's Base. - ------------------------------------------------------------------------*/ - if (CurrentObject[0]->What_Am_I()==RTTI_BUILDING && Base.Is_Node((BuildingClass *)CurrentObject[0])) { - return(false); - } - - /*------------------------------------------------------------------------ - Verify that the target house exists - ------------------------------------------------------------------------*/ - if (HouseClass::As_Pointer(newhouse)==NULL) { - return(false); - } - - /*------------------------------------------------------------------------ - Verify that this is a valid owner - ------------------------------------------------------------------------*/ - if (!Verify_House(newhouse, &CurrentObject[0]->Class_Of())) { - return(false); - } - - /*------------------------------------------------------------------------ - Change the house - ------------------------------------------------------------------------*/ - tp = (TechnoClass *)CurrentObject[0]; - tp->House = HouseClass::As_Pointer(newhouse); - - return(true); -} - - -#endif diff --git a/code/TIBERIANDAWN/MAPEDTM.CPP b/code/TIBERIANDAWN/MAPEDTM.CPP deleted file mode 100644 index adf8d77..0000000 --- a/code/TIBERIANDAWN/MAPEDTM.CPP +++ /dev/null @@ -1,2074 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapedtm.cpv 2.18 16 Oct 1995 16:52:16 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPEDTM.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 7, 1994 * - * * - * Last Update : April 9, 1996 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * MapEditClass::Handle_Teams -- main team-dialog-handling function * - * MapEditClass::Select_Team -- user selects a team from a list * - * MapEditClass::Edit_Team -- user edits a team's options * - * MapEditClass::Team_Members -- user picks makeup of a team * - * MapEditClass::Build_Mission_list -- fills in mission list box * - * MapEditClass::Draw_Member -- Draws a member of the team dialog box. * - * MapEditClass::Team_Members -- Team members dialog * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#ifdef SCENARIO_EDITOR - - -/*************************************************************************** - * MapEditClass::Handle_Teams -- main team-dialog-handling function * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/08/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Handle_Teams(char const * caption) -{ - int rc; - - /*------------------------------------------------------------------------ - Team dialog processing loop: - - Invoke the team selection dialog. If a team's selected, break - & return - - If user wants to edit the current team, do so - - If user wants to create new team, new a TeamTypeClass & edit it - - If user wants to delete team, delete the current team - - Keep looping until 'OK' - ------------------------------------------------------------------------*/ - for (;;) { - - /* - ............................. Select team ............................. - */ - rc = Select_Team(caption); - - /* - ............................. 'OK'; break ............................. - */ - if (rc == 0) { - break; - } else { - - /* - ............................... 'Edit' ................................ - */ - if (rc == 1 && CurTeam) { - if (Edit_Team()==0) { - Changed = 1; - } - } else { - - /* - ................................ 'New' ................................ - */ - if (rc == 2) { - /* - ........................ Create a new team ......................... - */ - CurTeam = new TeamTypeClass(); - if (CurTeam) { - /* - ................... delete it if user cancels ................... - */ - if (Edit_Team()==-1) { - delete CurTeam; - CurTeam = NULL; - } else { - Changed = 1; - } - } else { - - /* - ................. Unable to create; issue warning .................. - */ - CCMessageBox().Process("No more teams available."); - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - } - } else { - - /* - .............................. 'Delete' ............................... - */ - if (rc==3) { - if (CurTeam) { - CurTeam->Remove(); - CurTeam = NULL; - } - } - } - } - } - } -} - - -/*************************************************************************** - * MapEditClass::Select_Team -- user selects a team from a list * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Teams ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ Name House Class:Count,Class:Count ³³ ³ * - * ³ ³ Name House Class:Count,Class:Count ÃÄ´ ³ * - * ³ ³ Name House Class:Count,Class:Count ³ ³ ³ * - * ³ ³ Name House Class:Count,Class:Count ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ * - * ³ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ ³ * - * ³ [Edit] [New] [Delete] [OK] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, 1 = Edit, 2 = New, 3 = Delete * - * * - * WARNINGS: * - * Uses HIDBUFF. * - * * - * HISTORY: * - * 12/08/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Select_Team(char const * caption) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 528, // dialog width - D_DIALOG_H = 290, // dialog height - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), // centered x-coord - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), // centered y-coord - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center - - D_TXT8_H = 22, // ht of 8-pt text - D_MARGIN = 14, // margin width/height - - D_LIST_W = 500, - D_LIST_H = 208, - D_LIST_X = D_DIALOG_X + D_MARGIN, - D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_EDIT_W = 90, - D_EDIT_H = 18, - D_EDIT_X = D_DIALOG_X + (D_DIALOG_W / 8) - (D_EDIT_W / 2), - D_EDIT_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_EDIT_H, - - D_NEW_W = 90, - D_NEW_H = 18, - D_NEW_X = D_DIALOG_X + (D_DIALOG_W / 8) * 3 - (D_NEW_W / 2), - D_NEW_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_NEW_H, - - D_DELETE_W = 90, - D_DELETE_H = 18, - D_DELETE_X = D_DIALOG_X + (D_DIALOG_W / 8) * 5 - (D_DELETE_W / 2), - D_DELETE_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_DELETE_H, - - D_OK_W = 90, - D_OK_H = 18, - D_OK_X = D_DIALOG_X + (D_DIALOG_W / 8) * 7 - (D_OK_W / 2), - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - - TEAMTXT_LEN = 43, // max length of a team entry - }; - - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - TEAM_LIST=100, - BUTTON_EDIT, - BUTTON_NEW, - BUTTON_DELETE, - BUTTON_OK, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - char *teamtext[TEAMTYPE_MAX + 1]; // text for defined teams - KeyNumType input; // user input - bool edit_team = false; // true = user wants to edit - bool new_team = false; // true = user wants to new - bool del_team = false; // true = user wants to new - int i; // loop counters - int j; - int def_idx; // default list index - static int tabs[] = {120, 180}; // list box tab stops - char txt[10]; -// int housetxt; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands = NULL; // the button list - - ListClass teamlist (TEAM_LIST, - D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - TextButtonClass editbtn (BUTTON_EDIT, "Edit", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_EDIT_X, D_EDIT_Y, D_EDIT_W, D_EDIT_H); - - TextButtonClass newbtn (BUTTON_NEW, "New", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NEW_X, D_NEW_Y, D_NEW_W, D_NEW_H); - - TextButtonClass deletebtn (BUTTON_DELETE, "Delete", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_DELETE_X, D_DELETE_Y, D_DELETE_W, D_DELETE_H); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ........................... Fill in team names ........................... - */ - def_idx = 0; - for (i = 0; i < TeamTypes.Count(); i++) { - /* - ................... Generate string for this team ..................... - */ - //teamtext[i] = (char *)HidPage.Get_Graphic_Buffer()->Get_Buffer() + TEAMTXT_LEN * i; - teamtext[i] = new char[255]; - - /* - ........................ Fill in name & house ......................... - */ - strcpy(teamtext[i],TeamTypes.Ptr(i)->IniName); - strcat(teamtext[i],"\t"); - strcat(teamtext[i], HouseTypeClass::As_Reference(TeamTypes.Ptr(i)->House).Suffix); - strcat(teamtext[i],"\t"); - - /* - ................ Fill in class & count for all classes ................ - */ - for (j = 0; j < TeamTypes.Ptr(i)->ClassCount; j++) { - sprintf (txt,"%s:%d", TeamTypes.Ptr(i)->Class[j]->IniName, TeamTypes.Ptr(i)->DesiredNum[j]); - - /*.................................................................. - Add entry if there's room; break otherwise - (+ 3 for the ", " and the NULL; +3 again for the "..." for the next - entry) - ..................................................................*/ - if (strlen(txt) + strlen(teamtext[i]) + 6 < TEAMTXT_LEN) { - if (j > 0) { - strcat(teamtext[i],", "); - } - strcat(teamtext[i],txt); - } else { - strcat(teamtext[i], "..."); - break; - } - } - - /* - .................. Set def_idx if this is CurTeam ..................... - */ - if (TeamTypes.Ptr(i)==CurTeam) { - def_idx = i; - } - - /* - ........................... Add to list box ........................... - */ - teamlist.Add_Item(teamtext[i]); - } - - /* - ....................... Set CurTeam if it isn't .......................... - */ - if (TeamTypes.Count()==0) { - CurTeam = NULL; - } else { - if (!CurTeam) { - CurTeam = TeamTypes.Ptr(def_idx); - } - } - - /* - ............................ Create the list ............................. - */ - commands = &teamlist; - editbtn.Add_Tail(*commands); - newbtn.Add_Tail(*commands); - deletebtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - - /* - ------------------------ Init tab stops for list ------------------------- - */ - teamlist.Set_Tabs(tabs); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print(caption, D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (TEAM_LIST | KN_BUTTON): - def_idx = teamlist.Current_Index(); - if (def_idx < TeamTypes.Count()) - CurTeam = TeamTypes.Ptr(def_idx); - break; - - case (BUTTON_EDIT | KN_BUTTON): - if (CurTeam) { // only allow if there's one selected - process = false; - edit_team = true; - } - break; - - case (BUTTON_NEW | KN_BUTTON): - process = false; - new_team = true; - break; - - case (BUTTON_DELETE | KN_BUTTON): - process = false; - del_team = true; - break; - - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - for (i = 0; i < TeamTypes.Count(); i++) { - delete [] teamtext[i]; - } - if (edit_team) return(1); - if (new_team) return(2); - if (del_team) return(3); - return(0); -} - - -/*************************************************************************** - * MapEditClass::Edit_Team -- user edits a team's options * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Team Editor ³ * - * ³ ³ * - * ³ Name ______ [Roundabout] ³ * - * ³ Priority ______ [ GDI ] [Learning ] ³ * - * ³ Max Num ______ [ NOD ] [Suicide ] ³ * - * ³ Init Num ______ [Autocreate] ³ * - * ³ Fear ______ [Mercenary ] ³ * - * ³ [Prebuild ] ³ * - * ³ [Reinforce ] ³ * - * ³ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ ³^³ ³ ³^³ ³ * - * ³ ³ ÃÄ´ [Add >>] ³ ÃÄ´ ³ * - * ³ ³ ³ ³ [Insert] ³ ³ ³ ³ * - * ³ ³ ³ ³ [Delete] ³ ³ ³ ³ * - * ³ ³ ÃÄ´ ____ ³ ÃÄ´ ³ * - * ³ ³ ³v³ ³ ³v³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ ³ * - * ³ [Members] [Cancel] [OK] ³ * - * ³ ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * CurTeam must NOT be NULL when this function is called. * - * This routine invokes the Members dialog, which uses HIDBUFF. * - * * - * HISTORY: * - * 12/08/1994 BR : Created. * - *=========================================================================*/ -int MapEditClass::Edit_Team(void) -{ - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - enum { - D_DIALOG_W = 516, - D_DIALOG_H = 376, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_Y = ((400 - D_DIALOG_H) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT8_H = 22, - D_MARGIN = 14, - - D_NAME_W = 120, - D_NAME_H = 18, - D_NAME_X = D_DIALOG_X + D_MARGIN + 100, - D_NAME_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H, - - D_PRIORITY_W = 120, - D_PRIORITY_H = 18, - D_PRIORITY_X = D_DIALOG_X + D_MARGIN + 100, - D_PRIORITY_Y = D_NAME_Y + D_NAME_H, - - D_MAXNUM_W = 120, - D_MAXNUM_H = 18, - D_MAXNUM_X = D_DIALOG_X + D_MARGIN + 100, - D_MAXNUM_Y = D_PRIORITY_Y + D_PRIORITY_H, - - D_INITNUM_W = 120, - D_INITNUM_H = 18, - D_INITNUM_X = D_DIALOG_X + D_MARGIN + 100, - D_INITNUM_Y = D_MAXNUM_Y + D_MAXNUM_H, - - D_FEAR_W = 120, - D_FEAR_H = 18, - D_FEAR_X = D_DIALOG_X + D_MARGIN + 100, - D_FEAR_Y = D_INITNUM_Y + D_INITNUM_H, - - D_GDI_W = 100, - D_GDI_H = 18, - D_GDI_X = D_NAME_X + D_NAME_W + D_MARGIN, - D_GDI_Y = D_NAME_Y + D_NAME_H + D_NAME_H / 2, - - D_NOD_W = 100, - D_NOD_H = 18, - D_NOD_X = D_NAME_X + D_NAME_W + D_MARGIN, - D_NOD_Y = D_GDI_Y + D_GDI_H, - - D_NEU_W = 100, - D_NEU_H = 18, - D_NEU_X = D_NAME_X + D_NAME_W + D_MARGIN, - D_NEU_Y = D_NOD_Y + D_NOD_H, - - D_MULTI1_W = 50, - D_MULTI1_H = 18, - D_MULTI1_X = D_GDI_X, - D_MULTI1_Y = D_GDI_Y, - - D_MULTI2_W = 50, - D_MULTI2_H = 18, - D_MULTI2_X = D_GDI_X + D_MULTI2_W, - D_MULTI2_Y = D_GDI_Y, - - D_MULTI3_W = 50, - D_MULTI3_H = 18, - D_MULTI3_X = D_NOD_X, - D_MULTI3_Y = D_NOD_Y, - - D_MULTI4_W = 50, - D_MULTI4_H = 18, - D_MULTI4_X = D_NOD_X + D_MULTI4_W, - D_MULTI4_Y = D_NOD_Y, - - D_ROUNDABOUT_W = 130, - D_ROUNDABOUT_H = 18, - D_ROUNDABOUT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_ROUNDABOUT_W, - D_ROUNDABOUT_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H - 10, - - D_LEARNING_W = D_ROUNDABOUT_W, - D_LEARNING_H = 18, - D_LEARNING_X = D_ROUNDABOUT_X, - D_LEARNING_Y = D_ROUNDABOUT_Y + D_ROUNDABOUT_H, - - D_SUICIDE_W = D_ROUNDABOUT_W, - D_SUICIDE_H = 18, - D_SUICIDE_X = D_ROUNDABOUT_X, - D_SUICIDE_Y = D_LEARNING_Y + D_LEARNING_H, - - D_AUTOCREATE_W = D_ROUNDABOUT_W, - D_AUTOCREATE_H = 18, - D_AUTOCREATE_X = D_ROUNDABOUT_X, - D_AUTOCREATE_Y = D_SUICIDE_Y + D_SUICIDE_H, - - D_MERCENARY_W = D_ROUNDABOUT_W, - D_MERCENARY_H = 18, - D_MERCENARY_X = D_ROUNDABOUT_X, - D_MERCENARY_Y = D_AUTOCREATE_Y + D_AUTOCREATE_H, - - D_PREBUILT_W = D_ROUNDABOUT_W, - D_PREBUILT_H = 18, - D_PREBUILT_X = D_ROUNDABOUT_X, - D_PREBUILT_Y = D_MERCENARY_Y + D_MERCENARY_H, - - D_REINFORCE_W = D_ROUNDABOUT_W, - D_REINFORCE_H = 18, - D_REINFORCE_X = D_ROUNDABOUT_X, - D_REINFORCE_Y = D_PREBUILT_Y + D_PREBUILT_H, - - D_MISSION1_W = 180, - D_MISSION1_H = 128, - D_MISSION1_X = D_DIALOG_X + D_MARGIN, - D_MISSION1_Y = D_REINFORCE_Y + D_REINFORCE_H + D_MARGIN, - - D_MISSION2_W = 180, - D_MISSION2_H = 128, - D_MISSION2_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_MISSION2_W, - D_MISSION2_Y = D_MISSION1_Y, - - D_ADD_W = 100, - D_ADD_H = 18, - D_ADD_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN, - D_ADD_Y = D_MISSION1_Y + D_ADD_H, - - D_INSERT_W = 100, - D_INSERT_H = 18, - D_INSERT_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN, - D_INSERT_Y = D_ADD_Y + D_ADD_H, - - D_DEL_W = 100, - D_DEL_H = 18, - D_DEL_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN, - D_DEL_Y = D_INSERT_Y + D_INSERT_H, - - D_ARG_W = 100, - D_ARG_H = 18, - D_ARG_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN, - D_ARG_Y = D_DEL_Y + D_DEL_H, - - D_MEMBERS_W = 100, - D_MEMBERS_H = 18, - D_MEMBERS_X = D_DIALOG_X + (D_DIALOG_W / 6) - D_MEMBERS_W / 2, - D_MEMBERS_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_MEMBERS_H, - - D_CANCEL_W = 100, - D_CANCEL_H = 18, - D_CANCEL_X = D_DIALOG_X + (D_DIALOG_W / 6) * 3 - D_CANCEL_W / 2, - D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_CANCEL_H, - - D_OK_W = 100, - D_OK_H = 18, - D_OK_X = D_DIALOG_X + (D_DIALOG_W / 6) * 5 - D_OK_W / 2, - D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H, - }; - - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - BUTTON_NAME=100, - BUTTON_RECRUIT, - BUTTON_MAXNUM, - BUTTON_INITNUM, - BUTTON_FEAR, - BUTTON_GDI, - BUTTON_NOD, - BUTTON_NEU, - BUTTON_JP, // placeholder - BUTTON_MULTI1, - BUTTON_MULTI2, - BUTTON_MULTI3, - BUTTON_MULTI4, - BUTTON_MULTI5, - BUTTON_MULTI6, - BUTTON_ROUNDABOUT, - BUTTON_LEARNING, - BUTTON_SUICIDE, - BUTTON_AUTO, - BUTTON_MERCENARY, - BUTTON_PREBUILT, - BUTTON_REINFORCE, - BUTTON_MISSION1, - BUTTON_MISSION2, - BUTTON_ADD, - BUTTON_INSERT, - BUTTON_DEL, - BUTTON_ARG, - BUTTON_MEMBERS, - BUTTON_OK, - BUTTON_CANCEL, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables: - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - KeyNumType input; - bool cancel = false; // true = user cancels - char name_buf[12]; - char recr_buf[4]; - char maxnum_buf[4]; - char initnum_buf[4]; - char fear_buf[4]; - HousesType house; - int roundabout; - int learning; - int suicide; - int autocreate; - int mercenary; - int prebuilt; - int reinforce; - int missioncount; - TeamMissionStruct missions[TeamTypeClass::MAX_TEAM_MISSIONS]; - char missionbuf[TeamTypeClass::MAX_TEAM_MISSIONS][20]; - int curmission; // currently-selected mission index - - char arg_buf[4] = {0}; - static int tabs[] = {130, 180}; // list box tab stops - int i,j; - - /*........................................................................ - Buttons: - ........................................................................*/ - ControlClass *commands; - EditClass name_edt (BUTTON_NAME, - name_buf, 8, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NAME_X, D_NAME_Y, D_NAME_W, D_NAME_H, EditClass::ALPHANUMERIC); - - EditClass recr_edt (BUTTON_RECRUIT, - recr_buf, 3, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_PRIORITY_X, D_PRIORITY_Y, D_PRIORITY_W, D_PRIORITY_H, EditClass::NUMERIC); - - EditClass maxnum_edt (BUTTON_MAXNUM, - maxnum_buf, 3, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MAXNUM_X, D_MAXNUM_Y, D_MAXNUM_W, D_MAXNUM_H, EditClass::NUMERIC); - - EditClass initnum_edt (BUTTON_INITNUM, - initnum_buf, 3, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_INITNUM_X, D_INITNUM_Y, D_INITNUM_W, D_INITNUM_H, EditClass::NUMERIC); - - EditClass fear_edt (BUTTON_FEAR, - fear_buf, 3, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_FEAR_X, D_FEAR_Y, D_FEAR_W, D_FEAR_H, EditClass::NUMERIC); - - TextButtonClass gdibtn (BUTTON_GDI, "GDI", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H); - - TextButtonClass nodbtn (BUTTON_NOD, "NOD", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H); - - TextButtonClass neubtn (BUTTON_NEU, "NEUTRAL", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_NEU_X, D_NEU_Y, D_NEU_W, D_NEU_H); - - TextButtonClass multi1btn (BUTTON_MULTI1, "M1", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI1_X, D_MULTI1_Y, D_MULTI1_W, D_MULTI1_H); - - TextButtonClass multi2btn (BUTTON_MULTI2, "M2", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI2_X, D_MULTI2_Y, D_MULTI2_W, D_MULTI2_H); - - TextButtonClass multi3btn (BUTTON_MULTI3, "M3", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI3_X, D_MULTI3_Y, D_MULTI3_W, D_MULTI3_H); - - TextButtonClass multi4btn (BUTTON_MULTI4, "M4", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI4_X, D_MULTI4_Y, D_MULTI4_W, D_MULTI4_H); - - TextButtonClass roundbtn (BUTTON_ROUNDABOUT, "Roundabout", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_ROUNDABOUT_X, D_ROUNDABOUT_Y, D_ROUNDABOUT_W, D_ROUNDABOUT_H); - - TextButtonClass learnbtn (BUTTON_LEARNING, "Learning", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_LEARNING_X, D_LEARNING_Y, D_LEARNING_W, D_LEARNING_H); - - TextButtonClass suicidebtn (BUTTON_SUICIDE, "Suicide", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_SUICIDE_X, D_SUICIDE_Y, D_SUICIDE_W, D_SUICIDE_H); - - TextButtonClass autocreatebtn (BUTTON_AUTO, "Autocreate", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_AUTOCREATE_X, D_AUTOCREATE_Y, D_AUTOCREATE_W, D_AUTOCREATE_H); - - TextButtonClass mercbtn (BUTTON_MERCENARY, "Mercenary", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MERCENARY_X, D_MERCENARY_Y, D_MERCENARY_W, D_MERCENARY_H); - - TextButtonClass prebuiltbtn (BUTTON_PREBUILT, "Prebuild", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_PREBUILT_X, D_PREBUILT_Y, D_PREBUILT_W, D_PREBUILT_H); - - TextButtonClass reinforcebtn (BUTTON_REINFORCE, "Reinforce", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_REINFORCE_X, D_REINFORCE_Y, D_REINFORCE_W, D_REINFORCE_H); - - ListClass missionlist1 (BUTTON_MISSION1, - D_MISSION1_X, D_MISSION1_Y, D_MISSION1_W, D_MISSION1_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - ListClass missionlist2 (BUTTON_MISSION2, - D_MISSION2_X, D_MISSION2_Y, D_MISSION2_W, D_MISSION2_H, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - Hires_Retrieve("BTN-UP.SHP"), - Hires_Retrieve("BTN-DN.SHP")); - - TextButtonClass addbtn (BUTTON_ADD, "Add >>", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_ADD_X, D_ADD_Y, D_ADD_W, D_ADD_H); - - TextButtonClass insertbtn (BUTTON_INSERT, "Insert", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_INSERT_X, D_INSERT_Y, D_INSERT_W, D_INSERT_H); - - TextButtonClass delbtn (BUTTON_DEL, "Delete", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_DEL_X, D_DEL_Y, D_DEL_W, D_DEL_H); - - EditClass arg_edt (BUTTON_ARG, arg_buf, 4, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_ARG_X, D_ARG_Y, D_ARG_W, D_ARG_H, EditClass::ALPHANUMERIC); - - TextButtonClass membersbtn (BUTTON_MEMBERS, "Members", - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MEMBERS_X, D_MEMBERS_Y, D_MEMBERS_W, D_MEMBERS_H); - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ........................... Copy team's state ............................ - */ - strcpy(name_buf,CurTeam->IniName); - sprintf(recr_buf,"%d",CurTeam->RecruitPriority); - sprintf(maxnum_buf,"%d",CurTeam->MaxAllowed); - sprintf(initnum_buf,"%d",CurTeam->InitNum); - sprintf(fear_buf,"%d",CurTeam->Fear); - roundabout = CurTeam->IsRoundAbout; - learning = CurTeam->IsLearning; - suicide = CurTeam->IsSuicide; - house = CurTeam->House; - autocreate = CurTeam->IsAutocreate; - mercenary = CurTeam->IsMercenary; - prebuilt = CurTeam->IsPrebuilt; - reinforce = CurTeam->IsReinforcable; - - /* - ......................... Fill in mission lists .......................... - */ - for (i = 0; i < TMISSION_COUNT; i++) { - missionlist1.Add_Item(TeamTypeClass::Name_From_Mission((TeamMissionType)i)); - } - - missioncount = CurTeam->MissionCount; - for (i = 0; i < missioncount; i++) { - missions[i] = CurTeam->MissionList[i]; - } - Build_Mission_List(missioncount, missions, missionbuf, &missionlist2); - - curmission = 0; - if (missioncount) { - if (missions[curmission].Mission == TMISSION_MOVE || missions[curmission].Mission == TMISSION_UNLOAD) { - sprintf(arg_buf,"%c",missions[curmission].Argument + 'A'); - } else { - sprintf(arg_buf,"%d",missions[curmission].Argument); - } - } - missionlist2.Set_Tabs(tabs); - - /* - ......................... Init the button states ......................... - */ - name_edt.Set_Text(name_buf,8); - recr_edt.Set_Text(recr_buf,3); - maxnum_edt.Set_Text(maxnum_buf,3); - initnum_edt.Set_Text(initnum_buf,3); - fear_edt.Set_Text(fear_buf,3); - arg_edt.Set_Text(arg_buf,3); - - if (roundabout) { - roundbtn.Turn_On(); - } - if (learning) { - learnbtn.Turn_On(); - } - if (suicide) { - suicidebtn.Turn_On(); - } - if (autocreate) { - autocreatebtn.Turn_On(); - } - if (mercenary) { - mercbtn.Turn_On(); - } - if (reinforce) { - reinforcebtn.Turn_On(); - } - if (prebuilt) { - prebuiltbtn.Turn_On(); - } - - /* - ............................ Create the list ............................. - */ - commands = &okbtn; - cancelbtn.Add_Tail(*commands); - membersbtn.Add_Tail(*commands); - - name_edt.Add_Tail(*commands); - recr_edt.Add_Tail(*commands); - maxnum_edt.Add_Tail(*commands); - initnum_edt.Add_Tail(*commands); - fear_edt.Add_Tail(*commands); - - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - neubtn.Add_Tail(*commands); - - roundbtn.Add_Tail(*commands); - learnbtn.Add_Tail(*commands); - suicidebtn.Add_Tail(*commands); - autocreatebtn.Add_Tail(*commands); - mercbtn.Add_Tail(*commands); - prebuiltbtn.Add_Tail(*commands); - reinforcebtn.Add_Tail(*commands); - - missionlist1.Add_Tail(*commands); - missionlist2.Add_Tail(*commands); - addbtn.Add_Tail(*commands); - insertbtn.Add_Tail(*commands); - delbtn.Add_Tail(*commands); - arg_edt.Add_Tail(*commands); - - Set_House_Buttons (house, commands, BUTTON_GDI); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - - Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print("Team Edit", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Name", D_NAME_X - 5, D_NAME_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Priority", D_PRIORITY_X - 5, D_PRIORITY_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Max Num", D_MAXNUM_X - 5, D_MAXNUM_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Init Num", D_INITNUM_X - 5, D_INITNUM_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print("Fear", D_FEAR_X - 5, D_FEAR_Y, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (BUTTON_NAME | KN_BUTTON): - break; - - case (BUTTON_RECRUIT | KN_BUTTON): - break; - - case (BUTTON_MAXNUM | KN_BUTTON): - break; - - case (BUTTON_INITNUM | KN_BUTTON): - break; - - case (BUTTON_FEAR | KN_BUTTON): - break; - - /*.................................................................. - Toggle RoundAbout - ..................................................................*/ - case (BUTTON_ROUNDABOUT | KN_BUTTON): - if (roundabout) { - roundabout = 0; - roundbtn.Turn_Off(); - } else { - roundabout = 1; - roundbtn.Turn_On(); - } - break; - - /*.................................................................. - Toggle Learning - ..................................................................*/ - case (BUTTON_LEARNING | KN_BUTTON): - if (learning) { - learning = 0; - learnbtn.Turn_Off(); - } else { - learning = 1; - learnbtn.Turn_On(); - } - break; - - /*.................................................................. - Toggle Suicide - ..................................................................*/ - case (BUTTON_SUICIDE | KN_BUTTON): - if (suicide) { - suicide = 0; - suicidebtn.Turn_Off(); - } else { - suicide = 1; - suicidebtn.Turn_On(); - } - break; - - /*.................................................................. - Toggle Spy - ..................................................................*/ - case (BUTTON_AUTO | KN_BUTTON): - if (autocreate) { - autocreate = 0; - autocreatebtn.Turn_Off(); - } else { - autocreate = 1; - autocreatebtn.Turn_On(); - } - break; - - /*.................................................................. - Toggle Mercenary - ..................................................................*/ - case (BUTTON_MERCENARY | KN_BUTTON): - if (mercenary) { - mercenary = 0; - mercbtn.Turn_Off(); - } else { - mercenary = 1; - mercbtn.Turn_On(); - } - break; - - case (BUTTON_PREBUILT | KN_BUTTON): - if (prebuilt) { - prebuilt = 0; - prebuiltbtn.Turn_Off(); - } else { - prebuilt = 1; - prebuiltbtn.Turn_On(); - } - break; - - case (BUTTON_REINFORCE | KN_BUTTON): - if (reinforce) { - reinforce = 0; - reinforcebtn.Turn_Off(); - } else { - reinforce = 1; - reinforcebtn.Turn_On(); - } - break; - - /*.................................................................. - Select a Mission on the left-hand mission list - ..................................................................*/ - case (BUTTON_MISSION1 | KN_BUTTON): - break; - - /*.................................................................. - Select a Mission on the right-hand mission list; update the Argument - field to reflect the current value - ..................................................................*/ - case (BUTTON_MISSION2 | KN_BUTTON): - if (missionlist2.Count() > 0 && - missionlist2.Current_Index() != curmission) { - curmission = missionlist2.Current_Index(); - if (missions[curmission].Mission==TMISSION_MOVE || missions[curmission].Mission == TMISSION_UNLOAD) { - sprintf(arg_buf,"%c",missions[curmission].Argument + 'A'); - } else { - sprintf(arg_buf,"%d",missions[curmission].Argument); - } - arg_edt.Set_Text(arg_buf,3); - } - break; - - /*.................................................................. - Copy mission from left list box to right list box - ..................................................................*/ - case (BUTTON_ADD | KN_BUTTON): - case (BUTTON_INSERT | KN_BUTTON): - if (missioncount < TeamTypeClass::MAX_TEAM_MISSIONS) { - /* - ** Set 'i' to the position we're going to add into; this will - ** be just AFTER the current item if we're adding, and it will - ** be the current item if we're inserting. - */ - if (input == (BUTTON_ADD | KN_BUTTON)) { - i = missionlist2.Current_Index() + 1; - if (i < 0) { - i = 0; - } - if (i > missioncount) { - i = missioncount; - } - } else { - i = missionlist2.Current_Index(); - if (i < 0) { - i = 0; - } - if (i >= missioncount && missioncount > 0) { - i = missioncount - 1; - } - } - - /* - ** Move all other missions forward in the array - */ - for (j = missioncount; j > i; j--) { - missions[j] = missions[j - 1]; - } - - /* - ** Set the Mission value based on 1st list box's index - */ - missions[i].Mission = (TeamMissionType)(TMISSION_FIRST + missionlist1.Current_Index()); - - /* - ** Set the missions argument field - */ - if (missions[i].Mission == TMISSION_MOVE || missions[i].Mission == TMISSION_UNLOAD) { - missions[i].Argument = toupper(arg_buf[0]) - 'A'; - } else { - missions[i].Argument = atoi(arg_buf); - } - missioncount++; - - /* - ** Rebuild the list box from scratch - */ - Build_Mission_List(missioncount, missions, missionbuf, &missionlist2); - - /* - ** Update the list's current item index - */ - missionlist2.Set_Selected_Index(i); - } - break; - - /*.................................................................. - Delete mission from right-hand list box - ..................................................................*/ - case (BUTTON_DEL | KN_BUTTON): - if (missioncount > 0) { - i = missionlist2.Current_Index(); - if (i < 0 || i >= missioncount) { - break; - } - - /* - ** Move all missions back in the array - */ - for (j = i; j < missioncount - 1; j++) { - missions[j] = missions[j + 1]; - } - missioncount--; - - /* - ** Rebuild the list box from scratch - */ - Build_Mission_List(missioncount, missions, missionbuf, &missionlist2); - - /* - ** Update the list's current item index - */ - if (i >= missioncount) { - i--; - if (i < 0) { - i = 0; - } - missionlist2.Set_Selected_Index(i); - } - } - break; - - /*.................................................................. - Set house - ..................................................................*/ - case (BUTTON_GDI | KN_BUTTON): - case (BUTTON_NOD | KN_BUTTON): - case (BUTTON_NEU | KN_BUTTON): - case (BUTTON_MULTI1 | KN_BUTTON): - case (BUTTON_MULTI2 | KN_BUTTON): - case (BUTTON_MULTI3 | KN_BUTTON): - case (BUTTON_MULTI4 | KN_BUTTON): - house = (HousesType)( (input & (~KN_BUTTON)) - BUTTON_GDI); - Set_House_Buttons(house, commands, BUTTON_GDI); - break; - - /*.................................................................. - Invoke the members dialog - ..................................................................*/ - case (BUTTON_MEMBERS | KN_BUTTON): - /* - .................... Take editor focus away ..................... - */ - membersbtn.Turn_Off(); - - /* - ....................... Invoke the dialog ....................... - */ - Team_Members(house); - - /* - ............................ Redraw ............................. - */ - display = REDRAW_ALL; - break; - - /*.................................................................. - OK: return - ..................................................................*/ - case (BUTTON_OK | KN_BUTTON): - cancel = false; - process = false; - break; - - /*.................................................................. - Cancel: return - ..................................................................*/ - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - /*.................................................................. - Pass all other events to the currently-active text editor - ..................................................................*/ - default: - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - /* - ------------------------- If cancel, just return ------------------------- - */ - if (cancel) { - return(-1); - } - - /* - ------------------------ Save selections & return ------------------------ - */ - CurTeam->Set_Name(name_buf); - CurTeam->RecruitPriority = atoi(recr_buf); - CurTeam->MaxAllowed = atoi(maxnum_buf); - CurTeam->InitNum = atoi(initnum_buf); - CurTeam->IsRoundAbout = roundabout; - CurTeam->IsLearning = learning; - CurTeam->IsSuicide = suicide; - CurTeam->IsAutocreate = autocreate; - CurTeam->IsPrebuilt = prebuilt; - CurTeam->IsReinforcable = reinforce; - CurTeam->IsMercenary = mercenary; - CurTeam->House = house; - CurTeam->MissionCount = missioncount; - for (i = 0 ; i < missioncount; i++) { - CurTeam->MissionList[i] = missions[i]; - } - - return(0); -} - - -/*************************************************************************** - * MapEditClass::Team_Members -- user picks makeup of a team * - * * - * Team members are rendered in a 24 x 24 area; the Window coordinates * - * have to be set to this area when the object's 'Display()' routine is * - * called. Thus, the dialog's window coords have to be divisible by * - * 24. The height of the dialog is computed based on how many objects * - * there are in it. * - * * - * 10 pixels are left between rows of objects, so the # of that type of * - * object can be displayed underneath the object. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Team Members ³ * - * ³ ³ * - * ³ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ ³ * - * ³ [OK] [Cancel] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * house house to display objects for * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * CurTeam must NOT be NULL when this function is called. * - * This routine uses HIDBUFF for data storage. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - *=========================================================================*/ -#define TEENSY_WEENSY -/* -** Dialog & button dimensions -*/ -enum { - D_DIALOG_W = 608, - D_DIALOG_X = ((640 - D_DIALOG_W) / 2), - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_TXT6_H = 14, - D_MARGIN = 14, - -#ifdef TEENSY_WEENSY - //D_PICTURE_W = 32, - //D_PICTURE_H = 24, - D_PICTURE_W = 64, // 9 pictures / row, 16 pixel margin on each side - D_PICTURE_H = 48, -#else - //D_PICTURE_W = 32, - //D_PICTURE_H = 30, - D_PICTURE_W = 64, - D_PICTURE_H = 60, -#endif - D_ROW_H = (D_PICTURE_H + 6), - - D_OK_W = 100, - D_OK_H = 18, - D_OK_X = D_DIALOG_CX - 10 - D_OK_W, - D_OK_Y = 0, - - D_CANCEL_W = 100, - D_CANCEL_H = 18, - D_CANCEL_X = D_DIALOG_CX + 10, - D_CANCEL_Y = 0, - -}; - -/*************************************************************************** - * MapEditClass::Team_Members -- Team members dialog * - * * - * INPUT: * - * house house to show members for * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/09/1996 BRR : Created. * - *=========================================================================*/ -int MapEditClass::Team_Members(HousesType house) -{ - /* - ** Button enumerations: - */ - enum { - BUTTON_OK = 100, - BUTTON_CANCEL, - }; - - /* - ** Redraw values: in order from "top" to "bottom" layer of the dialog - ** (highest enum is the lowest layer). Each section of the map checks - ** the requested redraw level to see if it's supposed to draw; if it's - ** >= its level, it redraws. - */ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - RedrawType display; // requested redraw level - bool process; // loop while true - - /* - ............................ Dialog variables ............................ - */ - KeyNumType input; // user input - bool cancel = false; // true = user cancels - - /* - ......................... Team display variables ......................... - */ - const TechnoTypeClass **teamclass; // array of team classes - int *teamcount; // array of class counts - int numcols; // # units displayed horizontally - int numrows; // # units displayed vertically -// int col; // horizontal picture index -// int row; // vertical picture index -// int x,y; - - /* - ** Dialog dimensions. - */ - int dlg_y; - int dlg_h; // dialog height - int dlg_picture_top; // coord of top of pictures - int msg_y; // y-coord for object names - - /* - ** Values for parsing the classes. - */ - InfantryType i_id; - AircraftType a_id; - UnitType u_id; - int curclass = -1; // current index into 'teamclass'; can be invalid! - // (is based on current mouse position) - int numclasses; // current # classes in the team (limited to <=5) - int maxclasses; // max # classes available - int i,j; - - /* - ** Values for timing when mouse held down. - */ - int lheld = 0; - int rheld = 0; - long tdelay[3] = {5, 20, 0}; - int tindex = 0; - long heldtime; - - /* - ** Buttons. - */ - ControlClass *commands; - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_OK_X, D_OK_Y, D_OK_W, D_OK_H); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); - - /* - ** Set up the team data arrays (ObjectTypeClass pointers & count) - */ - teamclass = (const TechnoTypeClass **)(new TechnoTypeClass *[MAX_TEAM_CLASSES]); - teamcount = new int[MAX_TEAM_CLASSES]; - - /* - ** Fill in the ObjectTypeClass array with all available object type ptrs, - ** checking to be sure this house can own the object - */ - i = 0; - for (i_id = INFANTRY_FIRST; i_id < INFANTRY_COUNT; i_id++) { - if (Verify_House(house,&InfantryTypeClass::As_Reference(i_id))) { - teamclass[i] = &InfantryTypeClass::As_Reference(i_id); - i++; - } - } - - for (a_id = AIRCRAFT_FIRST; a_id < AIRCRAFT_COUNT; a_id++) { - if (Verify_House(house,&AircraftTypeClass::As_Reference(a_id))) { - teamclass[i] = &AircraftTypeClass::As_Reference(a_id); - i++; - } - } - - for (u_id = UNIT_FIRST; u_id < UNIT_COUNT; u_id++) { - if (Verify_House(house,&UnitTypeClass::As_Reference(u_id))) { - teamclass[i] = &UnitTypeClass::As_Reference(u_id); - i++; - } - } - - /* - ** Save max # classes. - */ - maxclasses = i; - - /* - ** Fill in the 'count' array with data from the current team: - ** - For every class in the current team, find that class type in the - ** 'teamclass' array & set its count value - */ - for (j = 0; j < maxclasses; j++) { - teamcount[j] = 0; - } - - /* - ** Loop through all classes in the team. - */ - for (i = 0; i < CurTeam->ClassCount; i++) { - - /* - ** Find this class in our array. - */ - for (j = 0; j < maxclasses; j++) { - - /* - ** Set the count; detect a match between the team's class & the - ** 'teamclass' array entry by comparing the actual pointers; typeid - ** won't work because E1 & E2 are the same type class. - */ - if (CurTeam->Class[i] == teamclass[j]) { - teamcount[j] = CurTeam->DesiredNum[i]; - break; - } - } - } - numclasses = CurTeam->ClassCount; - - /* - ** Set up the dialog dimensions based on number of classes we have to draw - ** - ** Compute picture rows & cols. - */ - numcols = (D_DIALOG_W - 16) / D_PICTURE_W; - numrows = (maxclasses + numcols - 1) / numcols; - - // - // Dialog's height = top margin + label + picture rows + - // margin + label + margin + btn - // - dlg_h = (D_MARGIN + D_TXT6_H + D_MARGIN + (numrows * D_ROW_H) + - D_MARGIN + D_TXT6_H + D_MARGIN + D_OK_H + D_MARGIN); - if (dlg_h > 400) { - dlg_h = 400; - } - dlg_y = (400 - dlg_h) / 2; - dlg_picture_top = dlg_y + D_MARGIN + D_TXT6_H + D_MARGIN; - msg_y = dlg_y + D_MARGIN + D_TXT6_H + D_MARGIN + (numrows * D_ROW_H) + D_MARGIN; - - okbtn.Y = dlg_y + dlg_h - D_MARGIN - D_OK_H; - cancelbtn.Y = dlg_y + dlg_h - D_MARGIN - D_CANCEL_H; - - /* - ** Draw to SeenBuff. - */ - Set_Logic_Page(SeenBuff); - - /* - ** Make sure 'house' is valid. - */ - if (house!=HOUSE_GOOD && house!=HOUSE_BAD && house != HOUSE_MULTI1 && - house != HOUSE_MULTI2 && house != HOUSE_MULTI3 && house != HOUSE_MULTI4 ) { - if (ScenPlayer == SCEN_PLAYER_MPLAYER) { - house = HOUSE_MULTI1; - } else { - house = HOUSE_GOOD; - } - } - - /* - ** Create the list. - */ - commands = &okbtn; - cancelbtn.Add_Tail(*commands); - - /* - ** Main Processing Loop. - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ** Invoke game callback. - */ - Call_Back(); - - /* - ** Refresh display if needed. - */ - if (display) { - - /* - ** Display the dialog box. - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - - /* - ** Display the constant background of this dialog. - */ - Dialog_Box(D_DIALOG_X, dlg_y, D_DIALOG_W, dlg_h); - Draw_Caption(TXT_NONE, D_DIALOG_X, dlg_y, D_DIALOG_W); - Fancy_Text_Print("Team Members", D_DIALOG_CX, dlg_y + D_MARGIN, CC_GREEN, TBLACK, - TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - - // - // Draw the objects. - // - for (i = 0; i < maxclasses; i++) { - // - // Display the object along with any count value for it. - // - Draw_Member(teamclass[i], i, teamcount[i], house, - D_DIALOG_X + 16, dlg_picture_top); - } - - if ((unsigned)curclass < maxclasses) { - Fancy_Text_Print(teamclass[curclass]->Full_Name(), - D_DIALOG_X + D_DIALOG_W / 2, msg_y, CC_TAN, TBLACK, - TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - } - } - - /* - ** Redraw the buttons. - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ** Get user input. - */ - input = commands->Input(); - - /* - ** Process input. - */ - switch (input) { - - /* - ** Mouse buttons set or clear 'held' values - */ - case (KN_LMOUSE): - if (curclass >= 0 && curclass < maxclasses) { - lheld = 1; - tindex = 2; - heldtime = 0; - } - break; - - case (KN_RMOUSE): - if (curclass >= 0 && curclass < maxclasses) { - rheld = 1; - tindex = 2; - heldtime = 0; - } - break; - - case ((int)KN_LMOUSE | (int)KN_RLSE_BIT): - lheld = 0; - break; - - case ((int)KN_RMOUSE | (int)KN_RLSE_BIT): - rheld = 0; - break; - - /* - ** OK: save values & return. - */ - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - - /* - ** Cancel: abort & return. - */ - case (BUTTON_CANCEL | KN_BUTTON): - cancel = true; - process = false; - break; - - default: - /* - ** Compute new 'curclass' based on mouse position. - */ - i = (Get_Mouse_X() - 16 - D_DIALOG_X) / D_PICTURE_W + - ((Get_Mouse_Y() - dlg_picture_top) / D_ROW_H) * numcols; - - /* - ** If it's changed, update class label. - */ - if (i != curclass) { - - curclass = i; - - /* - ** Clear out the previously printed name of the item. - */ - Hide_Mouse(); - LogicPage->Fill_Rect(D_DIALOG_X + 8, msg_y, D_DIALOG_X + D_DIALOG_W - 9, msg_y + D_TXT6_H, BLACK); - - if ((unsigned)curclass < maxclasses) { - Fancy_Text_Print(teamclass[curclass]->Full_Name(), - D_DIALOG_X + D_DIALOG_W / 2, msg_y, - CC_GREEN, TBLACK, - TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - } - - /* - ** Force buttons to not be held. - */ - lheld = 0; - rheld = 0; - Show_Mouse(); - } - break; - } - - /* - ** Check for a 'held' mouse button; if it's down, and the correct - ** amount of time has gone by, increment/decrement the count for the - ** current class. - */ - if (lheld) { - - /* - ** The first time in, TickCount - heldtime will be larger than - ** tdelay[2], so we increment the count immediately; then, we decrement - ** tindex to go to the next time delay, which is longer; then, decr. - ** again to go to the 1st time delay which is the shortest. - */ - if (TickCount.Time() - heldtime > tdelay[tindex]) { - heldtime = TickCount.Time(); - if (tindex) { - tindex--; - } - - /* - ** Detect addition of a new class. - */ - if (teamcount[curclass]==0) { - - /* - ** Don't allow more classes than we can handle. - */ - if (numclasses == TeamTypeClass::MAX_TEAM_CLASSCOUNT) { - continue; - } - numclasses++; - } - teamcount[curclass]++; - - /* - ** Update number label. - */ - Draw_Member(teamclass[curclass], curclass, teamcount[curclass], - house, D_DIALOG_X + 16, dlg_picture_top); - - } - - } else { - - if (rheld) { - - /* - ** The first time in, TickCount - heldtime will be larger than - ** tdelay[2], so we increment the count immediately; then, we decrement - ** tindex to go to the next time delay, which is longer; then, decr. - ** again to go to the 1st time delay which is the shortest. - */ - if (TickCount.Time() - heldtime > tdelay[tindex]) { - if (tindex) { - tindex--; - } - heldtime = TickCount.Time(); - - if (teamcount[curclass] > 0) { - teamcount[curclass]--; - - /* - ** Detect removal of a class. - */ - if (teamcount[curclass] == 0) { - numclasses--; - } - } - - /* - ** Update number label. - */ - Draw_Member(teamclass[curclass], curclass, teamcount[curclass], - house, D_DIALOG_X + 16, dlg_picture_top); - - } - } - } - } - - /* - ** Copy data into team. - */ - if (!cancel) { - CurTeam->ClassCount = numclasses; - i = 0; // current team class index - for (j = 0; j < maxclasses; j++) { - if (teamcount[j] > 0) { - CurTeam->DesiredNum[i] = teamcount[j]; - CurTeam->Class[i] = teamclass[j]; - i++; - } - } - } - - /* - ** Redraw the display. - */ - HiddenPage.Clear(); - Flag_To_Redraw(true); - Render(); - - delete [] teamclass; - delete [] teamcount; - - if (cancel) return(-1); - return(0); -} - - -/*********************************************************************************************** - * MapEditClass::Draw_Member -- Draws a member of the team dialog box. * - * * - * This routine will display the cameo image of the potential team member. In the corner, * - * it will show the current quantity of this member for the current team being edited. * - * * - * INPUT: ptr -- Pointer to the member object type. * - * * - * index -- The index into the team dialog box array of selectable objects. This is * - * used to determine the correct X and Y offsets to draw. * - * * - * quant -- The quantity number to display in the corner of the image. * - * * - * house -- The owner of this object. * - * pic_x, pic_y -- x,y coords of upper-left corner to start drawing at - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/02/1995 JLB : Created. * - *=============================================================================================*/ -void MapEditClass::Draw_Member(TechnoTypeClass const * ptr, int index, - int quant, HousesType house, int pic_x, int pic_y) -{ - int numcols = (D_DIALOG_W - 32) / D_PICTURE_W; - int col = index % numcols; - int row = index / numcols; - int x = pic_x + col * D_PICTURE_W; - int y = pic_y + row * D_ROW_H; - - WindowList[WINDOW_EDITOR][WINDOWX] = 0; - WindowList[WINDOW_EDITOR][WINDOWY] = 0; - WindowList[WINDOW_EDITOR][WINDOWWIDTH] = 640 / 8; - WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = 400; - Change_Window((int)WINDOW_EDITOR); - - Hide_Mouse(); - Draw_Box(x, y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_GREEN_DOWN, true); - - ptr->Display(x + D_PICTURE_W / 2, y + D_PICTURE_H / 2, WINDOW_EDITOR, house); - - if (quant > 0) { - Fancy_Text_Print("%d", x + 1, y + D_PICTURE_H - 16, - CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_DROPSHADOW, quant); - } - - Show_Mouse(); - -#if 0 - int numcols = (D_DIALOG_W - 16) / D_PICTURE_W; - int col = index % numcols; - int row = index / numcols; - int dlg_y = 0; - int x = D_DIALOG_X + 8 + col * D_PICTURE_W; - int y = dlg_y + 8 + 13 + row * D_ROW_H; - - /* - ** Change the window to this box. - */ - WindowList[WINDOW_EDITOR][WINDOWX] = x >> 3; - WindowList[WINDOW_EDITOR][WINDOWY] = y; - WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W >> 3; - WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H; - Change_Window((int)WINDOW_EDITOR); - - Hide_Mouse(); - Draw_Box(x, y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_GREEN_DOWN, true); - ptr->Display(WinW<<2, WinH>>1, WINDOW_EDITOR, house); - if (quant > 0) { - Fancy_Text_Print("%d", x+1, y+D_PICTURE_H-8, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_DROPSHADOW, quant); - } - Show_Mouse(); -#endif -} - - -/*************************************************************************** - * MapEditClass::Build_Mission_list -- fills in mission list box * - * * - * INPUT: * - * missioncount # of missions to add to the list * - * missions array of TeamMissionStruct's * - * missionbuf character arrays to store strings in * - * list list box to add strings to * - * * - * OUTPUT: * - * 0 = OK, -1 = cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - *=========================================================================*/ -void MapEditClass::Build_Mission_List(int missioncount, TeamMissionStruct *missions, - char missionbuf[TeamTypeClass::MAX_TEAM_MISSIONS][20], ListClass *list) -{ - /* - ** Start with an empty list - */ - while (list->Count()) { - list->Remove_Item(list->Get_Item(0)); - } - - for (int i = 0; i < missioncount; i++) { - /* - ** generate the string for a MOVE mission; the argument is the - ** letter-designation of the cell to move to. - */ - if (missions[i].Mission == TMISSION_MOVE || missions[i].Mission == TMISSION_UNLOAD) { - sprintf(missionbuf[i],"%s\t%c", - TeamTypeClass::Name_From_Mission(missions[i].Mission), - missions[i].Argument + 'A'); - } else { - - /* - ** All other missions take a numeric argument. - */ - sprintf(missionbuf[i],"%s\t%d", - TeamTypeClass::Name_From_Mission(missions[i].Mission), - missions[i].Argument); - } - - /* - ** Add the string to the list box - */ - list->Add_Item(missionbuf[i]); - } -} - -#endif diff --git a/code/TIBERIANDAWN/MAPSEL.CPP b/code/TIBERIANDAWN/MAPSEL.CPP deleted file mode 100644 index 673e0d9..0000000 --- a/code/TIBERIANDAWN/MAPSEL.CPP +++ /dev/null @@ -1,1274 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mapsel.cpv 1.8 16 Oct 1995 16:49:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MAPSEL.CPP * - * * - * Programmer : Barry W. Green * - * * - * Start Date : April 17, 1995 * - * * - * Last Update : April 27, 1995 [BWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Bit_It_In -- Pixel fade graphic copy. * - * Map_Selection -- Starts the whole process of selecting next map to go to * - * Print_Statistics -- Prints statistics on country selected * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "textblit.h" - -#ifndef DEMO - -void Map_Selection(void); -void Fading_Byte_Blit(int srcx, int srcy, int destx, int desty, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest); -void Print_Statistics(int country, int xpos, int ypos); -void Cycle_Call_Back_Delay(int time, unsigned char *pal); -int LowMedHiStr(int percentage); -extern int ControlQ; - -unsigned char CountryRemap[256]; -#ifdef OBSOLETE -unsigned char const High16Remap[256]={ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF -}; -#endif - -#define SDE SCEN_DIR_EAST -#define SDW SCEN_DIR_WEST -#define SDN SCEN_DIR_NONE -#define SVA SCEN_VAR_A -#define SVB SCEN_VAR_B -#define SVC SCEN_VAR_C -#define SVN SCEN_VAR_NONE -struct countrylist { - int Choices[2]; // # of map choices this time - 0 = no map selection screen - int Start[2]; - int ContAnim[2]; - int CountryColor[2][3]; - int CountryShape[2][3]; // shape in COUNTRYE.SHP - ScenarioDirType CountryDir[2][3]; - ScenarioVarType CountryVariant[2][3]; -} const CountryArray[27] = { -// GDI SCENARIO CHOICES -/* 0 */ {0}, /*E W*/ /* cont */ /* East colors */ /* West color*/ /* E frame W frame */ -/* 1 */ {{1,1}, { 0, 0}, { 3, 3},{{0x95, 0, 0},{0x95, 0, 0}}, {{17, 0, 0},{17, 0, 0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}}}, -/* 2 */ {{1,1}, {16,16}, { 19, 19},{{0x80, 0, 0},{0x80, 0, 0}}, {{ 0, 0, 0},{ 0, 0, 0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}}}, -/* 3 */ {{3,3}, {32,32}, { 35, 35},{{0x81,0x82,0x83},{0x81,0x82,0x83}}, {{ 3, 3, 1},{ 3, 3, 1}}, {{SDW,SDW,SDE},{SDN,SDN,SDN}},{{SVA,SVB,SVA},{SVN,SVN,SVN}}}, -/* 4 */ {{2,2}, {48,64}, { 51, 67},{{0x84,0x85, 0},{0x86,0x87, 0}}, {{ 4, 4, 0},{ 2, 2, 0}}, {{SDE,SDE,SDN},{SDW,SDW,SDN}},{{SVA,SVA,SVN},{SVA,SVB,SVN}}}, -/* 5 */ {{2,2}, {99,99}, {102,102},{{0x88,0x89, 0},{0x88,0x89, 0}}, {{ 7, 7, 0},{ 7, 7, 0}}, {{SDE,SDE,SDN},{SDE,SDE,SDN}},{{SVA,SVA,SVN},{SVA,SVA,SVN}}}, -/* 6 */ {{2,2}, {80,83}, { 86, 86},{{0x88,0x89, 0},{0x88,0x89, 0}}, {{ 7, 7, 0},{ 7, 7, 0}}, {{SDE,SDE,SDN},{SDE,SDE,SDN}},{{SVA,SVA,SVN},{SVA,SVA,SVN}}}, -/* 7 */ {{2,2}, {115,0}, {118, 0},{{0x8B,0x8A, 0},{0x8B,0x8A, 0}}, {{ 6, 8, 0},{ 6, 8, 0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}}}, -/* 8 */ {{1,1}, {131,0}, {134, 0},{{0x8C, 0, 0},{0x8C, 0, 0}}, {{ 9, 0, 0},{ 9, 0, 0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}}}, -/* 9 */ {{2,1}, {147,0}, {150, 0},{{0x8D,0x8E, 0},{ 0, 0, 0}}, {{10,13, 0},{ 0, 0, 0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}}}, -/* 10 */ {{1,1}, {163,0}, {166, 0},{{0x8F, 0, 0},{ 0, 0, 0}}, {{16, 0, 0},{ 0, 0, 0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}}}, -/* 11 */ {{2,1}, {179,0}, {182, 0},{{0x90,0x91, 0},{ 0, 0, 0}}, {{14,15, 0},{ 0, 0, 0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}}}, -/* 12 */ {{2,1}, {195,0}, {198, 0},{{0x92,0x93, 0},{ 0, 0, 0}}, {{12,12, 0},{ 0, 0, 0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}}}, -/* 13 */ {{1,1}, {211,0}, {214, 0},{{0x93, 0, 0},{ 0, 0, 0}}, {{12, 0, 0},{ 0, 0, 0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}}}, -/* 14 */ {{3,1}, { 0,0}, { 3, 0},{{0x81,0x82,0x83},{ 0, 0, 0}}, {{ 0, 0, 0},{ 0, 0, 0}}, {{SDE,SDE,SDE},{SDN,SDN,SDN}},{{SVA,SVB,SVC},{SVN,SVN,SVN}}}, - -// NOD SCENARIO CHOICES -// choices E/W start continue East colors West colors E shape W shape direction variant -/* 1 */ { {2,1}, { 0,0}, { 3, 0},{{0x80,0x81,0x00},{0,0,0}}, {{ 4, 4, 0},{0,0,0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}} }, -/* 2 */ { {2,1}, { 16,0}, { 19, 0},{{0x82,0x83,0x00},{0,0,0}}, {{ 6, 6, 0},{0,0,0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}} }, -/* 3 */ { {2,1}, { 32,0}, { 35, 0},{{0x84,0x85,0x00},{0,0,0}}, {{ 5, 5, 0},{0,0,0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}} }, -/* 4 */ { {1,1}, { 48,0}, { 51, 0},{{0x86,0x00,0x00},{0,0,0}}, {{ 0, 0, 0},{0,0,0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}} }, -/* 5 */ { {3,1}, { 64,0}, { 67, 0},{{0x87,0x88,0x89},{0,0,0}}, {{ 1, 2, 3},{0,0,0}}, {{SDE,SDE,SDE},{SDN,SDN,SDN}},{{SVA,SVB,SVC},{SVN,SVN,SVN}} }, -/* 6 */ { {3,1}, { 80,0}, { 83, 0},{{0x8A,0x8B,0x8C},{0,0,0}}, {{ 9, 7, 8},{0,0,0}}, {{SDE,SDE,SDE},{SDN,SDN,SDN}},{{SVA,SVB,SVC},{SVN,SVN,SVN}} }, -/* 7 */ { {2,1}, { 96,0}, { 99, 0},{{0x8D,0x8E,0x00},{0,0,0}}, {{10,10, 0},{0,0,0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}} }, -/* 8 */ { {1,1}, {112,0}, {115, 0},{{0xA0,0x00,0x00},{0,0,0}}, {{ 4, 4, 0},{0,0,0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}} }, -/* 9 */ { {2,1}, {128,0}, {131, 0},{{0x8F,0x90,0x00},{0,0,0}}, {{11,15, 0},{0,0,0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}} }, -/* 10 */ { {2,1}, {144,0}, {147, 0},{{0x91,0x92,0x00},{0,0,0}}, {{12,16, 0},{0,0,0}}, {{SDE,SDE,SDN},{SDN,SDN,SDN}},{{SVA,SVB,SVN},{SVN,SVN,SVN}} }, -/* 11 */ { {1,1}, {160,0}, {163, 0},{{0x93,0x00,0x00},{0,0,0}}, {{13, 0, 0},{0,0,0}}, {{SDE,SDN,SDN},{SDN,SDN,SDN}},{{SVA,SVN,SVN},{SVN,SVN,SVN}} }, -/* 12 */ { {3,1}, { 0,0}, { 3, 0},{{0x81,0x82,0x83},{0,0,0}}, {{14, 0, 0},{0,0,0}}, {{SDE,SDE,SDE},{SDN,SDN,SDN}},{{SVA,SVB,SVC},{SVN,SVN,SVN}} } -}; - -struct gdistats { - int nameindex; - int pop; - int area; - int capital; - int govt; - int gdp; - int conflict; - int military; -} const GDIStats[]={ -// Name Pop Area Capital Government GDP Conflict Military - { 0,TXT_MAP_P01, TXT_MAP_A00,TXT_MAP_C00, 0, TXT_MAP_GDP00, TXT_MAP_PC00, 0}, - { 1,TXT_MAP_P02, TXT_MAP_A01,TXT_MAP_C01, 1, TXT_MAP_GDP01, TXT_MAP_PC01, 3}, - { 1,TXT_MAP_P02, TXT_MAP_A01,TXT_MAP_C01, 1, TXT_MAP_GDP01, TXT_MAP_PC02, 3}, - { 2,TXT_MAP_P03, TXT_MAP_A02,TXT_MAP_C02, 0, TXT_MAP_GDP00, TXT_MAP_PC03, 1}, - { 3,TXT_MAP_P04, TXT_MAP_A03,TXT_MAP_C03, 3, TXT_MAP_GDP02, TXT_MAP_PC04, 1}, - { 3,TXT_MAP_P04, TXT_MAP_A03,TXT_MAP_C03, 3, TXT_MAP_GDP02, TXT_MAP_PC04, 1}, - { 4,TXT_MAP_P05, TXT_MAP_A04,TXT_MAP_C04, 2, TXT_MAP_GDP03, TXT_MAP_PC05, 5}, - { 4,TXT_MAP_P05, TXT_MAP_A04,TXT_MAP_C04, 2, TXT_MAP_GDP03, TXT_MAP_PC06, 5}, - { 5,TXT_MAP_P06, TXT_MAP_A05,TXT_MAP_C05, 0, TXT_MAP_GDP04, TXT_MAP_PC07, 2}, - { 5,TXT_MAP_P06, TXT_MAP_A05,TXT_MAP_C05, 0, TXT_MAP_GDP04, TXT_MAP_PC07, 2}, - { 6,TXT_MAP_P07, TXT_MAP_A06,TXT_MAP_C06, 0, TXT_MAP_GDP00, TXT_MAP_PC08, 0}, - { 7,TXT_MAP_P08, TXT_MAP_A07,TXT_MAP_C07, 4, TXT_MAP_GDP05, TXT_MAP_PC00, 2}, - { 8,TXT_MAP_P09, TXT_MAP_A08,TXT_MAP_C08, 4, TXT_MAP_GDP06, TXT_MAP_PC10, 2}, - { 9,TXT_MAP_P10, TXT_MAP_A09,TXT_MAP_C09, 0, TXT_MAP_GDP07, TXT_MAP_PC11, 1}, - {10,TXT_MAP_P11, TXT_MAP_A10,TXT_MAP_C10, 0, TXT_MAP_GDP08, TXT_MAP_PC12, 2}, - {11,TXT_MAP_P12, TXT_MAP_A11,TXT_MAP_C11, 5, TXT_MAP_GDP09, TXT_MAP_PC13, 3}, - {12,TXT_MAP_P13, TXT_MAP_A12,TXT_MAP_C12, 6, TXT_MAP_GDP10, TXT_MAP_PC14, 2}, - {13,TXT_MAP_P14, TXT_MAP_A13,TXT_MAP_C13, 0, TXT_MAP_GDP11, TXT_MAP_PC15, 2}, - {14,TXT_MAP_P15, TXT_MAP_A14,TXT_MAP_C14, 0, TXT_MAP_GDP12, TXT_MAP_PC16, 3}, - {14,TXT_MAP_P15, TXT_MAP_A14,TXT_MAP_C14, 0, TXT_MAP_GDP12, TXT_MAP_PC17, 3}, - {15,TXT_MAP_P16, TXT_MAP_A15,TXT_MAP_C15, 7, TXT_MAP_GDP13, TXT_MAP_PC18, 4}, -// Hack in a slot for Estonia - {34,TXT_MAP_P17, TXT_MAP_A16,TXT_MAP_C16, 0, TXT_MAP_GDP00, TXT_MAP_PC19, 0} -}; - -struct nodstats { - int nameindex; - int pop; - int expendable; - int capital; - int govt; - int corruptible; - int worth; - int conflict; - int military; - int probability; -} const NodStats[]={ -// Name Pop Expendable Capital Government Corruptible Worth Conflict Military Probability - {16, TXT_MAP_P18, 38, TXT_MAP_C17, 8, 86, TXT_MAP_GDP14, TXT_MAP_PC20, 0, 23}, - {17, TXT_MAP_P19, 75, TXT_MAP_C18, 0, 18, TXT_MAP_GDP15, TXT_MAP_PC21, 1, 82}, - {17, TXT_MAP_P19, 75, TXT_MAP_C18, 0, 18, TXT_MAP_GDP15, TXT_MAP_PC22, 1, 82}, - {18, TXT_MAP_P20, 50, TXT_MAP_C19, 9, 52, TXT_MAP_GDP16, TXT_MAP_PC23, 0, 72}, - {18, TXT_MAP_P20, 50, TXT_MAP_C19, 9, 52, TXT_MAP_GDP16, TXT_MAP_PC24, 0, 72}, - {19, TXT_MAP_P21, 80, TXT_MAP_C20, 0, 85, TXT_MAP_GDP17, TXT_MAP_PC25, 2, 35}, - {19, TXT_MAP_P21, 80, TXT_MAP_C20, 0, 85, TXT_MAP_GDP17, TXT_MAP_PC26, 2, 35}, - {20, TXT_MAP_P22, 50, TXT_MAP_C21, 10, 48, TXT_MAP_GDP17, TXT_MAP_PC27, 2, 24}, - {21, TXT_MAP_P23, 33, TXT_MAP_C22, 0, 28, TXT_MAP_GDP18, TXT_MAP_PC28, 3, 67}, - {22, TXT_MAP_P24, 75, TXT_MAP_C23, 6, 17, TXT_MAP_GDP19, TXT_MAP_PC29, 2, 80}, - {23, TXT_MAP_P25, 60, TXT_MAP_C24, 7, 93, TXT_MAP_GDP20, TXT_MAP_PC30, 3, 50}, - {24, TXT_MAP_P26, 5, TXT_MAP_C25, 0, 84, TXT_MAP_GDP21, TXT_MAP_PC31, 2, 22}, - {25, TXT_MAP_P27, 55, TXT_MAP_C26, 0, 48, TXT_MAP_GDP22, TXT_MAP_PC32, 3, 62}, - {26, TXT_MAP_P28, 65, TXT_MAP_C27, 0, 41, TXT_MAP_GDP23, TXT_MAP_PC33, 2, 49}, - {27, TXT_MAP_P29, 72, TXT_MAP_C28, 0, 74, TXT_MAP_GDP24, TXT_MAP_PC34, 3, 54}, - {27, TXT_MAP_P29, 72, TXT_MAP_C28, 0, 74, TXT_MAP_GDP24, TXT_MAP_PC35, 3, 54}, - {17, TXT_MAP_P30, 45, TXT_MAP_C29, 6, 3, TXT_MAP_GDP15, TXT_MAP_PC36, 3, 100}, - {28, TXT_MAP_P31, 45, TXT_MAP_C30, 0, 63, TXT_MAP_GDP25, TXT_MAP_PC37, 2, 66}, - {29, TXT_MAP_P32, 55, TXT_MAP_C31, 0, 27, TXT_MAP_GDP26, TXT_MAP_PC38, 2, 68}, - {30, TXT_MAP_P33, 5, TXT_MAP_C32, 0, 65, TXT_MAP_GDP27, TXT_MAP_PC39, 4, 74}, - {31, TXT_MAP_P34, 65, TXT_MAP_C33, 0, 52, TXT_MAP_GDP19, TXT_MAP_PC40, 2, 84}, - {32, TXT_MAP_P35, 2, TXT_MAP_C34, 11, 12, TXT_MAP_GDP28, TXT_MAP_PC41, 2, 92}, - {33, TXT_MAP_P36, 10, TXT_MAP_C35, 0, 8, TXT_MAP_GDP29, TXT_MAP_PC42, 1, 100} -}; - - - -/*********************************************************************************************** - * Map_Selection -- Starts the whole process of selecting next map to go to * - * * - * * - * INPUT: * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/17/1995 BWG : Created. * - *=============================================================================================*/ -void Map_Selection(void) -{ - void *anim, *progress, *oldfont, *greyearth, *greyearth2; - unsigned char localpalette[768]; - int scenario, lastscenario; - int house = PlayerPtr->Class->House; - int attackxcoord = 0; - - static int const _countryx[]={195,217,115,167, - 244, 97,130,142, - 171,170,139,158, - 180,207,177,213, - 201,198, - /* Nod countries */ - 69, 82,105,119, - 184,149,187,130, - 153,124,162,144, - 145,164,166,200, - 201}; - static int const _countryy[]={ 35, 57, 82, 75, - 93,111,108, 91, - 100,111,120,136, - 136,117,158,143, - 167,21, - /* Nod countries */ - 45, 80, 75, 76, - 31, 64, 69, 89, - 88,106,115,139, - 168,164,183,123, - 154}; - //static char const _greenpal[]={0,1,0x42,3,0x43,5,0x44,7,0x44,9,10,1,12,13,0x41,15}; - static char const _greenpal[]={0,0x41,0x42,0x43,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44}; - static char const _othergreenpal[]={0,0x21,0x22,0x23,0x24,0x25,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26}; - static char const _regpal[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; - GraphicBufferClass backpage(20*6,8); - - unsigned char *grey2palette = new unsigned char[768]; - unsigned char *progresspalette = new unsigned char[768]; - - - Keyboard::Clear(); - oldfont = Set_Font(ScoreFontPtr); - Set_Font_Palette(_regpal); - Set_Palette(BlackPalette); - - scenario = Scenario + ((house == HOUSE_GOOD) ? 0 : 14); - if (house == HOUSE_GOOD) { - lastscenario = (Scenario == 14); - if (Scenario == 15) return; - } else { - lastscenario = (Scenario == 12); - if (Scenario == 13) return; - } - - // Check if they're even entitled to map selection this time - if (CountryArray[scenario].Choices[ScenDir]==0) return; - - Theme.Queue_Song(THEME_MAP1); - PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL); - - /* - ** Extra graphic buffer to draw text into - */ - TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height(), (void*)NULL); - TextPrintBuffer->Clear(); - BlitList.Clear(); - - /* - ** Now start the process where we fade the gray earth in. - */ - greyearth = Open_Animation("GREYERTH.WSA", NULL, 0, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), localpalette); - greyearth2 = Open_Animation("E-BWTOCL.WSA", NULL, 0, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), grey2palette); - - /* - ** Load the spinning-globe anim - */ - if (house == HOUSE_GOOD) { - //anim = Open_Animation("EARTH_E.WSA", NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - anim = Open_Animation("HEARTH_E.WSA", NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - //progress = Open_Animation(lastscenario ? "BOSNIA.WSA" : "EUROPE.WSA",NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),progresspalette); - progress = Open_Animation(lastscenario ? "HBOSNIA.WSA" : "EUROPE.WSA",NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),progresspalette); - } else { - //anim = Open_Animation("EARTH_A.WSA", NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - anim = Open_Animation("HEARTH_A.WSA", NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - //progress = Open_Animation(lastscenario ? "S_AFRICA.WSA" : "AFRICA.WSA",NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),progresspalette); - progress = Open_Animation(lastscenario ? "HSAFRICA.WSA" : "AFRICA.WSA",NULL,0,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),progresspalette); - } - - void const * appear1 = MixFileClass::Retrieve("APPEAR1.AUD"); - void const * sfx4 = MixFileClass::Retrieve("SFX4.AUD"); - void const * text2 = MixFileClass::Retrieve("TEXT2.AUD"); - void const * target1 = MixFileClass::Retrieve("TARGET1.AUD"); - void const * target2 = MixFileClass::Retrieve("TARGET2.AUD"); -// void const * target3 = MixFileClass::Retrieve("TARGET3.AUD"); - void const * newtarg1 = MixFileClass::Retrieve("NEWTARG1.AUD"); - void const * beepy2 = MixFileClass::Retrieve("BEEPY2.AUD"); - void const * beepy3 = MixFileClass::Retrieve("BEEPY3.AUD"); - void const * beepy6 = MixFileClass::Retrieve("BEEPY6.AUD"); - void const * world2 = MixFileClass::Retrieve("WORLD2.AUD"); - void const * country1 = MixFileClass::Retrieve("COUNTRY1.AUD"); - void const * scold1 = MixFileClass::Retrieve("SCOLD1.AUD"); - - SysMemPage.Clear(); - PseudoSeenBuff->Clear(); - WWMouse->Erase_Mouse(&HidPage, TRUE); - HiddenPage.Clear(); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = Palette; - Increase_Palette_Luminance(InterpolationPalette , 30,30,30,63); - Read_Interpolation_Palette("MAP1.PAL"); -// SeenBuff.Blit(HidPage); - Animate_Frame(greyearth, SysMemPage, 0); - - Bit_It_In_Scale(0, 0, 320, 200, &SysMemPage, PseudoSeenBuff , &SeenBuff); - PseudoSeenBuff->Put_Pixel(237,92,TBLACK); - PseudoSeenBuff->Put_Pixel(237,93,TBLACK); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff,"MAP1.PAL"); - - InterpolationPaletteChanged = TRUE; - InterpolationPalette = localpalette; - Increase_Palette_Luminance(InterpolationPalette , 30,30,30,63); - Read_Interpolation_Palette("MAP_LOCL.PAL"); - Play_Sample(appear1, 255, Options.Normalize_Sound(110)); - Fade_Palette_To(localpalette, FADE_PALETTE_MEDIUM, Call_Back); - int i; - for (i = 1; i < Get_Animation_Frame_Count(greyearth); i++) { - Call_Back_Delay(4); - Animate_Frame(greyearth, *PseudoSeenBuff, i); - } - Close_Animation(greyearth); - Write_Interpolation_Palette("MAP_LOCL.PAL"); - - Call_Back_Delay(4); - SysMemPage.Clear(); - Animate_Frame(greyearth2, SysMemPage, 0); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = grey2palette; - Increase_Palette_Luminance(InterpolationPalette , 30,30,30,63); - Read_Interpolation_Palette("MAP_GRY2.PAL"); - Wait_Vert_Blank(); - Set_Palette(grey2palette); - SysMemPage.Blit(*PseudoSeenBuff); - Call_Back_Delay(4); - for (i = 1; i < Get_Animation_Frame_Count(greyearth2); i++) { - Animate_Frame(greyearth2,*PseudoSeenBuff,i); - Call_Back_Delay(4); - } - Close_Animation(greyearth2); - Write_Interpolation_Palette("MAP_GRY2.PAL"); - - /* - ** Copy the first frame up to the seenpage (while screen is black) - */ - SysMemPage.Clear(); - Animate_Frame(anim, SysMemPage, 1);//, 0,0, (WSAType)0,0,0); - SysMemPage.Blit(*PseudoSeenBuff); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff ,NULL); - - Stop_Speaking(); - - while (CountDownTimer.Time() || Is_Speaking()) { - Call_Back(); -// if (Keyboard::Check()) CountDownTimer.Set(0); - } - -// Keyboard::Clear(); - - /* - ** now make the grid appear - */ - SysMemPage.Blit(*PseudoSeenBuff); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff, NULL); - Play_Sample(sfx4, 255, Options.Normalize_Sound(130)); - Play_Sample(text2, 255, Options.Normalize_Sound(90)); - - - int frame = 1; - - while (frame < Get_Animation_Frame_Count(anim)) { - if (frame == 16 || frame == 33 || frame == 44 || frame == 70 || frame == 73) Play_Sample(text2, 255, Options.Normalize_Sound(90)); - if (frame == 21 || frame == 27) Play_Sample(target1, 255, Options.Normalize_Sound(90)); - if (frame == 45 || frame == 47 || frame == 49) Play_Sample(beepy6, 255, Options.Normalize_Sound(90)); - if (frame == 51) Play_Sample(world2, 255, Options.Normalize_Sound(90)); - if (frame == 70 || frame == 72) Play_Sample(beepy2, 255, Options.Normalize_Sound(90)); - if (frame == 74) Play_Sample(target2, 255, Options.Normalize_Sound(110)); - - switch (frame){ - case 1: - Alloc_Object(new MultiStagePrintClass(Text_String (TXT_READING_IMAGE_DATA), 0,10,_othergreenpal)); - break; - - case 16: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_READING_IMAGE_DATA)), 2*(10 + 12), BLACK); - break; - - case 17: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_READING_IMAGE_DATA)), 2*(10 + 12), TBLACK); - Alloc_Object(new MultiStagePrintClass("ANALYZING", 0,10,_othergreenpal)); - break; - - case 33: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ANALYZING)), 2*(10 + 12), BLACK); - break; - - case 34: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ANALYZING)), 2*(10 + 12), TBLACK); - Alloc_Object(new MultiStagePrintClass(Text_String (TXT_ENHANCING_IMAGE_DATA), 0,10,_othergreenpal)); - break; - - case 44: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE_DATA)), 2*(10 + 12), BLACK); - break; - - case 45: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE_DATA)), 2*(10 + 12), TBLACK); - Alloc_Object(new MultiStagePrintClass(Text_String(TXT_ISOLATING_OPERATIONAL_THEATER), 0,10,_othergreenpal)); - break; - - case 70: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String(TXT_ISOLATING_OPERATIONAL_THEATER)), 2*(10 + 12), BLACK); - break; - - case 71: - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String(TXT_ISOLATING_OPERATIONAL_THEATER)), 2*(10 + 12), TBLACK); - Alloc_Object(new MultiStagePrintClass(Text_String (TXT_ESTABLISHING_TRADITIONAL_BOUNDARIES), 0,10,_othergreenpal)); - break; - - case 74: - Alloc_Object(new MultiStagePrintClass(Text_String (TXT_FOR_VISUAL_REFERENCE), 0,22,_othergreenpal)); - break; - } - - - Animate_Frame(anim, *PseudoSeenBuff, frame++); - Call_Back_Delay(/*Keyboard::Check() ? 0 :*/ 3); - } - - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ESTABLISHING_TRADITIONAL_BOUNDARIES)), 2*(10 + 24), BLACK); - Call_Back_Delay (1); - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ESTABLISHING_TRADITIONAL_BOUNDARIES)), 2*(10 + 24), TBLACK); - Call_Back_Delay (1); - - Close_Animation(anim); - - Keyboard::Clear(); - BlitList.Clear(); - - /* - ** Freeze on the map of Europe or Africa - */ - - SysMemPage.Clear(); - Animate_Frame(progress,SysMemPage,0); - SysMemPage.Blit(*PseudoSeenBuff); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = progresspalette; - Increase_Palette_Luminance(InterpolationPalette , 30,30,30,63); - Read_Interpolation_Palette("MAP_PROG.PAL"); - - GraphicBufferClass *europe = new GraphicBufferClass(SysMemPage.Get_Width(),SysMemPage.Get_Height(),(GBC_Enum)0); - SysMemPage.Blit(*europe); - - /* - ** Now show territories as they existed last scenario - */ - int startframe = CountryArray[scenario].Start[ScenDir]; - if (startframe) { - Animate_Frame(progress,SysMemPage,startframe); - SysMemPage.Blit(*PseudoSeenBuff); - } - Set_Palette(progresspalette); - Call_Back_Delay(45); - //Write_Interpolation_Palette("MAP_PROG.PAL"); - - /* - ** Now dissolve in first advance of territories - */ - int xcoord = (house == HOUSE_GOOD ? 0 : 204); - SysMemPage.Blit(backpage, xcoord,1, 0,0, 20*6,8); - Play_Sample(text2, 255, Options.Normalize_Sound(90)); - if (house == HOUSE_GOOD) { - Alloc_Object(new ScorePrintClass(TXT_MAP_GDI,0,2,_greenpal)); - } else { - Alloc_Object(new ScorePrintClass(TXT_MAP_NOD,xcoord,2,_greenpal)); - } - Call_Back_Delay(60); - - Play_Sample(country1, 255, Options.Normalize_Sound(90)); - Animate_Frame(progress,SysMemPage,startframe+1); - Bit_It_In_Scale(0, 0, 320, 200, &SysMemPage, PseudoSeenBuff,&SeenBuff,1,1); - backpage.Blit(SysMemPage, 0,0, xcoord,1, 20*6,8); - Call_Back_Delay(85); - - /* - ** Now dissolve in second advance of territories - */ -#ifdef FRENCH - PseudoSeenBuff->Fill_Rect(xcoord,0,xcoord + 6*16 + 10,8,BLACK); - TextPrintBuffer->Fill_Rect(xcoord*2,0,2*(xcoord + 6*16 + 10),2*8,BLACK); -#else - PseudoSeenBuff->Fill_Rect(xcoord,0,xcoord + 6*16,8,BLACK); - TextPrintBuffer->Fill_Rect(2*xcoord,0,2*(xcoord + 6*16),2*8,BLACK); -#endif - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff,NULL); - SysMemPage.Blit(backpage, xcoord,1, 0,0, 20*6,8); - if (!lastscenario) { - Play_Sample(text2, 255, Options.Normalize_Sound(90)); - if (house == HOUSE_GOOD) { - Alloc_Object(new ScorePrintClass(TXT_MAP_NOD,0,12,_greenpal)); - } else { - Alloc_Object(new ScorePrintClass(TXT_MAP_GDI,xcoord,12,_greenpal)); - } - Call_Back_Delay(65); - } - - Play_Sample(country1, 255, Options.Normalize_Sound(90)); - Animate_Frame(progress,SysMemPage,startframe+2); - Bit_It_In_Scale(0, 0, 320, 200, &SysMemPage, PseudoSeenBuff , &SeenBuff,1,1); - backpage.Blit(SysMemPage, 0,0, xcoord,11, 20*6,8); - if (!lastscenario) Call_Back_Delay(85); -// Set_Font(oldfont); -#ifdef FRENCH - PseudoSeenBuff->Fill_Rect(xcoord,12,xcoord+6*16+10,20,BLACK); - TextPrintBuffer->Fill_Rect(2*xcoord,2*12,2*(xcoord+6*16+10),2*20,BLACK); -#else - PseudoSeenBuff->Fill_Rect(xcoord,12,xcoord+6*16,20,BLACK); - TextPrintBuffer->Fill_Rect(2*xcoord,2*12,2*(xcoord+6*16),2*20,BLACK); -#endif - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff,NULL); - - startframe = CountryArray[scenario].ContAnim[ScenDir]; - - /* - ** Now print the text over the page - */ - Play_Sample(text2, 255, Options.Normalize_Sound(90)); - Alloc_Object(new ScorePrintClass(TXT_MAP_LOCATE,0,160,_greenpal)); - Call_Back_Delay(20); - Alloc_Object(new ScorePrintClass(TXT_MAP_NEXT_MISSION, 0,170,_greenpal)); -#if (GERMAN | FRENCH) - Call_Back_Delay(20); - Alloc_Object(new ScorePrintClass(TXT_MAP_NEXT_MISS2, 0,180,_greenpal)); -#endif - Call_Back_Delay(50); - - /* - ** If we're on the last scenario, erase that text before doing the crosshairs - */ - if (lastscenario) { -#if (GERMAN | FRENCH) - SysMemPage.Fill_Rect(0,160, 20*6,186, TBLACK); - PseudoSeenBuff->Fill_Rect(0,160, 20*6,186, TBLACK); - TextPrintBuffer->Fill_Rect(0,2*160, 2*20*6,2*186, BLACK); - SeenBuff.Fill_Rect(0,2*160, 2*20*6,2*186, TBLACK); - HidPage.Fill_Rect(0,2*160, 2*20*6,2*186, TBLACK); -#else - SysMemPage.Fill_Rect(0,160, 20*6,176, TBLACK); - PseudoSeenBuff->Fill_Rect(0,160, 20*6,176, TBLACK); - TextPrintBuffer->Fill_Rect(0,2*160, 2*20*6,2*176, BLACK); - SeenBuff.Fill_Rect(0,2*160, 2*20*6,2*176, TBLACK); - HidPage.Fill_Rect(0,2*160, 2*20*6,2*176, TBLACK); -#endif - BlitList.Clear(); - Bit_It_In_Scale(0, 0, 320, 200, &SysMemPage, PseudoSeenBuff , &SeenBuff); - } - - /* - ** Fix up the palette that seems different for the last scenario - */ - if (lastscenario){ - InterpolationPaletteChanged = TRUE; - InterpolationPalette = CurrentPalette; - if (house == HOUSE_GOOD){ - Read_Interpolation_Palette("LASTSCNG.PAL"); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff, "LASTSCNG.PAL"); - }else{ - Read_Interpolation_Palette("LASTSCNB.PAL"); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff, "LASTSCNB.PAL"); - } - } - - - int q = 0; - for (frame = 0; frame < ((lastscenario) ? Get_Animation_Frame_Count(progress)-4 : 13); frame++) { - if (!frame) Play_Sample(beepy3, 255, Options.Normalize_Sound(90)); - if (frame == 2) Play_Sample(beepy3, 255, Options.Normalize_Sound(90)); - if (frame == 6) Play_Sample(newtarg1, 255, Options.Normalize_Sound(90)); - - - if (lastscenario){ - switch ( frame ){ - - case 23: - if (house == HOUSE_GOOD){ - Alloc_Object(new MultiStagePrintClass (Text_String (TXT_ENHANCING_IMAGE), 0, 10, _othergreenpal)); - }else{ -#if (FRENCH) - Alloc_Object(new MultiStagePrintClass (Text_String (TXT_ENHANCING_IMAGE), 180, 10, _othergreenpal)); -#else - Alloc_Object(new MultiStagePrintClass (Text_String (TXT_ENHANCING_IMAGE), 210, 10, _othergreenpal)); -#endif //(FRENCH) - } - - - case 35: - if (house == HOUSE_GOOD){ - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE)), 2*(10 + 12), BLACK); - }else{ -#if (FRENCH) - TextPrintBuffer->Fill_Rect (2*180, 2*10, 2*(180+String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE))), 2*(10 + 12), BLACK); -#else - TextPrintBuffer->Fill_Rect (2*210, 2*10, 2*(210+String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE))), 2*(10 + 12), BLACK); -#endif //(FRENCH) - } - break; - - case 36: - if (house == HOUSE_GOOD){ - TextPrintBuffer->Fill_Rect (0, 2*10, 2*String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE)), 2*(10 + 12), TBLACK); - }else{ -#if (FRENCH) - TextPrintBuffer->Fill_Rect (2*180, 2*10, 2*(180+String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE))), 2*(10 + 12), TBLACK); -#else - TextPrintBuffer->Fill_Rect (2*210, 2*10, 2*(210+String_Pixel_Width (Text_String (TXT_ENHANCING_IMAGE))), 2*(10 + 12), TBLACK); -#endif //(FRENCH) - } - break; - } - } - - Animate_Frame(progress,*PseudoSeenBuff,startframe + frame); - Call_Back_Delay(6); - /* Cause it to cycle on the flashing on the country for a little while */ - if (!lastscenario && frame == 4 && q < 4) { - frame = 2; - q++; - } - } - - int selection = 0, color = 0; - // erase the "Locating Coordinates" message... - Play_Sample(beepy6, 255, Options.Normalize_Sound(90)); - if (!lastscenario) { -#if (GERMAN | FRENCH) - SysMemPage.Fill_Rect( 0,160, 20*6,186, TBLACK); - PseudoSeenBuff->Fill_Rect(0,160, 20*6,186, TBLACK); - TextPrintBuffer->Fill_Rect(0,2*160, 2*20*6,2*186, BLACK); -#else - SysMemPage.Fill_Rect( 0,160, 20*6,176, TBLACK); - PseudoSeenBuff->Fill_Rect(0,160, 20*6,176, TBLACK); - TextPrintBuffer->Fill_Rect(0,2*160, 2*20*6,2*176, BLACK); -#endif - } - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff, NULL); - - /* - ** Now the crosshairs are over the target countries - loop until a - ** selection is made? - */ - int done = 0; - int framecounter = 0; - - if (house == HOUSE_GOOD) { - Load_Uncompress(CCFileClass(lastscenario ? "CLICK_EB.CPS" : "CLICK_E.CPS"), SysMemPage, SysMemPage); - } else { - Load_Uncompress(CCFileClass(lastscenario ? "CLICK_SA.CPS" : "CLICK_A.CPS"), SysMemPage, SysMemPage); - if (lastscenario) attackxcoord = 200; - } - -// Set_Font(ScoreFontPtr); - Play_Sample(text2, 255, Options.Normalize_Sound(90)); - Alloc_Object(new ScorePrintClass(TXT_MAP_SELECT,attackxcoord,160,_greenpal)); - Cycle_Call_Back_Delay(16,progresspalette); - Alloc_Object(new ScorePrintClass(TXT_MAP_TO_ATTACK,attackxcoord,170,_greenpal)); - Cycle_Call_Back_Delay(24,progresspalette); - while (Get_Mouse_State() > 0) Show_Mouse(); - - Keyboard::Clear(); - while (!done) { - Cycle_Call_Back_Delay(1,progresspalette); - - // Check for the mouse button - if (Keyboard::Check()) { - if ((Keyboard::Get() & 0x10FF) == KN_LMOUSE) { - for (selection = 0; selection < CountryArray[scenario].Choices[ScenDir]; selection++) { - color = SysMemPage.Get_Pixel(Get_Mouse_X()/2,Get_Mouse_Y()/2); - - /* - ** Special hack for Egypt the second time through - */ - if (CountryArray[scenario].CountryColor[ScenDir][selection] == 0xA0) { - if ((color == 0x80) || (color == 0x81)) color = 0xA0; - } - - if (CountryArray[scenario].CountryColor[ScenDir][selection] == color) { - Play_Sample(world2, 255, Options.Normalize_Sound(90)); - done = 1; - break; - } else { - Play_Sample(scold1, 255, Options.Normalize_Sound(90)); - } - } - } - } - } - ScenVar = CountryArray[scenario].CountryVariant[ScenDir][selection]; - ScenDir = CountryArray[scenario].CountryDir[ScenDir][selection]; - - if (!lastscenario) { - Close_Animation(progress); - - /* - ** Now it's time to highlight the country we're going to. - */ - void const * countryshape = MixFileClass::Retrieve(house == HOUSE_GOOD ? "COUNTRYE.SHP" : "COUNTRYA.SHP"); - - Hide_Mouse(); - // erase "Select country to attack" - PseudoSeenBuff->Fill_Rect(attackxcoord,160, attackxcoord+(17*6),178,BLACK); - TextPrintBuffer->Fill_Rect(2*attackxcoord,2*160, 2*(attackxcoord+(17*6)),2*178,BLACK); -#if (GERMAN | FRENCH) - PseudoSeenBuff->Fill_Rect(attackxcoord+(17*6),160, attackxcoord+(21*6),178,BLACK); - TextPrintBuffer->Fill_Rect(2*attackxcoord+(17*6*2),2*160, 2*(attackxcoord+(21*6)),2*178,BLACK); -#endif //GERMAN - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff ,NULL); - - /* - ** Draw the country's shape in non-fading colors - */ - Set_Logic_Page(SysMemPage); - europe->Blit(SysMemPage); - - int shape = CountryArray[scenario].CountryShape[ScenDir][selection]; - int xyindex = shape + (house == HOUSE_GOOD ? 0 : 18); - CC_Draw_Shape(countryshape, shape, - _countryx[xyindex],_countryy[xyindex], - WINDOW_MAIN, SHAPE_WIN_REL | SHAPE_CENTER, 0,0); - SysMemPage.Blit(*PseudoSeenBuff); - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff ,NULL); - - /* - ** Now clear the palette of all but the country's colors, and fade - ** the palette down - */ - CCFileClass("DARK_E.PAL").Read(localpalette, 768); -// Load_Data("DARK_E.PAL", localpalette, 768); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = localpalette; - Increase_Palette_Luminance(localpalette , 30,30,30,63); - Read_Interpolation_Palette("MAP_LOC2.PAL"); - Interpolate_2X_Scale(PseudoSeenBuff , &SeenBuff , "MAP_LOC2.PAL"); - Fade_Palette_To(localpalette, FADE_PALETTE_MEDIUM, Call_Back); - - countryshape = 0; - - Print_Statistics(color & 0x7F, _countryx[xyindex], _countryy[xyindex]); - } else { - CCFileClass(house == HOUSE_GOOD ? "DARK_B.PAL" : "DARK_SA.PAL").Read(localpalette, 768); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = localpalette; - Increase_Palette_Luminance(localpalette , 30,30,30,63); - Read_Interpolation_Palette("MAP_LOC3.PAL"); - Interpolate_2X_Scale(PseudoSeenBuff , &SeenBuff , "MAP_LOC3.PAL"); - Set_Palette(localpalette); -// Load_Data(house == HOUSE_GOOD ? "DARK_B.PAL" : "DARK_SA.PAL", localpalette, 768); - - Hide_Mouse(); -#if (GERMAN | FRENCH) - PseudoSeenBuff->Fill_Rect(attackxcoord, 160, 319, 178, BLACK); // erase "Select country to attack" - TextPrintBuffer->Fill_Rect(2*attackxcoord, 2*160, 639, 2*178, BLACK); // erase "Select country to attack" -#else - PseudoSeenBuff->Fill_Rect(attackxcoord, 160, attackxcoord + (17*6), 199, BLACK); // erase "Select country to attack" - TextPrintBuffer->Fill_Rect(2*attackxcoord, 2*160, 2*(attackxcoord + (17*6)), 2*199, BLACK); // erase "Select country to attack" -#endif - Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff, NULL); - Animate_Frame(progress, *PseudoSeenBuff, Get_Animation_Frame_Count(progress)-1); - Set_Palette(localpalette); - Close_Animation(progress); - PseudoSeenBuff->Blit(SysMemPage); - Print_Statistics(20, 160, house == HOUSE_GOOD ? 0 : 160); - } - - Theme.Queue_Song(THEME_NONE); - Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, NULL); - delete europe; - delete progresspalette; - delete grey2palette; - delete TextPrintBuffer; - TextPrintBuffer = NULL; - BlitList.Clear(); -} - - -/*************************************************************************** - * Print_Statistics -- Prints statistics on country selected * - * * - * * - * * - * INPUT: shape = country #, x & y = country's on-screen coords * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/27/1995 BWG : Created. * - *=========================================================================*/ -void Print_Statistics(int country, int xpos, int ypos) -{ - int index,newx; - void *oldfont; - static int const _gdistatnames[]={ - TXT_MAP_GDISTAT0, - TXT_MAP_GDISTAT1, - TXT_MAP_GDISTAT2, - TXT_MAP_GDISTAT3, - TXT_MAP_GDISTAT4, - TXT_MAP_GDISTAT5, - TXT_MAP_GDISTAT6 - }; - static int const _nodstatnames[]={ - TXT_MAP_GDISTAT0, - TXT_MAP_NODSTAT0, - TXT_MAP_GDISTAT2, - TXT_MAP_GDISTAT3, - TXT_MAP_NODSTAT1, - TXT_MAP_NODSTAT2, - TXT_MAP_GDISTAT5, - TXT_MAP_NODSTAT3, - TXT_MAP_NODSTAT4 - }; - static int const _countryname[]={ - TXT_MAP_COUNTRYNAME0, - TXT_MAP_COUNTRYNAME1, - TXT_MAP_COUNTRYNAME2, - TXT_MAP_COUNTRYNAME3, - TXT_MAP_COUNTRYNAME4, - TXT_MAP_COUNTRYNAME5, - TXT_MAP_COUNTRYNAME6, - TXT_MAP_COUNTRYNAME7, - TXT_MAP_COUNTRYNAME8, - TXT_MAP_COUNTRYNAME9, - TXT_MAP_COUNTRYNAME10, - TXT_MAP_COUNTRYNAME11, - TXT_MAP_COUNTRYNAME12, - TXT_MAP_COUNTRYNAME13, - TXT_MAP_COUNTRYNAME14, - TXT_MAP_COUNTRYNAME15, - TXT_MAP_COUNTRYNAME16, - TXT_MAP_COUNTRYNAME17, - TXT_MAP_COUNTRYNAME18, - TXT_MAP_COUNTRYNAME19, - TXT_MAP_COUNTRYNAME20, - TXT_MAP_COUNTRYNAME21, - TXT_MAP_COUNTRYNAME22, - TXT_MAP_COUNTRYNAME23, - TXT_MAP_COUNTRYNAME24, - TXT_MAP_COUNTRYNAME25, - TXT_MAP_COUNTRYNAME26, - TXT_MAP_COUNTRYNAME27, - TXT_MAP_COUNTRYNAME28, - TXT_MAP_COUNTRYNAME29, - TXT_MAP_COUNTRYNAME30, - TXT_MAP_COUNTRYNAME31, - TXT_MAP_COUNTRYNAME32, - TXT_MAP_COUNTRYNAME33, - TXT_MAP_COUNTRYNAME34 - }; - - static int const _govtnames[]={ - TXT_MAP_GOVT0, - TXT_MAP_GOVT1, - TXT_MAP_GOVT2, - TXT_MAP_GOVT3, - TXT_MAP_GOVT4, - TXT_MAP_GOVT5, - TXT_MAP_GOVT6, - TXT_MAP_GOVT7, - TXT_MAP_GOVT8, - TXT_MAP_GOVT9, - TXT_MAP_GOVT10, - TXT_MAP_GOVT11 - }; - static int const _armynames[]={ - TXT_MAP_ARMY0, - TXT_MAP_ARMY1, - TXT_MAP_ARMY2, - TXT_MAP_ARMY3, - TXT_MAP_ARMY4, - TXT_MAP_ARMY5 - }; - static int const _military[]={ - TXT_MAP_MILITARY0, - TXT_MAP_MILITARY1, - TXT_MAP_MILITARY2, - TXT_MAP_MILITARY3, - TXT_MAP_MILITARY4 - }; - - static char const _greenpal[]={0,0x41,0x42,0x43,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44}; - //static char const _greenpal[]={0,1,0x42,3,0x43,5,0x44,7,0x44,9,10,1,12,13,0x41,15}; - static char _deststr[16]; - -/* Change to the six-point font for Text_Print */ - oldfont = Set_Font(ScoreFontPtr); - -#ifdef GERMAN - xpos = 8; -#else - xpos = (xpos > 128) ? 8 : 136; -#endif - ypos = (ypos > 100) ? 8 : 104-6; - if (PlayerPtr->Class->House == HOUSE_GOOD) { - Alloc_Object(new ScorePrintClass(_countryname[GDIStats[country].nameindex],xpos,ypos,_greenpal)); - Call_Back_Delay(strlen(Text_String(_countryname[GDIStats[country].nameindex]))*3); - ypos += 16; - for (index = 0; index < 7; index ++) { - Alloc_Object(new ScorePrintClass(_gdistatnames[index],xpos,ypos,_greenpal)); - Call_Back_Delay(strlen(Text_String(_gdistatnames[index]+3))); - newx = xpos + 6*strlen(Text_String(_gdistatnames[index])); - switch (index) { - case 0: - Alloc_Object(new ScorePrintClass(GDIStats[country].pop,newx,ypos,_greenpal)); - break; - case 1: - Alloc_Object(new ScorePrintClass(GDIStats[country].area,newx,ypos,_greenpal)); - break; - case 2: - Alloc_Object(new ScorePrintClass(GDIStats[country].capital,newx,ypos,_greenpal)); - break; - case 3: - Alloc_Object(new ScorePrintClass(_govtnames[GDIStats[country].govt],newx,ypos,_greenpal)); - break; - case 4: - Alloc_Object(new ScorePrintClass(GDIStats[country].gdp,newx,ypos,_greenpal)); - break; - case 5: - Alloc_Object(new ScorePrintClass(GDIStats[country].conflict,newx,ypos,_greenpal)); - break; - case 6: - Alloc_Object(new ScorePrintClass(_armynames[GDIStats[country].military],newx,ypos,_greenpal)); - break; - } - ypos += 8; - } - } else { // Nod statistics - if (country > 30) { - country = 15; // hack for 2nd time in Egypt - } else { - if (country >=15) country++; // hack to account for Egypt - } - country++; - - Alloc_Object(new ScorePrintClass(_countryname[NodStats[country].nameindex],xpos,ypos,_greenpal)); - Call_Back_Delay(strlen(Text_String(_countryname[NodStats[country].nameindex]))*3); - ypos += 16; - for (index = 0; index < 9; index ++) { - Alloc_Object(new ScorePrintClass(_nodstatnames[index],xpos,ypos,_greenpal)); - Call_Back_Delay(strlen(Text_String(_nodstatnames[index]+3))); - newx = xpos + 6*strlen(Text_String(_nodstatnames[index])); - switch (index) { - case 0: - Alloc_Object(new ScorePrintClass(NodStats[country].pop,newx,ypos,_greenpal)); - break; - case 1: - sprintf(_deststr,"%d%%",NodStats[country].expendable); - Alloc_Object(new ScorePrintClass(_deststr,newx,ypos,_greenpal)); - break; - case 2: - Alloc_Object(new ScorePrintClass(NodStats[country].capital,newx,ypos,_greenpal)); - break; - case 3: - Alloc_Object(new ScorePrintClass(_govtnames[NodStats[country].govt],newx,ypos,_greenpal)); - break; - case 4: -#ifdef FIX_ME_LATER - sprintf(_deststr,"%s %d%%",LowMedHiStr(NodStats[country].corruptible),NodStats[country].corruptible); -#endif //FIX_ME_LATER - sprintf(_deststr,"%d%%",NodStats[country].corruptible); - Alloc_Object(new ScorePrintClass(_deststr,newx,ypos,_greenpal)); - break; - case 5: - Alloc_Object(new ScorePrintClass(NodStats[country].worth,newx,ypos,_greenpal)); - break; - case 6: - Alloc_Object(new ScorePrintClass(NodStats[country].conflict,newx,ypos,_greenpal)); - break; - case 7: - Alloc_Object(new ScorePrintClass(_military[NodStats[country].military],newx,ypos,_greenpal)); - break; - case 8: - sprintf(_deststr,"%d%%",NodStats[country].probability); - Alloc_Object(new ScorePrintClass(_deststr,newx,ypos,_greenpal)); - break; - } - ypos += 8; - } - } - -#ifdef FRENCH - Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2,94,193-6,_greenpal)); -#else - Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2,160-(17*3),193-6,_greenpal)); -#endif - - int done = 0; - while (!done) { - done = 1; - for (int x = 0; x < MAXSCOREOBJS; x++) if (ScoreObjs[x]) { - done = 0; - Call_Back_Delay(1); - } - } - Keyboard::Clear(); - while (Keyboard::Check()){ - Keyboard::Clear(); - } - while (!Keyboard::Check() && !ControlQ) { - Call_Back_Delay(1); - } - Keyboard::Clear(); - Set_Font(oldfont); -} - -#ifdef NEVER -/*************************************************************************** - * FADING_BYTE_BLIT -- 'Pixelized' incremental byte blit. * - * * - * This routine will perform the same function as Byte_Blit, but will * - * do so in an incremental (one piece at a time) method. This is * - * usefull for graphic 'fades' from one display to another. * - * * - * INPUT: srcx - Source page X byte position of upper left corner. * - * * - * srcy - Source page Y pixel position of upper left corner. * - * * - * destx - Dest page X byte position of upper left corner. * - * * - * desty - Dest page Y pixel position of upper left corner. * - * * - * w - Width of the blit in bytes. * - * * - * h - Height of the blit in pixels. * - * * - * src - PageType of the source page. * - * * - * dest - Page type of the destination. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine, although functionally equivalent to the * - * normal Byte_Blit, is very slow. Only use this when * - * the 'fading' graphic effect is desired. This means the * - * destination page should probably be the SEENPAGE. * - * * - * HISTORY: * - * 07/17/1991 JLB : Created from Bit_It_In() (LJC code). * - * 04/17/1995 BWG : Adapted to the C++ system. * - *=========================================================================*/ -void Fading_Byte_Blit(int srcx, int srcy, int destx, int desty, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest) -{ - unsigned int xindex, // Working array index var. - yindex; // Working y index var. - unsigned int x,y; // Extraction position indexes. - unsigned int tempy; // Temporary working Y index var. - int _xindex[40]; // X position array. - int _yindex[200]; // Y position array. - - // Anticipate two pixel rows per blit. - h >>= 1; - - // This routine is byte-aligned - srcx >>=3; - destx >>=3; - w >>=3; - - for (xindex = 0; xindex < w; xindex++) _xindex[xindex] = xindex; /* init the index array */ - for (yindex = 0; yindex < h; yindex++) _yindex[yindex] = yindex; /* init the index array */ - - /* - ** Shuffle the X indexes around a bit. This gives it - ** that 'random' feel while remaining precise. - */ - for (xindex = 0; xindex < w; xindex++) { - int temp; - - x = IRandom(0,w-1); - temp = _xindex[x]; - _xindex[x] = _xindex[xindex]; - _xindex[xindex] = temp; - } - - /* - ** Shuffle the Y indexes around a bit for the same reason that - ** the x indexes were shuffled. - */ - for (yindex = 0; yindex < h; yindex++) { - int temp; - - y = IRandom(0,h-1); - temp = _yindex[y]; - _yindex[y] = _yindex[yindex]; - _yindex[yindex] = temp; - } - - /* - ** Sweep through the indexes and 'construct' the destination display - ** from a series of miniature Byte_Blits. - */ - for (yindex = 0; yindex < h; yindex++) { - tempy = yindex; - Call_Back(); - for (xindex = 0; xindex < w; xindex++) { - x = _xindex[xindex]; - y = _yindex[tempy]; - tempy++; - if (tempy >= h) tempy = 0; - src->Blit(*dest, (srcx+x)<<3, srcy+(y<<1), (destx+x)<<3, desty+(y<<1), 1<<3, 2); - } - } -} -#endif - - - - - -void Cycle_Call_Back_Delay(int time, unsigned char *pal) -{ - static int _counter; - unsigned char r,g,b; - int i; - - while (time--) { - _counter = (++_counter & 3); - - if (!(_counter & 3) ) { - r = pal[249*3+0]; - g = pal[249*3+1]; - b = pal[249*3+2]; - - for (i = 249; i < 254; i++) { - pal[i*3+0] = pal[(i+1)*3+0]; - pal[i*3+1] = pal[(i+1)*3+1]; - pal[i*3+2] = pal[(i+1)*3+2]; - } - pal[254*3+0] = r; - pal[254*3+1] = g; - pal[254*3+2] = b; - - Set_Palette(pal); - } - Call_Back_Delay(1); - } -} - -int LowMedHiStr(int percentage) -{ - if (percentage < 30) return(TXT_MAP_LMH0); - if (percentage < 70) return(TXT_MAP_LMH1); - return(TXT_MAP_LMH2); -} - - - -#endif //DEMO - - -/*************************************************************************** - * Bit_It_In -- Pixel fade graphic copy. * - * * - * Copies a block of graphic memory using a 'random' pixel algorithm. * - * Typcial use would be to 'fade' some graphic display into another. * - * * - * INPUT: x,y - Pixel position of upper left corner of block. * - * * - * w,y - Pixel width and height of block to pixel blit. * - * * - * src - Page number of the source page. * - * * - * dest - Page number of the destination page. * - * * - * delay - # of frames to wait after each line fades in * - * * - * OUTPUT: none * - * * - * WARNINGS: This function uses PIXEL coordinates for the X and width * - * parameters. This is unlike the Byte_Blit() routine that * - * it most closely resembles. * - * * - * HISTORY: * - * 04/16/1991 JLB : Created. * - * 04/17/1995 BWG : Adapted to C++ library. * - *=========================================================================*/ - -void Bit_It_In_Scale(int x, int y, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest, GraphicViewPortClass * /*seen*/ , int delay, int dagger) -{ - short int *xindex,*yindex; - int n; - int i,j,k,m,j1; - short ScaleBuffer[320+200]; - - xindex = (short int *) ScaleBuffer; - yindex = xindex + 320; - - for (i=0; iLock() && dest->Lock()){ - for (i=0; i=h) j1=0; - - Buffer_Put_Pixel (dest,k,m,Buffer_Get_Pixel(src,k,m)); - //n=src->Get_Pixel(k,m); - //dest->Put_Pixel(k,m,n); - } - if (dagger) for (int q=j; q>=0; q--) { - Buffer_Put_Pixel(dest,160-(j-q),q,Buffer_Get_Pixel(src,160-(j-q),q)); - Buffer_Put_Pixel(dest,160+(j-q),q,Buffer_Get_Pixel(src,160+(j-q),q)); - //dest->Put_Pixel(160-(j-q),q,src->Get_Pixel(160-(j-q),q)); - //dest->Put_Pixel(160+(j-q),q,src->Get_Pixel(160+(j-q),q)); - } - } - src->Unlock(); - dest->Unlock(); - //if (seen){ - //Interpolate_2X_Scale(dest , seen ,NULL); - //} - } -} - -void Bit_It_In(int x, int y, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest, int delay, int dagger) -{ - Bit_It_In_Scale (x, y, w, h, src, dest, NULL , delay, dagger); -} - diff --git a/code/TIBERIANDAWN/MENUS.CPP b/code/TIBERIANDAWN/MENUS.CPP deleted file mode 100644 index 00e44d5..0000000 --- a/code/TIBERIANDAWN/MENUS.CPP +++ /dev/null @@ -1,938 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\menus.cpv 2.17 16 Oct 1995 16:50:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MENUS.CPP * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : May 17, 1995 [BRR] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Main_Menu -- Menu processing * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "ccdde.h" - -/***************************** -** Function prototypes -******************************/ - -#ifdef SCENARIO_EDITOR - -PRIVATE int Coordinates_In_Region(int x,int y,int inx1,int iny1,int inx2,int iny2); -PRIVATE int Select_To_Entry(int select, unsigned long bitfield, int index); -PRIVATE void Flash_Line(char const *text,int xpix,int ypix,unsigned nfgc,unsigned hfgc,unsigned bgc); - -int UnknownKey; - -PRIVATE int MenuUpdate=1; -PRIVATE int MenuSkip; - - -/*=========================================================================*/ -/* SELECT_TO_ENTRY: */ -/* */ -/* This routine converts a selection to the correct string entry. It */ -/* does this by search through a long bitfield starting at position index */ -/* until it finds the correct conversion to entries. */ -/* */ -/* INPUTS: int selection from menu, long the bit field to search, int */ -/* the starting index within the bit field. */ -/* RETURNS: int the index into the table of entries */ -/*=========================================================================*/ -PRIVATE int Select_To_Entry(int select, unsigned long bitfield, int index) -{ - int placement; - - if (bitfield==0xFFFFFFFFL) /* if all bits are set */ - return(select); /* then it as is */ - - placement=0; /* current pos zero */ - while (select) { /* while still ones */ - if (bitfield & (1L<<(placement+index))) /* if this flagged then */ - select--; /* decrement counter */ - placement++; /* and we moved a place */ - } - while (!(bitfield & (1L<<(placement+index)))) { - placement++; - } - - return(placement); /* return the position */ -} - - -/*=========================================================================*/ -/* FLASH_LINE: */ -/* */ -/* This routine will flash the line at the desired location for the */ -/* menu routine. It is way cool awesome! */ -/* */ -/* INPUTS: char *text, int x position on line, int y position, char */ -/* normal foreground color, char hilight foreground color, char */ -/* background color */ -/* RETURNS: none */ -/*=========================================================================*/ -PRIVATE void Flash_Line(char const *text,int xpix,int ypix,unsigned nfgc,unsigned hfgc,unsigned bgc) -{ - int loop; - - for (loop=0;loop<3;loop++) { - Hide_Mouse(); - Fancy_Text_Print(text,xpix,ypix,hfgc,bgc, TPF_8POINT|TPF_DROPSHADOW); - Delay(2); - Fancy_Text_Print(text,xpix,ypix,nfgc,bgc, TPF_8POINT|TPF_DROPSHADOW); - Show_Mouse(); - Delay(2); - } -} - -/*=========================================================================*/ -/* COORDINATES_IN_REGION: */ -/* */ -/* Test to see if a given pair of coordinates are within the given */ -/* rectangular region. */ -/* */ -/* INPUTS: int x to be tested, int y to be tested, int left x pos, */ -/* int top y pos, int right x pos, int bottom y pos */ -/* RETURNS: none */ -/*=========================================================================*/ -PRIVATE int Coordinates_In_Region(int x,int y,int inx1,int iny1,int inx2,int iny2) -{ - return((x>=inx1)&&(x<=inx2)&&(y>=iny1)&&(y<=iny2)); -} - -#ifdef NEVER -/*=========================================================================*/ -/* FIND_MENU_ITEMS: */ -/* */ -/* This routine finds the real total items in a menu when certain items */ -/* may be disabled by bit fields and the like. This is done by looping */ -/* through the fields, starting at the position passed in index and */ -/* counting the number of bits that are set. */ -/* */ -/* INPUTS: int the maximum number of items possible on the menu, long */ -/* the bit field of enabled and disabled items, char the index */ -/* point to start at within the list. */ -/* RETURNS: int the total number of items in the menu */ -/*=========================================================================*/ - int Find_Menu_Items(int maxitems, unsigned long field, char index) - { - int loop,ctr; - - if (field==0xFFFFFFFFL) /* if all bits are set */ - return(maxitems); /* then maxitems set */ - - for (loop=ctr=0;loop>1; /* adjustment for menus */ - - menuy = WinY+menuptr[MENUY]; /* get the absolute */ - menux = (WinX+menuptr[MENUX])<<3; /* coords of menu */ - normcol = menuptr[NORMCOL]; - litcol = menuptr[HILITE]; - - /* - ** Fetch a pending keystroke from the buffer if there is a keystroke - ** present. If no keystroke is pending then simple mouse tracking will - ** be done. - */ - key = 0; - UnknownKey = 0; - if (Keyboard::Check()) { - key = (Keyboard::Get()&0x18FF); /* mask off all but release bit */ - } - - /* - ** if we are using the mouse and it is installed, then find the mouse - ** coordinates of the menu and if we are not somewhere on the menu get - ** the heck outta here. If we are somewhere on the menu, then figure - ** out the new selected item, and continue forward. - */ - mx1=(WinX<<3)+(menuptr[MENUX]*FontWidth); /* get menu coords */ - my1=(WinY)+(menuptr[MENUY])-halfskip; /* from the menu */ - mx2=mx1+(menuptr[ITEMWIDTH]*FontWidth)-1; /* structure as */ - my2=my1+(menuptr[ITEMSHIGH]*menuskip)-1; /* necessary */ - - tempy=Get_Mouse_Y(); - if (Coordinates_In_Region(Get_Mouse_X(),tempy,mx1,my1,mx2,my2)&& MenuUpdate) { - newitem=(tempy-my1)/menuskip; - } - - switch (key) { - - case KN_UP: /* if the key moves up */ - newitem--; /* new item up one */ - if (newitem<0) /* if invalid new item */ - newitem=maxitem; /* put at list bottom */ - break; - case KN_DOWN: /* if key moves down */ - newitem++; /* new item down one */ - if (newitem>maxitem) /* if new item past */ - newitem=0; /* list end, clear */ - break; - case KN_HOME: /* if top of list key */ - case KN_PGUP: /* is selected then */ - newitem=0; /* new item = top */ - break; - case KN_END: /* if bottom of list is */ - case KN_PGDN: /* selected then */ - newitem=maxitem; /* new item = bottom */ - break; - - /* - ** Handle mouse button press. Set selection and then fall into the - ** normal menu item select logic. - */ - case KN_RMOUSE: - case KN_LMOUSE: - if (Coordinates_In_Region(_Kbd->MouseQX,_Kbd->MouseQY,mx1,my1,mx2,my2)) { - newitem = (_Kbd->MouseQY - my1) / menuskip; - } else { - UnknownKey = key; // Pass the unprocessed button click back. - break; - } - - /* - ** Normal menu item select logic. Will flash line and exit with menu - ** selection number. - */ - case KN_RETURN: /* if a selection is */ - case KN_SPACE: /* made with key */ - case KN_CENTER: - select=newitem; /* flag it made. */ - break; - - case 0: - break; - - /* - ** When no key was pressed or an unknown key was pressed, set the - ** global record of the key and exit normally. - ** EXCEPTION: If the key matches the first letter of any of the - ** menu entries, then presume it as a selection of - ** that entry. - */ - default: - for (idx = 0; idx < menuptr[ITEMSHIGH]; idx++) { - if (toupper(*(text[Select_To_Entry(idx,field,index)])) == toupper(Keyboard::To_ASCII((KeyNumType)(key&0x0FF)))) { - newitem = select = idx; - break; - } - } - UnknownKey = key; - break; - } - - if (newitem!=item) { - Hide_Mouse(); - idx=Select_To_Entry(item,field,index); - drawy=menuy+(item*menuskip); - Fancy_Text_Print(text[idx],menux,drawy,normcol,TBLACK, TPF_8POINT|TPF_DROPSHADOW); - idx=Select_To_Entry(newitem,field,index); - drawy=menuy+(newitem*menuskip); - Fancy_Text_Print(text[idx],menux,drawy,litcol,TBLACK, TPF_8POINT|TPF_DROPSHADOW); - Show_Mouse(); /* resurrect the mouse */ - } - - if (select!=-1) { - idx=Select_To_Entry(select,field,index); - Hide_Mouse(); /* get rid of the mouse */ - drawy=menuy+(newitem*menuskip); - Flash_Line(text[idx], menux, drawy, normcol, litcol, TBLACK); - Show_Mouse(); - select=idx; - } - - menuptr[MSELECTED]=newitem; /* update menu select */ - - return(select); -} - - -/*************************************************************************** - * Do_Menu -- Generic menu processor. * - * * - * This helper function displays a menu of specified entries and waits * - * for the player to make a selection. If a selection is made, then * - * a whole number (starting at 0) is returned matching the entry * - * selected. If ESC is pressed, then -1 is returned. * - * * - * INPUT: strings -- A pointer to an array of pointers to text strings. * - * Each entry in the list will be a menu entry that * - * can be selected. * - * * - * blue -- Should the special blue color be used to display * - * the menu? * - * * - * OUTPUT: Returns with the cardinal number of the selected menu entry. * - * If ESC was pressed, then -1 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/16/1994 JLB : Created. * - *=========================================================================*/ -int Do_Menu(char const **strings, bool blue) -{ - int count; // Number of entries in this menu. - int length; // The width of the menu (in pixels). - char const **ptr; // Working menu text pointer. - int selection; // Selection from user. - - if (!strings) return(-1); - Set_Logic_Page(SeenBuff); - Keyboard::Clear(); - - /* - ** Determine the number of entries in this string. - */ - ptr = strings; - count = 0; - while (*ptr++) { - count++; - } - MenuList[0][ITEMSHIGH] = count; - - /* - ** Determine the width of the menu by finding the length of the - ** longest menu entry. - */ - Fancy_Text_Print(TXT_NONE, 0, 0, 0, 0, TPF_8POINT|TPF_DROPSHADOW); - length = 0; - ptr = strings; - while (*ptr) { - length = MAX(length, (int)String_Pixel_Width(*ptr)); - ptr++; - } - length += 7; - MenuList[0][ITEMWIDTH] = length >> 3; - - /* - ** Adjust the window values to match the size of the - ** specified menu. - */ - WindowList[WINDOW_MENU][WINDOWWIDTH] = MenuList[0][ITEMWIDTH] + 2; - WindowList[WINDOW_MENU][WINDOWX] = 19 - (length >> 4); - WindowList[WINDOW_MENU][WINDOWY] = 174 - (unsigned)(MenuList[0][ITEMSHIGH] * (FontHeight+FontYSpacing)); - WindowList[WINDOW_MENU][WINDOWHEIGHT] = MenuList[0][ITEMSHIGH] * FontHeight + 5 /*11*/; - - /* - ** Display the menu. - */ - Change_Window((int)WINDOW_MENU); - Show_Mouse(); - Window_Box(WINDOW_MENU, blue ? BOXSTYLE_BLUE_UP : BOXSTYLE_RAISED); - Setup_Menu(0, strings, 0xFFFFL, 0, 0); - - Keyboard::Clear(); - selection = -1; - UnknownKey = 0; - while (selection == -1) { - Call_Back(); - selection = Check_Menu(0, strings, NULL, 0xFFL, 0); - if (UnknownKey != 0 || UnknownKey == KN_ESC || UnknownKey==KN_LMOUSE || UnknownKey==KN_RMOUSE) break; - } - Keyboard::Clear(); - Hide_Mouse(); - - Blit_Hid_Page_To_Seen_Buff(); - Change_Window((int)WINDOW_MAIN); - Map.Flag_To_Redraw(true); - return(selection); -} -#endif - - -/*************************************************************************** - * Main_Menu -- Menu processing * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * index of item selected, -1 if time out * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/17/1995 BRR : Created. * - *=========================================================================*/ -int Main_Menu(unsigned long timeout) -{ - enum { - D_DIALOG_W = 152*2, - D_DIALOG_H = 136*2, - D_DIALOG_X = 85*2, - D_DIALOG_Y = 0, - D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), - - D_START_W = 125*2, - D_START_H = 9*2, - D_START_X = 98*2, - D_START_Y = 35*2, - -#ifdef BONUS_MISSIONS - D_BONUS_W = 125*2, - D_BONUS_H = 9*2, - D_BONUS_X = 98*2, - D_BONUS_Y = 0, -#endif //BONUS_MISSIONS - - D_INTERNET_W = 125*2, - D_INTERNET_H = 9*2, - D_INTERNET_X = 98*2, - D_INTERNET_Y = 36*2, - - D_LOAD_W = 125*2, - D_LOAD_H = 9*2, - D_LOAD_X = 98*2, - D_LOAD_Y = 53*2, - - D_MULTI_W = 125*2, - D_MULTI_H = 9*2, - D_MULTI_X = 98*2, - D_MULTI_Y = 71*2, - - D_INTRO_W = 125*2, - D_INTRO_H = 9*2, - D_INTRO_X = 98*2, - D_INTRO_Y = 89*2, -#if (GERMAN | FRENCH) - D_EXIT_W = 83*2, -#else - D_EXIT_W = 63*2, -#endif - D_EXIT_H = 9*2, -#if (GERMAN | FRENCH) - D_EXIT_X = 118*2, -#else - D_EXIT_X = 128*2, -#endif - D_EXIT_Y = 111*2, - - }; - -#ifdef NEWMENU - int starty = 25*2; -#endif - - enum { -#ifdef NEWMENU - BUTTON_EXPAND=100*2, - BUTTON_START, -#ifdef BONUS_MISSIONS - BUTTON_BONUS, -#endif //BONUS_MISSIONS - BUTTON_INTERNET, -#else - BUTTON_START=100*2, -#endif - BUTTON_LOAD, - BUTTON_MULTI, - BUTTON_INTRO, - BUTTON_EXIT, - }; - -#ifdef NEWMENU - bool expansions = Expansion_Present(); -#endif - KeyNumType input; // input from user - int retval; // return value - int curbutton; -#ifdef NEWMENU -#ifdef BONUS_MISSIONS - TextButtonClass *buttons[8]; -#else - TextButtonClass *buttons[7]; -#endif //BONUS_MISSIONS -#else - TextButtonClass *buttons[5]; -#endif -// unsigned long starttime; - - ControlClass *commands = NULL; // the button list - -#ifdef NEWMENU -#ifdef BONUS_MISSIONS - int ystep = 13*2; -#else - int ystep = 15*2; -#endif //BONUS_MISSIONS - - if (expansions) ystep -= 2*2; - TextButtonClass expandbtn (BUTTON_EXPAND, TXT_NEW_MISSIONS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_START_X, starty, D_START_W, D_START_H); - if (expansions) starty += ystep; - - TextButtonClass startbtn (BUTTON_START, TXT_START_NEW_GAME, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_START_X, starty, D_START_W, D_START_H); - starty += ystep; - -#ifdef BONUS_MISSIONS - TextButtonClass bonusbtn (BUTTON_BONUS, TXT_BONUS_MISSIONS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_BONUS_X, starty, D_BONUS_W, D_BONUS_H); - starty += ystep; -#endif //BONUS_MISSIONS - - TextButtonClass internetbutton(BUTTON_INTERNET, TXT_INTERNET, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_INTERNET_X, starty, D_INTERNET_W, D_INTERNET_H); - starty += ystep; - - TextButtonClass loadbtn (BUTTON_LOAD, TXT_LOAD_MISSION, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_LOAD_X, starty, D_LOAD_W, D_LOAD_H); - starty += ystep; -#else - - TextButtonClass startbtn (BUTTON_START, TXT_START_NEW_GAME, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_START_X, D_START_Y, D_START_W, D_START_H); - - TextButtonClass loadbtn (BUTTON_LOAD, TXT_LOAD_MISSION, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_LOAD_X, D_LOAD_Y, D_LOAD_W, D_LOAD_H); - -#endif - - -#ifdef DEMO - TextButtonClass multibtn (BUTTON_MULTI, TXT_ORDER_INFO, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI_X, D_MULTI_Y, D_MULTI_W, D_MULTI_H); -#else - -#ifdef NEWMENU - TextButtonClass multibtn (BUTTON_MULTI, TXT_MULTIPLAYER_GAME, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI_X, starty, D_MULTI_W, D_MULTI_H); - starty += ystep; - - //TextButtonClass internetbutton(BUTTON_INTERNET, TXT_INTERNET, - // TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - // D_INTERNET_X, starty, D_INTERNET_W, D_INTERNET_H); - //starty += ystep; -#else - TextButtonClass multibtn (BUTTON_MULTI, TXT_MULTIPLAYER_GAME, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_MULTI_X, D_MULTI_Y, D_MULTI_W, D_MULTI_H); -#endif -#endif - -#ifdef NEWMENU -#ifdef DEMO - TextButtonClass introbtn (BUTTON_INTRO, TXT_JUST_INTRO, -#else //DEMO - TextButtonClass introbtn (BUTTON_INTRO, TXT_INTRO, -#endif //DEMO - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_INTRO_X, starty, D_INTRO_W, D_INTRO_H); - starty += ystep; - - TextButtonClass exitbtn (BUTTON_EXIT, TXT_EXIT_GAME, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -#if (GERMAN | FRENCH) - //D_EXIT_X, starty); - D_EXIT_X, starty, D_EXIT_W, D_EXIT_H); -#else - D_EXIT_X, starty, D_EXIT_W, D_EXIT_H); -#endif - starty += ystep; - -#else - -#ifdef DEMO - TextButtonClass introbtn (BUTTON_INTRO, TXT_JUST_INTRO, -#else //DEMO - TextButtonClass introbtn (BUTTON_INTRO, TXT_INTRO, -#endif //DEMO - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - D_INTRO_X, D_INTRO_Y, D_INTRO_W, D_INTRO_H); - - TextButtonClass exitbtn (BUTTON_EXIT, TXT_EXIT_GAME, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -#if (GERMAN | FRENCH) - //D_EXIT_X, D_EXIT_Y); - D_EXIT_X, D_EXIT_Y, D_EXIT_W, D_EXIT_H); -#else - D_EXIT_X, D_EXIT_Y, D_EXIT_W, D_EXIT_H); -#endif -#endif - - /* - ** Initialize - */ - Set_Logic_Page(SeenBuff); - Keyboard::Clear(); -#if (0) //PG_TO_FIX - starttime = TickCount.Time(); -#endif - /* - ** Create the list - */ - commands = &startbtn; -#ifdef NEWMENU - if (expansions) { - expandbtn.Add_Tail(*commands); - } -#endif -#ifdef BONUS_MISSIONS - bonusbtn.Add_Tail(*commands); -#endif //BONUS_MISSIONS - - -#ifndef DEMO - internetbutton.Add_Tail(*commands); -#endif //DEMO - loadbtn.Add_Tail(*commands); - multibtn.Add_Tail(*commands); - introbtn.Add_Tail(*commands); - exitbtn.Add_Tail(*commands); - - /* - ** Fill array of button ptrs - */ -#ifdef NEWMENU - if (expansions) { - curbutton = 0; - } else { - curbutton = 1; - } - int butt = 0; - - buttons[butt++] = &expandbtn; - buttons[butt++] = &startbtn; -#ifdef BONUS_MISSIONS - buttons[butt++] = &bonusbtn; -#endif //BONUS_MISSIONS - buttons[butt++] = &internetbutton; - buttons[butt++] = &loadbtn; - buttons[butt++] = &multibtn; - buttons[butt++] = &introbtn; - buttons[butt++] = &exitbtn; -#else - curbutton = 0; - buttons[0] = &startbtn; - buttons[1] = &loadbtn; - buttons[2] = &multibtn; - buttons[3] = &introbtn; - buttons[4] = &exitbtn; -#endif - buttons[curbutton]->Turn_On(); - - Keyboard::Clear(); - - Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - while (Get_Mouse_State() > 0) Show_Mouse(); - - /* - ** Main Processing Loop. - */ - bool display = true; - bool process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** If timeout expires, bail - */ -//PG_TO_FIX -#if (0) - if (timeout && TickCount.Time() - starttime > timeout) { - retval = -1; - process = false; - } -#endif - /* - ** Invoke game callback. - */ - Call_Back(); - - /* - ** Refresh display if needed. - */ - if (display) { - - /* - ** Load the background picture. - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - - /* - ** Display the title and text overlay for the menu. - */ - Set_Logic_Page(HidPage); - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); - Draw_Caption (TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); -#ifdef VIRGIN_CHEAT_KEYS -#ifdef DEMO - Version_Number(); - Fancy_Text_Print("Demo%s", D_DIALOG_X+D_DIALOG_W-5*2, D_DIALOG_Y+D_DIALOG_H-10*2, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, VersionText); -#else - Fancy_Text_Print("V.%d%s", D_DIALOG_X+D_DIALOG_W-5*2, D_DIALOG_Y+D_DIALOG_H-10*2, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, Version_Number(), VersionText, FOREIGN_VERSION_NUMBER); -#endif -// Fancy_Text_Print("V.%d%s%02d", D_DIALOG_X+D_DIALOG_W-5, D_DIALOG_Y+D_DIALOG_H-10, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, Version_Number(), VersionText, FOREIGN_VERSION_NUMBER); -#else -#ifdef DEMO - Version_Number(); - Fancy_Text_Print("Demo%s", D_DIALOG_X+D_DIALOG_W-5*2, D_DIALOG_Y+D_DIALOG_H-10*2, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, VersionText); -#else - Fancy_Text_Print("V.%d%s", D_DIALOG_X+D_DIALOG_W-5*2, D_DIALOG_Y+D_DIALOG_H-10*2, DKGREY, TBLACK, TPF_6POINT|TPF_FULLSHADOW|TPF_RIGHT, Version_Number(), VersionText); -#endif -#endif - - /* - ** Copy the menu to the visible page. - */ - Hide_Mouse(); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - Set_Logic_Page(SeenBuff); - startbtn.Draw_All(); - if (ScreenWidth==320){ - //ST - 1/2/2019 5:27PM - //ModeX_Blit (SeenBuff.Get_Graphic_Buffer()); - } - display = false; - } else { - if (RunningAsDLL) { - retval = -1; - process = false; - } - } - -#ifndef DEMO - /* - ** Check to see if WChat has told us to start playing an internet game - */ - if (DDEServer.Get_MPlayer_Game_Info()){ - retval = BUTTON_INTERNET - BUTTON_EXPAND; - process = false; - } -#endif //DEMO - - /* - ** Get and process player input. - */ - input = commands->Input(); - switch (input) { -#ifdef NEWMENU - case (BUTTON_EXPAND | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; - process = false; - break; - - case (BUTTON_INTERNET | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; - process = false; - break; - -#else -#define BUTTON_EXPAND BUTTON_START -#endif - - case (BUTTON_START | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; - process = false; - break; - -#ifdef BONUS_MISSIONS - case (BUTTON_BONUS | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; - process = false; - break; -#endif //BONUS_MISSIONS - - case (BUTTON_LOAD | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; -#ifdef DEMO - retval += 1; -#endif //DEMO - process = false; - break; - - case (BUTTON_MULTI | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; -#ifdef DEMO - retval += 1; -#endif //DEMO - process = false; - break; - - case (BUTTON_INTRO | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; -#ifdef DEMO - retval += 1; -#endif //DEMO - process = false; - break; - - case (BUTTON_EXIT | KN_BUTTON): - retval = (input & 0x7FFF) - BUTTON_EXPAND; -#ifdef DEMO - retval += 1; -#endif //DEMO - process = false; - break; - - case KN_UP: - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton--; -#ifdef NEWMENU - if (expansions) { - if (curbutton < 0) { - curbutton = 6; - } - } else { - if (curbutton < 1) { - curbutton = 6; - } - } -#else - if (curbutton < 0) { - curbutton = 4; - } -#endif - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case KN_DOWN: - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton++; -#ifdef NEWMENU - if (curbutton > 6) { - if (expansions) { - curbutton = 0; - } else { - curbutton = 1; - } - } -#else - if (curbutton > 4) { - curbutton = 0; - } -#endif - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case KN_RETURN: - buttons[curbutton]->IsPressed = true; - buttons[curbutton]->Draw_Me(true); - retval = curbutton; - process = false; - break; - - default: - break; - } - } - return(retval); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/MESSAGE.H b/code/TIBERIANDAWN/MESSAGE.H deleted file mode 100644 index f498db9..0000000 --- a/code/TIBERIANDAWN/MESSAGE.H +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -#define MESSAGE_NONE 0 // -#define MESSAGE_BUILD_WINDTRAP 1 // You must build a Windtrap -#define MESSAGE_STRUCT_CONCRETE 2 // Concrete: Use concrete to -#define MESSAGE_STRUCT_PALACE 3 // Palace: This is your -#define MESSAGE_STRUCT_LIGHT 4 // Light Factory: The Light -#define MESSAGE_STRUCT_HEAVY 5 // Heavy Factory: The Heavy -#define MESSAGE_STRUCT_HITECH 6 // Hi-Tech Factory: The -#define MESSAGE_STRUCT_IX 7 // House IX: The IX Research -#define MESSAGE_STRUCT_WOR 8 // WOR: Wor is used to train -#define MESSAGE_STRUCT_CONST 9 // Construction Facility: All -#define MESSAGE_STRUCT_WINDTRAP 10 // Windtrap: The windtrap -#define MESSAGE_STRUCT_BARRACKS 11 // Barracks: The Barracks is -#define MESSAGE_STRUCT_STARPORT 12 // Startport: The Starport is -#define MESSAGE_STRUCT_REFINERY 13 // Spice Refinery: The -#define MESSAGE_STRUCT_REPAIR 14 // Repair Facility: The Repair -#define MESSAGE_STRUCT_WALL 15 // Wall: The wall is used for -#define MESSAGE_STRUCT_TURRET 16 // Gun Turret: The cannon -#define MESSAGE_STRUCT_RTURRET 17 // Rocket Turret: The -#define MESSAGE_STRUCT_SILO 18 // Spice Silo: The Spice silo -#define MESSAGE_STRUCT_OUTPOST 19 // Outpost: The Outpost -#define MESSAGE_NEED_CONCRETE 20 // There isn't enough open -#define MESSAGE_SAND 21 // Sand: This is sand terrain. -#define MESSAGE_DUNE 22 // Sand Dunes: These are an -#define MESSAGE_ROCK 23 // Rock: This is rock terrain. -#define MESSAGE_MOUNT 24 // Mountain: Mountains on -#define MESSAGE_SPICE 25 // Spice Field: This is the -#define MESSAGE_ADJACENT 26 // Structures must be placed -#define MESSAGE_SEARCH4SPICE 27 // Search for spice fields to -#define MESSAGE_SANDWORM 28 // Warning: Sandworms diff --git a/code/TIBERIANDAWN/MISSION.CPP b/code/TIBERIANDAWN/MISSION.CPP deleted file mode 100644 index e75536d..0000000 --- a/code/TIBERIANDAWN/MISSION.CPP +++ /dev/null @@ -1,474 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mission.cpv 2.18 16 Oct 1995 16:49:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MISSION.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * MissionClass::AI -- Processes order script. * - * MissionClass::Assign_Mission -- Give an order to a unit. * - * MissionClass::Commence -- Start script with new order. * - * MissionClass::Debug_Dump -- Dumps status values to mono screen. * - * MissionClass::Get_Mission -- Fetches the mission that this object is acting under. * - * MissionClass::MissionClass -- Default constructor for the mission object type. * - * MissionClass::Mission_From_Name -- Fetch order pointer from its name. * - * MissionClass::Mission_Name -- Converts a mission number into an ASCII string. * - * MissionClass::Overide_Mission -- temporarily overides the units mission * - * MissionClass::Restore_Mission -- Restores overidden mission * - * MissionClass::Set_Mission -- Sets the mission to the specified value. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * MissionClass::MissionClass -- Default constructor for the mission object type. * - * * - * This is the default constructor for the mission class object. It sets the mission * - * handler into a default -- do nothing -- state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -MissionClass::MissionClass(void) -{ - Status = 0; - Timer = 0; - Mission = MISSION_NONE; - SuspendedMission = MISSION_NONE; - MissionQueue = MISSION_NONE; -} - - -int MissionClass::Mission_Sleep(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Ambush(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Attack(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Capture(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Guard(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Guard_Area(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Harvest(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Hunt(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Timed_Hunt(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Move(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Retreat(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Return(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Stop(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Unload(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Enter(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Construction(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Deconstruction(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Repair(void) {return TICKS_PER_SECOND*30;}; -int MissionClass::Mission_Missile(void) {return TICKS_PER_SECOND*30;}; - - -/*********************************************************************************************** - * MissionClass::Set_Mission -- Sets the mission to the specified value. * - * * - * Use this routine to set the current mission for this object. This routine will blast * - * over the current mission, bypassing the queue method. Call it when the mission needs * - * to be changed immediately. * - * * - * INPUT: mission -- The mission to set to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -void MissionClass::Set_Mission(MissionType mission) -{ - Mission = mission; - MissionQueue = MISSION_NONE; -} - - -/*********************************************************************************************** - * MissionClass::Get_Mission -- Fetches the mission that this object is acting under. * - * * - * Use this routine to fetch the mission that this object is CURRENTLY acting under. The * - * mission queue may be filled with a immanent mission change, but this routine does not * - * consider that. It only returns the CURRENT mission. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the mission that this unit is currently following. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -MissionType MissionClass::Get_Mission(void) const -{ - return(Mission == MISSION_NONE ? MissionQueue : Mission); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * MissionClass::Debug_Dump -- Dumps status values to mono screen. * - * * - * This is a debugging function that dumps this class' status to the monochrome screen * - * for review. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void MissionClass::Debug_Dump(MonoClass *mono) const -{ - mono->Set_Cursor(21, 1);mono->Printf("%5.5s[%4.4s]", MissionClass::Mission_Name(Mission), MissionClass::Mission_Name(MissionQueue)); -// mono->Text_Print(MissionClass::Mission_Name(Mission), 21, 1); - mono->Set_Cursor(20, 7);mono->Printf("%2d", (long)Timer); - mono->Set_Cursor(74, 1);mono->Printf("%2d", Status); - - ObjectClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * MissionClass::AI -- Processes order script. * - * * - * This routine will process the order script for as much time as * - * possible or until a script delay is detected. This routine should * - * be called for every unit once per game loop (if possible). * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/23/1994 JLB : Created. * - * 06/25/1995 JLB : Added new missions. * - *=============================================================================================*/ -void MissionClass::AI(void) -{ - ObjectClass::AI(); - - /* - ** This is the script AI equivalent processing. - */ - if (Timer.Expired() && Strength > 0) { - switch (Mission) { - default: - case MISSION_STICKY: - case MISSION_SLEEP: - Timer = Mission_Sleep(); - break; - - case MISSION_GUARD: - Timer = Mission_Guard(); - break; - - case MISSION_ENTER: - Timer = Mission_Enter(); - break; - - case MISSION_CONSTRUCTION: - Timer = Mission_Construction(); - break; - - case MISSION_DECONSTRUCTION: - Timer = Mission_Deconstruction(); - break; - - case MISSION_CAPTURE: - case MISSION_SABOTAGE: - Timer = Mission_Capture(); - break; - - case MISSION_MOVE: - Timer = Mission_Move(); - break; - - case MISSION_ATTACK: - Timer = Mission_Attack(); - break; - - case MISSION_RETREAT: - Timer = Mission_Retreat(); - break; - - case MISSION_HARVEST: - Timer = Mission_Harvest(); - break; - - case MISSION_GUARD_AREA: - Timer = Mission_Guard_Area(); - break; - - case MISSION_RETURN: - Timer = Mission_Return(); - break; - - case MISSION_STOP: - Timer = Mission_Stop(); - break; - - case MISSION_AMBUSH: - Timer = Mission_Ambush(); - break; - - case MISSION_HUNT: - case MISSION_RESCUE: - Timer = Mission_Hunt(); - break; - - case MISSION_TIMED_HUNT: - Timer = Mission_Timed_Hunt(); - break; - - case MISSION_UNLOAD: - Timer = Mission_Unload(); - break; - - case MISSION_REPAIR: - Timer = Mission_Repair(); - break; - - case MISSION_MISSILE: - Timer = Mission_Missile(); - break; - } - } -} - - -/*********************************************************************************************** - * MissionClass::Commence -- Start script with new order. * - * * - * This routine will start script processing according to any queued * - * order it may have. If there is no queued order, then this routine * - * does nothing. Call this routine whenever the unit is in a good * - * position to change its order (such as when it is stopped). * - * * - * INPUT: none * - * * - * OUTPUT: Did the mission actually change? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/23/1994 JLB : Created. * - * 07/14/1994 JLB : Simplified. * - * 06/17/1995 JLB : Returns success flag. * - *=============================================================================================*/ -bool MissionClass::Commence(void) -{ - if (MissionQueue != MISSION_NONE) { - Mission = MissionQueue; - MissionQueue = MISSION_NONE; - - /* - ** Force immediate state machine processing at the first state machine state value. - */ - Timer = 0; - Status = 0; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * MissionClass::Assign_Mission -- Give an order to a unit. * - * * - * This assigns an order to a unit. It does NOT do the AI, but merely * - * flags the unit for normal AI processing. At that time the computer * - * will determine the unit's course of action. * - * * - * INPUT: order -- Mission to give the unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/04/1991 JLB : Created. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void MissionClass::Assign_Mission(MissionType order) -{ - if (order == MISSION_NONE || Mission == order) return; - -// Status = 0; - MissionQueue = order; -} - - -/*********************************************************************************************** - * MissionClass::Mission_From_Name -- Fetch order pointer from its name. * - * * - * This routine is used to convert an ASCII order name into the actual * - * order number it represents. Typically, this is used when processing * - * a scenario INI file. * - * * - * INPUT: name -- The ASCII order name to process. * - * * - * OUTPUT: Returns with the actual order number that the ASCII name * - * represents. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - * 04/22/1994 JLB : Converted to static member function. * - *=============================================================================================*/ -MissionType MissionClass::Mission_From_Name(char const *name) -{ - MissionType order; - - if (name) { - for (order = MISSION_FIRST; order < MISSION_COUNT; order++) { - if (stricmp(Missions[order], name) == 0) { - return(order); - } - } - } - return(MISSION_NONE); -} - - -/*********************************************************************************************** - * MissionClass::Mission_Name -- Converts a mission number into an ASCII string. * - * * - * Use this routine to convert a mission number into the ASCII string that represents * - * it. Typical use of this is when generating an INI file. * - * * - * INPUT: mission -- The mission number to convert. * - * * - * OUTPUT: Returns with a pointer to the ASCII string that represents the mission type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -char const * MissionClass::Mission_Name(MissionType mission) -{ - return(mission == MISSION_NONE ? "None" : Missions[mission]); -} - - -/*********************************************************************************************** - * MissionClass::Override_Mission -- temporarily overides the units mission * - * * - * * - * * - * INPUT: MissionType mission - the mission we want to overide * - * TARGET tarcom - the new target we want to overide * - * TARGET navcom - the new navigation point to overide * - * * - * OUTPUT: none * - * * - * WARNINGS: If a mission is already overidden, the current mission is * - * just re-assigned. * - * * - * HISTORY: * - * 04/28/1995 PWG : Created. * - *=============================================================================================*/ -void MissionClass::Override_Mission(MissionType mission, TARGET, TARGET) -{ - if (MissionQueue != MISSION_NONE) { - SuspendedMission = MissionQueue; - } else { - SuspendedMission = Mission; - } - - Assign_Mission(mission); -} - - -/*********************************************************************************************** - * MissionClass::Restore_Mission -- Restores overidden mission * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/28/1995 PWG : Created. * - *=============================================================================================*/ -bool MissionClass::Restore_Mission(void) -{ - if (SuspendedMission != MISSION_NONE) { - Assign_Mission(SuspendedMission); - SuspendedMission= MISSION_NONE; - return(true); - } - return(false); -} - - -/*********************************************************************************************** -** Unit order names. These names correspond to the player selectable orders -** a unit can have. The system initiated orders have no use for the ASCII name -** associated, but they are listed here for completeness sake. -*/ -char const * MissionClass::Missions[MISSION_COUNT] = { - "Sleep", - "Attack", - "Move", - "Retreat", - "Guard", - "Sticky", - "Enter", - "Capture", - "Harvest", - "Area Guard", - "Return", - "Stop", - "Ambush", - "Hunt", - "Timed Hunt", - "Unload", - "Sabotage", - "Construction", - "Selling", - "Repair", - "Rescue", - "Missile", -}; diff --git a/code/TIBERIANDAWN/MISSION.H b/code/TIBERIANDAWN/MISSION.H deleted file mode 100644 index 5ee9d97..0000000 --- a/code/TIBERIANDAWN/MISSION.H +++ /dev/null @@ -1,133 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mission.h_v 2.16 16 Oct 1995 16:45:46 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MISSION.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MISSION_H -#define MISSION_H - -#include "object.h" -#include "monoc.h" - -/**************************************************************************** -** This handles order assignment and tracking. The order is used to guide -** overall AI processing. -*/ -class MissionClass : public ObjectClass -{ - public: - - /* - ** This the tactical strategy to use. It is used by the unit script. This - ** is a general guide for unit AI processing. - */ - MissionType Mission; - MissionType SuspendedMission; - - /* - ** The order queue is used for orders that should take effect when the vehicle - ** has reached the center point of a cell. The queued order number is +1 when stored here - ** so that 0 will indicated there is no queued order. - */ - MissionType MissionQueue; - - char Status; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - MissionClass(void); - virtual ~MissionClass(void) {}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - #ifdef CHEAT_KEYS - void Debug_Dump(MonoClass *mono) const; - #endif - - virtual MissionType Get_Mission(void) const; - virtual void Assign_Mission(MissionType mission); - virtual bool Commence(void); - virtual void AI(void); - - /* - ** Support functions. - */ - virtual int Mission_Sleep(void); - virtual int Mission_Ambush(void); - virtual int Mission_Attack(void); - virtual int Mission_Capture(void); - virtual int Mission_Guard(void); - virtual int Mission_Guard_Area(void); - virtual int Mission_Harvest(void); - virtual int Mission_Hunt(void); - virtual int Mission_Timed_Hunt(void); - virtual int Mission_Move(void); - virtual int Mission_Retreat(void); - virtual int Mission_Return(void); - virtual int Mission_Stop(void); - virtual int Mission_Unload(void); - virtual int Mission_Enter(void); - virtual int Mission_Construction(void); - virtual int Mission_Deconstruction(void); - virtual int Mission_Repair(void); - virtual int Mission_Missile(void); - virtual void Set_Mission(MissionType mission); - - static char const * Mission_Name(MissionType order); - static MissionType Mission_From_Name(char const *name); - virtual void Override_Mission(MissionType mission, TARGET, TARGET); - virtual bool Restore_Mission(void); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - private: - - /* - ** This the thread processing timer. When this value counts down to zero, then - ** more script processing may occur. - */ - TCountDownTimerClass Timer; - - /* - ** These are the order names as ASCII strings. - */ - static char const * Missions[MISSION_COUNT]; -}; - - -#endif diff --git a/code/TIBERIANDAWN/MIXFILE.CPP b/code/TIBERIANDAWN/MIXFILE.CPP deleted file mode 100644 index 2b39231..0000000 --- a/code/TIBERIANDAWN/MIXFILE.CPP +++ /dev/null @@ -1,522 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mixfile.cpv 2.18 16 Oct 1995 16:48:46 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MIXFILE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : January 23, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * MixFileClass::Cache -- Caches the named mixfile into RAM. * - * MixFileClass::Cache -- Loads this particular mixfile's data into RAM. * - * MixFileClass::Finder -- Finds the mixfile object that matches the name specified. * - * MixFileClass::Free -- Frees the allocated raw data block (not the index block). * - * MixFileClass::MixFileClass -- Constructor for mixfile object. * - * MixFileClass::Offset -- Determines if the file is in a mixfile and where its sublocation is.* - * MixFileClass::Offset -- Searches in mixfile for matching file and returns offset if found.* - * MixFileClass::Retrieve -- Retrieves a pointer to the specified data file. * - * MixFileClass::~MixFileClass -- Destructor for the mixfile object. * - * MixFileClass::Offset -- Determines the offset of the requested file from the mixfile system.* - * MixFileClass::Free -- Uncaches a cached mixfile. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" -#include -#include -#include -#include -#include -#include -#include "mixfile.h" - - -template int Compare(T const *obj1, T const *obj2) { - if (*obj1 < *obj2) return(-1); - if (*obj1 > *obj2) return(1); - return(0); -}; - - -/* -** This is the pointer to the first mixfile in the list of mixfiles registered -** with the mixfile system. -*/ -MixFileClass * MixFileClass::First = 0; - - -/*********************************************************************************************** - * MixFileClass::Free -- Uncaches a cached mixfile. * - * * - * Use this routine to uncache a mixfile that has been cached. * - * * - * INPUT: filename -- Pointer to the filename of the mixfile that is to be uncached. * - * * - * OUTPUT: bool; Was the mixfile found and freed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -bool MixFileClass::Free(char const *filename) -{ - MixFileClass * ptr = Finder(filename); - - if (ptr) { - ptr->Free(); - return(true); - } - return(false); -} - - -//#ifndef NOMEMCHECK -void MixFileClass::Free_All(void) -{ - while (First) { - delete First; - } -} -//#endif - - -/*********************************************************************************************** - * MixFileClass::~MixFileClass -- Destructor for the mixfile object. * - * * - * This destructor will free all memory allocated by this mixfile and will remove it from * - * the system. A mixfile removed in this fashion must be created anew in order to be * - * subsequent used. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - * 01/06/1995 JLB : Puts mixfile header table into EMS. * - *=============================================================================================*/ -MixFileClass::~MixFileClass(void) -{ - - /* - ** Deallocate any allocated memory. - */ - if (Filename) { - free((char *)Filename); - } - if (Data) { - delete [] Data; - } - if (Buffer) { - delete [] Buffer; - } - - /* - ** Unlink this mixfile object from the chain. - */ - if (this == First) { - First = (MixFileClass *)Get_Next(); - } else { - Remove(); - } - - // Can't do this here since the link class destructor hasn't been called yet, so clearing out the data will mess up the - // linked list. How did this work before? Did the watcom compiler call the destructors in a different order? - // ST - 1/3/2019 5:34PM - //Zap(); -} - - -/*********************************************************************************************** - * MixFileClass::MixFileClass -- Constructor for mixfile object. * - * * - * This is the constructor for the mixfile object. It takes a filename and a memory * - * handler object and registers the mixfile object with the system. The index block is * - * allocated and loaded from disk by this routine. * - * * - * INPUT: filename -- Pointer to the filename of the mixfile object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -MixFileClass::MixFileClass(char const *filename) -{ - CCFileClass file; // Working file object. - - /* - ** Load in the control block. It always remains resident. - */ - Data = 0; - Count = 0; - Buffer = 0; - file.Set_Name(filename); - Filename = strdup(file.File_Name()); - - if (!Force_CD_Available(RequiredCD)) { - Prog_End("MixFileClass::MixFileClass CD not found", true); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } - return; - } - - if (file.Is_Available(true)) { - FileHeader fileheader; - - file.Open(); - file.Read(&fileheader, sizeof(fileheader)); - Count = fileheader.count; - DataSize = fileheader.size; - - /* - ** Load up the offset control array. This could be located in - ** EMS if possible. - */ - Buffer = new SubBlock [Count]; - if (Buffer) { - file.Read(Buffer, Count * sizeof(SubBlock)); - } - file.Close(); - } else { -// delete this; - return; - } - - /* - ** Raw data block starts uncached. - */ - Data = 0; - - /* - ** Attach to list of mixfiles. - */ - Zap(); - if (!First) { - First = this; - } else { - Add_Tail(*First); - } -} - - -/*********************************************************************************************** - * MixFileClass::Retrieve -- Retrieves a pointer to the specified data file. * - * * - * This routine will return with a pointer to the specified data file if the file resides * - * in memory. Otherwise, this routine returns NULL. Use this routine to access a resident * - * file directly rather than going through the process of pseudo disk access. This will * - * save both time and RAM. * - * * - * INPUT: filename -- Pointer to the filename of the data file to retrieve a pointer to. * - * * - * OUTPUT: Returns with a pointer to the data file's data. If the file is not in RAM, then * - * NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/23/1994 JLB : Created. * - *=============================================================================================*/ -void const * MixFileClass::Retrieve(char const *filename) { - void *ptr = 0; - Offset(filename, &ptr); -// if (!ptr) { -// errno = ENOENT; -// File_Fatal(filename); -// } - return(ptr); -}; - - -/*********************************************************************************************** - * MixFileClass::Finder -- Finds the mixfile object that matches the name specified. * - * * - * This routine will scan through all registered mixfiles and return with a pointer to * - * the matching mixfile. If no mixfile could be found that matches the name specified, * - * then NULL is returned. * - * * - * INPUT: filename -- Pointer to the filename to search for. * - * * - * OUTPUT: Returns with a pointer to the matching mixfile -- if found. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -MixFileClass * MixFileClass::Finder(char const *filename) -{ - MixFileClass * ptr; - - ptr = First; - while (ptr) { - if (stricmp(&ptr->Filename[strlen(ptr->Filename)-strlen(filename)], filename) == 0) { - return(ptr); - } - ptr = (MixFileClass *)ptr->Get_Next(); - } - return(0); -} - - -/*********************************************************************************************** - * MixFileClass::Cache -- Caches the named mixfile into RAM. * - * * - * This routine will cache the mixfile, specified by name, into RAM. * - * * - * INPUT: filename -- The name of the mixfile that should be cached. * - * * - * OUTPUT: bool; Was the cache successful? * - * * - * WARNINGS: This routine could go to disk for a very long time. * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -bool MixFileClass::Cache(char const *filename) -{ - MixFileClass * mixer = Finder(filename); - - if (mixer) { - return(mixer->Cache()); - } - return(false); -} - - -/*********************************************************************************************** - * MixFileClass::Cache -- Loads this particular mixfile's data into RAM. * - * * - * This load the mixfile data into ram for this mixfile object. This is the counterpart * - * to the Free() function. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the file load successful? It could fail if there wasn't enough room * - * to allocate the raw data block. * - * * - * WARNINGS: This routine goes to disk for a potentially very long time. * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -bool MixFileClass::Cache(void) -{ - if (Data) return(true); - - Data = new char [DataSize]; - if (Data) { - CCFileClass file(Filename); - - file.Open(); - file.Seek(sizeof(SubBlock) * Count + sizeof(FileHeader)); - long actual = file.Read(Data, DataSize); - if (actual != DataSize) { -#ifdef GERMAN - Fatal("Korrupte .MIX-Datei \"%s\". Beim Versuch, %ld zu lesen, nur %ld gefunden.", Filename, DataSize, actual); -#else -#ifdef FRENCH - Fatal("Fichier .MIX corrumpu \"%s\". Essai de lecture de %ld, mais %ld obtenu.", Filename, DataSize, actual); -#else - Fatal("Corrupt .MIX file \"%s\". Tried to read %ld, but got %ld.", Filename, DataSize, actual); -#endif -#endif - } - file.Close(); - return(true); - } -#ifdef GERMAN - Fatal("Kann Datei \"%s\" nicht laden.", Filename); -#else -#ifdef FRENCH - Fatal("Impossible de charger \"%s\".", Filename); -#else - Fatal("Unable to load \"%s\".", Filename); -#endif -#endif - return(false); -} - - -/*********************************************************************************************** - * MixFileClass::Free -- Frees the allocated raw data block (not the index block). * - * * - * This routine will free the (presumably large) raw data block, but leave the index * - * block intact. By using this in conjunction with the Cache() function, one can maintain * - * tight control of memory usage. If the index block is desired to be freed, then the * - * mixfile object must be deleted. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -void MixFileClass::Free(void) -{ - if (Data) { - delete [] Data; - Data = 0; - } -} - - -/*********************************************************************************************** - * MixFileClass::Offset -- Determines if the file is in a mixfile and where its sublocation is.* - * * - * This routine will scan through all registers mixfiles in an attempt to locate the file * - * in question. Whether the file is located in RAM or on disk does not restrict this * - * search operation. * - * * - * INPUT: filename -- The filename of the file to search within the mixfile system. * - * * - * realptr -- Pointer to pointer that will be filled with the RAM pointer to * - * the file if it happens to be in RAM. NULL if otherwise. * - * * - * mixfile -- Pointer to the mixfile object that contains the file in question. * - * * - * offset -- The offset to the start of the data of the file. If the file is * - * on disk then this is the offset from the start of the file, if * - * it is located in RAM, then it is the offset from the start of the * - * raw data block. * - * * - * size -- Pointer to where the size of the file will be stored. * - * * - * OUTPUT: bool; Was the file found in one of the mixfiles? The value stored in "realptr" * - * will be NULL if it is on disk, otherwise it is in RAM. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1994 JLB : Created. * - *=============================================================================================*/ -//int _USERENTRY Compare(MixFileClass::SubBlock const *, MixFileClass::SubBlock const *); - -// int _USERENTRY compfunc(void const *ptr1, void const *ptr2) -int compfunc(void const *ptr1, void const *ptr2) -{ -// long diff = *(long const *)ptr1 - *(long const *)ptr2; -// return FP_SEG(diff); - - if (*(long const *)ptr1 < *(long const *)ptr2) return(-1); - if (*(long const *)ptr1 > *(long const *)ptr2) return(1); - return(0); -} - - -/*********************************************************************************************** - * MixFileClass::Offset -- Determines the offset of the requested file from the mixfile system.* - * * - * This routine will take the falename specified and search through the mixfile system * - * looking for it. If the file was found, then the mixfile it was found int, the offset * - * from the start of the mixfile, and the size of the embedded file will be returned. * - * Using this method it is possible for the CCFileClass system to process it as a normal * - * file. * - * * - * INPUT: filename -- The filename to search for. * - * * - * realptr -- Stores a pointer to the start of the file in memory here. If the * - * file is not in memory, then NULL is stored here. * - * * - * mixfile -- The pointer to the corresponding mixfile is placed here. If no * - * mixfile was found that contains the file, then NULL is stored here. * - * * - * offset -- The starting offset from the beginning of the parent mixfile is * - * stored here. * - * * - * size -- The size of the embedded file is stored here. * - * * - * OUTPUT: bool; Was the file found? The file may or may not be resident, but it does exist * - * and can be opened. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -bool MixFileClass::Offset(char const *filename, void ** realptr, MixFileClass ** mixfile, long * offset, long * size) -{ - MixFileClass * ptr; - - if (!filename) return(false); - - /* - ** Create the key block that will be used to binary search for the file. - */ - char file_name_copy[_MAX_PATH]; - strcpy(file_name_copy, filename); - strupr(file_name_copy); - long crc = Calculate_CRC(file_name_copy, strlen(file_name_copy)); - SubBlock key; - key.CRC = crc; - - /* - ** Sweep through all registered mixfiles, trying to find the file in question. - */ - ptr = First; - while (ptr) { - SubBlock * block; - - /* - ** Binary search for the file in this mixfile. If it is found, then extract the - ** appropriate information and store it in the locations provided and then return. - */ - block = (SubBlock *)bsearch(&key, ptr->Buffer, ptr->Count, sizeof(SubBlock), compfunc); - if (block) { - if (mixfile) *mixfile = ptr; - if (size) *size = block->Size; - if (realptr) *realptr = 0; - if (offset) *offset = block->Offset; - if (realptr && ptr->Data) { - *realptr = Add_Long_To_Pointer(ptr->Data, block->Offset); - } - if (!ptr->Data && offset) { - *offset += sizeof(SubBlock) * ptr->Count + sizeof(FileHeader); - } - return(true); - } - - /* - ** Advance to next mixfile. - */ - ptr = (MixFileClass *)ptr->Get_Next(); - } - - /* - ** All the mixfiles have been examined but no match was found. Return with the non success flag. - */ - return(false); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/MIXFILE.H b/code/TIBERIANDAWN/MIXFILE.H deleted file mode 100644 index 408fcbb..0000000 --- a/code/TIBERIANDAWN/MIXFILE.H +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mixfile.h_v 2.18 16 Oct 1995 16:47:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MIXFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 18, 1994 * - * * - * Last Update : October 18, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MIXFILE_H -#define MIXFILE_H - -#include -#include "link.h" - -class MixFileClass : public LinkClass -{ - public: - char const *Filename; // Filename of mixfile. - - MixFileClass(char const *filename); - ~MixFileClass(void); - - static bool Free(char const *filename); - static void Free_All(void); - void Free(void); - bool Cache(void); - static bool Cache(char const *filename); - static bool Offset(char const *filename, void ** realptr = 0, MixFileClass ** mixfile = 0, long * offset = 0, long * size = 0); - static void const * Retrieve(char const *filename); - - struct SubBlock { - long CRC; // CRC code for embedded file. - long Offset; // Offset from start of data section. - long Size; // Size of data subfile. - - int operator < (SubBlock & two) const {return (CRC < two.CRC);}; - int operator > (SubBlock & two) const {return (CRC > two.CRC);}; - int operator == (SubBlock & two) const {return (CRC == two.CRC);}; - }; - - private: - static MixFileClass * Finder(char const *filename); - long Offset(long crc, long *size = 0); - - typedef struct { - short count; - long size; - } FileHeader; - - int Count; // Number of sub-blocks. - long DataSize; // Size of raw data. - SubBlock * Buffer; // Array of sub blocks (could be in EMS). - void *Data; // Pointer to raw data. - - static MixFileClass * First; -}; - -#endif diff --git a/code/TIBERIANDAWN/MMX.ASM b/code/TIBERIANDAWN/MMX.ASM deleted file mode 100644 index 88032ae..0000000 --- a/code/TIBERIANDAWN/MMX.ASM +++ /dev/null @@ -1,328 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S I N C ** -;*************************************************************************** -;* * -;* Project Name : Command & Conquer * -;* * -;* File Name : MMX.ASM * -;* * -;* Programmer : Steve Tall * -;* * -;* Start Date : May 19th, 1996 * -;* * -;* Last Update : May 19th 1996 [ST] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - - ; include - - - .model flat - ;.686 - - - externdef C Detect_MMX_Availability:near - externdef C Single_Line_Trans_Entry:near - externdef C Next_Line:near - externdef C Init_MMX:near - externdef C MMX_Done:near - - externdef EndNewShapeJumpTable:byte - externdef NewShapeJumpTable:dword - externdef C Single_Line_Trans:near - externdef MMX_Single_Line_Trans:near - - - .code - -externdef C CPUType:byte - - - -;********************************************************************************************* -;* Detect_MMX_Availability -- Detect the presence of MMX technology. * -;* * -;* * -;* INPUT: Nothing * -;* * -;* OUTPUT: True if MMX technology is available. * -;* * -;* Warnings: * -;* * -;* Note: Based in part on CPUID32.ASM by Intel * -;* * -;* HISTORY: * -;* 05/19/96 ST : Created. * -;*===========================================================================================* - -Detect_MMX_Availability proc C - - local idflag:byte - local local_cputype:byte - - ; MMX always available now. ST - 1/3/2019 1:31PM - mov [CPUType], 5 - mov eax, 1 - ret - - -;assume processor is at least 386 -; -;check whether AC bit in eflags can be toggled. -;If not then processor is 386 - - mov [idflag],0 - - pushfd ;get Eflags in EAX - pop eax - mov ecx,eax ;save eflags - xor eax,40000h ;toggle AC bit in eflags - push eax ;new eflags on stack - popfd ;move new value into eflags - pushfd ;get new eflags back into eax - pop eax - xor eax,ecx ;if AC bit not toggled then CPU=386 - mov [local_cputype],3 - jz @@end_get_cpu ;cpu is 386 - - push ecx - popfd ;restore AC bit in eflags - - -;processor is at least 486 -; -;Check for ability to set/clear ID flag in EFLAGS -;ID flag indicates ability of processor to execute the CPUID instruction. -;486 not guaranteed to have CPUID inst? -; - mov [local_cputype],4 - mov eax,ecx ;original EFLAGS - xor eax,200000h ;toggle ID bit - push eax - popfd - pushfd - pop eax - xor eax,ecx ;check if still toggled - jz @@end_get_cpu - - -; Execute CPUID instruction to determine vendor, family, -; model and stepping. -; - - mov [idflag],1 ;flag ID is available - - xor eax,eax - cpuid - - mov dword ptr [VendorID],ebx - mov dword ptr [VendorID+4],edx - mov dword ptr [VendorID+8],ecx - mov dword ptr [VendorID+12]," " - - cmp eax,1 ;check if 1 is valid - jl @@end_get_cpu ;inp for cpuid inst. - - xor eax,eax - inc eax - - cpuid ;get stepping, model and family - - and ax,0f00H - shr ax,08H - - mov [local_cputype],al - -@@end_get_cpu: mov al,[local_cputype] - mov [CPUType],al - - -; -; We have the CPU type in al now. -; If we arent on at least a pentium then we can assume there is no MMX -; - cmp al,5 - jl @@no_mmx - - mov eax,1 - cpuid - test edx,00800000h - jz @@no_mmx - -; -; MMX detected - return true -; - mov eax,1 - ret - - -@@no_mmx: xor eax,eax - ret - - -Detect_MMX_Availability endp - - - -;********************************************************************************************* -;* Init_MMX -- Do any special inits required for MMX support * -;* * -;* * -;* INPUT: Nothing * -;* * -;* OUTPUT: None * -;* * -;* Warnings: * -;* * -;* HISTORY: * -;* 05/19/96 ST : Created. * -;*===========================================================================================* - -Init_MMX proc C - - mov edi,offset NewShapeJumpTable - mov ecx,offset EndNewShapeJumpTable - sub ecx,edi - shr ecx,2 - mov eax,offset Single_Line_Trans - mov ebx,offset MMX_Single_Line_Trans - cld - - -@@patch_loop: repnz scasd - jnz @@done - mov [edi-4],ebx - test ecx,ecx - jnz @@patch_loop - -@@done: ret - -Init_MMX endp - - - - - - -;********************************************************************************************* -;* MMX_Done -- Restores floating point capability after MMX usage * -;* * -;* * -;* INPUT: Nothing * -;* * -;* OUTPUT: None * -;* * -;* Warnings: * -;* * -;* HISTORY: * -;* 05/19/96 ST : Created. * -;*===========================================================================================* - -MMX_Done proc C - - emms - ret - -MMX_Done endp - - - - - - - - code segment page public use32 'code' ; Need stricter segment alignment - ; for pentium optimisations - - -;********************************************************************************************* -;* MMX_Single_Line_Trans -- draw a single line of transparent pixels using MMX technology * -;* * -;* * -;* INPUT: Esi - ptr to source data * -;* Edi - ptr to destination data * -;* Ecx - width to draw in bytes * -;* * -;* OUTPUT: None * -;* * -;* Warnings: * -;* * -;* HISTORY: * -;* 05/19/96 ST : Created. * -;*===========================================================================================* - - align 16 - -MMX_Single_Line_Trans proc near - -; -; If we are doing less than 8 bytes then dont use MMX -; - cmp ecx,8 - jge @@mmx_loop - push offset Single_Line_Trans_Entry - ret - -; -; Use MMX instructions to mask 8 bytes at once -; -; Creates a bitmask based on the source bytes equality with zero and then uses this to mask -; out the source bytes in the destination data. The advatage that MMX gives us is that there is -; no 'test for zero then jump' required to mask. -; - align 64 ;MMX instructions like 64 byte alignment! - -@@mmx_loop: - movq mm0,[esi] ; move 8 bytes of source into mm0 - pxor mm1,mm1 ; zero out mm1 - pcmpeqb mm1,mm0 ; compare mm0 with 0. Bits get set in mm1 - lea esi,[esi+8] ; adjust the source data pointer - pand mm1,[edi] ; and in the destination data to throw away the bytes which arent zero in the source - sub ecx,8 ; adjust the byte counter - por mm1,mm0 ; or in the source with the destination data - movq [edi],mm1 ; write back the destination data - lea edi,[edi+8] ; adjust the destination pointer - - cmp ecx,8 - jg @@mmx_loop - -; -; Jump to the approprite code for drawing the end of this line or going to the next one -; - push offset Next_Line - jcxz @@next_line - push offset Single_Line_Trans_Entry -@@next_line: ret - - -MMX_Single_Line_Trans endp - - -code ends - - .data - -CPUType db 0 -VendorID db "Not available",0,0,0,0,0,0 - - -end \ No newline at end of file diff --git a/code/TIBERIANDAWN/MONOC.CPP b/code/TIBERIANDAWN/MONOC.CPP deleted file mode 100644 index 8c6f785..0000000 --- a/code/TIBERIANDAWN/MONOC.CPP +++ /dev/null @@ -1,804 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\monoc.cpv 2.13 16 Oct 1995 16:50:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MONO.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 2, 1994 * - * * - * Last Update : October 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * MonoClass::Clear -- Clears the monochrome screen object. * - * MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. * - * MonoClass::MonoClass -- The default constructor for monochrome screen object. * - * MonoClass::operator = -- Handles making one mono object have the same imagery as another. * - * MonoClass::Print -- Prints the text string at the current cursor coordinates. * - * MonoClass::Printf -- Prints a formatted string to the monochrome screen. * - * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. * - * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. * - * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. * - * MonoClass::View -- Brings the mono object to the main display. * - * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -//#pragma inline -#include "function.h" -#include "monoc.h" - -#include -#include -#include -//#include -#include -#include - - -//extern void output(short port, short data); -//#pragma aux output parm [dx] [ax] = \ -// "out dx,al" \ -// "inc dx" \ -// "mov al,ah" \ -// "out dx,al" - - - -int MonoClass::Enabled = 0; -MonoClass * MonoClass::PageUsage[MonoClass::MAX_MONO_PAGES] = {0,0,0,0,0,0,0,0}; -//DOSSegmentClass MonoClass::MonoSegment(MonoClass::SEGMENT); -void * MonoClass::MonoSegment = (void*)0x000b0000; - -/* -** These are the IBM linedraw characters. -*/ -MonoClass::BoxDataType const MonoClass::CharData[MonoClass::COUNT] = { - {0xDA,0xC4,0xBF,0xB3,0xD9,0xC4,0xC0,0xB3}, // Single line - {0xD5,0xCD,0xB8,0xB3,0xBE,0xCD,0xD4,0xB3}, // Double horz. - {0xD6,0xC4,0xB7,0xBA,0xBD,0xC4,0xD3,0xBA}, // Double vert. - {0xC9,0xCD,0xBB,0xBA,0xBC,0xCD,0xC8,0xBA} // Double horz and vert. -}; - - -/*********************************************************************************************** - * MonoClass::MonoClass -- The default constructor for monochrome screen object. * - * * - * This is the constructor for monochrome screen objects. It handles allocating a free * - * monochrome page. If there are no more pages available, then this is a big error. The * - * page allocated may not be the visible one. Call the View function in order to bring * - * it to the displayed page. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -MonoClass::MonoClass(void) -{ - int index; - - Attrib = DEFAULT_ATTRIBUTE; // Normal text color. - X = Y = 0; - for (index = 0; index < MAX_MONO_PAGES; index++) { - if (!PageUsage[index]) { - PageUsage[index] = this; - Page = (char)index; - break; - } - } - if (index == MAX_MONO_PAGES) { - // Major error message should pop up here! - delete this; - } -} - - -/*********************************************************************************************** - * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. * - * * - * This is the default destructor for a monochrome screen object. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -MonoClass::~MonoClass(void) -{ - PageUsage[Page] = 0; -} - - -/*********************************************************************************************** - * MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. * - * * - * Use this routine to draw a box to the monochrome screen. The IBM line draw characters * - * are used to give the it a fancy appearance. There are several line draw modes supported. * - * * - * INPUT: x,y -- The coordinates of the upper left corner of the box. * - * * - * w,y -- The width and height (respectively) to make the box. * - * * - * attrib -- The text attribute to use when drawing the box outline characters. * - * * - * thick -- The thickness style to use. Examine the BoxStyleType enum for * - * elaboration on the supported styles. * - * * - * OUTPUT: none * - * * - * WARNINGS: The interior of the box is NOT cleared by this routine. It is advised that this * - * area be cleared before the box is drawn. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Draw_Box(int x, int y, int w, int h, char attrib, BoxStyleType thick) -{ - CellType cell; - char oldattrib = Attrib; - - if (!Enabled || !w || !h) return; - - cell.Attribute = attrib; - - /* - ** Draw the horizontal lines. - */ - for (int xpos = 0; xpos < w-2; xpos++) { - cell.Character = CharData[thick].TopEdge; - Store_Cell(cell, x+xpos+1, y); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x+xpos+1, y)); - cell.Character = CharData[thick].BottomEdge; - Store_Cell(cell, x+xpos+1, y+h-1); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x+xpos+1, y+h-1)); - } - - /* - ** Draw the vertical lines. - */ - for (int ypos = 0; ypos < h-2; ypos++) { - cell.Character = CharData[thick].LeftEdge; - Store_Cell(cell, x, y+ypos+1); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x, y+ypos+1)); - cell.Character = CharData[thick].RightEdge; - Store_Cell(cell, x+w-1, y+ypos+1); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x+w-1, y+ypos+1)); - } - - /* - ** Draw the four corners. - */ - if (w > 1 && h > 1) { - cell.Character = CharData[thick].UpperLeft; - Store_Cell(cell, x, y); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x, y)); - cell.Character = CharData[thick].UpperRight; - Store_Cell(cell, x+w-1, y); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x+w-1, y)); - cell.Character = CharData[thick].BottomRight; - Store_Cell(cell, x+w-1, y+h-1); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x+w-1, y+h-1)); - cell.Character = CharData[thick].BottomLeft; - Store_Cell(cell, x, y+h-1); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(x, y+h-1)); - } - - Attrib = oldattrib; -} - - -/*********************************************************************************************** - * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. * - * * - * Use this routine to set the monochrome's cursor position to the coordinates specified. * - * This is the normal way of controlling where the next Print or Printf will output the * - * text to. * - * * - * INPUT: x,y -- The coordinate to position the monochrome cursor. 0,0 is the upper left * - * corner. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Set_Cursor(int x, int y) -{ - #ifdef FIX_ME_LATER - int pos = (y*COLUMNS)+x; - - if (!Enabled) return; - - X = (char)(x%COLUMNS); - Y = (char)(y%LINES); - - if (Page == 0) { - _DX = CONTROL_PORT; - _AX = (short)(0x0E|(pos&0xFF00)); - asm { - out dx,al - inc dx - mov al,ah - out dx,al - } - - _DX = CONTROL_PORT; - _AX = (short)(0x0F|(pos<<8)); - asm { - out dx,al - inc dx - mov al,ah - out dx,al - } - -// outportb(CONTROL_PORT,0x0E|(pos&0xFF00)); -// outportb(CONTROL_PORT,0x0F|(pos<<8)); - } - - #endif //FIX_ME_LATER - -x=y; -y=x; -} - - -/*********************************************************************************************** - * MonoClass::Clear -- Clears the monochrome screen object. * - * * - * This routine will fill the monochrome screen object with spaces. It is clearing the * - * screen of data, making it free for output. The cursor is positioned at the upper left * - * corner of the screen by this routine. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Clear(void) -{ - CellType cell; -// int offset; - - if (!Enabled) return; - - Set_Cursor(0, 0); - - cell.Attribute = Attrib; - cell.Character = ' '; - -// offset = Offset(0, 0); - for (int y = 0; y < LINES; y++) { - for (int x = 0; x < COLUMNS; x++) { - Store_Cell(cell, x, y); - } - } -} - - -/*********************************************************************************************** - * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. * - * * - * Use this routine to scroll the monochrome screen up by the number of lines specified. * - * This routine is typically called by the printing functions so that the monochrome screen * - * behaves in the expected manner -- printing at the bottom of the screen scrolls it up * - * to make room for new text. * - * * - * INPUT: lines -- The number of lines to scroll the monochrome screen. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Scroll(int lines) -{ - CellType cell; - - if (!Enabled || lines <= 0) return; - - memmove( (void*)((long)MonoSegment + Offset(0, 0)), - (void*)((long)MonoSegment + Offset(0, lines)), - (LINES-lines)*COLUMNS*sizeof(CellType)); - -// DOSSegmentClass::Copy(MonoSegment, Offset(0, lines), MonoSegment, Offset(0, 0), (LINES-lines)*COLUMNS*sizeof(CellType)); - - Y--; - cell.Attribute = Attrib; - cell.Character = ' '; - - for (int l = LINES-lines; l < LINES; l++) { - for (int index = 0; index < COLUMNS; index++) { - Store_Cell(cell, index, l); -// MonoSegment.Copy_Word_To(*(short*)&cell, Offset(index, l)); - } - } -} - - -/*********************************************************************************************** - * MonoClass::Printf -- Prints a formatted string to the monochrome screen. * - * * - * Use this routine to output a formatted string, using the standard formatting options, * - * to the monochrome screen object's current cursor position. * - * * - * INPUT: text -- Pointer to the text to print. * - * * - * ... -- Any optional parameters to supply in formatting the text. * - * * - * OUTPUT: none * - * * - * WARNINGS: The total formatted text length must not exceed 255 characters. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Printf(char const *text, ...) -{ - va_list va; - /* - ** The buffer object is placed at the end of the local variable list - ** so that if the sprintf happens to spill past the end, it isn't likely - ** to trash anything (important). The buffer is then manually truncated - ** to maximum allowed size before being printed. - */ - char buffer[256]; - - if (!Enabled) return; - - va_start(va, text); - vsprintf(buffer, text, va); - buffer[sizeof(buffer)-1] = '\0'; - - Print(buffer); - va_end(va); -} - - -#ifdef NEVER -void MonoClass::Printf(int text, ...) -{ - va_list va; - /* - ** The buffer object is placed at the end of the local variable list - ** so that if the sprintf happens to spill past the end, it isn't likely - ** to trash anything (important). The buffer is then manually truncated - ** to maximum allowed size before being printed. - */ - char buffer[256]; - - if (!Enabled) return; - - va_start(va, text); - vsprintf(buffer, Text_String(text), va); - buffer[sizeof(buffer)-1] = '\0'; - - Print(buffer); - va_end(va); -} -#endif - - -/*********************************************************************************************** - * MonoClass::Print -- Prints the text string at the current cursor coordinates. * - * * - * Use this routine to output the specified text string at the monochrome object's current * - * text coordinate position. * - * * - * INPUT: ptr -- Pointer to the string to print. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Print(char const *ptr) -{ -// int optr; - char startcol = X; - char const * text; - CellType cell; - - if (!ptr || !Enabled) return; - - text = ptr; - cell.Attribute = Attrib; -// optr = Offset(X, Y); - while (*text) { - - /* - ** Sometimes the character string is used for cursor control instead - ** of plain text output. Check for this case. - */ - switch (*text) { - - /* - ** The "return" code behaves as it did in the old C library - ** mono system. That is, it returns the cursor position to - ** the next line but at the starting column of the print. - */ - case '\r': - X = startcol; - Y++; - Scroll(Y-(LINES-1)); -// optr = Offset(X, Y); - break; - - /* - ** The "newline" code behaves like the console newline character. - ** That is, it moves the cursor down one line and at the first - ** column. - */ - case '\n': - X = 0; - Y++; - Scroll(Y-(LINES-1)); -// optr = Offset(X, Y); - break; - - /* - ** All other characters are output directly and the cursor moves - ** rightward to match. If the cursor wraps past the right - ** edge is it moved to the next now down at left margin. If the - ** cursor goes off the bottom of the display, the display is scrolled - ** upward a line. - */ - default: - cell.Character = *text; - Store_Cell(cell, X, Y); -// MonoSegment.Copy_Word_To(*(short*)&cell, optr); -// optr += sizeof(CellType); - - X++; - if (X >= COLUMNS) { - X = 0; - Y++; - - if (Y > (LINES-1)) { - Scroll(Y-(LINES-1)); -// optr = Offset(X, Y); - } - } - break; - - } - text++; - } - - Set_Cursor(X, Y); -} - - -/*********************************************************************************************** - * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. * - * * - * Use this routine to output text to the monochrome object at the X and Y coordinates * - * specified. * - * * - * INPUT: text -- Pointer to the text string to display. * - * * - * x,y -- The X and Y character coordinates to start the printing at. * - * * - * attrib-- Optional parameter that specifies what text attribute code to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::Text_Print(char const *text, int x, int y, char attrib) -{ - char oldx = X; - char oldy = Y; - char oldattrib = Attrib; - - X = (char)x; - Y = (char)y; - Attrib = attrib; - Print(text); - Attrib = oldattrib; - Set_Cursor(oldx, oldy); -} - -#ifdef NEVER -void MonoClass::Text_Print(int text, int x, int y, char attrib) -{ - char oldx = X; - char oldy = Y; - char oldattrib = Attrib; - - if (text != TXT_NONE) { - X = (char)x; - Y = (char)y; - Attrib = attrib; - Print(Text_String(text)); - Attrib = oldattrib; - Set_Cursor(oldx, oldy); - } -} - -void MonoClass::Print(int text) -{ - Print(Text_String(text)); -} -#endif - - -/*********************************************************************************************** - * MonoClass::operator = -- Handles making one mono object have the same imagery as another. * - * * - * The assignment operator will handle copying the imagery from one monochrome object to * - * another. Use this routine in to make two monochrome class objects visually identical. * - * * - * INPUT: src -- A reference to the source (right side) monochrome object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -MonoClass & MonoClass::operator = (MonoClass const & src) -{ - memcpy((void*)((long)MonoSegment + src.Offset(0, 0)), (void*)((long)MonoSegment + Offset(0, 0)), SIZE_OF_PAGE); -// DOSSegmentClass::Copy(MonoSegment, src.Offset(0, 0), MonoSegment, Offset(0,0), SIZE_OF_PAGE); - Set_Cursor(src.X, src.Y); - return(*this); -} - - -/*********************************************************************************************** - * MonoClass::View -- Brings the mono object to the main display. * - * * - * Use this routine to display the mono object on the monochrome screen. It is possible * - * that the mono object exists on some background screen memory. Calling this routine will * - * perform the necessary memory swapping to bring the data to the front. The mono object * - * that was currently being viewed is not destroyed by this function. It is merely moved * - * off to some background page. It can be treated normally, except that is just isn't * - * visible. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void MonoClass::View(void) -{ - MonoClass *displace; // The page that is being displaced. - - if (Get_Current() == this) return; - - /* - ** If the visible page is already assigned to a real monochrome page - ** object, then it must be swapped with the new one. - */ - displace = Get_Current(); - if (displace) { - char temp[SIZE_OF_PAGE]; - - memcpy(&temp[0], MonoSegment, SIZE_OF_PAGE); - memcpy(MonoSegment, (void*)((long)MonoSegment + Offset(0, 0)), SIZE_OF_PAGE); - memcpy((void*)((long)MonoSegment + Offset(0, 0)), &temp[0], SIZE_OF_PAGE); - -// DOSSegmentClass::Swap(MonoSegment, Offset(0, 0), MonoSegment, 0, SIZE_OF_PAGE); - displace->Page = Page; - - } else { - - /* - ** Just copy the new page over since the display page is not assigned - ** to a real monochrome page object. - */ - memcpy(MonoSegment, (void*)((long)MonoSegment + Offset(0, 0)), SIZE_OF_PAGE); -// DOSSegmentClass::Copy(MonoSegment, Offset(0, 0), MonoSegment, 0, SIZE_OF_PAGE); - } - PageUsage[Page] = displace; - PageUsage[0] = this; - Page = 0; - - Set_Cursor(X, Y); -} - - - -/************************************************************************************ -** This is the set of C wrapper functions that access the MonoClass support routines. -** Since the C interface doesn't have the ability to write to non-visible pages, it -** will just blast the output to whichever mono page is currently visible. If there is -** no mono class object that is visible, then one will be created -- BUT NOT FREED. -** Typically, this is ok, since the C interface will create only one MonoClass object -** and the system supports up to 8. -*/ -void Mono_Set_Cursor(int x, int y) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - mono->Set_Cursor(x, y); - } -} - -int Mono_Printf(char const *string, ...) -{ - va_list va; - char buffer[256]; - - buffer[0] = '\0'; - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - - va_start(va, string); - vsprintf(buffer, string, va); - - mono->Print(buffer); - - va_end(va); - } - return((short)strlen(buffer)); -} - - -void Mono_Clear_Screen(void) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - mono->Clear(); - } -} - -void Mono_Text_Print(void const *text, int x, int y, int attrib) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - mono->Text_Print((const char*)text, x, y, (char)attrib); - } -} - -void Mono_Draw_Rect(int x, int y, int w, int h, int attrib, int thick) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - mono->Draw_Box(x, y, w, h, (char)attrib, (MonoClass::BoxStyleType)thick); - } -} - -void Mono_Print(void const *text) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - mono->Print((const char*)text); - } -} - -int Mono_X(void) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - return(short)mono->Get_X(); - } - return(0); -} - -int Mono_Y(void) -{ - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - return(short)mono->Get_X(); - } - return(0); -} - - -void Mono_Put_Char(char , int ) -{ -} - -void Mono_Scroll(int ) -{ -} - -void Mono_View_Page(int ) -{ -} - - -#ifdef NEVER -int Mono_Printf(int string, ...) -{ - va_list va; - char buffer[256]; - - buffer[0] = '\0'; - if (MonoClass::Is_Enabled()) { - MonoClass *mono = MonoClass::Get_Current(); - if (!mono) { - mono = new MonoClass(); - mono->View(); - } - - va_start(va, string); - vsprintf(buffer, Text_String(string), va); - - mono->Print(buffer); - - va_end(va); - } - return((short)strlen(buffer)); -} -#endif - diff --git a/code/TIBERIANDAWN/MONOC.H b/code/TIBERIANDAWN/MONOC.H deleted file mode 100644 index 6d268da..0000000 --- a/code/TIBERIANDAWN/MONOC.H +++ /dev/null @@ -1,187 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\monoc.h_v 2.17 16 Oct 1995 16:45:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MONO.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 2, 1994 * - * * - * Last Update : July 2, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MONOC_H -#define MONOC_H - -//#include "dpmi.h" -//#include "function.h" - -class MonoClass { - /* - ** This is a private structure that is used to control which characters - ** are used when a box is drawn. Line drawing on the monochrome screen is - ** really made up of characters. This specifies which characters to use. - */ - typedef struct { - unsigned char UpperLeft; - unsigned char TopEdge; - unsigned char UpperRight; - unsigned char RightEdge; - unsigned char BottomRight; - unsigned char BottomEdge; - unsigned char BottomLeft; - unsigned char LeftEdge; - } BoxDataType; - - /* - ** Each cell is constructed of the actual character that is displayed and the - ** attribute to use. This character pair is located at every position on the - ** display (80 x 25). Since this cell pair can be represented by a "short" - ** integer, certain speed optimizations are taken in the monochrome drawing - ** code. - */ - typedef struct { - char Character; // Character to display. - char Attribute; // Attribute. - } CellType; - - /* - ** These private constants are used in the various monochrome operations. - */ - enum MonoClassPortEnums { - CONTROL_PORT=0x03B4, // CRTC control register. - DATA_PORT=0x03B5, // CRTC data register. - COLUMNS=80, // Number of columns. - LINES=25, // Number of lines. - SIZE_OF_PAGE=LINES*COLUMNS*sizeof(CellType), // Entire page size. - DEFAULT_ATTRIBUTE=0x02 // Normal white on black color attribute. - }; - - public: - enum MonoClassPageEnums { - MAX_MONO_PAGES=16, // Maximum RAM pages on mono card. - SEGMENT=0xB000 // Monochrome screen segment. - }; - - /* - ** These are the various box styles that may be used. - */ - typedef enum BoxStyleType { - SINGLE, // Single thickness. - DOUBLE_HORZ, // Double thick on the horizontal axis. - DOUBLE_VERT, // Double thick on the vertical axis. - DOUBLE, // Double thickness. - - COUNT - } BoxStyleType; - - MonoClass(void); - ~MonoClass(void); - - static void Enable(void) {Enabled = 1;}; - static void Disable(void) {Enabled = 0;}; - static int Is_Enabled(void) {return Enabled;}; - static MonoClass * Get_Current(void) {return PageUsage[0];}; - - void Draw_Box(int x, int y, int w, int h, char attrib=DEFAULT_ATTRIBUTE, BoxStyleType thick=SINGLE); - void Set_Default_Attribute(char attrib) {Attrib = attrib;}; - void Clear(void); - void Set_Cursor(int x, int y); - void Print(char const *text); - void Print(int text); - void Printf(char const *text, ...); - void Printf(int text, ...); - void Text_Print(char const *text, int x, int y, char attrib=DEFAULT_ATTRIBUTE); - void Text_Print(int text, int x, int y, char attrib=DEFAULT_ATTRIBUTE); - void View(void); - int Get_X(void) const {return X;}; - int Get_Y(void) const {return Y;}; - - /* - ** Handles deep copies for the mono class objects. This performs what is essentially - ** a screen copy. - */ - MonoClass & operator = (MonoClass const & ); - - /* - ** This merely makes a duplicate of the mono object into a newly created mono - ** object. - */ - MonoClass (MonoClass const &); - - private: - char X; // Cursor X position. - char Y; // Cursor Y position. - char Attrib; // Normal attribute to use if none specified. - char Page; // The current page to write to. - - /* - ** Helper functions to help with display operations. - */ - int Offset(int x=0, int y=0) const {return (SIZE_OF_PAGE*Page) + sizeof(CellType)*(x + (y*COLUMNS));}; - void Scroll(int lines); - void Store_Cell(CellType &cell, int x, int y) { - *(CellType *)((long)MonoSegment + Offset(x, y)) = cell; - }; - - /* - ** This is the segment/selector of the monochrome screen. - */ -// static DOSSegmentClass MonoSegment; - static void * MonoSegment; - - /* - ** This the the arrays of characters used for drawing boxes. - */ - static BoxDataType const CharData[4]; - - /* - ** This array contains pointers to the monochrome objects that are assigned - ** to each of the monochrome pages. As the monochrome pages are made visible, - ** they can be shuffled around between the actual locations. The first entry - ** in this table is the one that is visible. - */ - static MonoClass * PageUsage[MAX_MONO_PAGES]; - - /* - ** If this is true, then monochrome output is allowed. It defaults to false - ** so that monochrome output must be explicitly enabled. - */ - static int Enabled; -}; - -//extern int cdecl Mono_Printf(int string, ...); - - -void Mono_Set_Cursor(int x, int y); -int Mono_Printf(char const *string, ...); -void Mono_Clear_Screen(void); -void Mono_Text_Print(void const *text, int x, int y, int attrib); -void Mono_Draw_Rect(int x, int y, int w, int h, int attrib, int thick); -void Mono_Print(void const *text); -int Mono_X(void); -int Mono_Y(void); - -#endif diff --git a/code/TIBERIANDAWN/MOUSE.CPP b/code/TIBERIANDAWN/MOUSE.CPP deleted file mode 100644 index 29065bf..0000000 --- a/code/TIBERIANDAWN/MOUSE.CPP +++ /dev/null @@ -1,354 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mouse.cpv 2.18 16 Oct 1995 16:49:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MOUSE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : June 30, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * MouseClass::AI -- Process player input as it relates to the mouse * - * MouseClass::Override_Mouse_Shape -- Alters the shape of the mouse. * - * MouseClass::Init_Clear -- Sets the mouse system to a known state * - * MouseClass::MouseClass -- Default constructor for the mouse handler class. * - * MouseClass::One_Time -- Performs the one time initialization of the mouse system. * - * MouseClass::Set_Default_Mouse -- Sets the mouse to match the shape specified. * - * MouseClass::Revert_Mouse_Shape -- Reverts the mouse shape to the non overridden shape. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -** This points to the loaded mouse shapes. -*/ -void const * MouseClass::MouseShapes; - -/* -** This is the timer that controls the mouse animation. It is always at a fixed -** rate so it uses the constant system timer. -*/ -CountDownTimerClass MouseClass::Timer; - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * MouseClass::VTable; - - -/*********************************************************************************************** - * MouseClass::Set_Default_Mouse -- Sets the mouse to match the shape specified. * - * * - * This routine is used to inform the display system as to which mouse shape is desired. * - * * - * INPUT: mouse -- The mouse shape number to set the mouse to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -void MouseClass::Set_Default_Mouse(MouseType mouse, bool size) -{ - NormalMouseShape = mouse; - Override_Mouse_Shape(mouse, size); -} - - -/*********************************************************************************************** - * MouseClass::Revert_Mouse_Shape -- Reverts the mouse shape to the non overridden shape. * - * * - * Use this routine to cancel the effects of Override_Mouse_Shape(). It will revert the * - * mouse back to the original shape. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/27/1995 JLB : Created. * - *=============================================================================================*/ -void MouseClass::Revert_Mouse_Shape(void) -{ - Override_Mouse_Shape(NormalMouseShape, false); -} - - -void MouseClass::Mouse_Small(bool wwsmall) -{ - MouseStruct const * control = &MouseControl[CurrentMouseShape]; - - if (IsSmall == wwsmall) { - return; - } - - IsSmall = wwsmall; - - if (wwsmall) { - if (control->SmallFrame != -1) { - Set_Mouse_Cursor(control->X, control->Y, control->SmallFrame + Frame / 4); - } else { - Set_Mouse_Cursor(MouseControl[MOUSE_NORMAL].X, MouseControl[MOUSE_NORMAL].Y, MOUSE_NORMAL); - } - } else { - Set_Mouse_Cursor(control->X, control->Y, control->StartFrame + Frame / 4); - } -} - - -/*********************************************************************************************** - * MouseClass::Override_Mouse_Shape -- Alters the shape of the mouse. * - * * - * This routine is used to alter the shape of the mouse as needed. * - * Typical mouse shape change occurs when scrolling the map or * - * selecting targets. * - * * - * INPUT: mouse -- The mouse shape number to use. * - * * - * OUTPUT: bool; Was the mouse shape changed? * - * * - * WARNINGS: This is not intended to be used as a means to hide the * - * mouse. Nor will it work correctly if the mouse shape * - * file hasn't been loaded. * - * * - * HISTORY: * - * 03/10/1994 JLB : Created. * - * 06/03/1994 JLB : Made into member function. * - * 12/24/1994 JLB : Added small control parameter. * - *=============================================================================================*/ -bool MouseClass::Override_Mouse_Shape(MouseType mouse, bool wwsmall) -{ - MouseStruct const * control = &MouseControl[mouse]; - static bool startup = false; - int baseshp; - - /* - ** Only certain mouse shapes have a small counterpart. If the requested mouse - ** shape is not one of these, then force the small size override flag to false. - */ - if (control->SmallFrame == -1) { - wwsmall = false; - } - - /* - ** If the mouse shape is going to change, then inform the mouse driver of the - ** change. - */ - if (!startup || (MouseShapes && ((mouse != CurrentMouseShape) || (wwsmall != IsSmall)))) { - startup = true; - - Timer.Set(control->FrameRate); - Frame = 0; - -#ifdef OBSOLETE - Control.Set_Stage(0); - int rate = Options.Normalize_Delay(control->FrameRate); - Control.Set_Rate(MAX(rate, 1)); -#endif - baseshp = (wwsmall) ? control->SmallFrame : control->StartFrame; - - Set_Mouse_Cursor(control->X, control->Y, baseshp + Frame / 4); - CurrentMouseShape = mouse; - IsSmall = wwsmall; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * MouseClass::AI -- Process player input as it relates to the mouse * - * * - * This routine will is to be called once per game tick and is passed the player keyboard * - * or mouse input code. It processes this code and updates the mouse shape as appropriate. * - * * - * INPUT: input -- The player input code as returned from Keyboard::Get(). * - * * - * x,y -- The mouse coordinate values to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - * 03/27/1995 JLB : New animation control. * - * 05/28/1995 JLB : Moderates animation so is more steady regardless of speed. * - * 06/30/1995 JLB : Uses constant timer system. * - *=============================================================================================*/ -void MouseClass::AI(KeyNumType &input, int x, int y) -{ -// bool doit = false; - void *mouse_shape_ptr; - MouseStruct const * control = &MouseControl[CurrentMouseShape]; - - if (control->FrameRate && Timer.Time() == 0) { - - Frame++; - Frame %= control->FrameCount; - Timer.Set(control->FrameRate); - -#ifdef OBSOLETE - Control.Set_Stage(Control.Fetch_Stage() % control->FrameCount); -#endif - - if (!IsSmall || control->SmallFrame != -1) { - int baseframe = (IsSmall) ? control->SmallFrame : control->StartFrame; - Set_Mouse_Cursor(control->X, control->Y, baseframe + Frame); - } - } - - ScrollClass::AI(input, x, y); -} - - -/*********************************************************************************************** - * MouseClass::MouseClass -- Default constructor for the mouse handler class. * - * * - * This is the default constructor for the mouse handling class. It merely sets up the * - * mouse system to its default state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -MouseClass::MouseClass(void) -{ - CurrentMouseShape = MOUSE_NORMAL; - NormalMouseShape = MOUSE_NORMAL; - Timer.Start(); -} - - -/*********************************************************************************************** - * MouseClass::One_Time -- Performs the one time initialization of the mouse system. * - * * - * Use this routine to load the mouse data file and perform any other necessary one time * - * preparations for the game. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Only call this routine ONCE. * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void MouseClass::One_Time(void) -{ - ScrollClass::One_Time(); - - /* - ** Override the mouse shape file with the one in the current directory, but only if there - ** is an override file available. - */ - RawFileClass file("MOUSE.SHP"); - if (file.Is_Available()) { - MouseShapes = Load_Alloc_Data(file); - } else { - MouseShapes = MixFileClass::Retrieve("MOUSE.SHP"); - } - - VTable = ((void **)(((char *)this) + sizeof(VectorClass) - 4))[0]; -} - - -/*********************************************************************************************** - * MouseClass::Init_Clear -- Sets the mouse system to a known state * - * * - * This routine will reset the mouse handling system. Typically, this routine is called * - * when preparing for the beginning of a new scenario. * - * * - * INPUT: theater -- The theater that the scenario will take place. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void MouseClass::Init_Clear(void) -{ - ScrollClass::Init_Clear(); - IsSmall = false; - NormalMouseShape = MOUSE_NORMAL; -} - - -/* -** This array of structures is used to control the mouse animation -** sequences. -*/ -MouseClass::MouseStruct MouseClass::MouseControl[MOUSE_COUNT] = { - {0, 1, 0, 86, 0, 0}, // MOUSE_NORMAL - {1, 1, 0, -1, 15, 0}, // MOUSE_N - {2, 1, 0, -1, 29, 0}, // MOUSE_NE - {3, 1, 0, -1, 29, 12}, // MOUSE_E - {4, 1, 0, -1, 29, 23}, // MOUSE_SE - {5, 1, 0, -1, 15, 23}, // MOUSE_S - {6, 1, 0, -1, 0, 23}, // MOUSE_SW - {7, 1, 0, -1, 0, 13}, // MOUSE_W - {8, 1, 0, -1, 0, 0}, // MOUSE_NW - - {130, 1, 0, -1, 15, 0}, // MOUSE_NO_N - {131, 1, 0, -1, 29, 0}, // MOUSE_NO_NE - {132, 1, 0, -1, 29, 12}, // MOUSE_NO_E - {133, 1, 0, -1, 29, 23}, // MOUSE_NO_SE - {134, 1, 0, -1, 15, 23}, // MOUSE_NO_S - {135, 1, 0, -1, 0, 23}, // MOUSE_NO_SW - {136, 1, 0, -1, 0, 13}, // MOUSE_NO_W - {137, 1, 0, -1, 0, 0}, // MOUSE_NO_NW - - {11, 1, 0, 27, 15, 12}, // MOUSE_NO_MOVE - {10, 1, 0, 26, 15, 12}, // MOUSE_CAN_MOVE - {119, 3, 4, 148, 15, 12}, // MOUSE_ENTER - {53, 9, 4, -1, 15, 12}, // MOUSE_DEPLOY - {12, 6, 4, -1, 15, 12}, // MOUSE_CAN_SELECT - {18, 8, 4, 140, 15, 12}, // MOUSE_CAN_ATTACK - {62, 24, 2, -1, 15, 12}, // MOUSE_SELL_BACK - {154, 24, 2, -1, 15, 12}, // MOUSE_SELL_UNIT - {29, 24, 2, -1, 15, 12}, // MOUSE_REPAIR - {126, 1, 0, -1, 15, 12}, // MOUSE_NO_REPAIR - {125, 1, 0, -1, 15, 12}, // MOUSE_NO_SELL_BACK - {87, 1, 0, 151, 0, 0}, // MOUSE_RADAR_CURSOR - {103, 16, 2, -1, 15, 12}, // MOUSE_ION_CANNON - {96, 7, 4, -1, 15, 12}, // MOUSE_NUCLEAR_BOMB - {88, 8, 2, -1, 15, 12}, // MOUSE_AIR_STRIKE - {122, 3, 4, 127, 15, 12}, // MOUSE_DEMOLITIONS - {153, 1, 0, 152, 15, 12}, // MOUSE_AREA_GUARD -}; diff --git a/code/TIBERIANDAWN/MOUSE.H b/code/TIBERIANDAWN/MOUSE.H deleted file mode 100644 index 6bf5524..0000000 --- a/code/TIBERIANDAWN/MOUSE.H +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mouse.h_v 2.16 16 Oct 1995 16:45:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MOUSE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : December 15, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MOUSE_H -#define MOUSE_H - -#include "stage.h" -#include "scroll.h" - -class MouseClass: public ScrollClass -{ - public: - MouseClass(void); - - /* - ** Initialization - */ - virtual void One_Time(void); // One-time inits - virtual void Init_Clear(void); // Clears all to known state - - virtual void AI(KeyNumType &input, int x, int y); - virtual bool Override_Mouse_Shape(MouseType mouse, bool wwsmall=false); - virtual void Revert_Mouse_Shape(void); - virtual MouseType Get_Mouse_Shape(void) const {return NormalMouseShape;}; - virtual void Mouse_Small(bool wwsmall); - - /* - ** File I/O. - */ - virtual bool Load(FileClass & file); - virtual bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - virtual void Set_Default_Mouse(MouseType mouse, bool wwsmall = false); - - /* - ** This allows the tactical map input gadget access to change the - ** mouse shapes. - */ - friend class TacticalClass; - - private: - - /* - ** This type is used to control the frames and rates of the mouse - ** pointer. Some mouse pointers are actually looping animations. - */ - typedef struct MouseStruct - { - int StartFrame; // Starting frame number. - int FrameCount; // Number of animation frames. - int FrameRate; // Frame delay between changing frames. - int SmallFrame; // Start frame number for small version (if any). - int X,Y; // Hotspot X and Y offset. - } MouseStruct; - - /* - ** The control frames and rates for the various mouse pointers are stored - ** in this static array. - */ - static MouseStruct MouseControl[MOUSE_COUNT]; - - /* - ** If the small representation of the mouse is active, then this flag is true. - */ - unsigned IsSmall:1; - - /* - ** This points to the loaded mouse shapes. - */ - static void const * MouseShapes; - - /* - ** The mouse shape is controlled by these variables. These - ** hold the current mouse shape (so resetting won't be needlessly performed) and - ** the normal default mouse shape (when arrow shapes are needed). - */ - MouseType CurrentMouseShape; - MouseType NormalMouseShape; - - /* - ** For animating mouse shapes, this controls the frame and animation rate. - */ - static CountDownTimerClass Timer; - int Frame; -// StageClass Control; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - - -#endif diff --git a/code/TIBERIANDAWN/MPLAYER.CPP b/code/TIBERIANDAWN/MPLAYER.CPP deleted file mode 100644 index 22df5b0..0000000 --- a/code/TIBERIANDAWN/MPLAYER.CPP +++ /dev/null @@ -1,1417 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\mplayer.cpv 1.9 16 Oct 1995 16:51:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MPLAYER.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : April 14, 1995 * - * * - * Last Update : July 5, 1995 [BRR] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game * - * Read_MultiPlayer_Settings -- reads multi-player settings from conquer.ini * - * Write_MultiPlayer_Settings -- writes multi-player settings to conquer.ini * - * Read_Scenario_Descriptions -- reads multi-player scenario #'s # descriptions * - * Free_Scenario_Descriptions -- frees memory for the scenario descriptions * - * Computer_Message -- "sends" a message from the computer * - * Garble_Message -- "garbles" a message * - * Surrender_Dialog -- Prompts user for surrendering * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "tcpip.h" - -static void Garble_Message(char *buf); - -int Choose_Internet_Game(void); -int Get_Internet_Host_Or_Join(void); -int Get_IP_Address(void); -void Show_Internet_Connection_Progress(void); - -/*********************************************************************************************** - * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * GAME_NORMAL, GAME_MODEM, etc. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -GameType Select_MPlayer_Game (void) -{ -//PG_TO_FIX - return GAME_NORMAL; -#if (0) - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - bool ipx_avail = FALSE; - int number_of_buttons; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 190*factor; - int d_dialog_h = 26*4*factor; - int d_dialog_x = ((320*factor - d_dialog_w) / 2); -// d_dialog_y = ((200 - d_dialog_h) / 2), - int d_dialog_y = ((136*factor - d_dialog_h) / 2); - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); - - int d_txt6_h = 11 * factor; - int d_margin = 7 *factor; - - int d_modemserial_w = 80*factor; - int d_modemserial_h = 9*factor; - int d_modemserial_x = d_dialog_cx - d_modemserial_w / 2; - int d_modemserial_y = d_dialog_y + d_margin + d_txt6_h + d_margin; -#if (0) - int d_internet_w = 80*factor; - int d_internet_h = 9*factor; - int d_internet_x = d_dialog_cx - d_internet_w / 2; - int d_internet_y = d_modemserial_y + d_modemserial_h + 2*factor; -#endif //(0) - int d_ipx_w = 80*factor; - int d_ipx_h = 9*factor; - int d_ipx_x = d_dialog_cx - d_ipx_w / 2; - int d_ipx_y = d_modemserial_y + d_modemserial_h + 2*factor; -// int d_ipx_y = d_internet_y + d_internet_h + 2*factor; - - int d_cancel_w = 60*factor; - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx - d_cancel_w / 2; - int d_cancel_y = d_ipx_y + d_ipx_h + d_margin; - - CountDownTimerClass delay; - - /*........................................................................ - Button enumerations: - ........................................................................*/ - enum { - BUTTON_MODEMSERIAL = 100, -#if (0) - BUTTON_INTERNET, -#endif //(0) - BUTTON_IPX, - BUTTON_CANCEL, - - NUM_OF_BUTTONS = 3, - }; - number_of_buttons = NUM_OF_BUTTONS; - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, // includes map interior & coord values - REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - /*........................................................................ - Dialog variables: - ........................................................................*/ - KeyNumType input; // input from user - bool process; // loop while true - RedrawType display; // true = re-draw everything - GameType retval; // return value - int selection; - bool pressed; - int curbutton; - TextButtonClass *buttons[NUM_OF_BUTTONS]; - - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - // - // If neither IPX or winsock are active then do only the modem serial dialog - // - if (Ipx.Is_IPX()){ - ipx_avail = TRUE; - } - - - TextButtonClass modemserialbtn (BUTTON_MODEMSERIAL, TXT_MODEM_SERIAL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_modemserial_x, d_modemserial_y, d_modemserial_w, d_modemserial_h); -#if (0) - TextButtonClass internetbtn (BUTTON_INTERNET, TXT_INTERNET, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_internet_x, d_internet_y, d_internet_w, d_internet_h); -#endif //(0) - TextButtonClass ipxbtn (BUTTON_IPX, TXT_NETWORK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ipx_x, d_ipx_y, d_ipx_w, d_ipx_h); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ............................ Create the list ............................. - */ - commands = &modemserialbtn; -#if (0) - internetbtn.Add_Tail(*commands); -#endif //(0) - if (ipx_avail){ - ipxbtn.Add_Tail(*commands); - } - cancelbtn.Add_Tail(*commands); - - /* - ......................... Fill array of button ptrs ...................... - */ - curbutton = 0; - buttons[0] = &modemserialbtn; -#if (0) - buttons[1] = &internetbtn; -#endif //(0) - if (ipx_avail){ - buttons[1] = &ipxbtn; - buttons[2] = &cancelbtn; - }else{ - buttons[1] = &cancelbtn; - number_of_buttons--; - } - - buttons[curbutton]->Turn_On(); - - Keyboard::Clear(); - - Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - pressed = false; - while (process) { - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - /* - ..................... Refresh the backdrop ...................... - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - /* - ..................... Draw the background ....................... - */ - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - Draw_Caption (TXT_SELECT_MPLAYER_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - } - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Flag_List_To_Redraw(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (BUTTON_MODEMSERIAL | KN_BUTTON): - selection = BUTTON_MODEMSERIAL; - pressed = true; - break; - -#if (0) - case (BUTTON_INTERNET | KN_BUTTON): - selection = BUTTON_INTERNET; - pressed = true; - break; -#endif //(0) - - case (BUTTON_IPX | KN_BUTTON): - selection = BUTTON_IPX; - pressed = true; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - selection = BUTTON_CANCEL; - pressed = true; - break; - - case KN_UP: - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton--; - if (curbutton < 0) - curbutton = (number_of_buttons - 1); - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case KN_DOWN: - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton++; - if (curbutton > (number_of_buttons - 1) ) - curbutton = 0; - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case KN_RETURN: - selection = curbutton + BUTTON_MODEMSERIAL; - if (!ipx_avail) selection--; - pressed = true; - break; - - default: - break; - } - - if (pressed) { - // - // to make sure the selection is correct in case they used the mouse - // - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton = selection - BUTTON_MODEMSERIAL; - buttons[curbutton]->Turn_On(); -// buttons[curbutton]->Flag_To_Redraw(); - buttons[curbutton]->IsPressed = true; - buttons[curbutton]->Draw_Me(true); - - switch (selection) { - case (BUTTON_MODEMSERIAL): - - // - // Pop up the modem/serial/com port dialog - // - retval = Select_Serial_Dialog(); - - if (retval != GAME_NORMAL) { - process = false; - } else { - buttons[curbutton]->IsPressed = false; - display = REDRAW_ALL; - } - break; - -#if (0) - case (BUTTON_INTERNET): -//#define ONLY_FOR_E3 -#ifdef ONLY_FOR_E3 - Call_Back(); - Show_Internet_Connection_Progress(); //changed to do nothing - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - Call_Back(); - CCMessageBox().Process("Error! - Unable to ping KANE.WESTWOOD.COM"); - - buttons[curbutton]->IsPressed = false; - display = REDRAW_ALL; - - -#endif //ONLY_FOR_E3 - - -#ifdef FORCE_WINSOCK - if (Winsock.Init()){ - Read_MultiPlayer_Settings (); - int result = Choose_Internet_Game(); - - if (!result){ - Winsock.Close(); - buttons[curbutton]->IsPressed = false; - display = REDRAW_ALL; - break; - } - - result = Get_Internet_Host_Or_Join(); - if (result == 1){ - Winsock.Close(); - buttons[curbutton]->IsPressed = false; - display = REDRAW_ALL; - break; - } - Server = !result; - - if (Server){ -#if (0) - ModemGameToPlay = INTERNET_HOST; - Winsock.Start_Server(); -#else - result = Get_IP_Address(); - if (!result){ - Winsock.Close(); - buttons[curbutton]->IsPressed = false; - display = REDRAW_ALL; - break; - } - Winsock.Set_Host_Address(PlanetWestwoodIPAddress); - Winsock.Start_Server(); -#endif - - }else{ - ModemGameToPlay = INTERNET_JOIN; - result = Get_IP_Address(); - if (!result){ - Winsock.Close(); - buttons[curbutton]->IsPressed = false; - display = REDRAW_ALL; - break; - } - Winsock.Set_Host_Address(PlanetWestwoodIPAddress); - Winsock.Start_Client(); - } - - //CountDownTimerClass connect_timeout; - //connect_timeout.Set(15*60); - - ////Show_Internet_Connection_Progress(); - - if (!Winsock.Get_Connected()){ - Winsock.Close(); - return(GAME_NORMAL); - } - - SerialSettingsType *settings; - settings = &SerialDefaults; - Init_Null_Modem(settings); - if (Server){ - if (Com_Scenario_Dialog()){ - return (GAME_INTERNET); - }else{ - Winsock.Close(); - return (GAME_NORMAL); - } - }else{ - if (Com_Show_Scenario_Dialog()){ - return (GAME_INTERNET); - }else{ - Winsock.Close(); - return (GAME_NORMAL); - } - } - } -#endif //FORCE_WINSOCK - break; - -#endif //(0) - - case (BUTTON_IPX): - retval = GAME_IPX; - process = false; - break; - - case (BUTTON_CANCEL): - retval = GAME_NORMAL; - process = false; - break; - } - - pressed = false; - } - } - return(retval); -#endif -} - - -/*********************************************************************************************** - * Read_MultiPlayer_Settings -- reads multi-player settings from conquer.ini * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void Read_MultiPlayer_Settings (void) -{ -//PG_TO_FIX -#if (0) - char *buffer; // INI staging buffer pointer. - char *tbuffer; // Accumulation buffer of trigger IDs. - int len; // Length of data in buffer. - char *tokenptr; // ptr to token - PhoneEntryClass *phone; // a phone book entry - char *entry; // a phone book entry - char buf[128]; // buffer for parsing INI entry - int i; - CELL cell; - - /*------------------------------------------------------------------------ - Fetch working pointer to the INI staging buffer. Make sure that the buffer - is cleared out before proceeding. (Don't use the HidPage for this, since - the HidPage may be needed for various uncompressions during the INI - parsing.) - ------------------------------------------------------------------------*/ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - /*------------------------------------------------------------------------ - Clear the initstring entries - ------------------------------------------------------------------------*/ - for (i = 0; i < InitStrings.Count(); i++) { - delete[] InitStrings[i]; - } - InitStrings.Clear(); - - /*------------------------------------------------------------------------ - Clear the dialing entries - ------------------------------------------------------------------------*/ - for (i = 0; i < PhoneBook.Count(); i++) { - delete PhoneBook[i]; - } - PhoneBook.Clear(); - - /*------------------------------------------------------------------------ - Create filename and read the file. - ------------------------------------------------------------------------*/ - CCFileClass file ("CONQUER.INI"); - if (!file.Is_Available()) { - return; - } else { - file.Read(buffer, _ShapeBufferSize-1); - } - file.Close(); - - if (!Special.IsFromWChat){ - /*------------------------------------------------------------------------ - Get the player's last-used Handle - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString("MultiPlayer", "Handle", "Noname", MPlayerName, - sizeof(MPlayerName), buffer); - - /*------------------------------------------------------------------------ - Get the player's last-used Color - ------------------------------------------------------------------------*/ - MPlayerPrefColor = WWGetPrivateProfileInt("MultiPlayer", "Color", 0, buffer); - MPlayerHouse = (HousesType)WWGetPrivateProfileInt("MultiPlayer", "Side", - HOUSE_GOOD, buffer); - CurPhoneIdx = WWGetPrivateProfileInt("MultiPlayer", "PhoneIndex", -1, buffer); - }else{ - CurPhoneIdx = -1; - } - -#if 1 - TrapCheckHeap = WWGetPrivateProfileInt( "MultiPlayer", "CheckHeap", 0, buffer); -#endif - - /*------------------------------------------------------------------------ - Read in default serial settings - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString ("SerialDefaults", "ModemName", "NoName", SerialDefaults.ModemName, MODEM_NAME_MAX, buffer); - if (!strcmp ( SerialDefaults.ModemName, "NoName")) { - SerialDefaults.ModemName[0] = 0; - } - WWGetPrivateProfileString ("SerialDefaults", "Port", "0", buf, 5, buffer); - sscanf (buf, "%x", &SerialDefaults.Port); - SerialDefaults.IRQ = WWGetPrivateProfileInt("SerialDefaults", "IRQ", -1, buffer); - SerialDefaults.Baud = WWGetPrivateProfileInt("SerialDefaults", "Baud", -1, buffer); - SerialDefaults.Init = WWGetPrivateProfileInt("SerialDefaults", "Init", 0, buffer); - SerialDefaults.Compression = WWGetPrivateProfileInt ("SerialDefaults", "Compression", 0, buffer); - SerialDefaults.ErrorCorrection = WWGetPrivateProfileInt ("SerialDefaults", "ErrorCorrection", 0, buffer); - SerialDefaults.HardwareFlowControl = WWGetPrivateProfileInt ("SerialDefaults", "HardwareFlowControl", 1, buffer); - WWGetPrivateProfileString ("SerialDefaults", "DialMethod", "T", - buf, 2, buffer); - - - // find dial method - - for (i = 0; i < DIAL_METHODS; i++) { - if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { - SerialDefaults.DialMethod = (DialMethodType)i; - break; - } - } - - // if method not found set to touch tone - - if (i == DIAL_METHODS) { - SerialDefaults.DialMethod = DIAL_TOUCH_TONE; - } - - SerialDefaults.InitStringIndex = - WWGetPrivateProfileInt("SerialDefaults", - "InitStringIndex", 0, buffer); - - SerialDefaults.CallWaitStringIndex = - WWGetPrivateProfileInt("SerialDefaults", - "CallWaitStringIndex", CALL_WAIT_CUSTOM, - buffer); - - WWGetPrivateProfileString ("SerialDefaults", "CallWaitString", "", - SerialDefaults.CallWaitString, CWAITSTRBUF_MAX, buffer); - - if (SerialDefaults.IRQ == 0 || - SerialDefaults.Baud == 0) { - - SerialDefaults.Port = 0; - SerialDefaults.IRQ = -1; - SerialDefaults.Baud = -1; - } - - /*------------------------------------------------------------------------ - Set 'tbuffer' to point past the actual INI data - ------------------------------------------------------------------------*/ - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - /*------------------------------------------------------------------------ - Read all Base-Scenario names into 'tbuffer' - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString("InitStrings", NULL, NULL, tbuffer, - ShapeBufferSize-len, buffer); - - /*------------------------------------------------------------------------ - Read in & store each entry - ------------------------------------------------------------------------*/ - while (*tbuffer != '\0') { - entry = new char[ INITSTRBUF_MAX ]; - - entry[0] = 0; - - WWGetPrivateProfileString("InitStrings", tbuffer, NULL, entry, - INITSTRBUF_MAX, buffer); - - strupr( entry ); - - InitStrings.Add( entry ); - - tbuffer += strlen(tbuffer) + 1; - } - - // if no entries then have at least one - - if ( tbuffer == (buffer + len) ) { - entry = new char[ INITSTRBUF_MAX ]; - strcpy( entry, "ATZ" ); - InitStrings.Add( entry ); - SerialDefaults.InitStringIndex = 0; - } else { - len = strlen(buffer) + 2; - } - - /*------------------------------------------------------------------------ - Repeat the process for the phonebook - ------------------------------------------------------------------------*/ - tbuffer = buffer + len; - - /*------------------------------------------------------------------------ - Read in all phone book listings. - Format: Name=PhoneNum,Port,IRQ,Baud,InitString - ------------------------------------------------------------------------*/ - - /*........................................................................ - Read the entry names in - ........................................................................*/ - WWGetPrivateProfileString("PhoneBook", NULL, NULL, tbuffer, - ShapeBufferSize-len, buffer); - - while (*tbuffer != '\0') { - /*..................................................................... - Create a new phone book entry - .....................................................................*/ - phone = new PhoneEntryClass(); - - /*..................................................................... - Read the entire entry in - .....................................................................*/ - WWGetPrivateProfileString("PhoneBook", tbuffer, NULL, buf, 128, buffer); - - /*..................................................................... - Extract name, phone # & serial port settings - .....................................................................*/ - tokenptr = strtok( buf, "|" ); - if (tokenptr) { - strcpy( phone->Name, tokenptr ); - strupr( phone->Name ); - } else { - phone->Name[0] = 0; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - strcpy( phone->Number, tokenptr ); - strupr( phone->Number ); - } else { - phone->Number[0] = 0; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - sscanf( tokenptr, "%x", &phone->Settings.Port ); - } else { - phone->Settings.Port = 0; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.IRQ = atoi( tokenptr ); - } else { - phone->Settings.IRQ = -1; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.Baud = atoi( tokenptr ); - } else { - phone->Settings.Baud = -1; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.Compression = atoi( tokenptr ); - } else { - phone->Settings.Compression = 0; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.ErrorCorrection = atoi( tokenptr ); - } else { - phone->Settings.ErrorCorrection = 0; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.HardwareFlowControl = atoi( tokenptr ); - } else { - phone->Settings.HardwareFlowControl = 1; - } - - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - strcpy( buf, tokenptr ); - - // find dial method - - for (i = 0; i < DIAL_METHODS; i++) { - if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { - phone->Settings.DialMethod = (DialMethodType)i; - break; - } - } - - // if method not found set to touch tone - - if (i == DIAL_METHODS) { - phone->Settings.DialMethod = DIAL_TOUCH_TONE; - } - } else { - phone->Settings.DialMethod = DIAL_TOUCH_TONE; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.InitStringIndex = atoi( tokenptr ); - } else { - phone->Settings.InitStringIndex = 0; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - phone->Settings.CallWaitStringIndex = atoi( tokenptr ); - } else { - phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; - } - - tokenptr = strtok( NULL, "|" ); - if (tokenptr) { - strcpy (phone->Settings.CallWaitString, tokenptr); - } else { - phone->Settings.CallWaitString[0] = 0; - } - - /*..................................................................... - Add it to our list - .....................................................................*/ - PhoneBook.Add(phone); - - tbuffer += strlen(tbuffer) + 1; - } - - /*------------------------------------------------------------------------ - Read special recording playback values, to help find sync bugs - ------------------------------------------------------------------------*/ - if (PlaybackGame) { - TrapFrame = WWGetPrivateProfileInt ("SyncBug","Frame",0x7fffffff, buffer); - - TrapObjType = (RTTIType)WWGetPrivateProfileInt ("SyncBug","Type",RTTI_NONE, buffer); - WWGetPrivateProfileString ("SyncBug","Type","NONE",buf,80,buffer); - if (!stricmp(buf,"AIRCRAFT")) - TrapObjType = RTTI_AIRCRAFT; - else if (!stricmp(buf,"ANIM")) - TrapObjType = RTTI_ANIM; - else if (!stricmp(buf,"BUILDING")) - TrapObjType = RTTI_BUILDING; - else if (!stricmp(buf,"BULLET")) - TrapObjType = RTTI_BULLET; - else if (!stricmp(buf,"INFANTRY")) - TrapObjType = RTTI_INFANTRY; - else if (!stricmp(buf,"UNIT")) - TrapObjType = RTTI_UNIT; - else { - TrapObjType = RTTI_NONE; - } - - WWGetPrivateProfileString ("SyncBug","Coord","0",buf,80,buffer); - sscanf(buf,"%x",&TrapCoord); - - WWGetPrivateProfileString ("SyncBug","this","0",buf,80,buffer); - sscanf(buf,"%x",&TrapThis); - - WWGetPrivateProfileString ("SyncBug","Cell","0",buf,80,buffer); - cell = atoi(buf); - if (cell) { - TrapCell = &(Map[cell]); - } - } -#endif -} - - -/*********************************************************************************************** - * Write_MultiPlayer_Settings -- writes multi-player settings to conquer.ini * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void Write_MultiPlayer_Settings (void) -{ -//PG_TO_FIX -#if(0) - char * buffer; // INI staging buffer pointer. - CCFileClass file; - int i; - char entrytext[4]; - char buf[128]; // buffer for parsing INI entry - - /*------------------------------------------------------------------------ - Get a working pointer to the INI staging buffer. Make sure that the buffer - starts cleared out of any data. - ------------------------------------------------------------------------*/ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - file.Set_Name("CONQUER.INI"); - if (file.Is_Available()) { - file.Open(READ); - file.Read(buffer, _ShapeBufferSize-1); - file.Close(); - } - - /*------------------------------------------------------------------------ - Save the player's last-used Handle & Color - ------------------------------------------------------------------------*/ - WWWritePrivateProfileInt("MultiPlayer", "PhoneIndex", CurPhoneIdx, buffer); - WWWritePrivateProfileInt ("MultiPlayer", "Color", MPlayerPrefColor, buffer); - WWWritePrivateProfileInt ("MultiPlayer", "Side", MPlayerHouse, buffer); - WWWritePrivateProfileString("MultiPlayer", "Handle", MPlayerName, buffer); - - /*------------------------------------------------------------------------ - Clear all existing SerialDefault entries. - ------------------------------------------------------------------------*/ - WWWritePrivateProfileString ("SerialDefaults", NULL, NULL, buffer); - - /*------------------------------------------------------------------------ - Save default serial settings in opposite order you want to see them - ------------------------------------------------------------------------*/ - WWWritePrivateProfileString("SerialDefaults", "CallWaitString", - SerialDefaults.CallWaitString, buffer); - WWWritePrivateProfileInt ("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex, buffer); - WWWritePrivateProfileInt ("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex, buffer); - WWWritePrivateProfileInt ("SerialDefaults", "Init", SerialDefaults.Init, buffer); - WWWritePrivateProfileString("SerialDefaults", "DialMethod", - DialMethodCheck[ SerialDefaults.DialMethod ], buffer); - WWWritePrivateProfileInt ("SerialDefaults", "Baud", SerialDefaults.Baud, buffer); - WWWritePrivateProfileInt ("SerialDefaults", "IRQ", SerialDefaults.IRQ, buffer); - sprintf(buf, "%x", SerialDefaults.Port); - WWWritePrivateProfileString("SerialDefaults", "Port", buf, buffer); - WWWritePrivateProfileString("SerialDefaults", "ModemName", SerialDefaults.ModemName, buffer); - WWWritePrivateProfileInt ("SerialDefaults", "Compression", SerialDefaults.Compression , buffer); - WWWritePrivateProfileInt ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection, buffer); - WWWritePrivateProfileInt ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl, buffer); - - /*------------------------------------------------------------------------ - Clear all existing InitString entries. - ------------------------------------------------------------------------*/ - WWWritePrivateProfileString ("InitStrings", NULL, NULL, buffer); - - /*------------------------------------------------------------------------ - Save all InitString entries. In descending order so they come out in - ascending order. - ------------------------------------------------------------------------*/ - for (i = (InitStrings.Count() - 1); i >= 0; i--) { - sprintf( buf, "%03d", i); - WWWritePrivateProfileString ("InitStrings", buf, InitStrings[i], buffer); - } - - /*------------------------------------------------------------------------ - Clear all existing Phone Book entries. - ------------------------------------------------------------------------*/ - WWWritePrivateProfileString ("PhoneBook", NULL, NULL, buffer); - - /*------------------------------------------------------------------------ - Save all Phone Book entries. - Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString - ------------------------------------------------------------------------*/ - for (i = (PhoneBook.Count() - 1); i >= 0; i--) { - sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s", - PhoneBook[i]->Name, - PhoneBook[i]->Number, - PhoneBook[i]->Settings.Port, - PhoneBook[i]->Settings.IRQ, - PhoneBook[i]->Settings.Baud, - PhoneBook[i]->Settings.Compression, - PhoneBook[i]->Settings.ErrorCorrection, - PhoneBook[i]->Settings.HardwareFlowControl, - DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ], - PhoneBook[i]->Settings.InitStringIndex, - PhoneBook[i]->Settings.CallWaitStringIndex, - PhoneBook[i]->Settings.CallWaitString); - sprintf( entrytext, "%03d", i ); - WWWritePrivateProfileString ("PhoneBook", entrytext, buf, buffer); - } - - /*------------------------------------------------------------------------ - Write the INI data out to a file. - ------------------------------------------------------------------------*/ - file.Open(WRITE); - file.Write(buffer,strlen(buffer)); - file.Close(); -#endif -} - - -/*********************************************************************************************** - * Read_Scenario_Descriptions -- reads multi-player scenario #'s # descriptions * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void Read_Scenario_Descriptions (void) -{ - char *buffer; // INI staging buffer pointer. - CCFileClass file; - int i; - char fname[20]; - - /*------------------------------------------------------------------------ - Clear the scenario description lists - ------------------------------------------------------------------------*/ - MPlayerScenarios.Clear(); - MPlayerFilenum.Clear(); - - /*------------------------------------------------------------------------ - Loop through all possible scenario numbers; if a file is available, add - its number to the FileNum list. - ------------------------------------------------------------------------*/ - for (i = 0; i < 100; i++) { - Set_Scenario_Name(ScenarioName, i, SCEN_PLAYER_MPLAYER, - SCEN_DIR_EAST, SCEN_VAR_A); - sprintf(fname,"%s.INI",ScenarioName); - file.Set_Name (fname); - - if (file.Is_Available()) { - MPlayerFilenum.Add(i); - } - } - - /*------------------------------------------------------------------------ - Now, for every file in the FileNum list, read in the INI file, and extract - its description. - ------------------------------------------------------------------------*/ - for (i = 0; i < MPlayerFilenum.Count(); i++) { - /*..................................................................... - Fetch working pointer to the INI staging buffer. Make sure that the - buffer is cleared out before proceeding. - .....................................................................*/ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - /*..................................................................... - Create filename and read the file. - .....................................................................*/ - Set_Scenario_Name(ScenarioName, MPlayerFilenum[i], SCEN_PLAYER_MPLAYER, - SCEN_DIR_EAST, SCEN_VAR_A); - sprintf(fname,"%s.INI",ScenarioName); - file.Set_Name (fname); - file.Read(buffer, _ShapeBufferSize-1); - file.Close(); - - /*..................................................................... - Extract description & add it to the list. - .....................................................................*/ - WWGetPrivateProfileString("Basic", "Name", "Nulls-Ville", - MPlayerDescriptions[i], 40, buffer); - MPlayerScenarios.Add(MPlayerDescriptions[i]); - } -} - - -/*********************************************************************************************** - * Free_Scenario_Descriptions -- frees memory for the scenario descriptions * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/05/1995 BRR : Created. * - *=============================================================================================*/ -void Free_Scenario_Descriptions(void) -{ - /*------------------------------------------------------------------------ - Clear the scenario descriptions & filenames - ------------------------------------------------------------------------*/ - MPlayerScenarios.Clear(); - MPlayerFilenum.Clear(); - -//PG_TO_FIX -#if (0) - int i; - - /*------------------------------------------------------------------------ - Clear the initstring entries - ------------------------------------------------------------------------*/ - for (i = 0; i < InitStrings.Count(); i++) { - delete InitStrings[i]; - } - InitStrings.Clear(); - - /*------------------------------------------------------------------------ - Clear the dialing entries - ------------------------------------------------------------------------*/ - for (i = 0; i < PhoneBook.Count(); i++) { - delete PhoneBook[i]; - } - PhoneBook.Clear(); -#endif -} - - -/*************************************************************************** - * Computer_Message -- "sends" a message from the computer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/06/1995 BRR : Created. * - *=========================================================================*/ -void Computer_Message(void) -{ - int color; - char txt[160]; - HousesType house; - HouseClass *ptr; - - /*------------------------------------------------------------------------ - Find the computer house that the message will be from - ------------------------------------------------------------------------*/ - for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { - ptr = HouseClass::As_Pointer(house); - - if (!ptr || ptr->IsHuman || ptr->IsDefeated) { - continue; - } - - /*..................................................................... - Decode this house's color - .....................................................................*/ - color = MPlayerTColors[ptr->RemapColor]; - - /*..................................................................... - We now have a 1/4 chance of echoing one of the human players' messages - back. - .....................................................................*/ - if (IRandom(0,3) == 2) { - /*.................................................................. - Now we have a 1/3 chance of garbling the human message. - ..................................................................*/ - if (IRandom(0,2) == 1) { - Garble_Message(LastMessage); - } - - /*.................................................................. - Only add the message if there is one to add. - ..................................................................*/ - if (strlen(LastMessage)) { - sprintf(txt,"%s %s",Text_String(TXT_FROM_COMPUTER),LastMessage); - Messages.Add_Message(txt, color, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - } - } else { - sprintf(txt,"%s %s",Text_String(TXT_FROM_COMPUTER), - Text_String(TXT_COMP_MSG1 + IRandom(0,12))); - Messages.Add_Message(txt, color, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - } - - return; - } -} - - -/*************************************************************************** - * Garble_Message -- "garbles" a message * - * * - * INPUT: * - * buf buffer to garble; stores output message * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/06/1995 BRR : Created. * - *=========================================================================*/ -static void Garble_Message(char *buf) -{ - char txt[80]; - char punct[20]; // for punctuation - char *p; // working ptr - int numwords; // # words in the phrase - char *words[40]; // ptrs to various words in the phrase - int i,j; - - /*------------------------------------------------------------------------ - Pull off any trailing punctuation - ------------------------------------------------------------------------*/ - p = buf + strlen(buf) - 1; - while (1) { - if (p < buf) - break; - if (p[0]=='!' || p[0]=='.' || p[0]=='?') { - p--; - } else { - p++; - break; - } - if (strlen(p) >= (sizeof(punct) - 1) ) { - break; - } - } - strcpy (punct, p); - p[0] = 0; - - for (i = 0; i < 40; i++) { - words[i] = NULL; - } - - /*------------------------------------------------------------------------ - Copy the original buffer - ------------------------------------------------------------------------*/ - strcpy(txt,buf); - - /*------------------------------------------------------------------------ - Split it up into words - ------------------------------------------------------------------------*/ - p = strtok (txt, " "); - numwords = 0; - while (p) { - words[numwords] = p; - numwords++; - p = strtok (NULL, " "); - } - - /*------------------------------------------------------------------------ - Now randomly put the words back. Don't use the real random-number - generator, since different machines will have different LastMessage's, - and will go out of sync. - ------------------------------------------------------------------------*/ - buf[0] = 0; - for (i = 0; i < numwords; i++) { - j = Sim_IRandom(0,numwords); - if (words[j] == NULL) { // this word has been used already - i--; - continue; - } - strcat(buf,words[j]); - words[j] = NULL; - if (i < numwords-1) - strcat(buf," "); - } - strcat(buf,punct); -} - - -/*************************************************************************** - * Surrender_Dialog -- Prompts user for surrendering * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = user cancels, 1 = user wants to surrender. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/05/1995 BRR : Created. * - *=========================================================================*/ -int Surrender_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 170*factor; // dialog width - int d_dialog_h = 53*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // centered x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // coord of x-center - - int d_txt6_h = 6*factor+1; // ht of 6-pt text - int d_margin = 5*factor; // margin width/height - int d_topmargin = 20*factor; // top margin - - int d_ok_w = 45*factor; // ok width - int d_ok_h = 9*factor; // ok height - int d_ok_x = d_dialog_cx - d_ok_w - 5*factor; // ok x - int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin; // ok y - - int d_cancel_w = 45*factor; // cancel width - int d_cancel_h = 9*factor; // cancel height - int d_cancel_x = d_dialog_cx + 5*factor; // cancel x - int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin; // cancel y - - - /*........................................................................ - Button enumerations - ........................................................................*/ - enum { - BUTTON_OK = 100, - BUTTON_CANCEL, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display; // requested redraw level - bool process; // loop while true - KeyNumType input; - int retcode; - - /*........................................................................ - Buttons - ........................................................................*/ - ControlClass *commands = NULL; // the button list - - TextButtonClass okbtn (BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ok_x, d_ok_y, d_ok_w, d_ok_h); - - TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ......................... Create the button list ......................... - */ - commands = &okbtn; - cancelbtn.Add_Tail(*commands); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - if (Main_Loop()) { - retcode = 0; - process = false; - } - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - - /* - ...................... Display the dialog box ...................... - */ - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - Draw_Caption(TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); - - /* - ....................... Draw the captions ....................... - */ - Fancy_Text_Print(Text_String(TXT_SURRENDER), - d_dialog_cx, d_dialog_y + d_topmargin, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /* - ........................ Redraw the buttons ........................ - */ - if (display >= REDRAW_BUTTONS) { - commands->Flag_List_To_Redraw(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (KN_RETURN): - case (BUTTON_OK | KN_BUTTON): - retcode = 1; - process = false; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - retcode = 0; - process = false; - break; - - default: - break; - } - } - - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); - - return (retcode); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/MSGBOX.CPP b/code/TIBERIANDAWN/MSGBOX.CPP deleted file mode 100644 index 14b9e00..0000000 --- a/code/TIBERIANDAWN/MSGBOX.CPP +++ /dev/null @@ -1,479 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\msgbox.cpv 2.18 16 Oct 1995 16:50:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : August 24, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * CCMessageBox::Process -- Handles all the options graphic interface. * - * CCMessageBox::Process -- Displays message box. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "msgbox.h" -#include "gadget.h" - -#ifdef JAPANESE -CCMessageBox::CCMessageBox(int caption, bool pict) : Caption(caption), IsPicture(pict) -{ -} -#endif - -/*********************************************************************************************** - * CCMessageBox::Process -- pops up a message with yes/no, etc * - * * - * This function displays a dialog box with a one-line message, and * - * up to two buttons. The 2nd button is optional. The buttons default * - * to "OK" and nothing, respectively. The hotkeys for the buttons are * - * RETURN and ESCAPE. * - * * - * INPUT: * - * msg message to display * - * b1txt text for 1st button * - * b2txt text for 2nd button; NULL = no 2nd button * - * * - * OUTPUT: * - * # of button selected (0 = 1st) * - * * - * WARNINGS: * - * 'msg' text must be <= 38 chars * - * 'b1txt' and 'b2txt' must each be <= 18 chars * - * * - * HISTORY: * - * 11/08/1994 BR : Created. * - * 05/18/1995 JLB : Uses new font and dialog style. * - * 08/24/1995 JLB : Handles three buttons. * - *=============================================================================================*/ -#define BUTTON_1 1 -#define BUTTON_2 2 -#define BUTTON_3 3 -#define BUTTON_FLAG 0x8000 -int CCMessageBox::Process(const char *msg, const char *b1txt, const char *b2txt, const char *b3txt, bool preserve) -{ -#define BUFFSIZE (511) -//#define BUFFSIZE (255) - char buffer[BUFFSIZE]; - int retval; - bool process; // loop while true - KeyNumType input; // user input - int selection; - bool pressed; - int curbutton; - TextButtonClass *buttons[3]; - void *back; - BOOL display; // display level - int realval[5]; - - GraphicBufferClass seen_buff_save(VisiblePage.Get_Width(),VisiblePage.Get_Height(),(void*)NULL); - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - if (b1txt && *b1txt == '\0') b1txt = 0; - if (b2txt && *b2txt == '\0') b2txt = 0; - if (b3txt && *b3txt == '\0') b3txt = 0; - - /* - ** Examine the optional button parameters. Fetch the width and starting - ** characters for each. - */ - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6PT_GRAD|TPF_NOSHADOW); - char b1char, b2char, b3char; // 1st char of each string - int bwidth, bheight; // button width and height - int numbuttons = 0; - if (b1txt) { - b1char = toupper(b1txt[0]); - - /* - ** Build the button list. - */ - bheight = FontHeight + FontYSpacing + (2*factor); - bwidth = MAX((String_Pixel_Width(b1txt) + (8 *factor)), 30U * (unsigned)factor); - - if (b2txt) { - numbuttons = 2; - b2char = toupper(b2txt[0]); - bwidth = MAX((String_Pixel_Width( b2txt ) + (8*factor)), (unsigned)bwidth); - - if (b3txt) { - numbuttons = 3; - b3char = toupper(b3txt[0]); - } - - } else { - numbuttons = 1; - } - } - - /* - ** Determine the dimensions of the text to be used for the dialog box. - ** These dimensions will control how the dialog box looks. - */ - buffer[BUFFSIZE-1] = 0; - strncpy(buffer, msg, BUFFSIZE-2); - int width; - int height; - -#ifdef JAPANESE - if(IsPicture) { - width = 90; - height = 140 - 60; - } else -#endif - Format_Window_String(buffer, 255 * factor, width, height); - -//BG #ifdef JAPANESE -//BG if(!IsPicture) { -//BG #else - width = MAX(width, 50 * factor); - width += 40 * factor; -//BG #endif -//BG #ifdef JAPANESE -//BG } -//BG #endif - height += (numbuttons == 0) ? (30 * factor) : (60 * factor); - - int x = (SeenBuff.Get_Width() - width) / 2; - int y = (SeenBuff.Get_Height() - height) / 2; - - /* - ** Other inits. - */ - Set_Logic_Page(SeenBuff); - VisiblePage.Blit(seen_buff_save); - - /* - ** Initialize the button structures. All are initialized, even though one (or none) may - ** actually be added to the button list. - */ - TextButtonClass button1(BUTTON_1, b1txt, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - x + ((numbuttons == 1) ? ((width - bwidth) >> 1) : (10*factor)), y + height - (bheight + (5*factor)), bwidth); - - TextButtonClass button2(BUTTON_2, b2txt, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, - x + width - (bwidth + (10*factor)), y + height - (bheight + (5*factor)), bwidth); - - TextButtonClass button3(BUTTON_3, b3txt, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW, 0, y + height - (bheight + (5*factor))); - button3.X = x + ((width - button3.Width) >> 1); - - TextButtonClass * buttonlist = 0; - curbutton = 0; - - /* - ** Add and inialize the buttons to the button list. - */ - if (numbuttons) { - buttonlist = &button1; - buttons[0] = &button1; - realval[0] = BUTTON_1; - if (numbuttons > 2) { - button3.Add(*buttonlist); - buttons[1] = &button3; - realval[1] = BUTTON_3; - button2.Add(*buttonlist); - buttons[2] = &button2; - realval[2] = BUTTON_2; - buttons[curbutton]->Turn_On(); - } else if (numbuttons == 2) { - button2.Add(*buttonlist); - buttons[1] = &button2; - realval[1] = BUTTON_2; - buttons[curbutton]->Turn_On(); - } - } - - /* - ** Draw the dialog. - */ - Hide_Mouse(); - if (preserve) { - back = new char[width * height]; - SeenBuff.To_Buffer(x, y, width, height, back, width * height); - } - //display = TRUE; -#ifdef JAPANESE - if(IsPicture) { - Load_Uncompress(CCFileClass(msg), SysMemPage, SysMemPage); - SysMemPage.Blit(SeenBuff, 160, 100); - } else { -#endif - Dialog_Box(x, y, width, height); - Draw_Caption(Caption, x, y, width); - - /* - ** Draw the caption. - */ - Fancy_Text_Print(buffer, x + (20*factor), y + (25*factor), CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); -#ifdef JAPANESE - } -#endif - /* - ** Redraw the buttons. - */ - if (buttonlist) { - buttonlist->Draw_All(); - } - Show_Mouse(); - - /* - ** Main Processing Loop. - */ - if (buttonlist) { - process = true; - pressed = false; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - seen_buff_save.Blit(VisiblePage); - display = TRUE; - } - - if (display){ - display = FALSE; - - Hide_Mouse(); - -#ifdef JAPANESE - if(IsPicture) { - Load_Uncompress(CCFileClass(msg), SysMemPage, SysMemPage); - SysMemPage.Blit(SeenBuff, 160, 100); - } else { -#endif - Dialog_Box(x, y, width, height); - Draw_Caption(Caption, x, y, width); - - /* - ** Draw the caption. - */ - Fancy_Text_Print(buffer, x + (20 * factor), y + (25 * factor), CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); -#ifdef JAPANESE - } -#endif - /* - ** Redraw the buttons. - */ - if (buttonlist) { - buttonlist->Draw_All(); - } - Show_Mouse(); - } - - /* - ** Invoke game callback. - */ - Call_Back(); - - /* - ** Fetch and process input. - */ - input = buttonlist->Input(); - switch (input) { - case (BUTTON_1|BUTTON_FLAG): - selection = realval[0]; - pressed = true; - break; - - case (KN_ESC): - if (numbuttons > 2) { - selection = realval[1]; - pressed = true; - } else { - selection = realval[2]; - pressed = true; - } - break; - - - case (BUTTON_2|BUTTON_FLAG): - selection = realval[1]; - pressed = true; - break; - - case (BUTTON_3|BUTTON_FLAG): - selection = realval[2]; - pressed = true; - break; - - case (KN_LEFT): - if (numbuttons > 1) { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - - curbutton--; - if (curbutton < 0) { - curbutton = numbuttons - 1; - } - - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - break; - - case (KN_RIGHT): - if (numbuttons > 1) { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - - curbutton++; - if (curbutton > (numbuttons - 1) ) { - curbutton = 0; - } - - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - break; - - case (KN_RETURN): - selection = curbutton + BUTTON_1; - pressed = true; - break; - - /* - ** Check 'input' to see if it's the 1st char of button text - */ - default: -#ifdef NEVER - if (b1char == toupper(Keyboard::To_ASCII((KeyNumType)(input & 0xFF)))) { - selection = BUTTON_1; - pressed = true; - } else if (b2txt!=NULL && - b2char == toupper(Keyboard::To_ASCII((KeyNumType)(input & 0xFF)))) { - selection = BUTTON_2; - pressed = true; - } -#endif - break; - } - - if (pressed) { - switch (selection) { - case (BUTTON_1): - retval = 0; - process = false; - break; - - case (BUTTON_2): - retval = 1; - process = false; - break; - - case BUTTON_3: - retval = 2; - process = false; - break; - } - - pressed = false; - } - } - - } else { - - /* - ** Delay for a brief moment so that the dialog box will be visible long - ** enough to read the text. - */ - CountDownTimerClass timer(BT_SYSTEM, 0); - timer.Start(); - timer.Set(TICKS_PER_SECOND*4); - while (timer.Time() > 0) { - Call_Back(); - } - Keyboard::Clear(); - } - - /* - ** Restore the screen if necessary. - */ - if (preserve) { - Hide_Mouse(); - if (SeenBuff.Lock()){ - Buffer_To_Page(x, y, width, height, back, &SeenBuff); - } - SeenBuff.Unlock(); - delete[] back; - back = NULL; - Show_Mouse(); - } - return(retval); -} - - -/*********************************************************************************************** - * CCMessageBox::Process -- this one takes integer text arguments * - * * - * INPUT: * - * msg message to display * - * b1txt text for 1st button * - * b2txt text for 2nd button; NULL = no 2nd button * - * * - * OUTPUT: * - * # of button selected (0 = 1st) * - * * - * WARNINGS: * - * 'msg' text must be <= 38 chars * - * 'b1txt' and 'b2txt' must each be <= 18 chars * - * * - * HISTORY: * - * 12/12/1994 BR : Created. * - * 06/18/1995 JLB : Simplified. * - *=============================================================================================*/ -int CCMessageBox::Process(int msg, int b1txt, int b2txt, int b3txt, bool preserve) -{ - return(Process(Text_String(msg), b1txt, b2txt, b3txt, preserve)); -} - - -/*********************************************************************************************** - * CCMessageBox::Process -- Displays message box. * - * * - * This routine will display a message box and wait for player input. It varies from the * - * other message box functions only in the type of parameters it takes. * - * * - * INPUT: msg -- Pointer to text string for the message itself. * - * * - * b1txt -- Text number for the "ok" button. * - * * - * b2txt -- Text number for the "cancel" button. * - * * - * OUTPUT: Returns with the button selected. "true" if "OK" was pressed, and "false" if * - * "CANCEL" was pressed. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/18/1995 JLB : Created. * - *=============================================================================================*/ -int CCMessageBox::Process(char const *msg, int b1txt, int b2txt, int b3txt, bool preserve) -{ - return(Process(msg, Text_String(b1txt), Text_String(b2txt), Text_String(b3txt), preserve)); -} diff --git a/code/TIBERIANDAWN/MSGBOX.H b/code/TIBERIANDAWN/MSGBOX.H deleted file mode 100644 index 034e54d..0000000 --- a/code/TIBERIANDAWN/MSGBOX.H +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\msgbox.h_v 2.17 16 Oct 1995 16:47:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : June 8, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MSGBOX_H -#define MSGBOX_H - -#include "jshell.h" - -class CCMessageBox -{ - int Caption; -#ifdef JAPANESE - bool IsPicture; -#endif - public: -#ifdef JAPANESE - CCMessageBox(int caption=TXT_NONE, bool pict=false); -#else - CCMessageBox(int caption=TXT_NONE) {Caption = caption;}; -#endif - int Process(const char *msg, const char *b1txt, const char *b2txt=NULL, const char *b3txt=NULL, bool preserve=false); - int Process(int msg, int b1txt=TXT_OK, int b2txt=TXT_NONE, int b3txt=TXT_NONE, bool preserve=false); - int Process(char const *msg, int b1txt=TXT_OK, int b2txt=TXT_NONE, int b3txt=TXT_NONE, bool preserve=false); -}; - -#endif diff --git a/code/TIBERIANDAWN/MSGLIST.CPP b/code/TIBERIANDAWN/MSGLIST.CPP deleted file mode 100644 index a9e1e80..0000000 --- a/code/TIBERIANDAWN/MSGLIST.CPP +++ /dev/null @@ -1,809 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\msglist.cpv 1.4 16 Oct 1995 16:48:20 JOE_BOSTIC $ */ -/*************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MSGLIST.CPP * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 05/22/95 * - * * - * Last Update : June 26, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * MessageListClass::Add_Edit -- Adds editable string to message list * - * MessageListClass::Add_Message -- displays the given message * - * MessageListClass::Draw -- Draws the messages * - * MessageListClass::Get_Edit_Buf -- gets edit buffer * - * MessageListClass::Init -- Inits message system, sets options * - * MessageListClass::Input -- Handles input for sending messages * - * MessageListClass::Manage -- Manages multiplayer messages * - * MessageListClass::MessageListClass -- constructor * - * MessageListClass::~MessageListClass -- destructor * - * MessageListClass::Num_Messages -- returns # messages in the list * - * MessageListClass::Set_Width -- sets allowable width of messages * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -// ST = 12/17/2018 5:44PM -#ifndef TickCount -extern TimerClass TickCount; -#endif - -char MessageListClass::MessageBuffers[MAX_NUM_MESSAGES][MAX_MESSAGE_LENGTH + 30]; -char MessageListClass::BufferAvail[MAX_NUM_MESSAGES]; - -/*************************************************************************** - * MessageListClass::MessageListClass -- constructor * - * * - * INPUT: * - * x,y coord of upper-left of top message * - * max_msg max messages allowed, including edit message * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/21/1995 BRR : Created. * - *=========================================================================*/ -MessageListClass::MessageListClass(void) -{ - int i; - - MessageList = 0; - MessageX = 0; - MessageY = 0; - MaxMessages = 0; - MaxChars = 0; - Height = 0; - EditLabel = 0; - EditBuf = 0; - EditCurPos = 0; - EditInitPos = 0; - - for (i = 0; i < MAX_NUM_MESSAGES; i++) { - BufferAvail[i] = 1; - } - -} - - -/*************************************************************************** - * MessageListClass::~MessageListClass -- destructor * - * * - * INPUT: * - * x,y coord of upper-left of top message * - * max_msg max messages allowed, including edit message * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/21/1995 BRR : Created. * - *=========================================================================*/ -MessageListClass::~MessageListClass() -{ - Init(0,0,0,0,0); -} - - -/*************************************************************************** - * MessageListClass::Init -- Inits message system, sets options * - * * - * INPUT: * - * x,y coord of upper-left of top message * - * max_msg max messages allowed, including edit message * - * maxchars max # characters allowed per message * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/21/1995 BRR : Created. * - *=========================================================================*/ -void MessageListClass::Init(int x, int y, int max_msg, int maxchars, int height) -{ - TextLabelClass *txtlabel; - int i; - - /*------------------------------------------------------------------------ - Remove every entry in the list - ------------------------------------------------------------------------*/ - txtlabel = MessageList; - while (txtlabel) { - MessageList = (TextLabelClass *)txtlabel->Remove(); - delete txtlabel; - txtlabel = MessageList; - } - - /*------------------------------------------------------------------------ - Mark all buffers as available - ------------------------------------------------------------------------*/ - for (i = 0; i < MAX_NUM_MESSAGES; i++) { - BufferAvail[i] = 1; - } - - /*------------------------------------------------------------------------ - Init variables - ------------------------------------------------------------------------*/ - MessageList = 0; - MessageX = x; - MessageY = y; - - MaxMessages = max_msg; - if (MaxMessages > MAX_NUM_MESSAGES) - MaxMessages = MAX_NUM_MESSAGES; - - MaxChars = maxchars; - if (MaxChars > MAX_MESSAGE_LENGTH) - MaxChars = MAX_MESSAGE_LENGTH; - - Height = height; - EditLabel = 0; - EditBuf = 0; - EditCurPos = 0; - EditInitPos = 0; -} - - -/*************************************************************************** - * MessageListClass::Add_Message -- displays the given message * - * * - * INPUT: * - * txt text to display * - * color color to draw text in * - * style style to use * - * timeout # of ticks the thing is supposed to last (-1 = forever)* - * * - * OUTPUT: * - * ptr to new TextLabelClass object. * - * * - * WARNINGS: * - * The TextLabelClass's text buffer is free'd when the class is free'd, * - * so never pass it a static buffer. * - * * - * HISTORY: * - * 05/05/1995 BRR : Created. * - *=========================================================================*/ -TextLabelClass * MessageListClass::Add_Message(char *txt, int color, - TextPrintType style, int timeout, unsigned short magic_number, unsigned short crc) -{ - int num_msg; - TextLabelClass *txtlabel; - int x,y; - GadgetClass *gadg; - int i,j; - int found; - int position; - char *raw_string; - char *current_string; - char *s1,*s2; - bool same; -#if (0) -#if (GERMAN) - static int from_adjust = -1; -#else -#if (FRENCH) - static int from_adjust = -2; -#else - static int from_adjust = 0; -#endif -#endif -#endif //(0) - - /*------------------------------------------------------------------------ - Prevent a duplicate message. (The IPXManager Global Channel cannot detect - a resend of a packet, so sometimes two identical messages appear in a row.) - ------------------------------------------------------------------------*/ - if (MessageList) { - txtlabel = MessageList; - while (txtlabel) { - /* - ** Dont check for duplicates in multi-segment strings - */ - if (!txtlabel->Segments){ - if (!strcmp (txtlabel->Text,txt) && txtlabel->Color == color && - txtlabel->Style == style) { - return(txtlabel); - } - } - txtlabel = (TextLabelClass *)txtlabel->Get_Next(); - } - } - - - /* - ** If the magic number is a valid message tail then see if we - ** can add this message to the tail of an existing message (crc's must also match) - */ - if (magic_number > MESSAGE_HEAD_MAGIC_NUMBER && - magic_number < MESSAGE_HEAD_MAGIC_NUMBER+MAX_MESSAGE_SEGMENTS){ - - position = magic_number - MESSAGE_HEAD_MAGIC_NUMBER; - txtlabel = MessageList; - - while (txtlabel) { - if (txtlabel->Color == color && txtlabel->Style == style && txtlabel->CRC == crc) { - - same = true; - - s1 = strchr(txtlabel->Text, ':'); - s2 = strchr(txt, ':'); - - if (s1 && s2){ - *s1 = 0; - *s2 = 0; - - same = !strcmp (txtlabel->Text, txt); - - *s1 = ':'; - *s2 = ':'; - } - - if (same){ - - /* - ** If this message segment hasnt already come through then add it to the existing text - */ - if (! (txtlabel->Segments & (1 << position)) ) { - /* - ** Search for the ':' to find the actual message after the players name - */ - raw_string = s2; - current_string = s1; - if (raw_string++ && current_string++){ - memcpy (current_string + (position*(COMPAT_MESSAGE_LENGTH-5))/*+from_adjust*/, raw_string, COMPAT_MESSAGE_LENGTH-4); - /* - ** Flag this string segment as complete - */ - txtlabel->Segments |= 1<Get_Next(); - } - } - - - - /*------------------------------------------------------------------------ - Count the # of messages; if MaxMessages is going to be exceeded, remove - the top-most message. - ------------------------------------------------------------------------*/ - num_msg = 0; - if (MessageList) { - gadg = MessageList; - while (gadg) { - num_msg++; - gadg = gadg->Get_Next(); - } - } - /*........................................................................ - Remove the top-most message, but don't remove the edit message. - ........................................................................*/ - if ( (MaxMessages > 0) && ((num_msg + 1) > MaxMessages)) { - txtlabel = MessageList; - /*..................................................................... - If the top label is the edit label, go to the next one; if there is - no next one, just return. - .....................................................................*/ - if (txtlabel == EditLabel) - txtlabel = (TextLabelClass *)txtlabel->Get_Next(); - if (txtlabel==NULL) - return(NULL); - - /*..................................................................... - Remove this message from the list; mark its buffer as being available. - .....................................................................*/ - MessageList = (TextLabelClass *)txtlabel->Remove(); - for (i = 0; i < MAX_NUM_MESSAGES; i++) { - if (txtlabel->Text == MessageBuffers[i]) - BufferAvail[i] = 1; - } - delete txtlabel; - - /*..................................................................... - Recompute everyone's y-coordinate - .....................................................................*/ - y = MessageY; - if (MessageList) { - gadg = MessageList; - while (gadg) { - gadg->Y = y; - gadg = gadg->Get_Next(); - y += Height; - } - } - } - - /*------------------------------------------------------------------------ - Figure out the message's y-coordinate; put it below the other messages - ------------------------------------------------------------------------*/ - x = MessageX; - y = MessageY; - if (MessageList) { - gadg = MessageList; - while (gadg) { - gadg = gadg->Get_Next(); - y += Height; - } - } - - /*------------------------------------------------------------------------ - Create the message - ------------------------------------------------------------------------*/ - txtlabel = new TextLabelClass (txt, x, y, color, style); - if (timeout==-1) { - txtlabel->UserData = 0; - } else { - txtlabel->UserData = TickCount.Time() + timeout; - } - - /*------------------------------------------------------------------------ - Find a buffer to store our message in; if there are none, don't add the - message. - ------------------------------------------------------------------------*/ - found = 0; - txtlabel->Segments = 0; - txtlabel->CRC = crc; - - for (i = 0; i < MAX_NUM_MESSAGES; i++) { - if (BufferAvail[i]) { - BufferAvail[i] = 0; - memset (MessageBuffers[i],0,MAX_MESSAGE_LENGTH + 30); - strcpy (MessageBuffers[i],txt); - - /* - ** If this is a segment from a larger message then put it in the right place - ** in the buffer and clear out the rest with spaces - */ - if (magic_number >= MESSAGE_HEAD_MAGIC_NUMBER && - magic_number < MESSAGE_HEAD_MAGIC_NUMBER+MAX_MESSAGE_SEGMENTS){ - raw_string = strchr(txt, ':'); - char *dest_str = strchr(MessageBuffers[i], ':'); - if (dest_str){ - dest_str++; - }else{ - dest_str = MessageBuffers[i]; - } - - if (raw_string++){ - for (j=0 ; j<3 ; j++){ - if (! ((magic_number - j) == MESSAGE_HEAD_MAGIC_NUMBER)){ - memset (dest_str + j*(COMPAT_MESSAGE_LENGTH-4)/*+from_adjust*/, 32, COMPAT_MESSAGE_LENGTH-4); - }else{ - strcpy(dest_str + j*(COMPAT_MESSAGE_LENGTH-4)/*+from_adjust*/, raw_string); - } - } - *(dest_str +((COMPAT_MESSAGE_LENGTH-4)*MAX_MESSAGE_SEGMENTS-1)) = 0; - - } - position = magic_number - MESSAGE_HEAD_MAGIC_NUMBER; - txtlabel->Segments = 1<Text = MessageBuffers[i]; - found = 1; - break; - } - } - if (!found) { - delete txtlabel; - return (NULL); - } - - /*------------------------------------------------------------------------ - Attach the message to our list - ------------------------------------------------------------------------*/ - if (MessageList) { - txtlabel->Add_Tail (*MessageList); - } else { - MessageList = txtlabel; - } - - return(txtlabel); -} - - -/*************************************************************************** - * MessageListClass::Add_Edit -- Adds editable string to message list * - * * - * INPUT: * - * color color of edit message * - * style style of edit message * - * to string: who to send to * - * width width of editbox in pixels * - * * - * OUTPUT: * - * ptr to new TextLabelClass * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/22/1995 BRR : Created. * - *=========================================================================*/ -TextLabelClass * MessageListClass::Add_Edit(int color, TextPrintType style, - char *to, int width) -{ - /*------------------------------------------------------------------------ - Do nothing if we're already in "edit" mode - ------------------------------------------------------------------------*/ - if (EditLabel) - return(NULL); - - /*------------------------------------------------------------------------ - Initialize the buffer positions; add a new label to the label list. - ------------------------------------------------------------------------*/ - EditCurPos = EditInitPos = strlen(to); - EditLabel = Add_Message (to, color, style, -1, 0, 0); - Width = width; - - /*------------------------------------------------------------------------ - Save our edit buffer pointer. - ------------------------------------------------------------------------*/ - if (EditLabel) - EditBuf = EditLabel->Text; - else - EditBuf = NULL; - - return(EditLabel); -} - - -/*************************************************************************** - * MessageListClass::Get_Edit_Buf -- gets edit buffer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * ptr to edit buffer, minus the "To:" header * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/21/1995 BRR : Created. * - *=========================================================================*/ -char * MessageListClass::Get_Edit_Buf(void) -{ - if (!EditBuf) - return(NULL); - - return(EditBuf + EditInitPos); -} - - -/*************************************************************************** - * MessageListClass::Manage -- Manages multiplayer messages * - * * - * If this routine returns TRUE, the caller should update the display. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * 0 = no change has occurred, 1 = changed * - * * - * HISTORY: * - * 05/05/1995 BRR : Created. * - *=========================================================================*/ -int MessageListClass::Manage (void) -{ - TextLabelClass *txtlabel; - TextLabelClass *next; - int changed = 0; - int y; - GadgetClass *gadg; - int i; - - /*------------------------------------------------------------------------ - Loop through all messages - ------------------------------------------------------------------------*/ - txtlabel = MessageList; - while (txtlabel) { - /*..................................................................... - If this message's time is up, remove it from the list - .....................................................................*/ - if (txtlabel->UserData != 0 && (unsigned)TickCount.Time() > txtlabel->UserData) { - /*.................................................................. - If we're about to delete the edit message, clear our edit message - values. - ..................................................................*/ - if (txtlabel == EditLabel) { - EditLabel = 0; - EditBuf = 0; - } - /*.................................................................. - Save the next ptr in the list; remove this entry - ..................................................................*/ - next = (TextLabelClass *)txtlabel->Get_Next(); - MessageList = (TextLabelClass *)txtlabel->Remove(); - for (i = 0; i < MAX_NUM_MESSAGES; i++) { - if (txtlabel->Text == MessageBuffers[i]) - BufferAvail[i] = 1; - } - delete txtlabel; - changed = 1; - txtlabel = next; - } else { - txtlabel = (TextLabelClass *)txtlabel->Get_Next(); - } - } - - /*------------------------------------------------------------------------ - If a changed has been made, recompute the y-coord of all messages - ------------------------------------------------------------------------*/ - if (changed) { - - y = MessageY; - if (MessageList) { - gadg = MessageList; - while (gadg) { - gadg->Y = y; - gadg = gadg->Get_Next(); - y += Height; - } - } - } - - return(changed); -} - - -/*************************************************************************** - * MessageListClass::Input -- Handles input for sending messages * - * * - * INPUT: * - * input key value to process * - * * - * OUTPUT: * - * 1 = caller should redraw the message list (no need to complete * - * refresh, though) * - * 2 = caller should completely refresh the display. * - * 3 = caller should send the edit message. * - * (sets 'input' to 0 if it processes it.) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/05/1995 BRR : Created. * - *=========================================================================*/ -int MessageListClass::Input(KeyNumType &input) -{ - KeyASCIIType ascii; - int retcode = 0; - - /*------------------------------------------------------------------------ - Do nothing if nothing to do. - ------------------------------------------------------------------------*/ - if (input == KN_NONE) - return(0); - - /*------------------------------------------------------------------------ - Leave mouse events alone. - ------------------------------------------------------------------------*/ - if ( (input & (~KN_RLSE_BIT))==KN_LMOUSE || - (input & (~KN_RLSE_BIT))==KN_RMOUSE) - return(0); - - /*------------------------------------------------------------------------ - If we're in 'edit mode', handle keys - ------------------------------------------------------------------------*/ - if (EditLabel) { - ascii = (KeyASCIIType)(Keyboard::To_ASCII(input) & 0x00ff); - - /* - ** Allow numeric keypad presses to map to ascii numbers - */ - if ((input & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9') { - - input = (KeyNumType)(input & ~WWKEY_VK_BIT); - - } else { - /* - ** Filter out all special keys except return, escape and backspace - */ - if ((!(input & WWKEY_VK_BIT) && !(input & KN_BUTTON) - && ascii >= ' ' && ascii <= 127) - || (input & 0xff)== (KN_RETURN & 0xff) - || (input & 0xff)== (KN_BACKSPACE & 0xff) - || (input & 0xff)== (KN_ESC & 0xff) ) { - - //ascii = (KeyASCIIType)(Keyboard->To_ASCII(input)); - } else { - input = KN_NONE; - return (0); - } - } - - - switch (ascii) { - /*------------------------------------------------------------------ - ESC = abort message - ------------------------------------------------------------------*/ - case KA_ESC & 0xff: - EditLabel->UserData = 1; // force it to be removed - input = KN_NONE; - break; - - /*------------------------------------------------------------------ - RETURN = send the message - ------------------------------------------------------------------*/ - case KA_RETURN & 0xff: - EditLabel->UserData = 1; // force it to be removed - retcode = 3; - input = KN_NONE; - break; - - /*------------------------------------------------------------------ - BACKSPACE = remove a character - ------------------------------------------------------------------*/ - case KA_BACKSPACE & 0xff: - if (EditCurPos > EditInitPos) { - EditCurPos--; - EditBuf[EditCurPos] = 0; - retcode = 2; - } - input = KN_NONE; - break; - - /*------------------------------------------------------------------ - default: add a character. Reserve the last buffer position for null. - (EditCurPos - EditInitPos) is the buffer index # of the next - character, after the "To:" prefix. - ------------------------------------------------------------------*/ - default: - if ( (EditCurPos - EditInitPos) < (MaxChars - 1) ) { - if (!(input & WWKEY_VK_BIT) && ascii >= ' ' && ascii <= 127) { - EditBuf[EditCurPos] = ascii; - EditCurPos++; - retcode = 1; - - /* - ** Verify that the additional character would not overrun the on screen edit box. - */ - Fancy_Text_Print(TXT_NONE, 0, 0, EditLabel->Color, TBLACK, EditLabel->Style); - int width = String_Pixel_Width(EditBuf); - if (width >= Width){ - EditBuf[EditCurPos--] = 0; - retcode = 0; - } - - } - } - input = KN_NONE; - break; - } - } - - return(retcode); -} - - -/*************************************************************************** - * MessageListClass::Draw -- draws messages * - * * - * INPUT: * - * none * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/22/1995 BRR : Created. * - *=========================================================================*/ -void MessageListClass::Draw(void) -{ - if (MessageList) { - Hide_Mouse(); - MessageList->Draw_All(); - Show_Mouse(); - } -} - - -/*************************************************************************** - * MessageListClass::Num_Messages -- returns # messages in the list * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * # of messages * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/26/1995 BRR : Created. * - *=========================================================================*/ -int MessageListClass::Num_Messages(void) -{ - GadgetClass *gadg; - int num; - - num = 0; - - if (MessageList) { - gadg = MessageList; - while (gadg) { - num++; - gadg = gadg->Get_Next(); - } - } - - return (num); -} - - -/*************************************************************************** - * MessageListClass::Set_Width -- sets allowable width of messages * - * * - * INPUT: * - * width pixel width * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/26/1995 BRR : Created. * - *=========================================================================*/ -void MessageListClass::Set_Width(int width) -{ - GadgetClass *gadg; - - if (MessageList) { - gadg = MessageList; - while (gadg) { - ((TextLabelClass *)gadg)->PixWidth = width; - gadg = gadg->Get_Next(); - } - } -} - diff --git a/code/TIBERIANDAWN/MSGLIST.H b/code/TIBERIANDAWN/MSGLIST.H deleted file mode 100644 index 0786461..0000000 --- a/code/TIBERIANDAWN/MSGLIST.H +++ /dev/null @@ -1,106 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MSGLIST.H * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 05/22/95 * - * * - * Last Update : May 22, 1995 [BRR] * - * * - * How the messages work: * - * - MPlayerMessageList is a gadget list of all current messages * - * - MPlayerMessageX & Y are the upper left corner of the 1st message * - * - MPlayerMaxMessages is the max # of messages allowed, including * - * the editable message; 0 = no limit. * - * - EditLabel points to the textmessage gadget for the current editable * - * field. EditBuf points to the char buffer being edited. EditInitPos * - * & EditCurPos define buffer index positions. * - * - EditSendAddress is the IPX Address to send the message to when RETURN * - * is pressed. * - * * - * The UserData field in the TextLabelClass tells what the timeout for * - * each message is (0 = none). * - * When a message's timeout expires, it's deleted. When a new message * - * is added, the top message is deleted if MPlayerMaxMessages is exceeded. * - * * - * The Edit-able message is never deleted until ESC or RETURN is pressed. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MSGLIST_H -#define MSGLIST_H - -/* -** Class declaration -*/ -class MessageListClass { - public: - /* - ** Constructor/Destructor - */ - MessageListClass (void); - ~MessageListClass (); - - /* - ** Initialization - */ - void Init (int x, int y, int max_msg, int maxchars, int height); - TextLabelClass * Add_Message (char *txt, int color, TextPrintType style, int timeout, - unsigned short magic_number, unsigned short crc); - - /* - ** Message-editing routines - */ - TextLabelClass * Add_Edit (int color, TextPrintType style, char *to, int width); - char * Get_Edit_Buf (void); - - /* - ** Maintenance routines - */ - int Manage (void); - int Input (KeyNumType &input); - void Draw(void); - int Num_Messages(void); - void Set_Width(int width); - - private: - TextLabelClass * MessageList; // list of messages - int MessageX; // x-coord of upper-left - int MessageY; // y-coord of upper-left - int MaxMessages; // max messages allowed - int MaxChars; // max allowed chars per message - int Height; // height in pixels - TextLabelClass *EditLabel; // ptr to current edit label - char *EditBuf; // ptr to current edit buffer - int EditCurPos; // current edit position - int EditInitPos; // initial edit position - int Width; // Maximum width in pixels of editable string - - /* - ** Static buffers provided for messages. They must be long enough for - ** both the message, and for the "To" prefix on edited messages, or - ** the "From:" prefix on received messages. - */ - static char MessageBuffers[MAX_NUM_MESSAGES][MAX_MESSAGE_LENGTH + 30]; - static char BufferAvail[MAX_NUM_MESSAGES]; -}; - -#endif diff --git a/code/TIBERIANDAWN/MiscAsm.cpp b/code/TIBERIANDAWN/MiscAsm.cpp deleted file mode 100644 index 2aea545..0000000 --- a/code/TIBERIANDAWN/MiscAsm.cpp +++ /dev/null @@ -1,1578 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/* -** -** Misc. assembly code moved from headers -** -** -** -** -** -*/ - -#include "FUNCTION.H" - - - -extern "C" void __cdecl Mem_Copy(void const *source, void *dest, unsigned long bytes_to_copy) -{ - memcpy(dest, source, bytes_to_copy); -} - - -/*********************************************************************************************** - * Distance -- Determines the lepton distance between two coordinates. * - * * - * This routine is used to determine the distance between two coordinates. It uses the * - * Dragon Strike method of distance determination and thus it is very fast. * - * * - * INPUT: coord1 -- First coordinate. * - * * - * coord2 -- Second coordinate. * - * * - * OUTPUT: Returns the lepton distance between the two coordinates. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -int Distance_Coord(COORDINATE coord1, COORDINATE coord2) -{ - __asm { - mov eax,[coord1] - mov ebx,[coord2] - mov dx,ax - sub dx,bx - jg okx - neg dx - okx: - shr eax,16 - shr ebx,16 - sub ax,bx - jg oky - neg ax -oky: - cmp ax,dx - jg ok - xchg ax,dx -ok: - shr dx,1 - add ax,dx - } -} - - - - -/* -;*************************************************************************** -;* DESIRED_FACING16 -- Converts coordinates into a facing number. * -;* * -;* This converts coordinates into a desired facing number that ranges * -;* from 0 to 15 (0 equals North and going clockwise). * -;* * -;* INPUT: x1,y1 -- Position of origin point. * -;* * -;* x2,y2 -- Position of target. * -;* * -;* OUTPUT: Returns desired facing as a number from 0 to 255 but * -;* accurate to 22.5 degree increments. * -;* * -;* WARNINGS: If the two coordinates are the same, then -1 will be * -;* returned. It is up to you to handle this case. * -;* * -;* HISTORY: * -;* 08/14/1991 JLB : Created. * -;*=========================================================================* -*/ - -long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2) -{ - static const char _new_facing16[] = { - 3, 2, 4,-1, 1, 2,0,-1, - 13,14,12,-1,15,14,0,-1, - 5, 6, 4,-1, 7, 6,8,-1, - 11,10,12,-1, 9,10,8,-1 - }; - - - __asm { - xor ebx,ebx //; Index byte (built). - - //; Determine Y axis difference. - mov edx,[y1] - mov ecx,[y2] - sub edx,ecx //; DX = Y axis (signed). - jns short absy - inc ebx //; Set the signed bit. - neg edx //; ABS(y) -absy: - - //; Determine X axis difference. - shl ebx,1 - mov eax,[x1] - mov ecx,[x2] - sub ecx,eax //; CX = X axis (signed). - jns short absx - inc ebx //; Set the signed bit. - neg ecx //; ABS(x) -absx: - - //; Determine the greater axis. - cmp ecx,edx - jb short dxisbig - xchg ecx,edx -dxisbig: - rcl ebx,1 //; Y > X flag bit. - - //; Determine the closeness or farness of lesser axis. - mov eax,edx - inc eax //; Round up. - shr eax,1 - inc eax //; Round up. - shr eax,1 //; 1/4 of greater axis. - - cmp ecx,eax - rcl ebx,1 //; Very close to major axis bit. - - sub edx,eax - cmp edx,ecx - rcl ebx,1 //; Very far from major axis bit. - - xor eax,eax - mov al,[_new_facing16+ebx] - - //; Normalize to 0..FF range. - shl eax,4 - -// ret - } -} - - - - - - - - - - - - - - - -/* -;*************************************************************************** -;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. * -;* * -;* This is a desired facing algorithm that has a resolution of 0 * -;* through 255. * -;* * -;* INPUT: srcx,srcy -- Source coordinate. * -;* * -;* dstx,dsty -- Destination coordinate. * -;* * -;* OUTPUT: Returns with the desired facing to face the destination * -;* coordinate from the position of the source coordinate. North * -;* is 0, East is 64, etc. * -;* * -;* WARNINGS: This routine is slower than the other forms of desired * -;* facing calculation. Use this routine when accuracy is * -;* required. * -;* * -;* HISTORY: * -;* 12/24/1991 JLB : Adapted. * -;*=========================================================================*/ - -int __cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty) -{ - - __asm { - xor ebx,ebx //; Facing number. - - ////; Determine absolute X delta and left/right direction. - mov ecx,[dstx] - sub ecx,[srcx] - jge short xnotneg - neg ecx - mov ebx,11000000b //; Set bit 7 and 6 for leftward. -xnotneg: - - //; Determine absolute Y delta and top/bottom direction. - mov eax,[srcy] - sub eax,[dsty] - jge short ynotneg - xor ebx,01000000b //; Complement bit 6 for downward. - neg eax -ynotneg: - - //; Set DX=64 for quadrants 0 and 2. - mov edx,ebx - and edx,01000000b - xor edx,01000000b - - //; Determine if the direction is closer to the Y axis and make sure that - //; CX holds the larger of the two deltas. This is in preparation for the - //; divide. - cmp eax,ecx - jb short gotaxis - xchg eax,ecx - xor edx,01000000b //; Closer to Y axis so make DX=64 for quad 0 and 2. -gotaxis: - - //; If closer to the X axis then add 64 for quadrants 0 and 2. If - //; closer to the Y axis then add 64 for quadrants 1 and 3. Determined - //; add value is in DX and save on stack. - push edx - - //; Make sure that the division won't overflow. Reduce precision until - //; the larger number is less than 256 if it appears that an overflow - //; will occur. If the high byte of the divisor is not zero, then this - //; guarantees no overflow, so just abort shift operation. - test eax,0FFFFFF00h - jnz short nooverflow -again: - test ecx,0FFFFFF00h - jz short nooverflow - shr ecx,1 - shr eax,1 - jmp short again -nooverflow: - - //; Make sure that the division won't underflow (divide by zero). If - //; this would occur, then set the quotient to $FF and skip divide. - or ecx,ecx - jnz short nounderflow - mov eax,0FFFFFFFFh - jmp short divcomplete - - //; Derive a pseudo angle number for the octant. The angle is based - //; on $00 = angle matches long axis, $00 = angle matches $FF degrees. -nounderflow: - xor edx,edx - shld edx,eax,8 //; shift high byte of eax into dl - shl eax,8 - div ecx -divcomplete: - - //; Integrate the 5 most significant bits into the angle index. If DX - //; is not zero, then it is 64. This means that the dividend must be negated - //; before it is added into the final angle value. - shr eax,3 - pop edx - or edx,edx - je short noneg - dec edx - neg eax -noneg: - add eax,edx - add eax,ebx - and eax,0FFH -// ret - } -} - - - - - - - - - - - - -/* - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : FACING8.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 8, 1991 * -;* * -;* Last Update : February 6, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Desired_Facing8 -- Determines facing to reach a position. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Desired_Facing8 :NEAR -; INCLUDE "wwlib.i" - - DATASEG - -; 8 direction desired facing lookup table. Build the index according -; to the following bits: -; -; bit 3 = Is y2 < y1? -; bit 2 = Is x2 < x1? -; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)? -; bit 0 = Is the facing closer to a major axis? -//NewFacing8 DB 1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4 - -// CODESEG -*/ - -/* -;*************************************************************************** -;* DESIRED_FACING8 -- Determines facing to reach a position. * -;* * -;* This routine will return with the most desirable facing to reach * -;* one position from another. It is accurate to a resolution of 0 to * -;* 7. * -;* * -;* INPUT: x1,y1 -- Position of origin point. * -;* * -;* x2,y2 -- Position of target. * -;* * -;* OUTPUT: Returns desired facing as a number from 0..255 with an * -;* accuracy of 32 degree increments. * -;* * -;* WARNINGS: If the two coordinates are the same, then -1 will be * -;* returned. It is up to you to handle this case. * -;* * -;* HISTORY: * -;* 07/15/1991 JLB : Documented. * -;* 08/08/1991 JLB : Same position check. * -;* 08/14/1991 JLB : New algorithm * -;* 02/06/1995 BWG : Convert to 32-bit * -;*=========================================================================* -*/ -int __cdecl Desired_Facing8(long x1, long y1, long x2, long y2) -{ - - static const char _new_facing8[] = {1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4}; - - __asm { - - xor ebx,ebx //; Index byte (built). - - //; Determine Y axis difference. - mov edx,[y1] - mov ecx,[y2] - sub edx,ecx //; DX = Y axis (signed). - jns short absy - inc ebx //; Set the signed bit. - neg edx //; ABS(y) -absy: - - //; Determine X axis difference. - shl ebx,1 - mov eax,[x1] - mov ecx,[x2] - sub ecx,eax //; CX = X axis (signed). - jns short absx - inc ebx //; Set the signed bit. - neg ecx //; ABS(x) -absx: - - //; Determine the greater axis. - cmp ecx,edx - jb short dxisbig - xchg ecx,edx -dxisbig: - rcl ebx,1 //; Y > X flag bit. - - //; Determine the closeness or farness of lesser axis. - mov eax,edx - inc eax //; Round up. - shr eax,1 - - cmp ecx,eax - rcl ebx,1 //; Close to major axis bit. - - xor eax,eax - mov al,[_new_facing8+ebx] - - //; Normalize to 0..FF range. - shl eax,5 - -// ret - - } - -} - - - -#if (0) - -/* - ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/MiscAsm.cpp#57 $ -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : FACING16.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 8, 1991 * -;* * -;* Last Update : February 6, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Desired_Facing16 -- Converts coordinates into a facing number. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Desired_Facing16 :NEAR -; INCLUDE "wwlib.i" - - DATASEG - -; 16 direction desired facing lookup table. Build the index according -; to the following bits: -; -; bit 4 = Is y2 < y1? -; bit 3 = Is x2 < x1? -; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)? -; bit 1 = Is the lesser absolute difference very close to zero? -; bit 0 = Is the lesser absolute difference very close to the greater dist? -NewFacing16 DB 3, 2, 4,-1, 1, 2,0,-1 - DB 13,14,12,-1,15,14,0,-1 - DB 5, 6, 4,-1, 7, 6,8,-1 - DB 11,10,12,-1, 9,10,8,-1 - - CODESEG - -;*************************************************************************** -;* DESIRED_FACING16 -- Converts coordinates into a facing number. * -;* * -;* This converts coordinates into a desired facing number that ranges * -;* from 0 to 15 (0 equals North and going clockwise). * -;* * -;* INPUT: x1,y1 -- Position of origin point. * -;* * -;* x2,y2 -- Position of target. * -;* * -;* OUTPUT: Returns desired facing as a number from 0 to 255 but * -;* accurate to 22.5 degree increments. * -;* * -;* WARNINGS: If the two coordinates are the same, then -1 will be * -;* returned. It is up to you to handle this case. * -;* * -;* HISTORY: * -;* 08/14/1991 JLB : Created. * -;*=========================================================================* -*/ -long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2) -{ - - __asm { - xor ebx,ebx ; Index byte (built). - - ; Determine Y axis difference. - mov edx,[y1] - mov ecx,[y2] - sub edx,ecx //; DX = Y axis (signed). - jns short absy - inc ebx //; Set the signed bit. - neg edx //; ABS(y) -absy: - - //; Determine X axis difference. - shl ebx,1 - mov eax,[x1] - mov ecx,[x2] - sub ecx,eax //; CX = X axis (signed). - jns short absx - inc ebx //; Set the signed bit. - neg ecx //; ABS(x) -absx: - - //; Determine the greater axis. - cmp ecx,edx - jb short dxisbig - xchg ecx,edx -dxisbig: - rcl ebx,1 //; Y > X flag bit. - - //; Determine the closeness or farness of lesser axis. - mov eax,edx - inc eax //; Round up. - shr eax,1 - inc eax //; Round up. - shr eax,1 //; 1/4 of greater axis. - - cmp ecx,eax - rcl ebx,1 //; Very close to major axis bit. - - sub edx,eax - cmp edx,ecx - rcl ebx,1 //; Very far from major axis bit. - - xor eax,eax - mov al,[NewFacing16+ebx] - - //; Normalize to 0..FF range. - shl eax,4 - -// ret - } -} - - - - -#if (0) - PROC Desired_Facing16 C near - USES ebx, ecx, edx - - ARG x1:DWORD - ARG y1:DWORD - ARG x2:DWORD - ARG y2:DWORD - - xor ebx,ebx ; Index byte (built). - - ; Determine Y axis difference. - mov edx,[y1] - mov ecx,[y2] - sub edx,ecx ; DX = Y axis (signed). - jns short ??absy - inc ebx ; Set the signed bit. - neg edx ; ABS(y) -??absy: - - ; Determine X axis difference. - shl ebx,1 - mov eax,[x1] - mov ecx,[x2] - sub ecx,eax ; CX = X axis (signed). - jns short ??absx - inc ebx ; Set the signed bit. - neg ecx ; ABS(x) -??absx: - - ; Determine the greater axis. - cmp ecx,edx - jb short ??dxisbig - xchg ecx,edx -??dxisbig: - rcl ebx,1 ; Y > X flag bit. - - ; Determine the closeness or farness of lesser axis. - mov eax,edx - inc eax ; Round up. - shr eax,1 - inc eax ; Round up. - shr eax,1 ; 1/4 of greater axis. - - cmp ecx,eax - rcl ebx,1 ; Very close to major axis bit. - - sub edx,eax - cmp edx,ecx - rcl ebx,1 ; Very far from major axis bit. - - xor eax,eax - mov al,[NewFacing16+ebx] - - ; Normalize to 0..FF range. - shl eax,4 - - ret - - ENDP Desired_Facing16 - - END -#endif -#endif - - - - - - - - - - - - - - - - -/* -;*********************************************************************************************** -;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. * -;* * -;* This utility function will convert cardinal numbers into a fixed point fraction. The * -;* use of fixed point numbers occurs throughout the product -- since it is a convenient * -;* tool. The fixed point number is based on the formula: * -;* * -;* result = cardinal / base * -;* * -;* The accuracy of the fixed point number is limited to 1/256 as the lowest and up to * -;* 256 as the largest. * -;* * -;* INPUT: base -- The key number to base the fraction about. * -;* * -;* cardinal -- The other number (hey -- what do you call it?) * -;* * -;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates * -;* to the "base" parameter. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 02/17/1995 BWG : Created. * -;*=============================================================================================*/ - -unsigned int __cdecl Cardinal_To_Fixed(unsigned base, unsigned cardinal) -{ - __asm { - - mov eax,0FFFFh //; establish default return value - - mov ebx,[base] - or ebx, ebx - jz retneg1 //; if base==0, return 65535 - - mov eax,[cardinal] //; otherwise, return (cardinal*256)/base - shl eax,8 - xor edx,edx - div ebx - -retneg1: - //ret - - - } -} - -#if (0) - PROC Cardinal_To_Fixed C near - USES ebx, edx - - ARG base:DWORD - ARG cardinal:DWORD - - mov eax,0FFFFh ; establish default return value - - mov ebx,[base] - or ebx,ebx - jz near ??retneg1 ; if base==0, return 65535 - - mov eax,[cardinal] ; otherwise, return (cardinal*256)/base - shl eax,8 - xor edx,edx - div ebx - -??retneg1: - ret - - ENDP Cardinal_To_Fixed -#endif - -/* -;*********************************************************************************************** -;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. * -;* * -;* Use this routine to convert a fixed point number into a cardinal number. * -;* * -;* INPUT: base -- The base number that the original fixed point number was created from. * -;* * -;* fixed -- The fixed point number to convert. * -;* * -;* OUTPUT: Returns with the reconverted number. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 02/17/1995 BWG : Created. * -;*=============================================================================================*/ - -unsigned int __cdecl Fixed_To_Cardinal(unsigned base, unsigned fixed) -{ -// PROC Fixed_To_Cardinal C near -// USES edx - -// ARG base:DWORD -// ARG fixed:DWORD - - __asm { - mov eax,[base] - mul [fixed] - add eax,080h //; eax = (base * fixed) + 0x80 - - test eax,0FF000000h //; if high byte set, return FFFF - jnz rneg1 - shr eax,8 //; else, return eax/256 - jmp all_done -rneg1: - mov eax,0FFFFh //; establish default return value -all_done: - //ret - } - - -#if (0) - mov eax,[base] - mul [fixed] - add eax,080h ; eax = (base * fixed) + 0x80 - - test eax,0FF000000h ; if high byte set, return FFFF - jnz ??rneg1 - shr eax,8 ; else, return eax/256 - ret -??rneg1 : - mov eax,0FFFFh ; establish default return value - ret - - ENDP Fixed_To_Cardinal - - END -#endif - - -} - - - - - - - - - - - - - - - -void __cdecl Set_Bit(void * array, int bit, int value) -{ - __asm { - mov ecx, [bit] - mov eax, [value] - mov esi, [array] - mov ebx,ecx - shr ebx,5 - and ecx,01Fh - btr [esi+ebx*4],ecx - or eax,eax - jz ok - bts [esi+ebx*4],ecx -ok: - } -} - - -int __cdecl Get_Bit(void const * array, int bit) -{ - __asm { - mov eax, [bit] - mov esi, [array] - mov ebx,eax - shr ebx,5 - and eax,01Fh - bt [esi+ebx*4],eax - setc al - } -} - -int __cdecl First_True_Bit(void const * array) -{ - __asm { - mov esi, [array] - mov eax,-32 -again: - add eax,32 - mov ebx,[esi] - add esi,4 - bsf ebx,ebx - jz again - add eax,ebx - } -} - - -int __cdecl First_False_Bit(void const * array) -{ - __asm { - - mov esi, [array] - mov eax,-32 -again: - add eax,32 - mov ebx,[esi] - not ebx - add esi,4 - bsf ebx,ebx - jz again - add eax,ebx - } -} - -int __cdecl Bound(int original, int min, int max) -{ - __asm { - mov eax,[original] - mov ebx,[min] - mov ecx,[max] - cmp ebx,ecx - jl okorder - xchg ebx,ecx -okorder: cmp eax,ebx - jg okmin - mov eax,ebx -okmin: cmp eax,ecx - jl okmax - mov eax,ecx -okmax: - } -} - - - - - - - - - -CELL __cdecl Coord_Cell(COORDINATE coord) -{ - __asm { - mov eax, coord - mov ebx,eax - shr eax,010h - xor al,al - shr eax,2 - or al,bh - } - -} - - - - - - - - - -/* -;*********************************************************** -; SHAKE_SCREEN -; -; VOID Shake_Screen(int shakes); -; -; This routine shakes the screen the number of times indicated. -; -; Bounds Checking: None -; -;* -*/ -void __cdecl Shake_Screen(int shakes) -{ - // PG_TO_FIX - // Need a different solution for shaking the screen - shakes; -} - - - -#if (0) -GLOBAL C Shake_Screen :NEAR - - CODESEG - -;*********************************************************** -; SHAKE_SCREEN -; -; VOID Shake_Screen(int shakes); -; -; This routine shakes the screen the number of times indicated. -; -; Bounds Checking: None -; -;* - PROC Shake_Screen C near - USES ecx, edx - - ARG shakes:DWORD - ret - - mov ecx,[shakes] - -;;; push es -;;; mov ax,40h -;;; mov es,ax -;;; mov dx,[es:63h] -;;; pop es - mov eax,[0463h] ; get CRTC I/O port - mov dx,ax - add dl,6 ; video status port - -??top_loop: - -??start_retrace: - in al,dx - test al,8 - jz ??start_retrace - -??end_retrace: - in al,dx - test al,8 - jnz ??end_retrace - - cli - sub dl,6 ; dx = 3B4H or 3D4H - - mov ah,01 ; top word of start address - mov al,0Ch - out dx,al - xchg ah,al - inc dx - out dx,al - xchg ah,al - dec dx - - mov ah,040h ; bottom word = 40 (140h) - inc al - out dx,al - xchg ah,al - inc dx - out dx,al - xchg ah,al - - sti - add dl,5 - -??start_retrace2: - in al,dx - test al,8 - jz ??start_retrace2 - -??end_retrace2: - in al,dx - test al,8 - jnz ??end_retrace2 - -??start_retrace3: - in al,dx - test al,8 - jz ??start_retrace3 - -??end_retrace3: - in al,dx - test al,8 - jnz ??end_retrace3 - - cli - sub dl,6 ; dx = 3B4H or 3D4H - - mov ah,0 - mov al,0Ch - out dx,al - xchg ah,al - inc dx - out dx,al - xchg ah,al - dec dx - - mov ah,0 - inc al - out dx,al - xchg ah,al - inc dx - out dx,al - xchg ah,al - - sti - add dl,5 - - loop ??top_loop - - ret - - ENDP Shake_Screen - -;*********************************************************** - - END - -#endif - - - - - - - - - - - - - - -/* - -;*************************************************************************** -;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. * -;* * -;* This routine is used to build a special fading table for C&C. There * -;* are certain colors that get faded to and cannot be faded again. * -;* With this rule, it is possible to draw a shadow multiple times and * -;* not have it get any lighter or darker. * -;* * -;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. * -;* * -;* dest -- Pointer to the 256 byte remap table. * -;* * -;* color -- Color index of the color to "fade to". * -;* * -;* frac -- The fraction to fade to the specified color * -;* * -;* OUTPUT: Returns with pointer to the remap table. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 10/07/1992 JLB : Created. * -;*=========================================================================*/ - -void * __cdecl Conquer_Build_Fading_Table(void const *palette, void *dest, int color, int frac) -{ - /* - global C Conquer_Build_Fading_Table : NEAR - PROC Conquer_Build_Fading_Table C near - USES ebx, ecx, edi, esi - - ARG palette:DWORD - ARG dest:DWORD - ARG color:DWORD - ARG frac:DWORD - - LOCAL matchvalue:DWORD ; Last recorded match value. - LOCAL targetred:BYTE ; Target gun red. - LOCAL targetgreen:BYTE ; Target gun green. - LOCAL targetblue:BYTE ; Target gun blue. - LOCAL idealred:BYTE - LOCAL idealgreen:BYTE - LOCAL idealblue:BYTE - LOCAL matchcolor:BYTE ; Tentative match color. - -ALLOWED_COUNT EQU 16 -ALLOWED_START EQU 256-ALLOWED_COUNT - */ - -#define ALLOWED_COUNT 16 -#define ALLOWED_START 256-ALLOWED_COUNT - - int matchvalue = 0; //:DWORD ; Last recorded match value. - unsigned char targetred = 0; //BYTE ; Target gun red. - unsigned char targetgreen = 0; //BYTE ; Target gun green. - unsigned char targetblue = 0; //BYTE ; Target gun blue. - unsigned char idealred = 0; //BYTE - unsigned char idealgreen = 0; //BYTE - unsigned char idealblue = 0; //BYTE - unsigned char matchcolor = 0; //:BYTE ; Tentative match color. - - __asm { - - cld - - ; If the source palette is NULL, then just return with current fading table pointer. - cmp [palette],0 - je fini1 - cmp [dest],0 - je fini1 - - ; Fractions above 255 become 255. - mov eax,[frac] - cmp eax,0100h - jb short ok - mov [frac],0FFh - ok: - - ; Record the target gun values. - mov esi,[palette] - mov ebx,[color] - add esi,ebx - add esi,ebx - add esi,ebx - lodsb - mov [targetred],al - lodsb - mov [targetgreen],al - lodsb - mov [targetblue],al - - ; Main loop. - xor ebx,ebx ; Remap table index. - - ; Transparent black never gets remapped. - mov edi,[dest] - mov [edi],bl - inc edi - - ; EBX = source palette logical number (1..255). - ; EDI = running pointer into dest remap table. - mainloop: - inc ebx - mov esi,[palette] - add esi,ebx - add esi,ebx - add esi,ebx - - mov edx,[frac] - shr edx,1 - ; new = orig - ((orig-target) * fraction); - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetred] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl eax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealred],dh ; preserve ideal color gun value. - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetgreen] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl eax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealgreen],dh ; preserve ideal color gun value. - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetblue] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl eax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealblue],dh ; preserve ideal color gun value. - - ; Sweep through a limited set of existing colors to find the closest - ; matching color. - - mov eax,[color] - mov [matchcolor],al ; Default color (self). - mov [matchvalue],-1 ; Ridiculous match value init. - mov ecx,ALLOWED_COUNT - - mov esi,[palette] ; Pointer to original palette. - add esi,(ALLOWED_START)*3 - - ; BH = color index. - mov bh,ALLOWED_START - innerloop: - - xor edx,edx ; Comparison value starts null. - - ; Build the comparison value based on the sum of the differences of the color - ; guns squared. - lodsb - sub al,[idealred] - mov ah,al - imul ah - add edx,eax - - lodsb - sub al,[idealgreen] - mov ah,al - imul ah - add edx,eax - - lodsb - sub al,[idealblue] - mov ah,al - imul ah - add edx,eax - jz short perfect ; If perfect match found then quit early. - - cmp edx,[matchvalue] - jae short notclose - mov [matchvalue],edx ; Record new possible color. - mov [matchcolor],bh - notclose: - inc bh ; Checking color index. - loop innerloop - mov bh,[matchcolor] - perfect: - mov [matchcolor],bh - xor bh,bh ; Make BX valid main index again. - - ; When the loop exits, we have found the closest match. - mov al,[matchcolor] - stosb - cmp ebx,ALLOWED_START-1 - jne mainloop - - ; Fill the remainder of the remap table with values - ; that will remap the color to itself. - mov ecx,ALLOWED_COUNT - fillerloop: - inc bl - mov al,bl - stosb - loop fillerloop - - fini1: - mov esi,[dest] - mov eax,esi - - //ret - } -} - - - - - - -extern "C" long __cdecl Reverse_Long(long number) -{ - __asm { - mov eax,dword ptr [number] - xchg al,ah - ror eax,16 - xchg al,ah - } -} - - -extern "C" short __cdecl Reverse_Short(short number) -{ - __asm { - mov ax,[number] - xchg ah,al - } -} - - - -extern "C" long __cdecl Swap_Long(long number) -{ - __asm { - mov eax,dword ptr [number] - ror eax,16 - } -} - - - - - - - - -/* - - - -;*************************************************************************** -;* strtrim -- Remove the trailing white space from a string. * -;* * -;* Use this routine to remove white space characters from the beginning * -;* and end of the string. The string is modified in place by * -;* this routine. * -;* * -;* INPUT: buffer -- Pointer to the string to modify. * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 10/07/1992 JLB : Created. * -;*=========================================================================* -; VOID cdecl strtrim(BYTE *buffer); - global C strtrim :NEAR - PROC strtrim C near - USES ax, edi, esi - - ARG buffer:DWORD ; Pointer to string to modify. -*/ -void __cdecl strtrim(char *buffer) -{ - __asm { - cmp [buffer],0 - je short fini - - ; Prepare for string scanning by loading pointers. - cld - mov esi,[buffer] - mov edi,esi - - ; Strip white space from the start of the string. - looper: - lodsb - cmp al,20h ; Space - je short looper - cmp al,9 ; TAB - je short looper - stosb - - ; Copy the rest of the string. - gruntloop: - lodsb - stosb - or al,al - jnz short gruntloop - dec edi - ; Strip the white space from the end of the string. - looper2: - mov [edi],al - dec edi - mov ah,[edi] - cmp ah,20h - je short looper2 - cmp ah,9 - je short looper2 - - fini: - //ret - } -} - - -/* -;*************************************************************************** -;* Fat_Put_Pixel -- Draws a fat pixel. * -;* * -;* Use this routine to draw a "pixel" that is bigger than 1 pixel * -;* across. This routine is faster than drawing a similar small shape * -;* and faster than calling Fill_Rect. * -;* * -;* INPUT: x,y -- Screen coordinates to draw the pixel's upper * -;* left corner. * -;* * -;* color -- The color to render the pixel in. * -;* * -;* size -- The number of pixels width of the big "pixel". * -;* * -;* page -- The pointer to a GraphicBuffer class or something * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 03/17/1994 JLB : Created. * -;*=========================================================================* -; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page) - global C Fat_Put_Pixel:NEAR - PROC Fat_Put_Pixel C near - USES eax, ebx, ecx, edx, edi, esi - - ARG x:DWORD ; X coordinate of upper left pixel corner. - ARG y:DWORD ; Y coordinate of upper left pixel corner. - ARG color:DWORD ; Color to use for the "pixel". - ARG siz:DWORD ; Size of "pixel" to plot (square). - ARG gpage:DWORD ; graphic page address to plot onto -*/ - -void __cdecl Fat_Put_Pixel(int x, int y, int color, int siz, GraphicViewPortClass &gpage) -{ - __asm { - - cmp [siz],0 - je short exit_label - - ; Set EDI to point to start of logical page memory. - ;*=================================================================== - ; Get the viewport information and put bytes per row in ecx - ;*=================================================================== - mov ebx,[gpage] ; get a pointer to viewport - mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset - - ; Verify the the Y pixel offset is legal. - mov eax,[y] - cmp eax,[ebx]GraphicViewPortClass.Height ;YPIXEL_MAX - jae short exit_label - mov ecx,[ebx]GraphicViewPortClass.Width - add ecx,[ebx]GraphicViewPortClass.XAdd - add ecx,[ebx]GraphicViewPortClass.Pitch - mul ecx - add edi,eax - - ; Verify the the X pixel offset is legal. - - mov edx,[ebx]GraphicViewPortClass.Width - cmp edx,[x] - mov edx,ecx - jbe short exit_label - add edi,[x] - - ; Write the pixel to the screen. - mov ebx,[siz] ; Copy of pixel size. - sub edx,ebx ; Modulo to reach start of next row. - mov eax,[color] - again: - mov ecx,ebx - rep stosb - add edi,edx ; EDI points to start of next row. - dec [siz] - jnz short again - - exit_label: - //ret - } -} - - - - - - - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood Library * -;* * -;* File Name : CRC.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : June 12, 1992 * -;* * -;* Last Update : February 10, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Calculate_CRC :NEAR - - CODESEG -*/ - -extern "C" long __cdecl Calculate_CRC(void *buffer, long length) -{ - unsigned long crc; - - unsigned long local_length = (unsigned long) length; - - __asm { - ; Load pointer to data block. - mov [crc],0 - pushad - mov esi,[buffer] - cld - - ; Clear CRC to default (NULL) value. - xor ebx,ebx - - //; Fetch the length of the data block to CRC. - - mov ecx,[local_length] - - jecxz short fini - - ; Prepare the length counters. - mov edx,ecx - and dl,011b - shr ecx,2 - - ; Perform the bulk of the CRC scanning. - jecxz short remainder2 - accumloop: - lodsd - rol ebx,1 - add ebx,eax - loop accumloop - - ; Handle the remainder bytes. - remainder2: - or dl,dl - jz short fini - mov ecx,edx - xor eax,eax - - and ecx,0FFFFh - push ecx - nextbyte: - lodsb - ror eax,8 - loop nextbyte - pop ecx - neg ecx - add ecx,4 - shl ecx,3 - ror eax,cl - - ;nextbyte: - ; shl eax,8 - ; lodsb - ; loop nextbyte - rol ebx,1 - add ebx,eax - - fini: - mov [crc],ebx - popad - mov eax,[crc] - //ret - } -} - - - - - - -extern "C" void __cdecl Set_Palette_Range(void *palette) -{ - if (palette == NULL) { - return; - } - - memcpy(CurrentPalette, palette, 768); - Set_DD_Palette(palette); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/NETDLG.CPP b/code/TIBERIANDAWN/NETDLG.CPP deleted file mode 100644 index 7c44e49..0000000 --- a/code/TIBERIANDAWN/NETDLG.CPP +++ /dev/null @@ -1,5434 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\netdlg.cpv 2.17 16 Oct 1995 16:52:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : NETDLG.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : January 23, 1995 * - * * - * Last Update : July 8, 1995 [BRR] * - * * - *---------------------------------------------------------------------------------------------* - * * - * These routines establish & maintain peer-to-peer connections between this system * - * and all others in the game. Each system finds out the IPX address of the others, * - * and forms a direct connection (IPXConnectionClass) to that system. Systems are * - * found out via broadcast queries. Every system broadcasts its queries, and every * - * system replies to queries it receives. At the point when the game owner signals * - * 'OK', every system must know about all the other systems in the game. * - * * - * How Bridges are handled: * - * Currently, bridges are handled by specifying the destination IPX address of the * - * "server" (game owner's system) on the command-line. This address is used to * - * derive a broadcast address to that destination network, and this system's queries * - * are broadcast over its network & the server's network; replies to the queries come * - * with each system's IPX address attached, so once we have the address, we can form * - * a connection with any system on the bridged net. * - * * - * The flaw in this plan is that we can only cross one bridge. If there are 3 nets * - * bridged (A, B, & C), and the server is on net B, and we're on net A, our broadcasts * - * will reach nets A & B, but not C. The way to circumvent this (if it becomes a problem) * - * would be to have the server tell us what other systems are in its game, not each * - * individual player's system. Thus, each system would find out about all the other systems * - * by interacting with the game's owner system (this would be more involved than what * - * I'm doing here). * - * * - * Here's a list of all the different packets sent over the Global Channel: * - * * - * NET_QUERY_GAME * - * (no other data) * - * NET_ANSWER_GAME * - * Name: game owner's name * - * GameInfo: game's version & open state * - * NET_QUERY_PLAYER * - * Name: name of game we want players to respond for * - * NET_ANSWER_PLAYER * - * Name: player's name * - * PlayerInfo: info about player * - * NET_QUERY_JOIN * - * Name: name of player wanting to join * - * PlayerInfo: player's requested house & color * - * NET_CONFIRM_JOIN * - * PlayerInfo: approves player's house & color * - * NET_REJECT_JOIN * - * (no other data) * - * NET_GAME_OPTIONS * - * ScenarioInfo: info about scenario * - * NET_SIGN_OFF * - * Name: name of player signing off * - * NET_PING * - * (no other data) * - * NET_GO * - * Delay: value of one-way response time, in frames * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Clear_Game_List -- Clears the game-name listbox & 'Games' Vector * - * Clear_Player_List -- Clears the player-name listbox & Vector * - * Destroy_Connection -- destroys the given connection * - * Get_Join_Responses -- sends queries for the Join Dialog * - * Get_NewGame_Responses -- processes packets for New Game dialog * - * Init_Network -- initializes network stuff * - * Net_Join_Dialog -- lets user join an existing game, or start a new one * - * Net_New_Dialog -- lets user start a new game * - * Process_Global_Packet -- responds to remote queries * - * Remote_Connect -- handles connecting this user to others * - * Request_To_Join -- Sends a JOIN request packet to game owner * - * Send_Join_Queries -- sends queries for the Join Dialog * - * Shutdown_Network -- shuts down network stuff * - * Compute_Name_CRC -- computes CRC from char string * - * Net_Reconnect_Dialog -- Draws/updates the network reconnect dialog * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include -#include "tcpip.h" -#include "ccdde.h" -#define SHOW_MONO 0 - -// ST = 12/17/2018 5:44PM -#ifndef TickCount -extern TimerClass TickCount; -#endif - -#ifndef DEMO - -/*--------------------------------------------------------------------------- -The possible states of the join-game dialog ----------------------------------------------------------------------------*/ -typedef enum { - JOIN_REJECTED = -1, // we've been rejected - JOIN_NOTHING, // we're not trying to join a game - JOIN_WAIT_CONFIRM, // we're asking to join, & waiting for confirmation - JOIN_CONFIRMED, // we've been confirmed - JOIN_GAME_START, // the game we've joined is starting -} JoinStateType; - -/*--------------------------------------------------------------------------- -The possible return codes from Get_Join_Responses() ----------------------------------------------------------------------------*/ -typedef enum { - EV_NONE, // nothing happened - EV_STATE_CHANGE, // Join dialog is in a new state - EV_NEW_GAME, // a new game was detected - EV_NEW_PLAYER, // a new player was detected - EV_PLAYER_SIGNOFF, // a player has signed off - EV_GAME_SIGNOFF, // a gamed owner has signed off - EV_GAME_OPTIONS, // a game options packet was received - EV_MESSAGE, // a message was received -} JoinEventType; - - -/* -******************************** Prototypes ********************************* -*/ -static int Net_Join_Dialog(void); -static void Clear_Game_List (ListClass *gamelist); -static void Clear_Player_List (ListClass *playerlist); -static int Request_To_Join (char *playername, int join_index, ListClass *playerlist, - HousesType house, int color); -static void Send_Join_Queries(int curgame, int gamenow, int playernow); -static JoinEventType Get_Join_Responses(JoinStateType *joinstate, ListClass *gamelist, - ColorListClass *playerlist, int join_index); -static int Net_New_Dialog(void); -static JoinEventType Get_NewGame_Responses(ColorListClass *playerlist); -static int Net_Fake_New_Dialog(void); -static int Net_Fake_Join_Dialog(void); - - -/*********************************************************************************************** - * Init_Network -- initializes network stuff * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = Initialization OK, false = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -bool Init_Network (void) -{ - NetNumType net; - NetNodeType node; - - /*------------------------------------------------------------------------ - This call allocates all necessary queue buffers, allocates Real-mode - memory, and commands IPX to start listening on the Global Channel. - ------------------------------------------------------------------------*/ - if (!Ipx.Init()) - return(false); - - /*------------------------------------------------------------------------ - Allocate our "meta-packet" buffer - ------------------------------------------------------------------------*/ - if (!MetaPacket) { - MetaPacket = new char [sizeof (EventClass) * MAX_EVENTS]; - } - - /*------------------------------------------------------------------------ - Set up the IPX manager to cross a bridge - ------------------------------------------------------------------------*/ - if (!(GameToPlay == GAME_INTERNET)){ - if (IsBridge) { - BridgeNet.Get_Address(net,node); - Ipx.Set_Bridge(net); - } - } - - return(true); - -} /* end of Init_Network */ - - -/*********************************************************************************************** - * Shutdown_Network -- shuts down network stuff * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void Shutdown_Network (void) -{ - -// -// Note: The thought behind this section of code was that if the program -// terminates early, without an EventClass::EXIT event, it still needs to -// tell the other systems that it's gone, so it would send a SIGN_OFF packet. -// BUT, this causes a sync bug if the systems are running slow and this system -// is running ahead of the others; it will send the NET_SIGN_OFF >>before<< -// the other system execute their EventClass::EXIT event, and the other systems -// will kill the connection at some random Frame # & turn my stuff over to -// the computer possibly at different times. -// BRR, 10/29/96 -// -#if (0) - /*------------------------------------------------------------------------ - Broadcast a sign-off packet, by sending the packet over the Global Channel, - telling the IPX Manager that no ACK is required, and specifying a NULL - destination address. - ------------------------------------------------------------------------*/ - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy (GPacket.Name, MPlayerName); - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), 0, NULL); - - if (IsBridge && !Winsock.Get_Connected()) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, &BridgeNet); - } - - /*------------------------------------------------------------------------ - Wait for the packets to finish going out (or the Global Channel times out) - ------------------------------------------------------------------------*/ - for (;;) { - if (Ipx.Global_Num_Send()==0) { - break; - } - Ipx.Service(); - } - -#endif //(0) - - /*------------------------------------------------------------------------ - Delete our "meta-packet" - ------------------------------------------------------------------------*/ - delete [] MetaPacket; - MetaPacket = 0; - - /*------------------------------------------------------------------------ - If I was in a game, I'm not now, so clear the game name - ------------------------------------------------------------------------*/ - MPlayerGameName[0] = 0; -} - - -/*********************************************************************************************** - * Process_Global_Packet -- responds to remote queries * - * * - * The only commands from other systems this routine responds to are NET_QUERY_GAME * - * and NET_QUERY_PLAYER. The other commands are too context-specific to be able * - * to handle here, such as joining the game or signing off; but this routine handles * - * the majority of the program's needs. * - * * - * INPUT: * - * packet ptr to packet to process * - * address source address of sender * - * * - * OUTPUT: * - * true = packet was processed, false = wasn't * - * * - * WARNINGS: * - * MPlayerName & MPlayerGameName must have been filled in before this function * - * can be called. * - * * - * HISTORY: * - * 02/15/1995 BR : Created. * - *=============================================================================================*/ -bool Process_Global_Packet(GlobalPacketType *packet, IPXAddressClass *address) -{ - GlobalPacketType mypacket; - - /* - ---------------- Another system asking what game this is ----------------- - */ - if (packet->Command==NET_QUERY_GAME && NetStealth==0) { - /*..................................................................... - If the game is closed, let every player respond, and let the sender of - the query sort it all out. This way, if the game's host exits the game, - the game still shows up on other players' dialogs. - If the game is open, only the game owner may respond. - .....................................................................*/ - if (strlen(MPlayerName) > 0 && strlen(MPlayerGameName) > 0 && - ((!NetOpen) || (NetOpen && !strcmp(MPlayerName,MPlayerGameName)))) { - memset (packet, 0, sizeof(GlobalPacketType)); - - mypacket.Command = NET_ANSWER_GAME; - strcpy(mypacket.Name, MPlayerGameName); -#ifdef PATCH - if (IsV107) { - mypacket.GameInfo.Version = 1; - } else { - mypacket.GameInfo.Version = 2; - } -#else - mypacket.GameInfo.Version = Version_Number(); -#endif - mypacket.GameInfo.IsOpen = NetOpen; - - Ipx.Send_Global_Message (&mypacket, sizeof(GlobalPacketType), 1, - address); - } - return(true); - } else { - - /* - ----------------- Another system asking what player I am ----------------- - */ - if (packet->Command==NET_QUERY_PLAYER && - !strcmp (packet->Name, MPlayerGameName) && - (strlen(MPlayerGameName) > 0) && NetStealth==0) { - memset (packet, 0, sizeof(GlobalPacketType)); - - mypacket.Command = NET_ANSWER_PLAYER; - strcpy(mypacket.Name, MPlayerName); - mypacket.PlayerInfo.House = MPlayerHouse; - mypacket.PlayerInfo.Color = MPlayerColorIdx; - mypacket.PlayerInfo.NameCRC = Compute_Name_CRC(MPlayerGameName); - - Ipx.Send_Global_Message (&mypacket, sizeof(GlobalPacketType), 1, address); - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * Destroy_Connection -- destroys the given connection * - * * - * Call this routine when a connection goes bad, or another player signs off. * - * * - * INPUT: * - * id connection ID to destroy * - * error 0 = user signed off; 1 = connection error; otherwise, no error is shown. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/22/1995 BR : Created. * - *=============================================================================================*/ -void Destroy_Connection(int id, int error) -{ - int i,j; - HousesType house; - HouseClass *housep; - char txt[80]; - - /*------------------------------------------------------------------------ - Create a message to display to the user - ------------------------------------------------------------------------*/ - txt[0] = '\0'; - if (error==1) { - sprintf(txt,Text_String(TXT_CONNECTION_LOST),Ipx.Connection_Name(id)); - } else if (error==0) { - sprintf(txt,Text_String(TXT_LEFT_GAME),Ipx.Connection_Name(id)); - } - - if (strlen(txt)) { - Messages.Add_Message (txt, - MPlayerTColors[MPlayerID_To_ColorIndex((unsigned char)id)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - } - - /*------------------------------------------------------------------------ - Delete the IPX connection, shift the MPlayerID's & MPlayerHouses' back one. - ------------------------------------------------------------------------*/ - Ipx.Delete_Connection(id); - - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == (unsigned char)id) { - /*.................................................................. - Turn the player's house over to the computer's AI - ..................................................................*/ - house = MPlayerHouses[i]; - housep = HouseClass::As_Pointer (house); - housep->IsHuman = false; - housep->IsStarted = true; - - /*.................................................................. - Move arrays back by one - ..................................................................*/ - for (j = i; j < MPlayerCount - 1; j++) { - MPlayerID[j] = MPlayerID[j + 1]; - MPlayerHouses[j] = MPlayerHouses[j + 1]; - strcpy (MPlayerNames[j], MPlayerNames[j+1]); - TheirProcessTime[j] = TheirProcessTime[j+1]; - } - } - } - - MPlayerCount--; - - /*------------------------------------------------------------------------ - If we're the last player left, tell the user. - ------------------------------------------------------------------------*/ - if (MPlayerCount == 1) { - sprintf(txt,"%s",Text_String(TXT_JUST_YOU_AND_ME)); - Messages.Add_Message (txt, - MPlayerTColors[MPlayerID_To_ColorIndex((unsigned char)id)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - } - -} /* end of Destroy_Connection */ - - -/*********************************************************************************************** - * Remote_Connect -- handles connecting this user to others * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = connections established; false = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -bool Remote_Connect(void) -{ - int rc; - int stealth; // original state of NetStealth flag - - /*------------------------------------------------------------------------ - Init network timing parameters; these values should work for both a "real" - network, and a simulated modem network (ie Kali) - ------------------------------------------------------------------------*/ - Ipx.Set_Timing ( 30, // retry 2 times per second - -1, // ignore max retries - 600); // give up after 10 seconds - - /*------------------------------------------------------------------------ - Save the original value of the NetStealth flag, so we can turn stealth - off for now (during this portion of the dialogs, we must show ourselves) - ------------------------------------------------------------------------*/ - stealth = NetStealth; - NetStealth = 0; - - /*------------------------------------------------------------------------ - Init my game name to 0-length, since I haven't joined any game yet. - ------------------------------------------------------------------------*/ - MPlayerGameName[0] = 0; - - /*------------------------------------------------------------------------ - The game is now "open" for joining. Close it as soon as we exit this - routine. - ------------------------------------------------------------------------*/ - NetOpen = 1; - - /*------------------------------------------------------------------------ - Read the default values from the INI file - ------------------------------------------------------------------------*/ - Read_MultiPlayer_Settings (); - - /*------------------------------------------------------------------------ - Keep looping until something useful happens. - ------------------------------------------------------------------------*/ - while (1) { - /*--------------------------------------------------------------------- - Pop up the network Join/New dialog - ---------------------------------------------------------------------*/ - rc = Net_Join_Dialog(); - - /*--------------------------------------------------------------------- - -1 = user selected Cancel - ---------------------------------------------------------------------*/ - if (rc==-1) { - NetStealth = stealth; - NetOpen = 0; - return(false); - } else { - - /*--------------------------------------------------------------------- - 0 = user has joined an existing game; save values & return - ---------------------------------------------------------------------*/ - if (rc==0) { - Write_MultiPlayer_Settings (); - NetStealth = stealth; - NetOpen = 0; - - return(true); - } else { - - /*--------------------------------------------------------------------- - 1 = user requests New Network Game - ---------------------------------------------------------------------*/ - if (rc==1) { - /*.................................................................. - Pop up the New Network Game dialog; if user selects OK, return - 'true'; otherwise, return to the Join Dialog. - ..................................................................*/ - if (Net_New_Dialog()) { - Write_MultiPlayer_Settings (); - NetOpen = 0; - NetStealth = stealth; - NetOpen = 0; - - return(true); - } else { - continue; - } - } - } - } - } -} - - - -/*********************************************************************************************** - * Remote_Connect -- handles connecting this host to the server in an internet game * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = connections established; false = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -bool Server_Remote_Connect(void) -{ - int stealth; // original state of NetStealth flag - - /*------------------------------------------------------------------------ - Init network timing parameters; these values should work for both a "real" - network, and a simulated modem network (ie Kali) - ------------------------------------------------------------------------*/ - Ipx.Set_Timing ( 30, // retry 2 times per second - -1, // ignore max retries - 600); // give up after 10 seconds - - /*------------------------------------------------------------------------ - Save the original value of the NetStealth flag, so we can turn stealth - off for now (during this portion of the dialogs, we must show ourselves) - ------------------------------------------------------------------------*/ - stealth = NetStealth; - NetStealth = 0; - - /*------------------------------------------------------------------------ - The game is now "open" for joining. Close it as soon as we exit this - routine. - ------------------------------------------------------------------------*/ - NetOpen = 1; - - /*------------------------------------------------------------------------ - Read the default values from the INI file - ------------------------------------------------------------------------*/ - Read_MultiPlayer_Settings (); - - if (!Net_Fake_New_Dialog()){ - Write_MultiPlayer_Settings (); - return (false); - } - - NetOpen = 0; - NetStealth = stealth; - Write_MultiPlayer_Settings (); - return (true); -} - - -/*********************************************************************************************** - * Client_Remote_Connect -- handles connecting this client to the server in an internet game * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = connections established; false = not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 ST : Created. * - *=============================================================================================*/ -bool Client_Remote_Connect(void) -{ - int rc; - int stealth; // original state of NetStealth flag - - /*------------------------------------------------------------------------ - Init network timing parameters; these values should work for both a "real" - network, and a simulated modem network (ie Kali) - ------------------------------------------------------------------------*/ - Ipx.Set_Timing ( 30, // retry 2 times per second - -1, // ignore max retries - 600); // give up after 10 seconds - - /*------------------------------------------------------------------------ - Save the original value of the NetStealth flag, so we can turn stealth - off for now (during this portion of the dialogs, we must show ourselves) - ------------------------------------------------------------------------*/ - stealth = NetStealth; - NetStealth = 0; - - /*------------------------------------------------------------------------ - The game is now "open" for joining. Close it as soon as we exit this - routine. - ------------------------------------------------------------------------*/ - NetOpen = 1; - - /*------------------------------------------------------------------------ - Read the default values from the INI file - ------------------------------------------------------------------------*/ - Read_MultiPlayer_Settings (); - - /*--------------------------------------------------------------------- - Pop up the network Join/New dialog - ---------------------------------------------------------------------*/ - rc = Net_Fake_Join_Dialog(); - Write_MultiPlayer_Settings (); - - NetStealth = stealth; - NetOpen = 0; - - if (rc == -1) { - return(false); - } else { - return(true); - } -} - - - -/*********************************************************************************************** - * Net_Join_Dialog -- lets user join an existing game or start a new one * - * * - * This dialog displays an edit field for the player's name, and a list of all non-stealth- * - * mode games. Clicking once on a game name displays a list of who's in that game. Clicking * - * "New" takes the user to the Net_New dialog, where he waits for other users to join his * - * game. All other input is done through this dialog. * - * * - * The dialog has several "states": * - * * - * 1) Initially, it waits for the user to fill in his/her name and then to select Join or New; * - * if New is selected, this dialog is exited. * - * * - * 2) If Join is selected, the Join & New buttons are removed, but the Cancel button remains. * - * The join request is transmitted to the game's owner, and the message "Waiting for * - * Confirmation" is displayed, until a confirmation or denial is received from the game's * - * owner. The user may click Cancel at this point to cancel the join request. * - * (Once Join is selected, the name editing field is disabled, and becomes a display-only * - * field. If cancel is selected, it reappears as an edit field.) The user can still click * - * around & see who's in which games. * - * * - * 3) If the join request is denied, the dialog re-initializes to its pre-join state; the * - * Join & New buttons reappear, & the Name field is available again. * - * * - * 4) If join confirmation is obtained, the message just changes to "Confirmed. Waiting for * - * Entry Signal." or some such nonsense. The user can still click around & see who's * - * in which games. * - * * - * Any game running in Stealth mode won't show up on this dialog. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Network Games ³ * - * ³ ³ * - * ³ Your Name: ____________ ³ * - * ³ House: [GDI] [NOD] ³ * - * ³ Desired Color: [ ][ ][ ][ ] ³ * - * ³ ³ * - * ³ Games Players ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³(Bill's Game )³³ ³ Peter Parker GDI ³³ ³ * - * ³ ³ Peter Parker's Game ÃÄ´ ³ Mary Jane GDI ÃÄ´ ³ * - * ³ ³(Magnum PI's Game )³ ³ ³ JJ Jameson NOD ³ ³ ³ * - * ³ ³ ÃÄ´ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ Scenario: Big Long Description ³ * - * ³ Starting Credits: xxxx ³ * - * ³ Count: --- Level: --- ³ * - * ³ Bases: ON Crates: ON ³ * - * ³ Tiberium: ON AI Players: ON ³ * - * ³ ³ * - * ³ [Join] [Cancel] [New] ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ [Send Message] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * -1 = cancel, 0 = OK, 1 = New net game requested * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -static int Net_Join_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ -/* ###Change collision detected! C:\PROJECTS\CODE\NETDLG.CPP... */ - int d_dialog_w = 287 *factor; // dialog width - int d_dialog_h = 198*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 6*factor+1; // ht of 6-pt text - int d_margin1 = 5*factor; // large margin - int d_margin2 = 2*factor; // small margin - - int d_name_w = 70*factor; - int d_name_h = 9*factor; - int d_name_x = d_dialog_cx - 10*factor; - int d_name_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h; - - int d_gdi_w = 30*factor; - int d_gdi_h = 9*factor; - int d_gdi_x = d_dialog_cx - 10*factor; - int d_gdi_y = d_name_y + d_name_h + d_margin2; - - int d_nod_w = 30*factor; - int d_nod_h = 9*factor; - int d_nod_x = d_gdi_x + d_gdi_w; - int d_nod_y = d_name_y + d_name_h + d_margin2; - - int d_color_w = 10*factor; - int d_color_h = 9*factor; - int d_color_y = d_nod_y + d_nod_h + d_margin2; - - int d_gamelist_w = 160*factor; - int d_gamelist_h = 27*factor; - int d_gamelist_x = d_dialog_x + d_margin1; - int d_gamelist_y = d_color_y + d_color_h + d_margin1 + d_txt6_h; - - int d_playerlist_w = 106*factor; - int d_playerlist_h = 27*factor; - int d_playerlist_x = d_dialog_x + d_dialog_w - d_margin1 - d_playerlist_w; - int d_playerlist_y = d_color_y + d_color_h + d_margin1 + d_txt6_h; - - int d_msg1_y = d_gamelist_y + d_gamelist_h + d_margin1; - int d_msg2_y = d_msg1_y + d_txt6_h; - int d_msg3_y = d_msg2_y + d_txt6_h; - int d_msg4_y = d_msg3_y + d_txt6_h; - int d_msg5_y = d_msg4_y + d_txt6_h; - - int d_join_w = 40*factor; - int d_join_h = 9*factor; - int d_join_x = d_dialog_x + (d_dialog_w / 6) - (d_join_w / 2); - int d_join_y = d_msg5_y + d_txt6_h + d_margin1; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50*factor; -#else - int d_cancel_w = 40*factor; -#endif - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx - d_cancel_w / 2; - int d_cancel_y = d_msg5_y + d_txt6_h + d_margin1; - - int d_new_w = 40*factor; - int d_new_h = 9*factor; - int d_new_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_new_w / 2); - int d_new_y = d_msg5_y + d_txt6_h + d_margin1; - - int d_message_w = d_dialog_w - (d_margin1 * 2); - int d_message_h = 34*factor; - int d_message_x = d_dialog_x + d_margin1; - int d_message_y = d_cancel_y + d_cancel_h + d_margin1; - - int d_send_w = 80*factor; - int d_send_h = 9*factor; - int d_send_x = d_dialog_cx - (d_send_w / 2); - int d_send_y = d_message_y + d_message_h + d_margin2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_NAME = 100, - BUTTON_GDI, - BUTTON_NOD, - BUTTON_GAMELIST, - BUTTON_PLAYERLIST, - BUTTON_JOIN, - BUTTON_CANCEL, - BUTTON_NEW, - BUTTON_SEND, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_MESSAGE, - REDRAW_COLORS, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - KeyNumType input; - int cbox_x[] = { d_gdi_x, - d_gdi_x + d_color_w, - d_gdi_x + (d_color_w * 2), - d_gdi_x + (d_color_w * 3), - d_gdi_x + (d_color_w * 4), - d_gdi_x + (d_color_w * 5)}; - - JoinStateType joinstate = JOIN_NOTHING; // current "state" of this dialog - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - int tabs[] = {77*factor}; // tabs for player list box - int game_index = -1; // index of currently-selected game - int join_index = -1; // index of game we're joining - int rc = 0; // -1 = user cancelled, 1 = New - JoinEventType event; // event from incoming packet - int i,j; // loop counter - char txt[80]; - char const *p; - int parms_received; // 1 = game options received - int found; - - unsigned char tmp_id[MAX_PLAYERS]; // temp storage for sorting player ID's - int min_index; // for sorting player ID's - unsigned char min_id; // for sorting player ID's - unsigned char id; // connection ID - char * item; - unsigned long starttime; - - NodeNameType *who; - - int message_length; - int sent_so_far; - unsigned short magic_number; - unsigned short crc; - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - EditClass name_edt (BUTTON_NAME, - namebuf, MPLAYER_NAME_MAX, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); - - TextButtonClass gdibtn(BUTTON_GDI, TXT_G_D_I, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_gdi_x, d_gdi_y, d_gdi_w, d_gdi_h); - - TextButtonClass nodbtn(BUTTON_NOD, TXT_N_O_D, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_nod_x, d_nod_y, d_nod_w, d_nod_h); - - ListClass gamelist(BUTTON_GAMELIST, - d_gamelist_x, d_gamelist_y, d_gamelist_w, d_gamelist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - ColorListClass playerlist(BUTTON_PLAYERLIST, - d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - TextButtonClass joinbtn(BUTTON_JOIN, TXT_JOIN, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -#ifdef FRENCH - d_join_x, d_join_y); -#else - d_join_x, d_join_y, d_join_w, d_join_h); -#endif - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - TextButtonClass newbtn(BUTTON_NEW, TXT_NEW, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_new_x, d_new_y, d_new_w, d_new_h); - - TextButtonClass sendbtn(BUTTON_SEND, TXT_SEND_MESSAGE, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_send_x, d_send_y); -//#else - d_send_x, d_send_y, d_send_w, d_send_h); -//#endif - - playerlist.Set_Tabs(tabs); - - /* - ----------------------------- Various Inits ------------------------------ - */ - MPlayerColorIdx = MPlayerPrefColor; // init my preferred color - strcpy (namebuf, MPlayerName); // set my name - name_edt.Set_Text(namebuf,MPLAYER_NAME_MAX); - name_edt.Set_Color (MPlayerTColors[MPlayerColorIdx]); - - playerlist.Set_Selected_Style(ColorListClass::SELECT_NONE); - - if (MPlayerHouse==HOUSE_GOOD) { - gdibtn.Turn_On(); - } else { - nodbtn.Turn_On(); - } - - Fancy_Text_Print("", 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Messages.Init (d_message_x + 2, d_message_y + 2, 4, - MAX_MESSAGE_LENGTH, d_txt6_h); - - /* - --------------------------- Send network query --------------------------- - */ - Send_Join_Queries (game_index, 1, 0); - - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - /* - ---------------------------- Init Mono Output ---------------------------- - */ - #if(SHOW_MONO) - Ipx.Configure_Debug(-1, sizeof (GlobalHeaderType), - sizeof(NetCommandType), GlobalPacketNames, 11); - Ipx.Mono_Debug_Print(-1,1); - #endif - while (Get_Mouse_State() > 0) Show_Mouse(); - - /* - ---------------------------- Processing loop ----------------------------- - */ - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - #if(SHOW_MONO) - Ipx.Mono_Debug_Print(-1,0); - #endif - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_JOIN_NETWORK_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print(TXT_YOUR_NAME, - d_name_x - 5, d_name_y + 1, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_SIDE_COLON, - d_gdi_x - 5, d_gdi_y + 1, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_COLOR_COLON, - cbox_x[0] - 5, d_color_y + 1, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_GAMES, - d_gamelist_x + (d_gamelist_w / 2), d_gamelist_y - d_txt6_h, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_PLAYERS, - d_playerlist_x + (d_playerlist_w / 2), d_playerlist_y - d_txt6_h, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................... - Join-state-specific labels: - ...............................................................*/ - if (joinstate > JOIN_NOTHING) { - Fancy_Text_Print(namebuf, d_name_x, d_name_y + 1, CC_GREEN, - TBLACK, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - if (MPlayerHouse==HOUSE_GOOD) { - Fancy_Text_Print(TXT_G_D_I, d_gdi_x, d_gdi_y + 1, CC_GREEN, - TBLACK, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } else { - Fancy_Text_Print(TXT_N_O_D, d_gdi_x, d_gdi_y + 1, CC_GREEN, - TBLACK, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - } - - /* - .................... Rebuild the button list .................... - */ - cancelbtn.Zap(); - gamelist.Zap(); - playerlist.Zap(); - gdibtn.Zap(); - nodbtn.Zap(); - name_edt.Zap(); - joinbtn.Zap(); - newbtn.Zap(); - sendbtn.Zap(); - - commands = &cancelbtn; - gamelist.Add_Tail(*commands); - playerlist.Add_Tail(*commands); - /*............................................................... - Only add the name edit field, the House, Join & New buttons if - we're doing nothing, or we've just been rejected. - ...............................................................*/ - if (joinstate <= JOIN_NOTHING) { - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - name_edt.Add_Tail(*commands); - joinbtn.Add_Tail(*commands); - newbtn.Add_Tail(*commands); - } - if (joinstate == JOIN_CONFIRMED) - sendbtn.Add_Tail(*commands); - } - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - - /*.................................................................. - Draw the color boxes - ..................................................................*/ - if (display >= REDRAW_COLORS) { - for (i = 0; i < MAX_MPLAYER_COLORS; i++) { - LogicPage->Fill_Rect (cbox_x[i] + 1, d_color_y + 1, - cbox_x[i] + 1 + d_color_w - 2, d_color_y + 1 + d_color_h - 2, - MPlayerGColors[i]); - - if (i == MPlayerColorIdx) { - Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, - BOXSTYLE_GREEN_DOWN, false); - } else { - Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, - BOXSTYLE_GREEN_RAISED, false); - } - } - } - - /*.................................................................. - Draw the message: - - Erase an old message first - - If we're in a game, print the game options (if they've been - received) - - If we've been rejected from a game, print that message - ..................................................................*/ - if (display >= REDRAW_MESSAGE) { - Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, - BOXSTYLE_GREEN_BORDER, true); - Messages.Draw(); - - LogicPage->Fill_Rect( d_dialog_x + 2, - d_msg1_y, - d_dialog_x + d_dialog_w - 4, - d_msg5_y + d_txt6_h, - BLACK); - - if (joinstate==JOIN_CONFIRMED && parms_received) { - /*............................................................ - Scenario title - ............................................................*/ - p = Text_String(TXT_SCENARIO_COLON); - if (ScenarioIdx != -1) { - sprintf(txt,"%s %s",p, MPlayerScenarios[ScenarioIdx]); - - Fancy_Text_Print (txt, d_dialog_cx, - d_msg1_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW | TPF_CENTER); - } else { - sprintf(txt,"%s %s",p,Text_String(TXT_NOT_FOUND)); - - Fancy_Text_Print (txt, d_dialog_cx, - d_msg1_y, CC_NOD_COLOR, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW | TPF_CENTER); - } - - /*............................................................ - # of credits - ............................................................*/ - p = Text_String(TXT_START_CREDITS_COLON); - sprintf(txt, "%s %d", p, MPlayerCredits); - Fancy_Text_Print (txt, d_dialog_cx, - d_msg2_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW | TPF_CENTER); - - /*............................................................ - Count & Level values - ............................................................*/ - p = Text_String(TXT_COUNT); - sprintf(txt,"%s %d",p,MPlayerUnitCount); - Fancy_Text_Print (txt, - d_dialog_x + (d_dialog_w / 4) - String_Pixel_Width(p), - d_msg3_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - p = Text_String(TXT_LEVEL); - if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { - sprintf(txt, "%s %d", p, BuildLevel); - } else { - sprintf(txt, "%s **", p); - } - Fancy_Text_Print (txt, - d_dialog_x + d_dialog_w - (d_dialog_w / 4) - String_Pixel_Width(p), - d_msg3_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Bases - ............................................................*/ - p = Text_String(TXT_BASES_COLON); - if (MPlayerBases) { - sprintf(txt,"%s %s",p,Text_String(TXT_ON)); - } else { - sprintf(txt,"%s %s",p,Text_String(TXT_OFF)); - } - Fancy_Text_Print (txt, - d_dialog_x + (d_dialog_w / 4) - String_Pixel_Width(p), - d_msg4_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Tiberium - ............................................................*/ - p = Text_String(TXT_TIBERIUM_COLON); - if (MPlayerTiberium) { - sprintf(txt,"%s %s",p,Text_String(TXT_ON)); - } else { - sprintf(txt,"%s %s",p,Text_String(TXT_OFF)); - } - - Fancy_Text_Print (txt, - d_dialog_x + (d_dialog_w / 4) - String_Pixel_Width(p), - d_msg5_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Goody boxes - ............................................................*/ - p = Text_String(TXT_CRATES_COLON); - if (MPlayerGoodies) { - sprintf(txt,"%s %s",p,Text_String(TXT_ON)); - } else { - sprintf(txt,"%s %s",p,Text_String(TXT_OFF)); - } - - Fancy_Text_Print (txt, - d_dialog_x + d_dialog_w - (d_dialog_w / 4) - String_Pixel_Width(p), - d_msg4_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Computer AI players - ............................................................*/ - if (Special.IsCaptureTheFlag) { - p = Text_String(TXT_CAPTURE_THE_FLAG_COLON); - sprintf(txt,"%s %s",p,Text_String(TXT_ON)); - } else { - p = Text_String(TXT_AI_PLAYERS_COLON); - if (MPlayerGhosts) { - sprintf(txt,"%s %s",p,Text_String(TXT_ON)); - } else { - sprintf(txt,"%s %s",p,Text_String(TXT_OFF)); - } - } - Fancy_Text_Print (txt, - d_dialog_x + d_dialog_w - (d_dialog_w / 4) - String_Pixel_Width(p), - d_msg5_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - } else { - - /*............................................................... - Rejection notice - ...............................................................*/ - if (joinstate==JOIN_REJECTED) { - Fancy_Text_Print(TXT_REQUEST_DENIED, - d_dialog_cx, d_msg3_y, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - } - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - /*------------------------------------------------------------------ - User clicks on a color button: - - If we've joined a game, don't allow a new color selection - - otherwise, select that color - ------------------------------------------------------------------*/ - case KN_LMOUSE: - if (joinstate > JOIN_NOTHING) - break; - if (_Kbd->MouseQX > cbox_x[0] && - _Kbd->MouseQX < (cbox_x[MAX_MPLAYER_COLORS - 1] + d_color_w) && - _Kbd->MouseQY > d_color_y && - _Kbd->MouseQY < (d_color_y + d_color_h)) { - MPlayerPrefColor = (_Kbd->MouseQX - cbox_x[0]) / d_color_w; - MPlayerColorIdx = MPlayerPrefColor; - - name_edt.Set_Color (MPlayerTColors[MPlayerColorIdx]); - name_edt.Flag_To_Redraw(); - - display = REDRAW_COLORS; - } - break; - - /*------------------------------------------------------------------ - User clicks on the game list: - - If we've joined a game, don't allow the selected item to change; - otherwise: - - Clear the player list - - Send an immediate player query - ------------------------------------------------------------------*/ - case (BUTTON_GAMELIST | KN_BUTTON): - if (joinstate==JOIN_CONFIRMED) { - gamelist.Set_Selected_Index(game_index); - } else { - if (gamelist.Current_Index() != game_index) { - Clear_Player_List (&playerlist); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } - } - break; - - /*------------------------------------------------------------------ - House Buttons: set the player's desired House - ------------------------------------------------------------------*/ - case (BUTTON_GDI | KN_BUTTON): - MPlayerHouse = HOUSE_GOOD; - gdibtn.Turn_On(); - nodbtn.Turn_Off(); - break; - - case (BUTTON_NOD | KN_BUTTON): - MPlayerHouse = HOUSE_BAD; - gdibtn.Turn_Off(); - nodbtn.Turn_On(); - break; - - /*------------------------------------------------------------------ - JOIN: send a join request packet & switch to waiting-for-confirmation - mode. (Request_To_Join fills in MPlayerName with my namebuf.) - ------------------------------------------------------------------*/ - case (BUTTON_JOIN | KN_BUTTON): - name_edt.Clear_Focus(); - name_edt.Flag_To_Redraw(); - - join_index = gamelist.Current_Index(); - parms_received = 0; - if (Request_To_Join (namebuf, join_index, &playerlist, MPlayerHouse, - MPlayerColorIdx)) { - joinstate = JOIN_WAIT_CONFIRM; - } else { - display = REDRAW_ALL; - } - break; - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF - - If we're part of a game, stay in this dialog; otherwise, exit - ------------------------------------------------------------------*/ - case (KN_ESC): - if (Messages.Get_Edit_Buf() != NULL) { - Messages.Input(input); - display = REDRAW_MESSAGE; - break; - } - case (BUTTON_CANCEL | KN_BUTTON): - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy(GPacket.Name,MPlayerName); - - /*............................................................... - If we're joined to a game, make extra sure the other players in - that game know I'm exiting; send my SIGN_OFF as an ack-required - packet. Do not send this packet to myself (index 0). - ...............................................................*/ - if (joinstate == JOIN_CONFIRMED) { - // - // Remove myself from the player list box - // - if (playerlist.Count()) { // added: BRR 6/14/96 - item = (char *)(playerlist.Get_Item(0)); - playerlist.Remove_Item(item); - delete [] item; - playerlist.Flag_To_Redraw(); - } - - // - // Remove myself from the Players list - // - if (Players.Count()) { // added: BRR 6/14/96 - who = Players[0]; - Players.Delete(0); - delete who; - } - - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - } - - /*............................................................... - Now broadcast my SIGN_OFF so other players looking at this game - know I'm leaving. - ...............................................................*/ - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - - if (IsBridge) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - if (joinstate != JOIN_CONFIRMED) { - process = false; - rc = -1; - } else { - MPlayerGameName[0] = 0; - joinstate = JOIN_NOTHING; - display = REDRAW_ALL; - } - break; - - /*------------------------------------------------------------------ - NEW: bail out with return code 1 - ------------------------------------------------------------------*/ - case (BUTTON_NEW | KN_BUTTON): - /* - .................. Force user to enter a name ................... - */ - if (strlen(namebuf)==0) { - CCMessageBox().Process(TXT_NAME_ERROR); - display = REDRAW_ALL; - break; - } - /* - ..................... Ensure name is unique ..................... - */ - found = 0; - for (i = 0; i < Games.Count(); i++) { - if (!stricmp(Games[i]->Name, namebuf)) { - found = 1; - CCMessageBox().Process (TXT_GAMENAME_MUSTBE_UNIQUE); - display = REDRAW_ALL; - break; - } - } - if (found) - break; - /* - .................... Save player & game name .................... - */ - strcpy(MPlayerName,namebuf); - strcpy(MPlayerGameName,namebuf); - - name_edt.Clear_Focus(); - name_edt.Flag_To_Redraw(); - - rc = 1; - process = false; - break; - - /*------------------------------------------------------------------ - Default: manage the inter-player messages - ------------------------------------------------------------------*/ - default: - /*............................................................... - F4/SEND/'M' = edit a message - ...............................................................*/ - if (Messages.Get_Edit_Buf()==NULL) { - if ( (input == KN_M && joinstate==JOIN_CONFIRMED) || - input==(BUTTON_SEND | KN_BUTTON) || input == KN_F4) { - memset (txt, 0, 80); - - strcpy(txt,Text_String(TXT_TO_ALL)); // "To All:" - - Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, d_message_w-70*factor); - - if (joinstate <= JOIN_NOTHING) { - name_edt.Clear_Focus(); - name_edt.Flag_To_Redraw(); - } - - display = REDRAW_MESSAGE; - - break; - } - } else - - /*............................................................... - If we're already editing a message and the user clicks on - 'Send', translate our input to a Return so Messages.Input() will - work properly. - ...............................................................*/ - if (input==(BUTTON_SEND | KN_BUTTON)) { - input = KN_RETURN; - } - - /*............................................................... - Manage the message system (get rid of old messages) - ...............................................................*/ - if (Messages.Manage()) { - display = REDRAW_MESSAGE; - } - - /*............................................................... - Service keyboard input for any message being edited. - ...............................................................*/ - i = Messages.Input(input); - - /*............................................................... - If 'Input' returned 1, it means refresh the message display. - ...............................................................*/ - if (i==1) { - Messages.Draw(); - } else { - - /*............................................................... - If 'Input' returned 2, it means redraw the message display. - ...............................................................*/ - if (i==2) { - display = REDRAW_MESSAGE; - } else { - - /*............................................................... - If 'input' returned 3, it means send the current message. - ...............................................................*/ - if (i==3) { - long actual_message_size; - char *the_string; - - sent_so_far = 0; - magic_number = MESSAGE_HEAD_MAGIC_NUMBER; - message_length = strlen(Messages.Get_Edit_Buf()); - crc = (unsigned short) - (Calculate_CRC(Messages.Get_Edit_Buf(),message_length) &0xffff); - - while ( sent_so_far < message_length ){ - GPacket.Command = NET_MESSAGE; - strcpy (GPacket.Name, namebuf); - memcpy (GPacket.Message.Buf, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); - - /* - ** Steve I's stuff for splitting message on word boundries - */ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - - /* Start at the end of the message and find a space with 10 chars. */ - the_string = GPacket.Message.Buf; - while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && - the_string[actual_message_size] != ' '){ - --actual_message_size; - } - if ( the_string[actual_message_size] == ' ' ){ - - /* Now delete the extra characters after the space (they musnt print) */ - for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ - the_string[i + actual_message_size] = 0; //0xff; ST - 12/18/2018 11:36AM - } - }else{ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - } - - - *(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-5) = 0; - *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-4)) = magic_number; - *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-2)) = crc; - GPacket.Message.ID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - GPacket.Message.NameCRC = Compute_Name_CRC(MPlayerGameName); - - /*.................................................................. - Send the message to every player in our player list. The local - system will also receive this message, since it's in the Player list. - ..................................................................*/ - if (joinstate == JOIN_CONFIRMED) { - for (i = 1; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, - sizeof(GlobalPacketType), 1, &(Players[i]->Address)); - Ipx.Service(); - } - - sprintf(txt,Text_String (TXT_FROM), MPlayerName, GPacket.Message.Buf); - Messages.Add_Message (txt, - MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, magic_number, crc); - } - else { - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, - sizeof(GlobalPacketType), 1, &(Players[i]->Address)); - Ipx.Service(); - } - } - magic_number++; - sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; - } - } - } - } - break; - } - - /*--------------------------------------------------------------------- - Resend our query packets - ---------------------------------------------------------------------*/ - Send_Join_Queries(game_index, 0, 0); - - /*--------------------------------------------------------------------- - Process incoming packets - ---------------------------------------------------------------------*/ - event = Get_Join_Responses(&joinstate, &gamelist, &playerlist, - join_index); - /*..................................................................... - If we've changed state, redraw everything; if we're starting the game, - break out of the loop. If we've just joined, send out a player query - so I'll get added to the list instantly. - .....................................................................*/ - if (event == EV_STATE_CHANGE) { - display = REDRAW_ALL; - if (joinstate==JOIN_GAME_START) { - rc = 0; - process = false; - } else { - - /*.................................................................. - If we're newly-confirmed, immediately send out a player query - ..................................................................*/ - if (joinstate==JOIN_CONFIRMED) { - - Clear_Player_List(&playerlist); - - item = new char [MPLAYER_NAME_MAX + 4]; - if (MPlayerHouse==HOUSE_GOOD) { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_G_D_I)); - } else { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_N_O_D)); - } - playerlist.Add_Item (item, MPlayerTColors[MPlayerColorIdx]); - - who = new NodeNameType; - strcpy(who->Name, MPlayerName); - who->Address = IPXAddressClass(); - who->Player.House = MPlayerHouse; - who->Player.Color = MPlayerColorIdx; - Players.Add (who); - - Send_Join_Queries (game_index, 0, 1); - } else { - - /*.................................................................. - If we've been rejected, clear any messages we may have been typing. - ..................................................................*/ - if (joinstate==JOIN_REJECTED) { - - // - // Remove myself from the player list box - // - if (playerlist.Count()) { // added: BRR 6/14/96 - item = (char *)(playerlist.Get_Item(0)); - if (item){ - playerlist.Remove_Item(item); - delete [] item; - playerlist.Flag_To_Redraw(); - } - } - - // - // Remove myself from the Players list - // - if (Players.Count()){ - who = Players[0]; - Players.Delete(0); - delete who; - } - - Messages.Init (d_message_x + 2, d_message_y + 2, 4, - MAX_MESSAGE_LENGTH, d_txt6_h); - } - } - } - } else - - /*..................................................................... - If a new game is detected, and it's the first game on our list, - automatically send out a player query for that game. - .....................................................................*/ - if (event == EV_NEW_GAME && gamelist.Count()==1) { - gamelist.Set_Selected_Index(0); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } else - - /*..................................................................... - If the game options have changed, print them. - .....................................................................*/ - if (event == EV_GAME_OPTIONS) { - parms_received = 1; - display = REDRAW_MESSAGE; - } else - - /*..................................................................... - Draw an incoming message - .....................................................................*/ - if (event == EV_MESSAGE) { - display = REDRAW_MESSAGE; - } else - - /*..................................................................... - A game before the one I've selected is gone, so we have a new index now. - 'game_index' must be kept set to the currently-selected list item, so - we send out queries for the currently-selected game. It's therefore - imperative that we detect any changes to the game list. - If we're joined in a game, we must decrement our game_index to keep - it aligned with the game we're joined to. - .....................................................................*/ - if (event == EV_GAME_SIGNOFF) { - if (joinstate==JOIN_CONFIRMED) { - game_index--; - join_index--; - gamelist.Set_Selected_Index(join_index); - } else { - gamelist.Flag_To_Redraw(); - Clear_Player_List(&playerlist); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } - } - - /*--------------------------------------------------------------------- - Service the Ipx connections - ---------------------------------------------------------------------*/ - Ipx.Service(); - - /*--------------------------------------------------------------------- - Clean out the Game List; if an old entry is found: - - Remove it - - Clear the player list - - Send queries for the new selected game, if there is one - ---------------------------------------------------------------------*/ - for (i = 0; i < Games.Count(); i++) { - if (TickCount.Time() - Games[i]->Game.LastTime > 400) { - Games.Delete(Games[i]); - item = (char *)(gamelist.Get_Item (i)); - gamelist.Remove_Item (item); - delete [] item; - if (i <= game_index) { - gamelist.Flag_To_Redraw(); - Clear_Player_List(&playerlist); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } - } - } - - /*--------------------------------------------------------------------- - Service the sounds & score; GameActive must be false at this point, - so Call_Back() doesn't intercept global messages from me! - ---------------------------------------------------------------------*/ - Call_Back(); - } - - /*------------------------------------------------------------------------ - Establish connections with all other players. - ------------------------------------------------------------------------*/ - if (rc == 0) { - /*..................................................................... - If the other guys are playing a scenario I don't have (sniff), I can't - play. Try to bail gracefully. - .....................................................................*/ - if (ScenarioIdx==-1) { - CCMessageBox().Process (TXT_UNABLE_PLAY_WAAUGH); - - // - // Remove myself from the player list box - // - if (playerlist.Count()) { // added: BRR 6/14/96 - item = (char *)(playerlist.Get_Item(0)); - playerlist.Remove_Item(item); - delete [] item; - playerlist.Flag_To_Redraw(); - } - - // - // Remove myself from the Players list - // - if (Players.Count()) { // added: BRR 6/14/96 - who = Players[0]; - Players.Delete(0); - delete who; - } - - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy (GPacket.Name, MPlayerName); - - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - - if (IsBridge) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - rc = -1; - - } else { - - /*.................................................................. - Set the number of players in this game, and my ID - ..................................................................*/ - MPlayerCount = Players.Count(); - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - /*.................................................................. - Get the scenario number - ..................................................................*/ - Scenario = MPlayerFilenum[ScenarioIdx]; - - /*.................................................................. - Form connections with all other players. Form the IPX Connection ID - from the player's Color and House. This will let us extract any - player's color & house at any time. Fill in 'tmp_id' while we're - doing this. - ..................................................................*/ - for (i = 0; i < Players.Count(); i++) { - - /*............................................................... - Only create the connection if it's not myself! - ...............................................................*/ - if (strcmp (MPlayerName, Players[i]->Name)) { - id = Build_MPlayerID(Players[i]->Player.Color, - Players[i]->Player.House); - - tmp_id[i] = id; - - Ipx.Create_Connection((int)id, Players[i]->Name, &(Players[i]->Address) ); - } else { - tmp_id[i] = MPlayerLocalID; - } - } - - /*.................................................................. - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - ..................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - min_index = 0; - min_id = 0xff; - for (j = 0; j < MPlayerCount; j++) { - if (tmp_id[j] < min_id) { - min_id = tmp_id[j]; - min_index = j; - } - } - MPlayerID[i] = tmp_id[min_index]; - tmp_id[min_index] = 0xff; - } - /*.................................................................. - Fill in the array of player names, including my own. - ..................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == MPlayerLocalID) { - strcpy (MPlayerNames[i], MPlayerName); - } else { - strcpy (MPlayerNames[i], Ipx.Connection_Name(MPlayerID[i])); - } - } - } - /*--------------------------------------------------------------------- - Wait a while, polling the IPX service routines, to give our ACK - a chance to get to the other system. If he doesn't get our ACK, he'll - be waiting the whole time we load MIX files. - ---------------------------------------------------------------------*/ - i = MAX(Ipx.Global_Response_Time() * 2, (unsigned long)60); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < (unsigned)i) { - Ipx.Service(); - } - } - - /*------------------------------------------------------------------------ - Init network timing values, using previous response times as a measure - of what our retry delta & timeout should be. - ------------------------------------------------------------------------*/ - Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1, - Ipx.Global_Response_Time() * 4); - - /*------------------------------------------------------------------------ - Clear all lists - ------------------------------------------------------------------------*/ - Clear_Game_List(&gamelist); - Clear_Player_List(&playerlist); - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - return(rc); -} - - -/*************************************************************************** - * Clear_Game_List -- Clears the game-name listbox & 'Games' Vector * - * * - * Assumes each entry in 'Games' & the list box have been allocated * - * separately. * - * * - * INPUT: * - * gamelist ptr to list box * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - *=========================================================================*/ -static void Clear_Game_List (ListClass *gamelist) -{ - char * item; - int i; - - /*------------------------------------------------------------------------ - Clear the list box - ------------------------------------------------------------------------*/ - while (gamelist->Count()) { - item = (char *)(gamelist->Get_Item (0)); - gamelist->Remove_Item(item); - delete [] item; - } - gamelist->Flag_To_Redraw(); - - /*------------------------------------------------------------------------ - Clear the 'Games' Vector - ------------------------------------------------------------------------*/ - for (i = 0; i < Games.Count(); i++) - delete Games[i]; - - Games.Clear(); - -} /* end of Clear_Game_List */ - - -/*************************************************************************** - * Clear_Player_List -- Clears the player-name listbox & Vector * - * * - * Assumes each entry in 'Players' & the list box have been allocated * - * separately. * - * * - * INPUT: * - * playerlist ptr to list box * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - *=========================================================================*/ -static void Clear_Player_List (ListClass *playerlist) -{ - char * item; - int i; - - /*------------------------------------------------------------------------ - Clear the list box - ------------------------------------------------------------------------*/ - while (playerlist->Count()) { - item = (char *)(playerlist->Get_Item(0)); - playerlist->Remove_Item(item); - delete [] item; - } - playerlist->Flag_To_Redraw(); - - /*------------------------------------------------------------------------ - Clear the 'Players' Vector - ------------------------------------------------------------------------*/ - for (i = 0; i < Players.Count(); i++) - delete Players[i]; - - Players.Clear(); - -} /* end of Clear_Player_List */ - - -/*************************************************************************** - * Request_To_Join -- Sends a JOIN request packet to game owner * - * * - * Regardless of the return code, the Join Dialog will need to be redrawn * - * after calling this routine. * - * * - * INPUT: * - * playername player's name * - * join_index index of game we're joining * - * playerlist listbox containing other players' names * - * house requested house * - * color requested color * - * * - * OUTPUT: * - * 1 = Packet sent, 0 = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - *=========================================================================*/ -static int Request_To_Join (char *playername, int join_index, ListClass *playerlist, - HousesType house, int color) -{ - int i; - - playerlist = playerlist; // shaddup, Mr stupid compiler! - - /* - --------------------------- Validate join_index -------------------------- - */ - if ( (Games.Count()==0) || join_index > Games.Count() || join_index < 0) { - CCMessageBox().Process (TXT_NOTHING_TO_JOIN); - return(false); - } - - /* - ----------------------- Force user to enter a name ----------------------- - */ - if (strlen(playername)==0) { - CCMessageBox().Process (TXT_NAME_ERROR); - return(false); - } - - /* - ------------------------- The game must be open -------------------------- - */ - if (!Games[join_index]->Game.IsOpen) { - CCMessageBox().Process(TXT_GAME_IS_CLOSED); - return (false); - } - - /* - ------------------------ Make sure name is unique ------------------------ - */ - for (i = 0; i < Players.Count(); i++) { - if (!stricmp(playername, Players[i]->Name)) { - CCMessageBox().Process (TXT_NAME_MUSTBE_UNIQUE); - return(false); - } - } - - /* - ----------------------------- Check version #'s -------------------------- - */ - int v; -#ifdef PATCH - if (IsV107) { - v = 1; - } else { - v = 2; - } -#else - v = Version_Number(); -#endif - if (Games[join_index]->Game.Version > v) { - CCMessageBox().Process (TXT_YOURGAME_OUTDATED); - return(false); - } else { - if (Games[join_index]->Game.Version < v) { - CCMessageBox().Process (TXT_DESTGAME_OUTDATED); - return(false); - } - } - - /* - ----------------------------- Save game name ----------------------------- - */ - strcpy (MPlayerName,playername); - - /* - ----------------------- Send packet to game's owner ---------------------- - */ - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_QUERY_JOIN; - strcpy (GPacket.Name, MPlayerName); - GPacket.PlayerInfo.House = house; - GPacket.PlayerInfo.Color = color; - - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Games[join_index]->Address)); - - return(true); -} - - -/*********************************************************************************************** - * Send_Join_Queries -- sends queries for the Join Dialog * - * * - * This routine [re]sends the queries related to the Join Dialog: * - * - NET_QUERY_GAME * - * - NET_QUERY_PLAYER for the game currently selected (if there is one) * - * * - * The queries are "staggered" in time so they aren't all sent at once; otherwise, we'd * - * be inundated with reply packets & we'd miss some (even though the replies will require * - * ACK's). * - * * - * INPUT: * - * curgame index of currently-selected game; -1 = none * - * gamenow if 1, will immediately send the game query * - * playernow if 1, will immediately send the player query for currently-selected game * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - * 04/15/1995 BRR : Created. * - *=============================================================================================*/ -static void Send_Join_Queries(int curgame, int gamenow, int playernow) -{ - static int lasttime1 = 0; // time since last Game query sent out - static int lasttime2 = 0; // time since last Player query sent out - - /*------------------------------------------------------------------------ - Send the game-name query if the time has expired, or we're told to do - it right now - ------------------------------------------------------------------------*/ - if ( (TickCount.Time() - lasttime1 > 120) || gamenow) { - lasttime1 = TickCount.Time(); - - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_QUERY_GAME; - - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, NULL); - - /*..................................................................... - If the user specified a remote server address, broadcast over that - network, too. - .....................................................................*/ - if (IsBridge) - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - - /*------------------------------------------------------------------------ - Send the player query for the game currently clicked on, if the time has - expired and there is a currently-selected game, or we're told to do it - right now - ------------------------------------------------------------------------*/ - if ( (curgame != -1) && curgame < Games.Count() && - ((TickCount.Time() - lasttime2 > 35) || playernow) ) { - lasttime2 = TickCount.Time(); - - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_QUERY_PLAYER; - strcpy (GPacket.Name, Games[curgame]->Name); - - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, NULL); - - /*..................................................................... - If the user specified a remote server address, broadcast over that - network, too. - .....................................................................*/ - if (IsBridge) - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - -} /* end of Send_Join_Queries */ - - -/*********************************************************************************************** - * Get_Join_Responses -- sends queries for the Join Dialog * - * * - * This routine polls the Global Channel to see if there are any incoming packets; * - * if so, it processes them. This routine can change the state of the Join Dialog, or * - * the contents of the list boxes, based on what the packet is. * - * * - * The list boxes are passed in as pointers; they can't be made globals, because they * - * can't be constructed, because they require shape pointers to the arrow buttons, and * - * the mix files won't have been initialized when the global variables' constructors are * - * called. * - * * - * This routine sets the globals * - * MPlayerHouse (from NET_CONFIRM_JOIN) * - * MPlayerColorIdx (from NET_CONFIRM_JOIN) * - * MPlayerBases (from NET_GAME_OPTIONS) * - * MPlayerTiberium (from NET_GAME_OPTIONS) * - * MPlayerGoodies (from NET_GAME_OPTIONS) * - * MPlayerGhosts (from NET_GAME_OPTIONS) * - * ScenarioIdx (from NET_GAME_OPTIONS; -1 = scenario not found) * - * * - * INPUT: * - * joinstate current state of Join Dialog * - * gamelist list box containing game names * - * playerlist list box containing player names for the currently-selected game * - * join_index index of the game we've joined or are asking to join * - * * - * OUTPUT: * - * Event that occurred * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - * 04/15/1995 BRR : Created. * - *=============================================================================================*/ -static JoinEventType Get_Join_Responses(JoinStateType *joinstate, ListClass *gamelist, - ColorListClass *playerlist, int join_index) -{ - int rc; - char * item; // general-purpose string - NodeNameType *who; // node to add to Games or Players - int i; - int found; - JoinEventType retcode = EV_NONE; - char txt[80]; - int color; - unsigned short magic_number; - unsigned short crc; - - /*------------------------------------------------------------------------ - If there is no incoming packet, just return - ------------------------------------------------------------------------*/ - rc = Ipx.Get_Global_Message (&GPacket, &GPacketlen, &GAddress, &GProductID); - if (!rc || GProductID != IPXGlobalConnClass::COMMAND_AND_CONQUER) - return(EV_NONE); - - /*------------------------------------------------------------------------ - If we're joined in a game, handle the packet in a standard way; otherwise, - don't answer standard queries. - ------------------------------------------------------------------------*/ - if ( (*joinstate)==JOIN_CONFIRMED && - Process_Global_Packet(&GPacket,&GAddress)!=0) - return(EV_NONE); - - /*------------------------------------------------------------------------ - NET_ANSWER_GAME: Another system is answering our GAME query, so add that - system to our list box if it's new. - ------------------------------------------------------------------------*/ - if (GPacket.Command==NET_ANSWER_GAME) { - /*..................................................................... - See if this name is unique - .....................................................................*/ - retcode = EV_NONE; - found = 0; - for (i = 0; i < Games.Count(); i++) { - if (!strcmp(Games[i]->Name, GPacket.Name)) { - found = 1; - /*............................................................... - If name was found, update the node's time stamp & IsOpen flag. - ...............................................................*/ - Games[i]->Game.LastTime = TickCount.Time(); - if (Games[i]->Game.IsOpen != GPacket.GameInfo.IsOpen) { - item = (char *)gamelist->Get_Item(i); - if (GPacket.GameInfo.IsOpen) { - sprintf(item,Text_String(TXT_THATGUYS_GAME),GPacket.Name); - } else { - sprintf(item,Text_String(TXT_THATGUYS_GAME_BRACKET),GPacket.Name); - } - Games[i]->Game.IsOpen = GPacket.GameInfo.IsOpen; - gamelist->Flag_To_Redraw(); - /*............................................................ - If this game has gone from closed to open, copy the responder's - address into our Game slot, since the guy responding to this - must be game owner. - ............................................................*/ - if (Games[i]->Game.IsOpen) - Games[i]->Address = GAddress; - } - break; - } - } - /*..................................................................... - name not found (or addresses are different); add it to 'Games' - .....................................................................*/ - if (found==0) { - /*.................................................................. - Create a new node structure, fill it in, add it to 'Games' - ..................................................................*/ - who = new NodeNameType; - strcpy(who->Name, GPacket.Name); - who->Address = GAddress; - who->Game.Version = GPacket.GameInfo.Version; - who->Game.IsOpen = GPacket.GameInfo.IsOpen; - who->Game.LastTime = TickCount.Time(); - Games.Add (who); - - /*.................................................................. - Create a string for "xxx's Game", leaving room for brackets around - the string if it's a closed game - ..................................................................*/ - item = new char [MPLAYER_NAME_MAX + 9]; - if (GPacket.GameInfo.IsOpen) { - sprintf(item,Text_String(TXT_THATGUYS_GAME),GPacket.Name); - } else { - sprintf(item,Text_String(TXT_THATGUYS_GAME_BRACKET),GPacket.Name); - } - gamelist->Add_Item(item); - - retcode = EV_NEW_GAME; - } - } - - /*------------------------------------------------------------------------ - NET_ANSWER_PLAYER: Another system is answering our PLAYER query, so add it - to our player list box & the Player Vector if it's new - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_ANSWER_PLAYER) { - /*..................................................................... - See if this name is unique - .....................................................................*/ - retcode = EV_NONE; - found = 0; - for (i = 0; i < Players.Count(); i++) { - /*.................................................................. - If the address is already present, re-copy their name, color & - house into the existing entry, in case they've changed it without - our knowledge; set the 'found' flag so we won't create a new entry. - ..................................................................*/ - if (Players[i]->Address==GAddress) { - strcpy(Players[i]->Name, GPacket.Name); - Players[i]->Player.House = GPacket.PlayerInfo.House; - Players[i]->Player.Color = GPacket.PlayerInfo.Color; - playerlist->Colors[i] = MPlayerTColors[GPacket.PlayerInfo.Color]; - found = 1; - break; - } - } - /*..................................................................... - Don't add this player if he's not part of the game that's selected. - .....................................................................*/ - i = gamelist->Current_Index(); - if (Games.Count() && GPacket.PlayerInfo.NameCRC != Compute_Name_CRC(Games[i]->Name)) - found = 1; - - /* - ** Dont add this player if its really me! (hack, hack) - */ - if (!strcmp(GPacket.Name, MPlayerName)){ - found = 1; - } - - - /*..................................................................... - name not found (or address didn't match); add to player list box & Vector - .....................................................................*/ - if (found==0) { - /*.................................................................. - Create & add a node to the Vector - ..................................................................*/ - who = new NodeNameType; - strcpy(who->Name, GPacket.Name); - who->Address = GAddress; - who->Player.House = GPacket.PlayerInfo.House; - who->Player.Color = GPacket.PlayerInfo.Color; - Players.Add (who); - - /*.................................................................. - Create & add a string to the list box - ..................................................................*/ - item = new char [MPLAYER_NAME_MAX + 4]; - if (GPacket.PlayerInfo.House==HOUSE_GOOD) { - sprintf(item,"%s\t%s",GPacket.Name,Text_String(TXT_G_D_I)); - } else { - sprintf(item,"%s\t%s",GPacket.Name,Text_String(TXT_N_O_D)); - } - playerlist->Add_Item(item, MPlayerTColors[who->Player.Color]); - - retcode = EV_NEW_PLAYER; - } - } - - /*------------------------------------------------------------------------ - NET_CONFIRM_JOIN: The game owner has confirmed our JOIN query; mark us as - being confirmed, and start answering queries from other systems - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_CONFIRM_JOIN) { - if ( (*joinstate) != JOIN_CONFIRMED) { - strcpy (MPlayerGameName, GPacket.Name); - MPlayerHouse = GPacket.PlayerInfo.House; - MPlayerColorIdx = GPacket.PlayerInfo.Color; - - (*joinstate) = JOIN_CONFIRMED; - retcode = EV_STATE_CHANGE; - } - } - - /*------------------------------------------------------------------------ - NET_REJECT_JOIN: The game owner has turned down our JOIN query; restore - the dialog state to its first pop-up state. Broadcast a sign-off to - tell all other systems that I'm no longer a part of any game; this way, - I'll be properly removed from their dialogs. - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_REJECT_JOIN) { - if ( (*joinstate) != JOIN_REJECTED) { - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy (GPacket.Name,MPlayerName); - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), 0, NULL); - - if (IsBridge) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - MPlayerGameName[0] = 0; - - (*joinstate) = JOIN_REJECTED; - retcode = EV_STATE_CHANGE; - } - } - - /*------------------------------------------------------------------------ - NET_GAME_OPTIONS: The game owner has changed the game options & is sending - us the new values. - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_GAME_OPTIONS) { - if ( (*joinstate)==JOIN_CONFIRMED) { - MPlayerCredits = GPacket.ScenarioInfo.Credits; - MPlayerBases = GPacket.ScenarioInfo.IsBases; - MPlayerTiberium = GPacket.ScenarioInfo.IsTiberium; - MPlayerGoodies = GPacket.ScenarioInfo.IsGoodies; - MPlayerGhosts = GPacket.ScenarioInfo.IsGhosties; - BuildLevel = GPacket.ScenarioInfo.BuildLevel; - MPlayerUnitCount = GPacket.ScenarioInfo.UnitCount; - Seed = GPacket.ScenarioInfo.Seed; - Special = GPacket.ScenarioInfo.Special; - Options.GameSpeed = GPacket.ScenarioInfo.GameSpeed; - - if (MPlayerTiberium) { - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - } else { - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - } - - if (Winsock.Get_Connected()){ - ScenarioIdx = GPacket.ScenarioInfo.Scenario; - }else{ - - ScenarioIdx = -1; - for (i = 0; i < MPlayerFilenum.Count(); i++) { - if (GPacket.ScenarioInfo.Scenario == MPlayerFilenum[i]) - ScenarioIdx = i; - } - } - - retcode = EV_GAME_OPTIONS; - } - } - - /*------------------------------------------------------------------------ - NET_SIGN_OFF: Another system is signing off: search for that system in - both the game list & player list, & remove it if found - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_SIGN_OFF) { - /*..................................................................... - Remove this name from the list of games - .....................................................................*/ - for (i = 0; i < Games.Count(); i++) { - if (!strcmp(Games[i]->Name, GPacket.Name) && - Games[i]->Address==GAddress) { - /*............................................................... - If the system signing off is the currently-selected list - item, clear the player list since that game is no longer - forming. - ...............................................................*/ - if (i==gamelist->Current_Index()) { - Clear_Player_List (playerlist); - } - - /*............................................................... - If the system signing off was the owner of our game, mark - ourselves as rejected - ...............................................................*/ - if ( (*joinstate) > JOIN_NOTHING && i==join_index) { - (*joinstate) = JOIN_REJECTED; - retcode = EV_STATE_CHANGE; - } - - /* - ....................... Set my return code ...................... - */ - if (retcode == EV_NONE) { - if (i <= gamelist->Current_Index()) { - retcode = EV_GAME_SIGNOFF; - } else { - retcode = EV_PLAYER_SIGNOFF; - } - } - - /* - ................. Remove game name from game list ............... - */ - Games.Delete(Games[i]); - item = (char *)(gamelist->Get_Item (i)); - gamelist->Remove_Item (item); - delete [] item; - gamelist->Flag_To_Redraw(); - - } - } - /*..................................................................... - Remove this name from the list of players - .....................................................................*/ - for (i = 0; i < Players.Count(); i++) { - /* - ..................... Name found; remove it ..................... - */ - if (Players[i]->Address==GAddress) { - item = (char *)(playerlist->Get_Item(i)); - playerlist->Remove_Item(item); - delete [] item; - Players.Delete(Players[i]); - playerlist->Flag_To_Redraw(); - - if (retcode == EV_NONE) - retcode = EV_PLAYER_SIGNOFF; - } - } - } - - /*------------------------------------------------------------------------ - NET_GO: The game's owner is signalling us to start playing. - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_GO) { - if ( (*joinstate)==JOIN_CONFIRMED) { - MPlayerMaxAhead = GPacket.ResponseTime.OneWay; - (*joinstate) = JOIN_GAME_START; - retcode = EV_STATE_CHANGE; -CCDebugString ("C&C95 - Received the 'GO' packet\n"); - } - } - - /*------------------------------------------------------------------------ - NET_MESSAGE: Someone is sending us a message - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_MESSAGE) { - sprintf(txt,Text_String (TXT_FROM), GPacket.Name, GPacket.Message.Buf); - magic_number = *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-4)); - crc = *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-2)); - color = MPlayerID_To_ColorIndex(GPacket.Message.ID); - Messages.Add_Message (txt, MPlayerTColors[color], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); - retcode = EV_MESSAGE; - } - - /*------------------------------------------------------------------------ - NET_PING: Someone is pinging me to get a response time measure (will only - happen after I've joined a game). Do nothing; the IPX Manager will handle - sending an ACK, and updating the response time measurements. - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_PING) { - retcode = EV_NONE; - } - - /*------------------------------------------------------------------------ - Default case: nothing happened. (This case will be hit every time I - receive my own NET_QUERY_GAME or NET_QUERY_PLAYER packets.) - ------------------------------------------------------------------------*/ - else { - retcode = EV_NONE; - } - - return(retcode); -} - - -/*********************************************************************************************** - * Net_New_Dialog -- lets user start a new game * - * * - * This dialog shows a list of who's requesting to join this game, and lets * - * the game initiator selectively approve each user. * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ New Network Game ³ * - * ³ ³ * - * ³ Players Scenario ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ Boffo ³³ ³ Hell's Kitchen ³³ ³ * - * ³ ³ Bozo ÃÄ´ ³ Heaven's Gate ÃÄ´ ³ * - * ³ ³ Bonzo ³ ³ ³ ... ³ ³ ³ * - * ³ ³ ÃÄ´ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ [Reject] Count:--- ## ³ * - * ³ Level:--- ## ³ * - * ³ ³ * - * ³ Credits: _____ ³ * - * ³ [ Bases ] [ Crates ] ³ * - * ³ [ Tiberium ] [ AI Players ] ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ [Send Message] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = success, false = cancel * - * * - * WARNINGS: * - * MPlayerName & MPlayerGameName must contain this player's name. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -static int Net_New_Dialog(void) -{ -/* ###Change collision detected! C:\PROJECTS\CODE\NETDLG.CPP... */ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - //D_DIALOG_W = 281; // dialog width - int d_dialog_w = 287*factor; // dialog width - int d_dialog_h = 177*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 6*factor+1; // ht of 6-pt text - int d_margin1 = 5*factor; // margin width/height - int d_margin2 = 2*factor; // margin width/height - - //d_playerlist_w = 100; - int d_playerlist_w = 106*factor; - int d_playerlist_h = 27*factor; - int d_playerlist_x = d_dialog_x + d_margin1; - int d_playerlist_y = d_dialog_y + d_margin1 + (d_txt6_h * 3); - - int d_scenariolist_w = 162*factor; - int d_scenariolist_h = 27*factor; - int d_scenariolist_x = d_dialog_x + d_dialog_w - d_margin1 - d_scenariolist_w; - int d_scenariolist_y = d_dialog_y + d_margin1 + (d_txt6_h * 3); - -#if (GERMAN | FRENCH) - int d_reject_w = 55*factor; -#else - int d_reject_w = 45*factor; -#endif - int d_reject_h = 9*factor; - int d_reject_x = d_playerlist_x + (d_playerlist_w / 2) - (d_reject_w / 2); - int d_reject_y = d_playerlist_y + d_playerlist_h + d_margin2; - - int d_count_w = 25*factor; - int d_count_h = d_txt6_h; - int d_count_x = d_scenariolist_x + (d_scenariolist_w / 2); - int d_count_y = d_scenariolist_y + d_scenariolist_h + d_margin2; - - int d_level_w = 25*factor; - int d_level_h = d_txt6_h; - int d_level_x = d_scenariolist_x + (d_scenariolist_w / 2); - int d_level_y = d_count_y + d_count_h; - - int d_credits_w = ((CREDITSBUF_MAX - 1) * 7*factor) + 4*factor; - //int d_credits_w = ((CREDITSBUF_MAX - 1) * 6*factor) + 3*factor; - int d_credits_h = 9*factor; - int d_credits_x = d_dialog_cx + 2*factor; - int d_credits_y = d_level_y + d_level_h + d_margin1; - -#if (GERMAN | FRENCH) - int d_bases_w = 120*factor;//bga:100; -#else - int d_bases_w = 100*factor; -#endif - int d_bases_h = 9*factor; - int d_bases_x = d_dialog_cx - d_bases_w - d_margin2; - int d_bases_y = d_credits_y + d_credits_h + d_margin2; - -#if (GERMAN | FRENCH) - int d_tiberium_w = 120*factor; -#else - int d_tiberium_w = 100*factor; -#endif - int d_tiberium_h = 9*factor; - int d_tiberium_x = d_dialog_cx - d_bases_w - d_margin2; - int d_tiberium_y = d_bases_y + d_bases_h + d_margin2; - -#if (GERMAN | FRENCH) - int d_goodies_w = 120*factor; -#else - int d_goodies_w = 100*factor; -#endif - int d_goodies_h = 9*factor; - int d_goodies_x = d_dialog_cx + d_margin2; - int d_goodies_y = d_credits_y + d_credits_h + d_margin2; - -#if (GERMAN | FRENCH) - int d_ghosts_w = 120*factor; -#else - int d_ghosts_w = 100*factor; -#endif - int d_ghosts_h = 9*factor; - int d_ghosts_x = d_dialog_cx + d_margin2; - int d_ghosts_y = d_goodies_y + d_goodies_h + d_margin2; - - int d_ok_w = 45*factor; - int d_ok_h = 9*factor; - int d_ok_x = d_dialog_cx - d_margin2 - (d_bases_w / 2) - (d_ok_w / 2); - int d_ok_y = d_ghosts_y + d_ghosts_h + d_margin1; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50*factor; -#else - int d_cancel_w = 45*factor; -#endif - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx + d_margin2 + (d_goodies_w / 2) - (d_cancel_w / 2); - int d_cancel_y = d_ghosts_y + d_ghosts_h + d_margin1; - - int d_message_w = d_dialog_w - (d_margin1 * 2); - int d_message_h = 34*factor; - int d_message_x = d_dialog_x + d_margin1; - int d_message_y = d_cancel_y + d_cancel_h + d_margin1; - - int d_send_w = 80*factor; - int d_send_h = 9*factor; - int d_send_x = d_dialog_cx - (d_send_w / 2); - int d_send_y = d_message_y + d_message_h + d_margin2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_PLAYERLIST = 100, - BUTTON_SCENARIOLIST, - BUTTON_REJECT, - BUTTON_COUNT, - BUTTON_LEVEL, - BUTTON_CREDITS, - BUTTON_BASES, - BUTTON_TIBERIUM, - BUTTON_GOODIES, - BUTTON_GHOSTS, - BUTTON_OK, - BUTTON_CANCEL, - BUTTON_SEND, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_UNIT_COUNT, - REDRAW_MESSAGE, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - KeyNumType input; - - char credbuf[CREDITSBUF_MAX]; // for credit edit box - int old_cred; // old value in credits buffer - int transmit; // 1 = re-transmit new game options - - long ok_timer = 0; // for timing OK button - int index; // index for rejecting a player - int rc; - int i,j; - char *item; - int tabs[] = {77*factor}; // tabs for player list box - - long ping_timer = 0; // for sending Ping packets - - unsigned char tmp_id[MAX_PLAYERS]; // temp storage for sorting player ID's - int min_index; // for sorting player ID's - unsigned char min_id; // for sorting player ID's - unsigned char id; // connection ID - char txt[80]; - JoinEventType whahoppa; // event generated by received packets - static int first_time = 1; // 1 = 1st time this dialog is run - - int message_length; - int sent_so_far; - unsigned short magic_number; - unsigned short crc; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - - ColorListClass playerlist(BUTTON_PLAYERLIST, - d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - ListClass scenariolist(BUTTON_SCENARIOLIST, - d_scenariolist_x, d_scenariolist_y, d_scenariolist_w, d_scenariolist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - EditClass credit_edt (BUTTON_CREDITS, - credbuf, CREDITSBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_credits_x, d_credits_y, d_credits_w, d_credits_h, EditClass::ALPHANUMERIC); - - TextButtonClass rejectbtn(BUTTON_REJECT, TXT_REJECT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_reject_x, d_reject_y); -//#else - d_reject_x, d_reject_y, d_reject_w, d_reject_h); -//#endif - - GaugeClass countgauge (BUTTON_COUNT, - d_count_x, d_count_y, d_count_w, d_count_h); - - GaugeClass levelgauge (BUTTON_LEVEL, - d_level_x, d_level_y, d_level_w, d_level_h); - - TextButtonClass basesbtn(BUTTON_BASES, TXT_BASES_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_bases_x, d_bases_y, d_bases_w, d_bases_h); - - TextButtonClass tiberiumbtn(BUTTON_TIBERIUM, TXT_TIBERIUM_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_tiberium_x, d_tiberium_y, d_tiberium_w, d_tiberium_h); - - TextButtonClass goodiesbtn(BUTTON_GOODIES, TXT_CRATES_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_goodies_x, d_goodies_y, d_goodies_w, d_goodies_h); - - TextButtonClass ghostsbtn(BUTTON_GHOSTS, TXT_AI_PLAYERS_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ghosts_x, d_ghosts_y, d_ghosts_w, d_ghosts_h); - - TextButtonClass okbtn(BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ok_x, d_ok_y, d_ok_w, d_ok_h); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - TextButtonClass sendbtn(BUTTON_SEND, TXT_SEND_MESSAGE, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_send_x, d_send_y); -//#else - d_send_x, d_send_y, d_send_w, d_send_h); -//#endif - - /* - ------------------------- Build the button list -------------------------- - */ - commands = &playerlist; - scenariolist.Add_Tail(*commands); - credit_edt.Add_Tail(*commands); - rejectbtn.Add_Tail(*commands); - countgauge.Add_Tail(*commands); - levelgauge.Add_Tail(*commands); - basesbtn.Add_Tail(*commands); - tiberiumbtn.Add_Tail(*commands); - goodiesbtn.Add_Tail(*commands); - ghostsbtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - sendbtn.Add_Tail(*commands); - - playerlist.Set_Tabs(tabs); - - /* - ----------------------------- Various Inits ------------------------------ - */ - /*........................................................................ - Init dialog values, only the first time through - ........................................................................*/ - if (first_time) { - MPlayerCredits = 3000; // init credits & credit buffer - MPlayerBases = 1; // init scenario parameters - MPlayerTiberium = 0; - MPlayerGoodies = 0; - MPlayerGhosts = 0; - Special.IsCaptureTheFlag = 0; - MPlayerUnitCount = (MPlayerCountMax[MPlayerBases] + MPlayerCountMin[MPlayerBases]) / 2; - first_time = 0; - } - - /*........................................................................ - Init button states - ........................................................................*/ - if (MPlayerBases) { - basesbtn.Turn_On(); - basesbtn.Set_Text(TXT_BASES_ON); - } - if (MPlayerTiberium) { - tiberiumbtn.Turn_On(); - tiberiumbtn.Set_Text(TXT_TIBERIUM_ON); - } - if (MPlayerGoodies) { - goodiesbtn.Turn_On(); - goodiesbtn.Set_Text(TXT_CRATES_ON); - } - if (MPlayerGhosts) { - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_AI_PLAYERS_ON); - } - if (Special.IsCaptureTheFlag) { - MPlayerGhosts = 0; - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_CAPTURE_THE_FLAG); - } - - sprintf(credbuf, "%d", MPlayerCredits); - credit_edt.Set_Text(credbuf, CREDITSBUF_MAX); - old_cred = MPlayerCredits; - - levelgauge.Set_Maximum(MPLAYER_BUILD_LEVEL_MAX - 1); - levelgauge.Set_Value(BuildLevel - 1); - - countgauge.Set_Maximum(MPlayerCountMax[MPlayerBases] - MPlayerCountMin[MPlayerBases]); - countgauge.Set_Value(MPlayerUnitCount - MPlayerCountMin[MPlayerBases]); - - /*........................................................................ - Init other scenario parameters - ........................................................................*/ - Special.IsTGrowth = MPlayerTiberium; - Special.IsTSpread = MPlayerTiberium; - transmit = 0; - - /*........................................................................ - Init scenario description list box - ........................................................................*/ - for (i = 0; i < MPlayerScenarios.Count(); i++) { - scenariolist.Add_Item (strupr(MPlayerScenarios[i])); - } - ScenarioIdx = 0; // 1st scenario is selected - - /*........................................................................ - Init player color-used flags - ........................................................................*/ - for (i = 0; i < MAX_MPLAYER_COLORS; i++) { - ColorUsed[i] = 0; // init all colors to available - } - ColorUsed[MPlayerColorIdx] = 1; // set my color to used - playerlist.Set_Selected_Style(ColorListClass::SELECT_BAR, CC_GREEN_SHADOW); - - /*........................................................................ - Init random-number generator, & create a seed to be used for all random - numbers from here on out - ........................................................................*/ - //ST - 12/18/2018 11:37AM - //randomize(); - //Seed = rand(); - - /*........................................................................ - Init the message display system - ........................................................................*/ - Messages.Init (d_message_x + 2*factor, d_message_y + 2*factor, 4, MAX_MESSAGE_LENGTH, - d_txt6_h); - - /*------------------------------------------------------------------------ - Add myself to the list. Note that since I'm not in the Players Vector, - the Vector & listbox are now 1 out of sync. - ------------------------------------------------------------------------*/ - item = new char [MPLAYER_NAME_MAX + 4]; - if (MPlayerHouse==HOUSE_GOOD) { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_G_D_I)); - } else { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_N_O_D)); - } - playerlist.Add_Item(item, MPlayerTColors[MPlayerColorIdx]); - - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - while (Get_Mouse_State() > 0) Show_Mouse(); - - /* - ---------------------------- Processing loop ----------------------------- - */ - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - #if(SHOW_MONO) - Ipx.Mono_Debug_Print(-1,0); - #endif - /* - ...................... Refresh display if needed ...................... - */ - if (display == REDRAW_UNIT_COUNT){ - /* - ** Wipe the background behind the unit count then reprint it - */ - LogicPage->Fill_Rect(d_count_x + d_count_w + 2*factor, - d_count_y, - d_count_x + d_count_w + 2*factor + 20, - d_count_y + 12, - 0 ); - sprintf(txt,"%d",MPlayerUnitCount); - Fancy_Text_Print (txt, d_count_x + d_count_w + 2*factor, d_count_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - display = REDRAW_NONE; - } - - - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - - /* - ** Reload and draw the title page - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_NETGAME_SETUP, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print(TXT_PLAYERS, - d_playerlist_x + (d_playerlist_w / 2), d_playerlist_y - d_txt6_h, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_CENTER); - - Fancy_Text_Print(TXT_SCENARIOS, - d_scenariolist_x + (d_scenariolist_w / 2), - d_scenariolist_y - d_txt6_h, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_CENTER); - - Fancy_Text_Print (TXT_COUNT, d_count_x - 2*factor, d_count_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); - - sprintf(txt,"%d",MPlayerUnitCount); - Fancy_Text_Print (txt, d_count_x + d_count_w + 2*factor, d_count_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - - Fancy_Text_Print (TXT_LEVEL, d_level_x - 2*factor, d_level_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); - - if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { - sprintf(txt,"%d",BuildLevel); - } else { - sprintf(txt, "**"); - } - Fancy_Text_Print (txt, d_level_x + d_level_w + 2*factor, d_level_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - - Fancy_Text_Print (TXT_START_CREDITS_COLON, d_credits_x - 5*factor, - d_credits_y + 1*factor, CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); - - } - - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - - /*.................................................................. - Draw the messages: - - Erase an old message first - - If we're in a game, print the game options (if they've been - received) - - If we've been rejected from a game, print that message - ..................................................................*/ - if (display >= REDRAW_MESSAGE) { - Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, - BOXSTYLE_GREEN_BORDER, true); - Messages.Draw(); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - /*------------------------------------------------------------------ - New Scenario selected. - ------------------------------------------------------------------*/ - case (BUTTON_SCENARIOLIST | KN_BUTTON): - if (scenariolist.Current_Index() != ScenarioIdx) { - ScenarioIdx = scenariolist.Current_Index(); - MPlayerCredits = atoi(credbuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - Reject the currently-selected player (don't allow rejecting myself, - who will be the first entry in the list) - ------------------------------------------------------------------*/ - case (BUTTON_REJECT | KN_BUTTON): - index = playerlist.Current_Index(); - if (index == 0) { - CCMessageBox().Process (TXT_CANT_REJECT_SELF, TXT_OOPS); - display = REDRAW_ALL; - break; - } else { - if (index < 0 || index >= playerlist.Count()) { - CCMessageBox().Process (TXT_SELECT_PLAYER_REJECT,TXT_OOPS); - display = REDRAW_ALL; - break; - } - } - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_REJECT_JOIN; - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), 1, - &(Players[index - 1]->Address)); - break; - - /*------------------------------------------------------------------ - User adjusts max # units - ------------------------------------------------------------------*/ - case (BUTTON_COUNT | KN_BUTTON): - MPlayerUnitCount = countgauge.Get_Value() + MPlayerCountMin[MPlayerBases]; - - Hide_Mouse(); - LogicPage->Fill_Rect (d_count_x + d_count_w + 2*factor, d_count_y, - d_count_x + d_count_w + 14*factor, d_count_y + 6*factor, BLACK); - - sprintf(txt,"%d",MPlayerUnitCount); - Fancy_Text_Print (txt, d_count_x + d_count_w + 2*factor, d_count_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - Show_Mouse(); - - transmit = 1; - break; - - /*------------------------------------------------------------------ - User adjusts build level - ------------------------------------------------------------------*/ - case (BUTTON_LEVEL | KN_BUTTON): - BuildLevel = levelgauge.Get_Value() + 1; - if (BuildLevel > MPLAYER_BUILD_LEVEL_MAX) // if it's pegged, max it out - BuildLevel = MPLAYER_BUILD_LEVEL_MAX; - - Hide_Mouse(); - LogicPage->Fill_Rect (d_level_x + d_level_w + 2*factor, d_level_y, - d_level_x + d_level_w + 14*factor, d_level_y + 6*factor, BLACK); - - if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { - sprintf(txt,"%d",BuildLevel); - } else { - sprintf(txt, "**"); - } - Fancy_Text_Print (txt, d_level_x + d_level_w + 2*factor, d_level_y, - CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL); - Show_Mouse(); - - transmit = 1; - break; - - /*------------------------------------------------------------------ - User edits the credits value; retransmit new game options - ------------------------------------------------------------------*/ - case (BUTTON_CREDITS | KN_BUTTON): - MPlayerCredits = atoi(credbuf); - transmit = 1; - break; - - /*------------------------------------------------------------------ - Toggle bases: - - Clear scenario list & rebuild it with new names - - toggle bases button, change its text - - adjust the MPlayerUnitCount to reflect the new allowed range, - using the current gauge setting - - Change the unit count gauge limit & value - ------------------------------------------------------------------*/ - case (BUTTON_BASES | KN_BUTTON): - if (MPlayerBases) { - MPlayerBases = 0; - basesbtn.Turn_Off(); - basesbtn.Set_Text(TXT_BASES_OFF); - MPlayerUnitCount = Fixed_To_Cardinal (MPlayerCountMax[0]-MPlayerCountMin[0], - Cardinal_To_Fixed(MPlayerCountMax[1]-MPlayerCountMin[1], - MPlayerUnitCount-MPlayerCountMin[1])) + MPlayerCountMin[0]; - } else { - MPlayerBases = 1; - basesbtn.Turn_On(); - basesbtn.Set_Text(TXT_BASES_ON); - MPlayerUnitCount = Fixed_To_Cardinal (MPlayerCountMax[1]-MPlayerCountMin[1], - Cardinal_To_Fixed(MPlayerCountMax[0]-MPlayerCountMin[0], - MPlayerUnitCount-MPlayerCountMin[0])) + MPlayerCountMin[1]; - } - MPlayerCredits = atoi(credbuf); - countgauge.Set_Maximum(MPlayerCountMax[MPlayerBases] - MPlayerCountMin[MPlayerBases]); - countgauge.Set_Value(MPlayerUnitCount - MPlayerCountMin[MPlayerBases]); - transmit = 1; - countgauge.Flag_To_Redraw(); - display = REDRAW_UNIT_COUNT; - break; - - /*------------------------------------------------------------------ - Toggle tiberium - ------------------------------------------------------------------*/ - case (BUTTON_TIBERIUM | KN_BUTTON): - if (MPlayerTiberium) { - MPlayerTiberium = 0; - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - tiberiumbtn.Turn_Off(); - tiberiumbtn.Set_Text(TXT_TIBERIUM_OFF); - } else { - MPlayerTiberium = 1; - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - tiberiumbtn.Turn_On(); - tiberiumbtn.Set_Text(TXT_TIBERIUM_ON); - } - MPlayerCredits = atoi(credbuf); - transmit = 1; - break; - - /*------------------------------------------------------------------ - Toggle goodies - ------------------------------------------------------------------*/ - case (BUTTON_GOODIES | KN_BUTTON): - if (MPlayerGoodies) { - MPlayerGoodies = 0; - goodiesbtn.Turn_Off(); - goodiesbtn.Set_Text(TXT_CRATES_OFF); - } else { - MPlayerGoodies = 1; - goodiesbtn.Turn_On(); - goodiesbtn.Set_Text(TXT_CRATES_ON); - } - MPlayerCredits = atoi(credbuf); - transmit = 1; - break; - - /*------------------------------------------------------------------ - Toggle ghosts/capture-the-flag - ------------------------------------------------------------------*/ - case (BUTTON_GHOSTS | KN_BUTTON): - if (!MPlayerGhosts && !Special.IsCaptureTheFlag) { // ghosts OFF => ghosts ON - MPlayerGhosts = 1; - Special.IsCaptureTheFlag = 0; - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_AI_PLAYERS_ON); - } else { - if (MPlayerGhosts) { // ghosts ON => capture-flag - MPlayerGhosts = 0; - Special.IsCaptureTheFlag = 1; - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_CAPTURE_THE_FLAG); - } else { - if (Special.IsCaptureTheFlag) { // capture-flag => AI OFF - MPlayerGhosts = 0; - Special.IsCaptureTheFlag = 0; - ghostsbtn.Turn_Off(); - ghostsbtn.Set_Text(TXT_AI_PLAYERS_OFF); - } - } - } - - MPlayerCredits = atoi(credbuf); - transmit = 1; - break; - - /*------------------------------------------------------------------ - OK: exit loop with TRUE status - ------------------------------------------------------------------*/ - case (BUTTON_OK | KN_BUTTON): - /*............................................................... - If a new player has joined in the last second, don't allow - an OK; force a wait longer than 1 second (to give all players - a chance to know about this new guy) - ...............................................................*/ - i = MAX(Ipx.Global_Response_Time() * 2, (unsigned long)60); - while (TickCount.Time() - ok_timer < i) - Ipx.Service(); - - /*............................................................... - If there are at least 2 players, go ahead & play; error otherwise - ...............................................................*/ - if (MPlayerSolo || Players.Count() > 0) { - rc = TRUE; - process = FALSE; - } else { - CCMessageBox().Process (TXT_ONLY_ONE,TXT_OOPS,NULL); - display = REDRAW_ALL; - } - break; - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF, bail out with error code - ------------------------------------------------------------------*/ - case (KN_ESC): - if (Messages.Get_Edit_Buf() != NULL) { - Messages.Input(input); - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - break; - } - case (BUTTON_CANCEL | KN_BUTTON): - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy (GPacket.Name, MPlayerName); - - /*............................................................... - Broadcast my sign-off over my network - ...............................................................*/ - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - /*............................................................... - Broadcast my sign-off over a bridged network if there is one - ...............................................................*/ - if (IsBridge) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - /*............................................................... - And now, just be absolutely sure, send my sign-off to each - player in my game. (If there's a bridge between us, the other - player will have specified my address, so he can cross the - bridge; but I may not have specified a bridge address, so the - only way I have of crossing the bridge is to send a packet - directly to him.) - ...............................................................*/ - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - MPlayerGameName[0] = 0; - process = false; - rc = false; - break; - - /*------------------------------------------------------------------ - Default: manage the inter-player messages - ------------------------------------------------------------------*/ - default: - /*............................................................... - F4/SEND/'M' = send a message - ...............................................................*/ - if (Messages.Get_Edit_Buf()==NULL) { - if (input == KN_M || input==(BUTTON_SEND | KN_BUTTON) || - input == KN_F4) { - memset (txt, 0, 80); - - strcpy(txt,Text_String(TXT_TO_ALL)); // "To All:" - - Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, d_message_w-70*factor); - - credit_edt.Clear_Focus(); - credit_edt.Flag_To_Redraw(); - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - - break; - } - } else { - - /*............................................................... - If we're already editing a message and the user clicks on - 'Send', translate our input to a Return so Messages.Input() will - work properly. - ...............................................................*/ - if (input==(BUTTON_SEND | KN_BUTTON)) { - input = KN_RETURN; - } - } - - /*............................................................... - Manage the message system (get rid of old messages) - ...............................................................*/ - if (Messages.Manage()) { - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } - - /*............................................................... - Re-draw the messages & service keyboard input for any message - being edited. - ...............................................................*/ - i = Messages.Input(input); - - /*............................................................... - If 'Input' returned 1, it means refresh the message display. - ...............................................................*/ - if (i==1) { - Messages.Draw(); - } - - /*............................................................... - If 'Input' returned 2, it means redraw the message display. - ...............................................................*/ - else if (i==2) { - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } - - /*............................................................... - If 'input' returned 3, it means send the current message. - ...............................................................*/ - else if (i==3) { - long actual_message_size; - char *the_string; - - sent_so_far = 0; - magic_number = MESSAGE_HEAD_MAGIC_NUMBER; - message_length = strlen(Messages.Get_Edit_Buf()); - crc = (unsigned short) - (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) &0xffff); - while ( sent_so_far < message_length ){ - memset (&GPacket, 0, sizeof(GlobalPacketType)); - GPacket.Command = NET_MESSAGE; - strcpy (GPacket.Name, MPlayerName); - memcpy (GPacket.Message.Buf, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); - - /* - ** Steve I's stuff for splitting message on word boundries - */ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - - /* Start at the end of the message and find a space with 10 chars. */ - the_string = GPacket.Message.Buf; - while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && - the_string[actual_message_size] != ' '){ - --actual_message_size; - } - if ( the_string[actual_message_size] == ' ' ){ - - /* Now delete the extra characters after the space (they musnt print) */ - for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ - the_string[i + actual_message_size] = 0; //0xff; ST - 12/18/2018 11:37AM - } - }else{ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - } - - *(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-5) = 0; - *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-4)) = magic_number; - *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-2)) = crc; - GPacket.Message.ID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - GPacket.Message.NameCRC = Compute_Name_CRC(MPlayerGameName); - - /*.................................................................. - Send the message to every player in our player list. - ..................................................................*/ - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - /*.................................................................. - Add the message to our own list, since we're not in the player list - on this dialog. - ..................................................................*/ - sprintf(txt,Text_String (TXT_FROM), MPlayerName, GPacket.Message.Buf); - Messages.Add_Message (txt, MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); - - magic_number++; - sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; - - } - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } - } - - /*--------------------------------------------------------------------- - Detect editing of the credits buffer, transmit new values to players - ---------------------------------------------------------------------*/ - if (atoi(credbuf) != old_cred) { - old_cred = Bound(atoi(credbuf), 0, 9999); - MPlayerCredits = old_cred; - transmit = 1; - sprintf(credbuf, "%d", MPlayerCredits); - credit_edt.Set_Text(credbuf, CREDITSBUF_MAX); - } - - /*--------------------------------------------------------------------- - Process incoming packets - ---------------------------------------------------------------------*/ - whahoppa = Get_NewGame_Responses(&playerlist); - if (whahoppa == EV_NEW_PLAYER) { - ok_timer = TickCount.Time(); - transmit = 1; - } else { - if (whahoppa == EV_MESSAGE) { - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } - } - - /*--------------------------------------------------------------------- - If our Transmit flag is set, we need to send out a game option packet - ---------------------------------------------------------------------*/ - if (transmit) { - for (i = 0; i < Players.Count(); i++) { - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_GAME_OPTIONS; - GPacket.ScenarioInfo.Scenario = MPlayerFilenum[ScenarioIdx]; - GPacket.ScenarioInfo.Credits = MPlayerCredits; - GPacket.ScenarioInfo.IsBases = MPlayerBases; - GPacket.ScenarioInfo.IsTiberium = MPlayerTiberium; - GPacket.ScenarioInfo.IsGoodies = MPlayerGoodies; - GPacket.ScenarioInfo.IsGhosties = MPlayerGhosts; - GPacket.ScenarioInfo.BuildLevel = BuildLevel; - GPacket.ScenarioInfo.UnitCount = MPlayerUnitCount; - GPacket.ScenarioInfo.Seed = Seed; - GPacket.ScenarioInfo.Special = Special; - GPacket.ScenarioInfo.GameSpeed = Options.GameSpeed; - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &(Players[i]->Address) ); - } - transmit = 0; - } - - /*--------------------------------------------------------------------- - Ping every player in my game, to force the Global Channel to measure - the connection response time. - ---------------------------------------------------------------------*/ - if (TickCount.Time() - ping_timer > 15) { - memset (&GPacket, 0, sizeof(GlobalPacketType)); - GPacket.Command = NET_PING; - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &(Players[i]->Address) ); - } - ping_timer = TickCount.Time(); - } - - /*--------------------------------------------------------------------- - Service the Ipx connections - ---------------------------------------------------------------------*/ - Ipx.Service(); - - /*--------------------------------------------------------------------- - Service the sounds & score; GameActive must be false at this point, - so Call_Back() doesn't intercept global messages from me! - ---------------------------------------------------------------------*/ - Call_Back(); - - } /* end of while */ - - /*------------------------------------------------------------------------ - Establish connections with all other players. - ------------------------------------------------------------------------*/ - if (rc) { - /*..................................................................... - Set the number of players in this game, and my ID - .....................................................................*/ - MPlayerCount = Players.Count() + 1; - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - /*..................................................................... - Get the scenario filename - .....................................................................*/ - Scenario = MPlayerFilenum[ScenarioIdx]; - - /*..................................................................... - Compute frame delay value for packet transmissions: - - Divide global channel's response time by 8 (2 to convert to 1-way - value, 4 more to convert from ticks to frames) - .....................................................................*/ - MPlayerMaxAhead = MAX( (Ipx.Global_Response_Time() / 8), (unsigned long)2); - - /*..................................................................... - Send all players the NET_GO packet. Wait until all ACK's have been - received. - .....................................................................*/ - memset (&GPacket, 0, sizeof(GlobalPacketType)); - GPacket.Command = NET_GO; - GPacket.ResponseTime.OneWay = MPlayerMaxAhead; - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &(Players[i]->Address) ); - /*.................................................................. - Wait for all the ACK's to come in. - ..................................................................*/ - while (Ipx.Global_Num_Send() > 0) - Ipx.Service(); - } - - /*..................................................................... - Form connections with all other players. Form the IPX Connection ID - from the player's Color (high byte) and House (low byte). This - will let us extract any player's color & house at any time. - Fill in 'tmp_id' while we're doing this. - .....................................................................*/ - for (i = 0; i < Players.Count(); i++) { - id = Build_MPlayerID (Players[i]->Player.Color, - Players[i]->Player.House); - - tmp_id[i] = id; - - Ipx.Create_Connection(id, Players[i]->Name, &(Players[i]->Address) ); - } - tmp_id[i] = MPlayerLocalID; - - /*..................................................................... - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - .....................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - min_index = 0; - min_id = 0xff; - for (j = 0; j < MPlayerCount; j++) { - if (tmp_id[j] < min_id) { - min_id = tmp_id[j]; - min_index = j; - } - } - MPlayerID[i] = tmp_id[min_index]; - tmp_id[min_index] = 0xff; - } - /*..................................................................... - Fill in the array of player names, including my own. - .....................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == MPlayerLocalID) { - strcpy (MPlayerNames[i], MPlayerName); - } else { - strcpy (MPlayerNames[i], Ipx.Connection_Name(MPlayerID[i])); - } - } - } - - /*------------------------------------------------------------------------ - Init network timing values, using previous response times as a measure - of what our retry delta & timeout should be. - ------------------------------------------------------------------------*/ - Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1, - Ipx.Global_Response_Time() * 4); - - /*------------------------------------------------------------------------ - Clear all lists - ------------------------------------------------------------------------*/ - while (scenariolist.Count()) { - scenariolist.Remove_Item(scenariolist.Get_Item(0)); - } - Clear_Player_List(&playerlist); - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - return(rc); -} - - -/*************************************************************************** - * Get_NewGame_Responses -- processes packets for New Game dialog * - * * - * This routine can modify the contents of the given list box, as well * - * as the contents of the Players Vector global. * - * * - * INPUT: * - * playerlist list of players in this game * - * * - * OUTPUT: * - * EV_NONE = nothing happened * - * EV_NEW_PLAYER = a new player has joined; false otherwise * - * EV_MESSAGE = a message was received * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/18/1995 BRR : Created. * - *=========================================================================*/ -static JoinEventType Get_NewGame_Responses(ColorListClass *playerlist) -{ - int rc; - char * item; // general-purpose string - NodeNameType *who; // node to add to Players Vector - int i; - int found; - JoinEventType retval = EV_NONE; - int resend; - char txt[80]; - int color; - unsigned short magic_number; - unsigned short crc; - - /*------------------------------------------------------------------------ - If there is no incoming packet, just return - ------------------------------------------------------------------------*/ - rc = Ipx.Get_Global_Message (&GPacket, &GPacketlen, &GAddress, &GProductID); - if (!rc || GProductID != IPXGlobalConnClass::COMMAND_AND_CONQUER) { - return(EV_NONE); - } - - /*------------------------------------------------------------------------ - Try to handle the packet in a standard way - ------------------------------------------------------------------------*/ - if (Process_Global_Packet(&GPacket,&GAddress) != 0) { - return(EV_NONE); - } else - - /*------------------------------------------------------------------------ - NET_QUERY_JOIN: - ------------------------------------------------------------------------*/ - if (GPacket.Command==NET_QUERY_JOIN) { - /*..................................................................... - See if this name is unique: - - If the name matches, but the address is different, reject this player - - If the name & address match, this packet must be a re-send of a - prevous request; in this case, do nothing. The other player must have - received my CONFIRM_JOIN packet (since it was sent with an ACK - required), so we can ignore this resend. - .....................................................................*/ - found = 0; - resend = 0; - for (i = 0; i < Players.Count(); i++) { - if (!strcmp(Players[i]->Name,GPacket.Name)) { - if (Players[i]->Address != GAddress) { - found = 1; - } - else { - resend = 1; - } - break; - } - } - if (!strcmp (MPlayerName, GPacket.Name)) { - found = 1; - } - - /*..................................................................... - Reject if name is a duplicate, or if there are too many players: - .....................................................................*/ - if (found || (Players.Count() >= (MPlayerMax - 1) && !resend) ) { - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_REJECT_JOIN; - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &GAddress); - } - - /*..................................................................... - If this packet is NOT a resend, accept the player. Grant him the - requested color if possible. - .....................................................................*/ - else if (!resend) { - /*.................................................................. - Add node to the Vector list - ..................................................................*/ - who = new NodeNameType; - strcpy(who->Name, GPacket.Name); - who->Address = GAddress; - who->Player.House = GPacket.PlayerInfo.House; - Players.Add (who); - - /*.................................................................. - Set player's color; if requested color isn't used, give it to him; - otherwise, give him the 1st available color. Mark the color we - give him as used. - ..................................................................*/ - if (ColorUsed[GPacket.PlayerInfo.Color] == 0) { - who->Player.Color = GPacket.PlayerInfo.Color; - } else { - for (i = 0; i < MAX_MPLAYER_COLORS; i++) { - if (ColorUsed[i]==0) { - who->Player.Color = i; - break; - } - } - } - ColorUsed[who->Player.Color] = 1; - - /*.................................................................. - Add player name to the list box - ..................................................................*/ - item = new char [MPLAYER_NAME_MAX + 4]; - if (GPacket.PlayerInfo.House==HOUSE_GOOD) { - sprintf(item,"%s\t%s",GPacket.Name,Text_String(TXT_G_D_I)); - } else { - sprintf(item,"%s\t%s",GPacket.Name,Text_String(TXT_N_O_D)); - } - playerlist->Add_Item (item, MPlayerTColors[who->Player.Color]); - - /*.................................................................. - Send a confirmation packet - ..................................................................*/ - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_CONFIRM_JOIN; - strcpy(GPacket.Name,MPlayerName); - GPacket.PlayerInfo.House = who->Player.House; - GPacket.PlayerInfo.Color = who->Player.Color; - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &GAddress); - - retval = EV_NEW_PLAYER; - } - } - - /*------------------------------------------------------------------------ - NET_SIGN_OFF: Another system is signing off: search for that system in - the player list, & remove it if found - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_SIGN_OFF) { - for (i = 0; i < Players.Count(); i++) { - /* - ....................... Name found; remove it ...................... - */ - if (!strcmp (Players[i]->Name, GPacket.Name) && - Players[i]->Address==GAddress) { - /*............................................................... - Remove from the list box - ...............................................................*/ - item = (char *)(playerlist->Get_Item(i + 1)); - playerlist->Remove_Item(item); - playerlist->Flag_To_Redraw(); - delete [] item; - /*............................................................... - Mark his color as available - ...............................................................*/ - ColorUsed[Players[i]->Player.Color] = 0; - /*............................................................... - Delete from the Vector list - ...............................................................*/ - Players.Delete(Players[i]); - break; - } - } - } - - /*------------------------------------------------------------------------ - NET_MESSAGE: Someone is sending us a message - ------------------------------------------------------------------------*/ - else if (GPacket.Command==NET_MESSAGE) { - sprintf(txt,Text_String (TXT_FROM), GPacket.Name, GPacket.Message.Buf); - magic_number = *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-4)); - crc = *((unsigned short*)(GPacket.Message.Buf + COMPAT_MESSAGE_LENGTH-2)); - color = MPlayerID_To_ColorIndex(GPacket.Message.ID); - Messages.Add_Message (txt, MPlayerTColors[color], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); - retval = EV_MESSAGE; - } - - return(retval); -} - - - -/*************************************************************************** - * Compute_Name_CRC -- computes CRC from char string * - * * - * INPUT: * - * name string to create CRC for * - * * - * OUTPUT: * - * CRC * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/29/1995 BRR : Created. * - *=========================================================================*/ -unsigned long Compute_Name_CRC(char *name) -{ - char buf[80]; - unsigned long crc = 0L; - int i; - - strcpy (buf, name); - strupr (buf); - - for (i = 0; i < (int)strlen(buf); i++) { - Add_CRC (&crc, (unsigned long)buf[i]); - } - - return (crc); -} - -/*************************************************************************** - * Net_Reconnect_Dialog -- Draws/updates the network reconnect dialog * - * * - * INPUT: * - * reconn 1 = reconnect, 0 = waiting for first-time connection * - * fresh 1 = draw from scratch, 0 = only update time counter * - * oldest_index IPX connection index of oldest connection * - * (only used for reconnection) * - * timeval value to print in the countdown field * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/08/1995 BRR : Created. * - *=========================================================================*/ -void Net_Reconnect_Dialog(int reconn, int fresh, int oldest_index, - unsigned long timeval) -{ - static int x,y,w,h; - int id; - char buf1[40] = {0}; - char buf2[40] = {0}; - char const *buf3 = ""; - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - int d_txt6_h = 6*factor+1; - int d_margin = 5*factor; - - - /*------------------------------------------------------------------------ - Draw the dialog from scratch - ------------------------------------------------------------------------*/ - if (fresh) { - Fancy_Text_Print ("", 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - if (reconn) { - id = Ipx.Connection_ID(oldest_index); - sprintf(buf1,Text_String(TXT_RECONNECTING_TO), - Ipx.Connection_Name(id)); - } else { - sprintf(buf1,Text_String(TXT_WAITING_FOR_CONNECTIONS)); - } - sprintf(buf2,Text_String(TXT_TIME_ALLOWED), timeval + 1); - buf3 = Text_String(TXT_PRESS_ESC); - - w = MAX(String_Pixel_Width(buf1),String_Pixel_Width(buf2)); - w = MAX(String_Pixel_Width(buf3), (unsigned)w); - w += (d_margin * 4); - h = (d_txt6_h * 3) + (d_margin * 6); - x = 160*factor - (w / 2); - y = 100*factor - (h / 2); - - Hide_Mouse(); - Set_Logic_Page(SeenBuff); - Dialog_Box(x, y, w, h); - - Fancy_Text_Print (buf1, 160*factor, y + (d_margin * 2), CC_GREEN, BLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print (buf2, 160*factor, y + (d_margin * 2) + d_txt6_h + d_margin, - CC_GREEN, BLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print (buf3, 160*factor, y + (d_margin * 2) + (d_txt6_h + d_margin) * 2, - CC_GREEN, BLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Show_Mouse(); - - } else { - - /*------------------------------------------------------------------------ - Just update the timeout value on the dialog - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Set_Logic_Page(SeenBuff); - - sprintf(buf2,Text_String(TXT_TIME_ALLOWED), timeval + 1); - int pixwidth = String_Pixel_Width (buf2); - LogicPage->Fill_Rect (160*factor - (pixwidth/2) - 12, y+(d_margin*2) + d_txt6_h + d_margin, - 160*factor + (pixwidth/2) + 12, y+(d_margin*2) + d_txt6_h*2 + d_margin, - TBLACK); - Fancy_Text_Print (buf2, 160*factor, y + (d_margin * 2) + d_txt6_h + d_margin, - CC_GREEN, BLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Show_Mouse(); - } -} - - - - - - -/*********************************************************************************************** - * Wait_For_Focus -- Wait for game to be in focus before proceeding * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 1/6/97 3:23PM ST : Created * - *=============================================================================================*/ -void Wait_For_Focus (void) -{ - CountDownTimerClass focus_timer; - focus_timer.Set(5*60); - ShowWindow ( MainWindow, SW_SHOWMAXIMIZED ); - - /* - ** Process the message loop until we are in focus. - */ - if (!GameInFocus){ - CCDebugString ("C&C95 - Waiting for game to come into focus."); - do { - CCDebugString ("."); - Keyboard::Check(); - if (!focus_timer.Time()){ - CCDebugString ("C&C95 - Calling SetForgroundWindow.\n"); - SetForegroundWindow ( MainWindow ); - CCDebugString ("C&C95 - Calling ShowWindow.\n"); - ShowWindow ( MainWindow, SW_SHOWMAXIMIZED ); - focus_timer.Set(5*60); - } - - }while (!GameInFocus); - CCDebugString ("\n"); - AllSurfaces.SurfacesRestored=FALSE; - } -} - - - - - -extern bool Spawn_WChat(bool can_launch); - -/*********************************************************************************************** - * Net_Fake_New_Dialog -- Just like Net_New_Dialog but without the Dialog. For internet play * - * * - * This 'dialog' does all the non-dialog game set up stuff that is done in the normal * - * network game set up dialog. The only visible button is 'cancel' * - * * - * INPUT: Nothing * - * * - * OUTPUT: true if successfully connected * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/24/96 10:34AM ST : Created * - *=============================================================================================*/ -static int Net_Fake_New_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - int d_dialog_w = 120*factor; // dialog width - int d_dialog_h = 80*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - //d_playerlist_w = 100; - int d_playerlist_w = 106*factor; - int d_playerlist_h = 27*factor; - //int d_playerlist_x = 10 * factor; //off screen - int d_playerlist_x = 500*factor; //10 * factor; //off screen - int d_playerlist_y = d_dialog_y + 20; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50*factor; -#else - int d_cancel_w = 45*factor; -#endif - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx - (d_cancel_w / 2); - int d_cancel_y = d_dialog_y + d_dialog_h - 20*factor; - -#if (GERMAN | FRENCH) - int width=160*factor; - int height=80*factor; -#else - int width=120*factor; - int height=80*factor; -#endif //GERMAN | FRENCH - - bool player_joined = false; - CountDownTimerClass join_timer; - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String((char*)Text_String(TXT_CONNECTING), SeenBuff.Get_Height(), width, height); - -#if (GERMAN | FRENCH) - d_dialog_w = width + 25*factor; - d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - d_cancel_x = d_dialog_cx - (d_cancel_w / 2); -#endif - - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - BUTTON_PLAYERLIST, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_MESSAGE, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - KeyNumType input; - - char credbuf[CREDITSBUF_MAX]; // for credit edit box - int old_cred; // old value in credits buffer - int transmit; // 1 = re-transmit new game options - - long ok_timer = 0; // for timing OK button - int rc; - int i,j; - char *item; - int tabs[] = {77*factor}; // tabs for player list box - - long ping_timer = 0; // for sending Ping packets - - unsigned char tmp_id[MAX_PLAYERS]; // temp storage for sorting player ID's - int min_index; // for sorting player ID's - unsigned char min_id; // for sorting player ID's - unsigned char id; // connection ID - JoinEventType whahoppa; // event generated by received packets - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - ColorListClass playerlist(BUTTON_PLAYERLIST, - d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - - CCDebugString ("C&C95 - In new game dialog - initialising lists.\n"); - /* - ------------------------- Build the button list -------------------------- - */ - commands = &playerlist; - cancelbtn.Add_Tail(*commands); - - playerlist.Set_Tabs(tabs); - - /* - ----------------------------- Various Inits ------------------------------ - */ - - sprintf(credbuf, "%d", MPlayerCredits); - old_cred = MPlayerCredits; - - /*........................................................................ - Init other scenario parameters - ........................................................................*/ - Special.IsTGrowth = MPlayerTiberium; - Special.IsTSpread = MPlayerTiberium; - transmit = 0; - - /*........................................................................ - Init player color-used flags - ........................................................................*/ - for (i = 0; i < MAX_MPLAYER_COLORS; i++) { - ColorUsed[i] = 0; // init all colors to available - } - ColorUsed[MPlayerColorIdx] = 1; // set my color to used - playerlist.Set_Selected_Style(ColorListClass::SELECT_BAR, CC_GREEN_SHADOW); - - /*........................................................................ - Init random-number generator, & create a seed to be used for all random - numbers from here on out - ........................................................................*/ - //ST - 12/18/2018 11:37AM - //randomize(); - //Seed = rand(); - - /*------------------------------------------------------------------------ - Add myself to the list. Note that since I'm not in the Players Vector, - the Vector & listbox are now 1 out of sync. - ------------------------------------------------------------------------*/ - item = new char [MPLAYER_NAME_MAX + 4]; - if (MPlayerHouse==HOUSE_GOOD) { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_G_D_I)); - } else { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_N_O_D)); - } - playerlist.Add_Item(item, MPlayerTColors[MPlayerColorIdx]); - - Wait_For_Focus(); - - CCDebugString ("C&C95 - About to uncompress title page.\n"); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - CCDebugString ("C&C95 - About to set the palette.\n"); - Set_Palette(Palette); - CCDebugString ("C&C95 - Palette was set OK.\n"); - - if (LogicPage != &SeenBuff && LogicPage!= &HidPage){ - CCDebugString ("C&C95 - Logic page invalid"); - Set_Logic_Page (SeenBuff); - } - - char a_buffer [128]; - sprintf (a_buffer, "Number of players:%d", Players.Count()); - CCDebugString (a_buffer); - - -#ifdef VIRTUAL_SUBNET_SERVER - /* - ** Send a bogus packet to wake up the VSS - */ - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = (NetCommandType)50; //Invalid command - strcpy (GPacket.Name, MPlayerName); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), 0, NULL); -#endif //VIRTUAL_SUBNET_SERVER - - - CCDebugString ("C&C95 - About to reveal mouse\n"); - while (Get_Mouse_State() > 0) Show_Mouse(); - - /* - ---------------------------- Processing loop ----------------------------- - */ - CCDebugString ("C&C95 - Entering join dialogue loop\n"); - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print(TXT_CONNECTING, d_dialog_cx-width/2, d_dialog_y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF, bail out with error code - ------------------------------------------------------------------*/ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy (GPacket.Name, MPlayerName); - - /*............................................................... - Broadcast my sign-off over my network - ...............................................................*/ - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - /*............................................................... - Broadcast my sign-off over a bridged network if there is one - ...............................................................*/ - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - /*............................................................... - And now, just be absolutely sure, send my sign-off to each - player in my game. (If there's a bridge between us, the other - player will have specified my address, so he can cross the - bridge; but I may not have specified a bridge address, so the - only way I have of crossing the bridge is to send a packet - directly to him.) - ...............................................................*/ - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - MPlayerGameName[0] = 0; - process = false; - rc = false; - Send_Data_To_DDE_Server ("Hello", strlen("Hello"), DDEServerClass::DDE_CONNECTION_FAILED); - GameStatisticsPacketSent = false; - Spawn_WChat(false); - break; - - /*------------------------------------------------------------------ - default: exit loop with TRUE status - ------------------------------------------------------------------*/ - default: -#ifdef VIRTUAL_SUBNET_SERVER - if (Players.Count() == InternetMaxPlayers-1){ - - -#else //VIRTUAL_SUBNET_SERVER - if (Players.Count() > 0){ -#endif // VIRTUAL_SUBNET_SERVER - -//char ddkks[128]; -//sprintf (ddkks, "C&C95 - Players.Count() = %d\n", Players.Count()); -//CCDebugString (ddkks); - - /* - ** Wait for several secs after receiving request to join before sending - ** start game packet - */ - if (!player_joined){ - player_joined = true; - join_timer.Set (3*60, true); - break; - }else{ - if (join_timer.Time()) break; - } - -CCDebugString ("C&C95 - Join timer expired\n"); - - /*............................................................... - If a new player has joined in the last second, don't allow - an OK; force a wait longer than 2 seconds (to give all players - a chance to know about this new guy) - ...............................................................*/ - i = MAX(Ipx.Global_Response_Time() * 2, (unsigned long)120); - while (TickCount.Time() - ok_timer < i) - Ipx.Service(); - - /*............................................................... - If there are at least 2 players, go ahead & play; error otherwise - ...............................................................*/ - if (MPlayerSolo || Players.Count() > 0) { - rc = TRUE; - process = FALSE; - } else { - CCMessageBox().Process (TXT_ONLY_ONE,TXT_OOPS,NULL); - display = REDRAW_ALL; - } - } - break; - } - - /*--------------------------------------------------------------------- - Process incoming packets - ---------------------------------------------------------------------*/ - whahoppa = Get_NewGame_Responses(&playerlist); - if (whahoppa == EV_NEW_PLAYER) { - ok_timer = TickCount.Time(); - transmit = 1; - } else { - if (whahoppa == EV_MESSAGE) { - display = REDRAW_MESSAGE; - } - } - - /*--------------------------------------------------------------------- - If our Transmit flag is set, we need to send out a game option packet - ---------------------------------------------------------------------*/ - if (transmit) { - for (i = 0; i < Players.Count(); i++) { - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_GAME_OPTIONS; - GPacket.ScenarioInfo.Scenario = ScenarioIdx; //MPlayerFilenum[ScenarioIdx]; - GPacket.ScenarioInfo.Credits = MPlayerCredits; - GPacket.ScenarioInfo.IsBases = MPlayerBases; - GPacket.ScenarioInfo.IsTiberium = MPlayerTiberium; - GPacket.ScenarioInfo.IsGoodies = MPlayerGoodies; - GPacket.ScenarioInfo.IsGhosties = MPlayerGhosts; - GPacket.ScenarioInfo.BuildLevel = BuildLevel; - GPacket.ScenarioInfo.UnitCount = MPlayerUnitCount; - GPacket.ScenarioInfo.Seed = Seed; - GPacket.ScenarioInfo.Special = Special; - GPacket.ScenarioInfo.GameSpeed = Options.GameSpeed; - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &(Players[i]->Address) ); - } - transmit = 0; - } - - /*--------------------------------------------------------------------- - Ping every player in my game, to force the Global Channel to measure - the connection response time. - ---------------------------------------------------------------------*/ - if (TickCount.Time() - ping_timer > 15) { - memset (&GPacket, 0, sizeof(GlobalPacketType)); - GPacket.Command = NET_PING; - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &(Players[i]->Address) ); - } - ping_timer = TickCount.Time(); - } - - /*--------------------------------------------------------------------- - Service the Ipx connections - ---------------------------------------------------------------------*/ - Ipx.Service(); - - /*--------------------------------------------------------------------- - Service the sounds & score; GameActive must be false at this point, - so Call_Back() doesn't intercept global messages from me! - ---------------------------------------------------------------------*/ - Call_Back(); - - } /* end of while */ - -CCDebugString ("C&C95 - Exited process loop\n"); - - /*------------------------------------------------------------------------ - Establish connections with all other players. - ------------------------------------------------------------------------*/ - if (rc) { - /*..................................................................... - Set the number of players in this game, and my ID - .....................................................................*/ - MPlayerCount = Players.Count() + 1; - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - /*..................................................................... - Get the scenario filename - .....................................................................*/ - Scenario = ScenarioIdx; //PlayerFilenum[ScenarioIdx]; We are passed actual number now from wchat not index from - //Scenario = MPlayerFilenum[ScenarioIdx]; - - /*..................................................................... - Compute frame delay value for packet transmissions: - - Divide global channel's response time by 8 (2 to convert to 1-way - value, 4 more to convert from ticks to frames) - .....................................................................*/ - MPlayerMaxAhead = MAX( (Ipx.Global_Response_Time() / 8), (unsigned long)2); - - /*..................................................................... - Send all players the NET_GO packet. Wait until all ACK's have been - received. - .....................................................................*/ -CCDebugString ("C&C95 - Sending the 'GO' packet\n"); - memset (&GPacket, 0, sizeof(GlobalPacketType)); - GPacket.Command = NET_GO; - GPacket.ResponseTime.OneWay = MPlayerMaxAhead; - for (i = 0; i < Players.Count(); i++) { -char flopbuf [128]; -sprintf (flopbuf, "Sending 'GO' packet to address %d\n", *((unsigned short*)&(Players[i]->Address))); -CCDebugString (flopbuf); - - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 1, &(Players[i]->Address) ); - /*.................................................................. - Wait for all the ACK's to come in. - ..................................................................*/ - while (Ipx.Global_Num_Send() > 0) - Ipx.Service(); - } - - /*..................................................................... - Form connections with all other players. Form the IPX Connection ID - from the player's Color (high byte) and House (low byte). This - will let us extract any player's color & house at any time. - Fill in 'tmp_id' while we're doing this. - .....................................................................*/ - for (i = 0; i < Players.Count(); i++) { - id = Build_MPlayerID (Players[i]->Player.Color, - Players[i]->Player.House); - - tmp_id[i] = id; - - Ipx.Create_Connection(id, Players[i]->Name, &(Players[i]->Address) ); - } - -#ifdef VIRTUAL_SUBNET_SERVER -CCDebugString ("C&C95 - Creating connection to the VSS\n"); - /* - ** Create an additional connection to the VSS - */ - if (UseVirtualSubnetServer){ - IPXAddressClass vss_global_address; - NetNodeType vss_node; - NetNumType vss_net; - memset (vss_net, 1, sizeof (vss_net)); - memset (vss_node, 0, sizeof (vss_node)); - vss_global_address.Set_Address(vss_net, vss_node); - Ipx.Create_Connection( VSS_ID, "VSS", &vss_global_address); - } -#endif //VIRTUAL_SUBNET_SERVER - tmp_id[i] = MPlayerLocalID; - - /*..................................................................... - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - .....................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - min_index = 0; - min_id = 0xff; - for (j = 0; j < MPlayerCount; j++) { - if (tmp_id[j] < min_id) { - min_id = tmp_id[j]; - min_index = j; - } - } - MPlayerID[i] = tmp_id[min_index]; - tmp_id[min_index] = 0xff; - } - /*..................................................................... - Fill in the array of player names, including my own. - .....................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == MPlayerLocalID) { - strcpy (MPlayerNames[i], MPlayerName); - } else { - strcpy (MPlayerNames[i], Ipx.Connection_Name(MPlayerID[i])); - } - } - } - - /*------------------------------------------------------------------------ - Init network timing values, using previous response times as a measure - of what our retry delta & timeout should be. - ------------------------------------------------------------------------*/ - Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1, - Ipx.Global_Response_Time() * 4); - - /*------------------------------------------------------------------------ - Clear all lists - ------------------------------------------------------------------------*/ - Clear_Player_List(&playerlist); - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - if (rc){ - Wait_For_Focus(); - } - - return(rc); -} - - - - - - -/*********************************************************************************************** - * Net_Fake_Join_Dialog -- Like Net_Join_Dialog but with no dialogs. For Internet Play. * - * * - * This 'dialog' does all the non-dialog game set up stuff that is done in the normal * - * network game set up dialog. The only visible button is 'cancel' * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: 0 = good, -1 = bad * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/24/96 11:07AM ST : Created * - *=============================================================================================*/ - -static int Net_Fake_Join_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ -/* ###Change collision detected! C:\PROJECTS\CODE\NETDLG.CPP... */ - int d_dialog_w = 120 *factor; // dialog width - int d_dialog_h = 80*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_margin1=10; - int d_txt6_h=15; - - int d_gamelist_w = 160*factor; - int d_gamelist_h = 27*factor; - int d_gamelist_x = 500*factor; //230*factor; //Off screen - //int d_gamelist_x = 230*factor; //Off screen - int d_gamelist_y = d_dialog_y + 20; - - int d_playerlist_w = 106*factor; - int d_playerlist_h = 27*factor; - //int d_playerlist_x = 10 * factor; //Off screen - int d_playerlist_x = 500*factor; //10 * factor; //Off screen - int d_playerlist_y = d_gamelist_y + 20; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50*factor; -#else - int d_cancel_w = 45*factor; -#endif - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx - d_cancel_w / 2; - int d_cancel_y = d_dialog_y + d_dialog_h - 20*factor; - - bool ready_to_go = false; - -#if (GERMAN | FRENCH) - int width=160*factor; - int height=80*factor; -#else - int width=120*factor; - int height=80*factor; -#endif //GERMAN | FRENCH - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String((char*)Text_String(TXT_CONNECTING), SeenBuff.Get_Height(), width, height); - -#if (GERMAN | FRENCH) - d_dialog_w = width + 25*factor; - d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - d_cancel_x = d_dialog_cx - (d_cancel_w / 2); -#endif - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - BUTTON_GAMELIST, - BUTTON_PLAYERLIST, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_MESSAGE, - REDRAW_COLORS, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - KeyNumType input; - - JoinStateType joinstate = JOIN_NOTHING; // current "state" of this dialog - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - int game_index = -1; // index of currently-selected game - int join_index = -1; // index of game we're joining - int rc = 0; // -1 = user cancelled, 1 = New - JoinEventType event; // event from incoming packet - int i,j; // loop counter - int parms_received; // 1 = game options received - - unsigned char tmp_id[MAX_PLAYERS]; // temp storage for sorting player ID's - int min_index; // for sorting player ID's - unsigned char min_id; // for sorting player ID's - unsigned char id; // connection ID - char * item; - unsigned long starttime; - - NodeNameType *who; - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - ColorListClass playerlist(BUTTON_PLAYERLIST, - d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - ListClass gamelist(BUTTON_GAMELIST, - d_gamelist_x, d_gamelist_y, d_gamelist_w, d_gamelist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - /* - ----------------------------- Various Inits ------------------------------ - */ - //MPlayerColorIdx = MPlayerPrefColor; // init my preferred color - - playerlist.Set_Selected_Style(ColorListClass::SELECT_NONE); - - Fancy_Text_Print("", 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /* - --------------------------- Send network query --------------------------- - */ - CCDebugString ("C&C95 - About to call Send_Join_Queries.\n"); - Send_Join_Queries (game_index, 1, 0); - - Wait_For_Focus(); - - CCDebugString ("C&C95 - About to uncompress title page.\n"); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - CCDebugString ("C&C95 - About to set the palette.\n"); - Set_Palette(Palette); - CCDebugString ("C&C95 - Palette was set OK.\n"); - - if (LogicPage != &SeenBuff && LogicPage!= &HidPage){ - CCDebugString ("C&C95 - Logic page invalid\n"); - Set_Logic_Page (SeenBuff); - } - - - char a_buffer [128]; - sprintf (a_buffer, "C&C95 - Number of players:%d\n", Players.Count()); - CCDebugString (a_buffer); - - /* - ---------------------------- Init Mono Output ---------------------------- - */ - CCDebugString ("C&C95 - About to reveal mouse\n"); - while (Get_Mouse_State() > 0) Show_Mouse(); - - /* - ---------------------------- Processing loop ----------------------------- - */ - CCDebugString ("C&C95 - Entering join dialogue loop\n"); - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print(TXT_CONNECTING, d_dialog_cx-width/2, d_dialog_y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /* - .................... Rebuild the button list .................... - */ - cancelbtn.Zap(); - gamelist.Zap(); - playerlist.Zap(); - - commands = &cancelbtn; - gamelist.Add_Tail(*commands); - playerlist.Add_Tail(*commands); - } - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Draw_All(); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF - - If we're part of a game, stay in this dialog; otherwise, exit - ------------------------------------------------------------------*/ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy(GPacket.Name,MPlayerName); - - /*............................................................... - If we're joined to a game, make extra sure the other players in - that game know I'm exiting; send my SIGN_OFF as an ack-required - packet. Do not send this packet to myself (index 0). - ...............................................................*/ - if (joinstate == JOIN_CONFIRMED) { - // - // Remove myself from the player list box - // - item = (char *)(playerlist.Get_Item(0)); - playerlist.Remove_Item(item); - delete [] item; - playerlist.Flag_To_Redraw(); - - // - // Remove myself from the Players list - // - who = Players[0]; - Players.Delete(0); - delete who; - - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - } - - /*............................................................... - Now broadcast my SIGN_OFF so other players looking at this game - know I'm leaving. - ...............................................................*/ - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - - if (IsBridge) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - Send_Data_To_DDE_Server ("Hello", strlen("Hello"), DDEServerClass::DDE_CONNECTION_FAILED); - GameStatisticsPacketSent = false; - Spawn_WChat(false); - process = false; - rc = -1; -#if (0) - if (joinstate != JOIN_CONFIRMED) { - process = false; - rc = -1; - } else { - MPlayerGameName[0] = 0; - joinstate = JOIN_NOTHING; - display = REDRAW_ALL; - } -#endif //(0) - break; - - /*------------------------------------------------------------------ - JOIN: send a join request packet & switch to waiting-for-confirmation - mode. (Request_To_Join fills in MPlayerName with my namebuf.) - ------------------------------------------------------------------*/ - default: - if (joinstate == JOIN_NOTHING && Games.Count()!=0){ - gamelist.Set_Selected_Index(0); - join_index = gamelist.Current_Index(); - parms_received = 0; - if (Request_To_Join (MPlayerName, join_index, &playerlist, MPlayerHouse, - MPlayerColorIdx)) { - joinstate = JOIN_WAIT_CONFIRM; - } else { - display = REDRAW_ALL; - } - } - break; - - } - - /*--------------------------------------------------------------------- - Resend our query packets - ---------------------------------------------------------------------*/ - Send_Join_Queries(game_index, 0, 0); - - /*--------------------------------------------------------------------- - Process incoming packets - ---------------------------------------------------------------------*/ - event = Get_Join_Responses(&joinstate, &gamelist, &playerlist, - join_index); - /*..................................................................... - If we've changed state, redraw everything; if we're starting the game, - break out of the loop. If we've just joined, send out a player query - so I'll get added to the list instantly. - .....................................................................*/ - if (event == EV_STATE_CHANGE) { - display = REDRAW_ALL; - if (joinstate==JOIN_GAME_START) { -CCDebugString ("C&C95 - Received 'GO' packet\n"); - - ready_to_go = true; - } else { - - /*.................................................................. - If we're newly-confirmed, immediately send out a player query - ..................................................................*/ - if (joinstate==JOIN_CONFIRMED) { - - Clear_Player_List(&playerlist); - - item = new char [MPLAYER_NAME_MAX + 4]; - if (MPlayerHouse==HOUSE_GOOD) { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_G_D_I)); - } else { - sprintf(item,"%s\t%s",MPlayerName,Text_String(TXT_N_O_D)); - } - playerlist.Add_Item (item, MPlayerTColors[MPlayerColorIdx]); - - who = new NodeNameType; - strcpy(who->Name, MPlayerName); - who->Address = IPXAddressClass(); - who->Player.House = MPlayerHouse; - who->Player.Color = MPlayerColorIdx; - Players.Add (who); - - Send_Join_Queries (game_index, 0, 1); - } else { - - /*.................................................................. - If we've been rejected, clear any messages we may have been typing. - ..................................................................*/ - if (joinstate==JOIN_REJECTED) { - - // - // Remove myself from the player list box - // - item = (char *)(playerlist.Get_Item(0)); - if (item){ - playerlist.Remove_Item(item); - delete [] item; - playerlist.Flag_To_Redraw(); - } - - // - // Remove myself from the Players list - // - if (Players.Count()){ - who = Players[0]; - Players.Delete(0); - delete who; - } - } - } - } - } else - - /*..................................................................... - If a new game is detected, and it's the first game on our list, - automatically send out a player query for that game. - .....................................................................*/ - if (event == EV_NEW_GAME && gamelist.Count()==1) { - gamelist.Set_Selected_Index(0); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } else - - /*..................................................................... - If the game options have changed, print them. - .....................................................................*/ - if (event == EV_GAME_OPTIONS) { - parms_received = 1; - display = REDRAW_MESSAGE; - } else - - /*..................................................................... - Draw an incoming message - .....................................................................*/ - if (event == EV_MESSAGE) { - display = REDRAW_MESSAGE; - } else - - /*..................................................................... - A game before the one I've selected is gone, so we have a new index now. - 'game_index' must be kept set to the currently-selected list item, so - we send out queries for the currently-selected game. It's therefore - imperative that we detect any changes to the game list. - If we're joined in a game, we must decrement our game_index to keep - it aligned with the game we're joined to. - .....................................................................*/ - if (event == EV_GAME_SIGNOFF) { - if (joinstate==JOIN_CONFIRMED) { - game_index--; - join_index--; - gamelist.Set_Selected_Index(join_index); - } else { - gamelist.Flag_To_Redraw(); - Clear_Player_List(&playerlist); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } - } - - /*--------------------------------------------------------------------- - Service the Ipx connections - ---------------------------------------------------------------------*/ - Ipx.Service(); - - /*--------------------------------------------------------------------- - Clean out the Game List; if an old entry is found: - - Remove it - - Clear the player list - - Send queries for the new selected game, if there is one - ---------------------------------------------------------------------*/ - for (i = 0; i < Games.Count(); i++) { - if (TickCount.Time() - Games[i]->Game.LastTime > 400) { - Games.Delete(Games[i]); - item = (char *)(gamelist.Get_Item (i)); - gamelist.Remove_Item (item); - delete [] item; - if (i <= game_index) { - gamelist.Flag_To_Redraw(); - Clear_Player_List(&playerlist); - game_index = gamelist.Current_Index(); - Send_Join_Queries (game_index, 0, 1); - } - } - } - - /* - ** If we were flagged to start the game and we recognise both players then quit the loop - */ - -//char ddkks[128]; -//sprintf (ddkks, "C&C95 - Players.Count() = %d\n", Players.Count()); -//CCDebugString (ddkks); - if (ready_to_go){ // && Players.Count() == InternetMaxPlayers){ - rc = 0; - process = false; - } - - /*--------------------------------------------------------------------- - Service the sounds & score; GameActive must be false at this point, - so Call_Back() doesn't intercept global messages from me! - ---------------------------------------------------------------------*/ - Call_Back(); - } - - /*------------------------------------------------------------------------ - Establish connections with all other players. - ------------------------------------------------------------------------*/ - if (rc == 0) { - /*..................................................................... - If the other guys are playing a scenario I don't have (sniff), I can't - play. Try to bail gracefully. - .....................................................................*/ - if (ScenarioIdx==-1) { - CCMessageBox().Process (TXT_UNABLE_PLAY_WAAUGH); - - // - // Remove myself from the player list box - // - item = (char *)(playerlist.Get_Item(0)); - playerlist.Remove_Item(item); - delete [] item; - playerlist.Flag_To_Redraw(); - - // - // Remove myself from the Players list - // - who = Players[0]; - Players.Delete(0); - delete who; - - memset (&GPacket, 0, sizeof(GlobalPacketType)); - - GPacket.Command = NET_SIGN_OFF; - strcpy (GPacket.Name, MPlayerName); - - for (i = 0; i < Players.Count(); i++) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 1, - &(Players[i]->Address)); - Ipx.Service(); - } - - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - Ipx.Send_Global_Message (&GPacket, sizeof (GlobalPacketType), - 0, NULL); - - if (IsBridge) { - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - Ipx.Send_Global_Message (&GPacket, sizeof(GlobalPacketType), 0, - &BridgeNet); - } - - while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ; - - rc = -1; - - } else { - - /*.................................................................. - Set the number of players in this game, and my ID - ..................................................................*/ - MPlayerCount = Players.Count(); - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - /*.................................................................. - Get the scenario number - ..................................................................*/ - Scenario = ScenarioIdx; //PlayerFilenum[ScenarioIdx]; We are passed actual number now from wchat not index from - - /*.................................................................. - Form connections with all other players. Form the IPX Connection ID - from the player's Color and House. This will let us extract any - player's color & house at any time. Fill in 'tmp_id' while we're - doing this. - ..................................................................*/ - for (i = 0; i < Players.Count(); i++) { - - /*............................................................... - Only create the connection if it's not myself! - ...............................................................*/ - if (strcmp (MPlayerName, Players[i]->Name)) { - id = Build_MPlayerID(Players[i]->Player.Color, - Players[i]->Player.House); - - tmp_id[i] = id; - - Ipx.Create_Connection((int)id, Players[i]->Name, &(Players[i]->Address) ); - } else { - tmp_id[i] = MPlayerLocalID; - } - } - -#ifdef VIRTUAL_SUBNET_SERVER - /* - ** Create an additional connection to the VSS - */ - if (UseVirtualSubnetServer){ - IPXAddressClass vss_global_address; - NetNodeType vss_node; - NetNumType vss_net; - memset (vss_net, 1, sizeof (vss_net)); - memset (vss_node, 0, sizeof (vss_node)); - vss_global_address.Set_Address(vss_net, vss_node); - Ipx.Create_Connection( VSS_ID, "VSS", &vss_global_address); - } -#endif //VIRTUAL_SUBNET_SERVER - - /*.................................................................. - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - ..................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - min_index = 0; - min_id = 0xff; - for (j = 0; j < MPlayerCount; j++) { - if (tmp_id[j] < min_id) { - min_id = tmp_id[j]; - min_index = j; - } - } - MPlayerID[i] = tmp_id[min_index]; - tmp_id[min_index] = 0xff; - } - /*.................................................................. - Fill in the array of player names, including my own. - ..................................................................*/ - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == MPlayerLocalID) { - strcpy (MPlayerNames[i], MPlayerName); - } else { - strcpy (MPlayerNames[i], Ipx.Connection_Name(MPlayerID[i])); - } - } - } - /*--------------------------------------------------------------------- - Wait a while, polling the IPX service routines, to give our ACK - a chance to get to the other system. If he doesn't get our ACK, he'll - be waiting the whole time we load MIX files. - ---------------------------------------------------------------------*/ - i = MAX(Ipx.Global_Response_Time() * 2, (unsigned long)120); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < (unsigned)i) { - Ipx.Service(); - } - } - - /*------------------------------------------------------------------------ - Init network timing values, using previous response times as a measure - of what our retry delta & timeout should be. - ------------------------------------------------------------------------*/ - Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1, - Ipx.Global_Response_Time() * 4); - - /*------------------------------------------------------------------------ - Clear all lists - ------------------------------------------------------------------------*/ - Clear_Game_List(&gamelist); - Clear_Player_List(&playerlist); - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - if (rc != -1){ - Wait_For_Focus(); - } - - return(rc); -} - - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/NOSEQCON.CPP b/code/TIBERIANDAWN/NOSEQCON.CPP deleted file mode 100644 index f2458b8..0000000 --- a/code/TIBERIANDAWN/NOSEQCON.CPP +++ /dev/null @@ -1,687 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\noseqcon.cpv 1.9 16 Oct 1995 16:49:38 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SEQCONN.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 20, 1994 * - * * - * Last Update : April 9, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * NonSequencedConnClass::NonSequencedConnClass -- class constructor * - * NonSequencedConnClass::~NonSequencedConnClass -- class destructor * - * NonSequencedConnClass::Init -- Initializes connection queue to empty * - * NonSequencedConnClass::Send_Packet -- adds a packet to the send queue * - * NonSequencedConnClass::Receive_Packet -- adds packet to receive queue * - * NonSequencedConnClass::Get_Packet -- gets a packet from receive queue * - * NonSequencedConnClass::Service_Send_Queue -- services the send queue * - * NonSequencedConnClass::Service_Receive_Queue -- services recieve queue* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * NonSequencedConnClass::NonSequencedConnClass -- class constructor * - * * - * INPUT: * - * numsend desired # of entries for the send queue * - * numreceive desired # of entries for the recieve queue * - * maxlen max length of an application packet * - * magicnum the packet "magic number" for this connection * - * retry_delta the time to wait between sends * - * max_retries the max # of retries allowed for a packet * - * (-1 means retry forever, based on this parameter) * - * timeout the max amount of time before we give up on a packet * - * (-1 means retry forever, based on this parameter) * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -NonSequencedConnClass::NonSequencedConnClass (int numsend, int numreceive, - int maxlen, unsigned short magicnum, unsigned long retry_delta, - unsigned long max_retries, unsigned long timeout) : - ConnectionClass (maxlen, magicnum, retry_delta, max_retries, timeout) -{ - /*------------------------------------------------------------------------ - Allocate the packet Queue. This will store incoming packets (which will - be placed there by the Connection Manager), and outgoing packets (which - are placed there by this class when it "sends" a packet). - ------------------------------------------------------------------------*/ - Queue = new CommBufferClass (numsend, numreceive, MaxPacketLen); -} - - -/*************************************************************************** - * NonSequencedConnClass::~NonSequencedConnClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -NonSequencedConnClass::~NonSequencedConnClass () -{ - delete Queue; -} - - -/*************************************************************************** - * NonSequencedConnClass::Init -- Initializes connection queue to empty * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -void NonSequencedConnClass::Init (void) -{ - NumRecNoAck = 0; - NumRecAck = 0; - NumSendNoAck = 0; - NumSendAck = 0; - - LastSeqID = 0xffffffff; - LastReadID = 0xffffffff; - - Queue->Init(); -} - - -/*************************************************************************** - * NonSequencedConnClass::Send_Packet -- adds a packet to the send queue * - * * - * This routine prefixes the given buffer with a CommHeaderType and * - * queues the resulting packet into the Send Queue. (It's actually the * - * Service() routine that handles the hardware-dependent Send of the data).* - * The packet's MagicNumber, Code, and PacketID are set here. * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buffer * - * ack_req true = ACK is required for this packet; false = isn't * - * * - * OUTPUT: * - * 1 = packet was queue'd OK, 0 = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NonSequencedConnClass::Send_Packet (void * buf, int buflen, int ack_req) -{ - /*........................................................................ - Set the magic # for the packet - ........................................................................*/ - ((CommHeaderType *)PacketBuf)->MagicNumber = MagicNum; - - /*........................................................................ - Set the packet Code: DATA_ACK if it requires an ACK, NOACK if it doesn't - Set the packet ID to the appropriate counter value. - ........................................................................*/ - if (ack_req) { - ((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_ACK; - ((CommHeaderType *)PacketBuf)->PacketID = NumSendAck; - } else { - ((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_NOACK; - ((CommHeaderType *)PacketBuf)->PacketID = NumSendNoAck; - } - - /*........................................................................ - Now build the packet - ........................................................................*/ - memcpy(PacketBuf + sizeof(CommHeaderType), buf, buflen); - - /*........................................................................ - Add it to the queue. - ........................................................................*/ - if (Queue->Queue_Send(PacketBuf,buflen + sizeof(CommHeaderType))) { - if (ack_req) { -// Smart_Printf( "Packet ack Queued ID %d \n", ((CommHeaderType *)PacketBuf)->PacketID ); - NumSendAck++; - } else { -// Smart_Printf( "Packet noack Queued ID %d \n", ((CommHeaderType *)PacketBuf)->PacketID ); - NumSendNoAck++; - } - return(true); - } else { -// Smart_Printf( "Packet not Queued ID %d \n", ((CommHeaderType *)PacketBuf)->PacketID ); - return(false); - } -} - - -/*************************************************************************** - * NonSequencedConnClass::Receive_Packet -- adds packet to the receive queue * - * * - * INPUT: * - * buf buffer to process (already includes CommHeaderType) * - * buflen length of buffer to process * - * * - * OUTPUT: * - * 1 = packet was processed OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NonSequencedConnClass::Receive_Packet (void * buf, int buflen) -{ - CommHeaderType *packet; // ptr to packet header - SendQueueType *send_entry; // ptr to send entry header - ReceiveQueueType *rec_entry; // ptr to recv entry header - CommHeaderType *entry_data; // ptr to queue entry data - CommHeaderType ackpacket; // ACK packet to send - int i; - int save_packet = 1; // 0 = this is a resend - int found; - - /* - --------------------------- Check the magic # ---------------------------- - */ - packet = (CommHeaderType *)buf; - if (packet->MagicNumber != MagicNum) { -// Smart_Printf( "Bad Magic Number\n" ); - return(false); - } - - /*------------------------------------------------------------------------ - Handle an incoming ACK - ------------------------------------------------------------------------*/ - if (packet->Code == PACKET_ACK) { - - for (i = 0; i < Queue->Num_Send(); i++) { - /* - ....................... Get queue entry ptr ........................ - */ - send_entry = Queue->Get_Send(i); - /* - ............... If ptr is valid, get ptr to its data ............... - */ - if (send_entry != NULL) { - entry_data = (CommHeaderType *)send_entry->Buffer; - /* - .............. If ACK is for this entry, mark it ................ - */ - if (packet->PacketID==entry_data->PacketID && - entry_data->Code == PACKET_DATA_ACK) { -// Smart_Printf( "Received ACK for %d \n", packet->PacketID ); - send_entry->IsACK = 1; - break; - } - } - } - -//{ -// if (i == Queue->Num_Send() ) { -// Smart_Printf( "Received bad ACK for %d \n", packet->PacketID ); -// } -//} - - return(true); - } - - /*------------------------------------------------------------------------ - Handle an incoming PACKET_DATA_NOACK packet - ------------------------------------------------------------------------*/ - else if (packet->Code == PACKET_DATA_NOACK) { - /*--------------------------------------------------------------------- - If there's only one slot left, don't tie up the queue with this packet - ---------------------------------------------------------------------*/ - if (Queue->Max_Receive() - Queue->Num_Receive() <= 1) { -// Smart_Printf( "Only one slot left don't tie up with DATA NOACK packet %d \n", packet->PacketID ); - return(false); - } - - /*--------------------------------------------------------------------- - Error if we can't queue the packet - ---------------------------------------------------------------------*/ - if (!Queue->Queue_Receive (buf, buflen)) { -// Smart_Printf( "Can't Queue the packet %d \n", packet->PacketID ); - return(false); - } - -// Smart_Printf( "Queued DATA NOACK for %d \n", packet->PacketID ); - NumRecNoAck++; - - return(true); - } - - /*------------------------------------------------------------------------ - Handle an incoming PACKET_DATA_ACK packet - ------------------------------------------------------------------------*/ - else if (packet->Code == PACKET_DATA_ACK) { -// Smart_Printf( "Looking at ID %d, LastSeqID=%d \n", packet->PacketID, LastSeqID ); - /*.................................................................... - If this is a packet requires an ACK, and it's ID is older than our - "oldest" ID, we know it's a resend; send an ACK, but don't queue it - ....................................................................*/ - if (packet->PacketID <= LastSeqID && LastSeqID != 0xffffffff) { -// Smart_Printf( "Older than oldest\n" ); - save_packet = 0; - } - /*.................................................................... - Otherwise, scan the queue for this entry; if it's found, it's a - resend, so don't save it. - ....................................................................*/ - else { - save_packet = 1; - for (i = 0; i < Queue->Num_Receive(); i++) { - rec_entry = Queue->Get_Receive(i); - if (rec_entry) { - entry_data = (CommHeaderType *)rec_entry->Buffer; - /*........................................................... - Packet is found; it's a resend - ...........................................................*/ - if (entry_data->Code == PACKET_DATA_ACK && - entry_data->PacketID == packet->PacketID) { -// Smart_Printf( "It's a resend\n" ); - save_packet = 0; - break; - } - } - } - } /* end of scan for resend */ - - /*--------------------------------------------------------------------- - Queue the packet & update our LastSeqID value. - ---------------------------------------------------------------------*/ - if (save_packet) { - /*------------------------------------------------------------------ - If there's only one slot left, make sure we only put a packet in it if - this packet will let us increment our LastSeqID; otherwise, we'll get - stuck, forever unable to increment LastSeqID. - ------------------------------------------------------------------*/ - if (Queue->Max_Receive() - Queue->Num_Receive() <= 1) { - if (packet->PacketID != (LastSeqID + 1) ) { -// Smart_Printf( "One slot left not what we looking for max=%d,num=%d \n", -// Queue->Max_Receive(), Queue->Num_Receive() ); - return(0); - } - } - - /*------------------------------------------------------------------ - If we can't queue the packet, return; don't send an ACK. - ------------------------------------------------------------------*/ - if (!Queue->Queue_Receive (buf, buflen)) { -// Smart_Printf( "unable to queue packet\n" ); - return(0); - } - - NumRecAck++; - - /*------------------------------------------------------------------ - Update our LastSeqID value if we can. Anything less than LastSeqID - we'll know is a resend. - ------------------------------------------------------------------*/ - if (packet->PacketID == (LastSeqID + 1)) { - LastSeqID = packet->PacketID; - /*............................................................ - Now that we have a new 'LastSeqID', search our Queue to see if - the next ID is there; if so, keep checking for the next one; - break only when the next one isn't found. This forces - LastSeqID to be the largest possible value. - ............................................................*/ - do { - found = 0; - for (i = 0; i < Queue->Num_Receive(); i++) { - - rec_entry = Queue->Get_Receive(i); - - if (rec_entry) { - entry_data = (CommHeaderType *)rec_entry->Buffer; - - /*...................................................... - Entry is found - ......................................................*/ - if (entry_data->Code == PACKET_DATA_ACK && - entry_data->PacketID == (LastSeqID + 1)) { - - LastSeqID = entry_data->PacketID; - found = 1; - break; - } - } - } - } while (found); - } - } /* end of save packet */ - - /*--------------------------------------------------------------------- - Send an ACK, regardless of whether this was a resend or not. - ---------------------------------------------------------------------*/ - ackpacket.MagicNumber = Magic_Num(); - ackpacket.Code = PACKET_ACK; - ackpacket.PacketID = packet->PacketID; -// Smart_Printf( "Sending ACK for %d \n", packet->PacketID ); - Send ((char *)&ackpacket, sizeof(CommHeaderType)); - - return(true); - - } else { -// Smart_Printf( "invalid packet type %d \n", packet->Code ); - } - - return(false); -} - - -/*************************************************************************** - * NonSequencedConnClass::Get_Packet -- gets a packet from receive queue * - * * - * INPUT: * - * buf location to store buffer * - * buflen filled in with length of 'buf' * - * * - * OUTPUT: * - * 1 = packet was read, 0 = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NonSequencedConnClass::Get_Packet (void * buf, int *buflen) -{ - ReceiveQueueType *rec_entry; // ptr to receive entry header - int packetlen; // size of received packet - CommHeaderType *entry_data; - int i; - - /*------------------------------------------------------------------------ - Ensure that we read the packets in order. LastReadID is the ID of the - last PACKET_DATA_ACK packet we read. - ------------------------------------------------------------------------*/ - for (i = 0; i < Queue->Num_Receive(); i++) { - - rec_entry = Queue->Get_Receive(i); - - /*..................................................................... - Only read this entry if it hasn't been yet - .....................................................................*/ - if (rec_entry && rec_entry->IsRead==0) { - - entry_data = (CommHeaderType *)rec_entry->Buffer; - - /*.................................................................. - If this is a DATA_ACK packet, its ID must be one greater than - the last one we read. - ..................................................................*/ - if ( (entry_data->Code == PACKET_DATA_ACK) && - (entry_data->PacketID == (LastReadID + 1))) { - - LastReadID = entry_data->PacketID; - rec_entry->IsRead = 1; - - packetlen = rec_entry->BufLen - sizeof(CommHeaderType); - if (packetlen > 0) { - memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType), packetlen); - } - (*buflen) = packetlen; - return(true); - } - /*.................................................................. - If this is a DATA_NOACK packet, who cares what the ID is? - ..................................................................*/ - else if (entry_data->Code == PACKET_DATA_NOACK) { - - rec_entry->IsRead = 1; - - packetlen = rec_entry->BufLen - sizeof(CommHeaderType); - if (packetlen > 0) { - memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType), packetlen); - } - (*buflen) = packetlen; - return(true); - } - } - } - - return(false); -} - - -/*************************************************************************** - * NonSequencedConnClass::Service_Send_Queue -- services the send queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NonSequencedConnClass::Service_Send_Queue (void) -{ - int i; - int num_entries; - SendQueueType *send_entry; // ptr to send queue entry - CommHeaderType *packet_hdr; // packet header - unsigned long curtime; // current time - int bad_conn = 0; - - /*------------------------------------------------------------------------ - Remove any ACK'd packets from the queue - ------------------------------------------------------------------------*/ - for (i = 0; i < Queue->Num_Send(); i++) { - /* - ------------------------- Get this queue entry ------------------------ - */ - send_entry = Queue->Get_Send(i); - /* - ---------------- If ACK has been received, unqueue it ----------------- - */ - if (send_entry->IsACK) { - /* - ................ Update this queue's response time ................. - */ - packet_hdr = (CommHeaderType *)send_entry->Buffer; - if (packet_hdr->Code == PACKET_DATA_ACK) { - Queue->Add_Delay(Time() - send_entry->FirstTime); - } - /* - ....................... unqueue the packet ......................... - */ - Queue->UnQueue_Send(NULL,NULL,i); - i--; - } - } - - /*------------------------------------------------------------------------ - Loop through all entries in the Send queue. [Re]Send any entries that - need it. - ------------------------------------------------------------------------*/ - num_entries = Queue->Num_Send(); - - for (i = 0; i < num_entries; i++) { - send_entry = Queue->Get_Send(i); - - if (send_entry->IsACK) { - continue; - } - - /*..................................................................... - Only send the message if time has elapsed. (The message's Time - fields are init'd to 0 when a message is queue'd or unqueue'd, so the - first time through, the delta time will appear large.) - .....................................................................*/ - curtime = Time(); - if (curtime - send_entry->LastTime > RetryDelta) { - /* - ......................... Send the message ......................... - */ -#if(0) -{ - packet_hdr = (CommHeaderType *)send_entry->Buffer; - if (send_entry->SendCount) { - if (packet_hdr->Code == PACKET_DATA_NOACK) { -// Smart_Printf( "Resending DATA NOACK for %d \n", packet_hdr->PacketID ); - } else { - if (packet_hdr->Code == PACKET_DATA_ACK) { -// Smart_Printf( "Resending DATA ACK for %d \n", packet_hdr->PacketID ); - } - } - } else { - if (packet_hdr->Code == PACKET_DATA_NOACK) { -// Smart_Printf( "Sending DATA NOACK for %d \n", packet_hdr->PacketID ); - } else { - if (packet_hdr->Code == PACKET_DATA_ACK) { -// Smart_Printf( "Sending DATA ACK for %d \n", packet_hdr->PacketID ); - } - } - } -} -#endif - Send (send_entry->Buffer, send_entry->BufLen); - - /* - ....................... Fill in Time fields ........................ - */ - send_entry->LastTime = curtime; - if (send_entry->SendCount==0) { - send_entry->FirstTime = curtime; - /*............................................................... - If this is the 1st time we're sending this packet, and it doesn't - require an ACK, mark it as ACK'd; then, the next time through, - it will just be removed from the queue. - ...............................................................*/ - packet_hdr = (CommHeaderType *)send_entry->Buffer; - if (packet_hdr->Code == PACKET_DATA_NOACK) { - send_entry->IsACK = 1; - } - } - /* - ......................... Update SendCount ......................... - */ - send_entry->SendCount++; - /*.................................................................. - Perform error detection, based on either MaxRetries or Timeout - ..................................................................*/ - if (MaxRetries != -1 && send_entry->SendCount > MaxRetries) { -// Smart_Printf( "Max Retries!!! %d !!! \n", MaxRetries ); - bad_conn = 1; - } - - if (Timeout != -1 && - (send_entry->LastTime - send_entry->FirstTime) > Timeout) { -// Smart_Printf( "Timed out!!! Time %d, Timeout %d, buflen %d !!! \n", -// (send_entry->LastTime - send_entry->FirstTime), Timeout, -// send_entry->BufLen ); - bad_conn = 1; - } - } - } - - /*------------------------------------------------------------------------ - If the connection is going bad, return an error - ------------------------------------------------------------------------*/ - if (bad_conn) { -// Smart_Printf( "Connection going bad!!! \n" ); - return(false); - } else { - return(true); - } -} - - -/*************************************************************************** - * NonSequencedConnClass::Service_Receive_Queue -- services recieve queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NonSequencedConnClass::Service_Receive_Queue (void) -{ - ReceiveQueueType *rec_entry; // ptr to receive entry header - CommHeaderType *packet_hdr; // packet header - int i; - - /*------------------------------------------------------------------------ - Remove all dead packets. - PACKET_DATA_NOACK: if it's been read, throw it away. - PACKET_DATA_ACK: if it's been read, and its ID is older than LastSeqID, - throw it away. - ------------------------------------------------------------------------*/ - for (i = 0; i < Queue->Num_Receive(); i++) { - rec_entry = Queue->Get_Receive(i); - - if (rec_entry->IsRead) { - packet_hdr = (CommHeaderType *)(rec_entry->Buffer); - - if (packet_hdr->Code == PACKET_DATA_NOACK) { - Queue->UnQueue_Receive(NULL,NULL,i); - i--; - } else { - if (packet_hdr->PacketID < LastSeqID) { - Queue->UnQueue_Receive(NULL,NULL,i); - i--; - } - } - } - } - - return(true); -} - - diff --git a/code/TIBERIANDAWN/NOSEQCON.H b/code/TIBERIANDAWN/NOSEQCON.H deleted file mode 100644 index 22134ca..0000000 --- a/code/TIBERIANDAWN/NOSEQCON.H +++ /dev/null @@ -1,126 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\noseqcon.h_v 1.12 16 Oct 1995 16:46:22 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : NOSEQCON.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 9, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This class provides a "Non-Sequenced" ACK/Retry approach to packet * - * transmission. It sends out as many packets as are in the queue, whose * - * resend delta times have expired; and it ACK's any packets its received * - * who haven't been ACK'd yet. Thus, order of delivery is NOT guaranteed; * - * however, the performance is better than the Sequenced approach. * - * * - * A derived class must provide: * - * - Init: Initialization of any hardware-specific values. * - * - Send: a hardware-dependent send routine. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef NONSEQCONN_H -#define NONSEQCONN_H - - -/* -********************************* Includes ********************************** -*/ -#include "connect.h" -#include "combuf.h" - - -/* -***************************** Class Declaration ***************************** -*/ -class NonSequencedConnClass : public ConnectionClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - NonSequencedConnClass (int numsend, int numrecieve, int maxlen, - unsigned short magicnum, unsigned long retry_delta, - unsigned long max_retries, unsigned long timeout); - virtual ~NonSequencedConnClass (); - - /*..................................................................... - Initialization. - .....................................................................*/ - virtual void Init (void); - - /*..................................................................... - Send/Receive routines. - .....................................................................*/ - virtual int Send_Packet (void * buf, int buflen, int ack_req); - virtual int Receive_Packet (void * buf, int buflen); - virtual int Get_Packet (void * buf, int *buflen); - - /*..................................................................... - The packet "queue"; this non-sequenced version isn't really much of - a queue, but more of a repository. - .....................................................................*/ - CommBufferClass *Queue; - - /* - -------------------------- Protected Interface --------------------------- - */ - protected: - /*..................................................................... - Routines to service the Send & Receive queues. - .....................................................................*/ - virtual int Service_Send_Queue (void); - virtual int Service_Receive_Queue (void); - - /*..................................................................... - Running totals of # of packets we send & receive which require an ACK, - and those that don't. - .....................................................................*/ - unsigned long NumRecNoAck; - unsigned long NumRecAck; - unsigned long NumSendNoAck; - unsigned long NumSendAck; - - /*..................................................................... - This is the ID of the last consecutively-received packet; anything older - than this, we know is a resend. Anything newer than this MUST be lying - around in the Queue for us to detect it as a resend. - .....................................................................*/ - unsigned long LastSeqID; - - /*..................................................................... - This is the ID of the PACKET_DATA_ACK packet we read last; it ensures - that the application reads that type of packet in order. - .....................................................................*/ - unsigned long LastReadID; -}; - -#endif - - diff --git a/code/TIBERIANDAWN/NULLCONN.CPP b/code/TIBERIANDAWN/NULLCONN.CPP deleted file mode 100644 index b1f572e..0000000 --- a/code/TIBERIANDAWN/NULLCONN.CPP +++ /dev/null @@ -1,267 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\nullconn.cpv 1.10 16 Oct 1995 16:51:36 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : NULLCONN.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : April 5, 1995 * - * * - * Last Update : April 20, 1995 [DRD] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * NullModemConnClass::NullModemConnClass -- class constructor * - * NullModemConnClass::~NullModemConnClass -- class destructor * - * NullModemConnClass::Init -- hardware-dependent initialization * - * NullModemConnClass::Send -- hardware-dependent packet sending * - * NullModemConnClass::Compute_CRC -- computes CRC for given buffer * - * NullModemConnClass::Packet_Overhead_Size -- number of extra bytes * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "wincomm.h" -#include "tcpip.h" - -//PG_TO_FIX -#if (0) - -/*************************************************************************** - * NullModemConnClass::NullModemConnClass -- class constructor * - * * - * INPUT: * - * numsend desired # send queue entries * - * numreceive desired # send receive entries * - * maxlen max length of application's packets * - * magicnum application-defined magic # for the packets * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -NullModemConnClass::NullModemConnClass (int numsend, int numreceive, - int maxlen, unsigned short magicnum) : - NonSequencedConnClass (numsend, numreceive, maxlen, magicnum, - 60, // Retry Delta Time - -1, // Max Retries (-1 means ignore this timeout parameter) - 1200) // Timeout: 20 seconds -{ - /*------------------------------------------------------------------------ - Pre-set the port value to NULL, so Send won't send until we've been Init'd - ------------------------------------------------------------------------*/ - PortHandle = NULL; - - /*------------------------------------------------------------------------ - Allocate the Send Buffer; the parent constructor has set MaxPacketLen, - so we can use it in our computation. - ------------------------------------------------------------------------*/ -// SendBuf = new char [MaxPacketLen + sizeof(int) * 3]; - SendBuf = new char [ Actual_Max_Packet() ]; - -} /* end of NullModemConnClass */ - - -/*************************************************************************** - * NullModemConnClass::~NullModemConnClass -- class destructor * - * * - * INPUT: * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -NullModemConnClass::~NullModemConnClass () -{ - delete [] SendBuf; - -} /* end of ~NullModemConnClass */ - - -/*************************************************************************** - * NullModemConnClass::Init -- hardware-dependent initialization * - * * - * INPUT: * - * port GreenLeaf port handle * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -void NullModemConnClass::Init (HANDLE port_handle) -{ - NonSequencedConnClass::Init(); - PortHandle = port_handle; - -} /* end of Init */ - - -/*************************************************************************** - * NullModemConnClass::Send -- hardware-dependent packet sending * - * * - * INPUT: * - * port GreenLeaf port handle * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * 1 = OK, 0 = error * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NullModemConnClass::Send (char *buf, int buflen) -{ - //int status; - int *ibuf; - SerialHeaderType *header; - unsigned long sendlen; - - - /*------------------------------------------------------------------------ - Error if we haven't been properly initialized - ------------------------------------------------------------------------*/ - if ( PortHandle == NULL ) - return(false); - - /*------------------------------------------------------------------------ - Package the data into the Send Buffer - ------------------------------------------------------------------------*/ - header = (SerialHeaderType *) SendBuf; - header->MagicNumber = PACKET_SERIAL_START; - header->Length = (short) buflen; - header->MagicNumber2 = PACKET_SERIAL_VERIFY; - - sendlen = sizeof( SerialHeaderType ); - memcpy (SendBuf + sendlen, buf, buflen); - sendlen += buflen; - ibuf = (int *)(SendBuf + sendlen); - *ibuf = Compute_CRC( buf, buflen ); - sendlen += sizeof( int ); - - *(SendBuf + sendlen) = '\r'; - sendlen += 1; - - /*------------------------------------------------------------------------ - Send the data - ------------------------------------------------------------------------*/ - //status = -#ifdef FORCE_WINSOCK - if (Winsock.Get_Connected() || GameToPlay == GAME_INTERNET){ - Winsock.Write(SendBuf, (int)sendlen); - }else{ - SerialPort->Write_To_Serial_Port((unsigned char *)SendBuf, (int)sendlen ); - } -#else - SerialPort->Write_To_Serial_Port((unsigned char *)SendBuf, (int)sendlen ); -#endif //WINSOCK - - //if ( status == ASSUCCESS ) { - return(true); - //} else { -// Smart_Printf( "Write Buffer status %d, Port->status %d, sendlen %d \n", status, Port->status, sendlen ); - // return(false); - //} -} - - -/*************************************************************************** - * NullModemConnClass::Compute_CRC -- computes CRC for given buffer * - * * - * INPUT: * - * buf buffer to compute CRC for * - * buflen length of buffer in bytes * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NullModemConnClass::Compute_CRC (char *buf, int buflen) -{ - unsigned int sum, hibit; - - sum = 0; - for (int i = 0; i < buflen; i++) { - if ( sum & 0x80000000 ) { // check hi bit to rotate into low bit - hibit = 1; - } else { - hibit = 0; - } - - sum <<= 1; - sum += (hibit + (unsigned char)buf[i]); - } - - return((int)sum); -} - - -/*************************************************************************** - * NullModemConnClass::Packet_Overhead_Size -- number of extra bytes * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * number of bytes used for communications only. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/20/1995 DRD : Created. * - *=========================================================================*/ -int NullModemConnClass::Packet_Overhead_Size ( void ) -{ - // - // short for Null Modem Magic Number - // short for Null Modem length of packet - // int for Null Modem CRC check - // CommHeaderType for Queued packets - // - - return( (PACKET_SERIAL_OVERHEAD_SIZE + sizeof(CommHeaderType)) ); - -} /* end of Packet_Overhead_Size */ - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/NULLCONN.H b/code/TIBERIANDAWN/NULLCONN.H deleted file mode 100644 index 44bc74f..0000000 --- a/code/TIBERIANDAWN/NULLCONN.H +++ /dev/null @@ -1,137 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\nullconn.h_v 1.12 16 Oct 1995 16:45:54 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : NULLCONN.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 3, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This is the Connection Class for a NULL-Modem connection. It inherits * - * a Queue, PacketBuf, timeout variables from ConnectionClass. It * - * inherits its Send_/Receive_/Get_Packet functions, and the non-sequenced * - * ACK/Retry logic in Service_Send_Queue & Service_Recieve_Queue from * - * NonSequencedConnClass. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef NULLCONN_H -#define NULLCONN_H - - -/* -********************************* Includes ********************************** -*/ -#include "noseqcon.h" -#include "commlib.h" - -/* -********************************** Defines ********************************** -*/ -#define PACKET_SERIAL_START 0xDABD -#define PACKET_SERIAL_VERIFY 0xDEAF - -#define PACKET_SERIAL_OVERHEAD_SIZE (sizeof( SerialHeaderType ) + sizeof( SerialCRCType )) - -typedef struct { - unsigned short MagicNumber; - unsigned short Length; - unsigned short MagicNumber2; -} SerialHeaderType; - -typedef struct { - int SerialCRC; -} SerialCRCType; - - -/* -***************************** Class Declaration ***************************** -*/ -class NullModemConnClass : public NonSequencedConnClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - NullModemConnClass (int numsend, int numrecieve, int maxlen, - unsigned short magicnum); - virtual ~NullModemConnClass (); - - /*..................................................................... - Initialization. - .....................................................................*/ - void Init (HANDLE port_handle); - - /*..................................................................... - Utility routines. - .....................................................................*/ - unsigned long Actual_Max_Packet (void) { return (MaxPacketLen + (sizeof(SerialHeaderType)) + sizeof(int) + sizeof (char)); } - - /*..................................................................... - This routine computes a CRC value for the given buffer. - .....................................................................*/ - static int Compute_CRC(char *buf, int buflen); - - /*..................................................................... - This routine returns the number of bytes extra added the packet - for communication. - .....................................................................*/ - static int Packet_Overhead_Size( void ); - - /* - --------------------------- Private Interface ---------------------------- - */ - protected: - /*..................................................................... - This routine actually performs a hardware-dependent data send. - .....................................................................*/ - int Send (char *buf, int buflen); - - /*..................................................................... - This is the PORT value used by the GreenLeaf calls. - .....................................................................*/ - HANDLE PortHandle; - PORT *Port; - - /*..................................................................... - This buffer is a staging area for data sent out; it includes the - packet sent by the parent class (which includes the application's - packet, plus the CommHeaderType header), plus: - - 2-byte buffer start ID - - 2-byte length - - 4-byte CRC value (at the end of the buffer) - This is the actual packet that gets sent across the serial line. - .....................................................................*/ - char *SendBuf; -}; - -#endif - -/************************** end of nullconn.h ******************************/ - diff --git a/code/TIBERIANDAWN/NULLDLG.CPP b/code/TIBERIANDAWN/NULLDLG.CPP deleted file mode 100644 index 7d72104..0000000 --- a/code/TIBERIANDAWN/NULLDLG.CPP +++ /dev/null @@ -1,8360 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\nulldlg.cpv 1.9 16 Oct 1995 16:52:12 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : NULLDLG.CPP * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 04/29/95 * - * * - * Last Update : April 29, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Init_Null_Modem -- Initializes Null Modem communications * - * Shutdown_Modem -- Shuts down modem/null-modem communications * - * Test_Null_Modem -- Null-Modem test routine * - * Reconnect_Null_Modem -- allows user to reconnect * - * Destroy_Null_Connection -- destroys the given connection * - * Select_Serial_Dialog -- Serial Communications menu dialog * - * Com_Settings_Dialog -- Lets user select serial port settings * - * Com_Scenario_Dialog -- Serial game scenario selection dialog * - * Phone_Dialog -- Lets user edit phone directory & dial * - * Build_InitString_Listbox -- [re]builds the initstring entry listbox * - * Init_String_Compare -- for qsort * - * Build_Phone_Listbox -- [re]builds the phone entry listbox * - * Phone_Compare -- for qsort * - * Edit_Phone_Dialog -- lets user edit a phone book entry * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include "function.h" -#include "wincomm.h" -#include "modemreg.h" -#include "tcpip.h" - -//PG_TO_FIX -#if (0) -ModemRegistryEntryClass *ModemRegistry = NULL; //Ptr to modem registry data - -// -// how much time (ticks) to go by before thinking other system -// is not responding. -// -#define PACKET_SENDING_TIMEOUT 1800 -#define PACKET_CANCEL_TIMEOUT 900 - -// -// how much time (ticks) to go by before sending another packet -// of game options or serial connect. -// -#define PACKET_RETRANS_TIME 30 -#define PACKET_REDRAW_TIME 60 - - -static int Reconnect_Null_Modem( void ); -static int Com_Settings_Dialog( SerialSettingsType *settings ); -static int Phone_Dialog (void); -static void Build_Init_String_Listbox (ListClass *list, EditClass *edit, char *buf, int *index); -static int Init_String_Compare (const void *p1, const void *p2); -static void Build_Phone_Listbox (ListClass *list, EditClass *edit, char *buf); -static int Phone_Compare (const void *p1, const void *p2); -static int Edit_Phone_Dialog (PhoneEntryClass *phone); -static bool Dial_Modem( SerialSettingsType *settings, bool reconnect ); -static bool Answer_Modem( SerialSettingsType *settings, bool reconnect ); -static void Modem_Echo( char c ); - -void Smart_Printf( char *format, ... ); -void Hex_Dump_Data( char *buffer, int length ); -void itoh( int i, char *s); - - -static SerialPacketType SendPacket; -static SerialPacketType ReceivePacket; -char TheirName[MPLAYER_NAME_MAX]; -unsigned char TheirColor; -HousesType TheirHouse; -unsigned char TheirID; -static char DialString[ CWAITSTRBUF_MAX + PhoneEntryClass::PHONE_MAX_NUM - 1 ]; -static SerialSettingsType *DialSettings; - -#define SHOW_MONO 0 - -/*************************************************************************** - * Init_Null_Modem -- Initializes Null Modem communications * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = OK, false = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -int Init_Null_Modem( SerialSettingsType *settings ) -{ - - if ( NullModem.Init( settings->Port, settings->IRQ, - settings->ModemName, - settings->Baud, 0, 8, 1, - settings->HardwareFlowControl ) ) { - - - return(true); - } else { - return(false); - } -} - - -/*************************************************************************** - * Shutdown_Modem -- Shuts down modem/null-modem communications * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -void Shutdown_Modem( void ) -{ - if (!PlaybackGame) { - if (GameToPlay == GAME_MODEM) { - NullModem.Hangup_Modem(); - } - } - - // - // close port - // - NullModem.Shutdown(); -} - - -/*************************************************************************** - * Modem_Signoff -- sends EXIT event * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/03/1995 DRD : Created. * - *=========================================================================*/ -void Modem_Signoff( void ) -{ - unsigned long starttime; - EventClass event; - - if (!PlaybackGame) { - /*------------------------------------------------------------------------ - Send a sign-off packet - ------------------------------------------------------------------------*/ - event.Type = EventClass::EXIT; - NullModem.Send_Message (&event,sizeof(EventClass),0); - NullModem.Send_Message (&event,sizeof(EventClass),0); - - starttime = TickCount.Time(); - while( (TickCount.Time() - starttime) < 30) { - NullModem.Service(); - } - } -} - - -/*************************************************************************** - * Test_Null_Modem -- Null-Modem test routine * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = failure to connect; 1 = I'm the game owner, 2 = I'm not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -int Test_Null_Modem( void ) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /*........................................................................ - Dialog variables - ........................................................................*/ - bool process = true; // process while true - KeyNumType input; - - int retval; - unsigned long starttime; - int packetlen; - - int x,y,width,height; // dialog dimensions - char buffer[80*3]; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - /* - ** Determine the dimensions of the text to be used for the dialog box. - ** These dimensions will control how the dialog box looks. - */ - strcpy( buffer, Text_String( TXT_WAITING_CONNECT ) ); - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(buffer, 200*factor, width, height); - - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (320*factor - width) / 2; - y = (200*factor - height) / 2; - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8 *factor)) >> 1), - y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - process = true; - - /* - ............................ Create the list ............................. - */ - commands = &cancelbtn; - - commands->Flag_List_To_Redraw(); - - /* - ............................ Draw the dialog ............................. - */ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - - Dialog_Box(x, y, width, height); - Draw_Caption(TXT_NONE, x, y, width); - - Fancy_Text_Print(buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - commands->Draw_All(); - while (Get_Mouse_State() > 0) Show_Mouse(); - - /* - ** This is supposed to be a direct connection so hang up any modem on this port - ** just to annoy British Telecom - */ - /* - ** Go into break mode - */ - SetCommBreak(SerialPort->Get_Port_Handle()); - - /* - ** Send hangup command - */ - SerialPort->Write_To_Serial_Port ((unsigned char*)"ATH\r", strlen("ATH\r")); - CountDownTimerClass time; - time.Set(2*60); - while (time.Time()){} - - /* - ** Back out of break mode - */ - ClearCommBreak(SerialPort->Get_Port_Handle()); - - /* - ** Drop DTR as well - just in case the modem still hasnt got the message - */ - EscapeCommFunction(SerialPort->Get_Port_Handle(), CLRDTR); - - - /*------------------------------------------------------------------------ - Check for a packet. If we detect one, the other system has already been - started. Wait 1/2 sec for him to receive my ACK, then exit with success. - Note: The initial time must be a little longer than the resend delay. - Just in case we just missed the packet. - ------------------------------------------------------------------------*/ - starttime = TickCount.Time(); - while ( TickCount.Time() - starttime < 80) { - NullModem.Service(); - if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { - if (ReceivePacket.Command == SERIAL_CONNECT) { - //Smart_Printf( "Received SERIAL_CONNECT %d, ID %d \n", ReceivePacket.Seed, ReceivePacket.ID ); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 30) - NullModem.Service(); - process = false; - retval = 2; - break; - } - } - } - - /*------------------------------------------------------------------------ - Send a packet across. As long as Num_Send() is non-zero, the other system - hasn't received it yet. - ------------------------------------------------------------------------*/ - if (process) { - memset (&SendPacket, 0, sizeof(SerialPacketType)); - SendPacket.Command = SERIAL_CONNECT; - // - // put time from start of game for determining the host in case of tie. - // - SendPacket.Seed = TickCount.Time(); - SendPacket.ID = (int) buffer; // address of buffer for more uniqueness. - - //Smart_Printf( "Sending SERIAL_CONNECT %d, ID %d \n", SendPacket.Seed, SendPacket.ID ); - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 80) { - NullModem.Service(); - if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { - if (ReceivePacket.Command == SERIAL_CONNECT) { - //Smart_Printf( "Received2 SERIAL_CONNECT %d, ID %d \n", ReceivePacket.Seed, ReceivePacket.ID ); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 30) - NullModem.Service(); - - // - // whoever has the highest time is the host - // - if (ReceivePacket.Seed > SendPacket.Seed) { - process = false; - retval = 2; - } else { - if (ReceivePacket.Seed == SendPacket.Seed) { - if (ReceivePacket.ID > SendPacket.ID) { - process = false; - retval = 2; - } else - // - // if they are equal then it's a loopback cable or a modem - // - if (ReceivePacket.ID == SendPacket.ID) { - process = false; - retval = 3; - } - } - } - - break; - } - } - } - } - - starttime = TickCount.Time(); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - commands->Draw_All(); - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - //Smart_Printf( "Canceled waiting for SERIAL_CONNECT\n" ); - retval = 0; - process = false; - break; - - default: - break; - } - /*..................................................................... - Service the connection. - .....................................................................*/ - NullModem.Service(); - if (NullModem.Num_Send() == 0) { - //Smart_Printf( "No more messages to send.\n" ); - if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { - if (ReceivePacket.Command == SERIAL_CONNECT) { - //Smart_Printf( "Received3 SERIAL_CONNECT %d, ID %d \n", ReceivePacket.Seed, ReceivePacket.ID ); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 30) - NullModem.Service(); - - // - // whoever has the highest time is the host - // - if (ReceivePacket.Seed > SendPacket.Seed) { - process = false; - retval = 2; - } else { - - if (ReceivePacket.Seed == SendPacket.Seed) { - if (ReceivePacket.ID > SendPacket.ID) { - process = false; - retval = 2; - } else { - - // - // if they are equal then it's a loopback cable or a modem - // - if (ReceivePacket.ID == SendPacket.ID) { - process = false; - retval = 3; - } - } - } - } - - } else { - retval = 0; - process = false; - } - } else { - retval = 1; - process = false; - } - } - - if (TickCount.Time() - starttime > 3600) { // only wait 1 minute - retval = 0; - process = false; - } - } /* end of while */ - - return( retval ); - -} - - -/*************************************************************************** - * Reconnect_Modem -- allows user to reconnect * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = failure to connect; 1 = connect OK * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -int Reconnect_Modem( void ) -{ - int status; - int modemstatus; - - - switch (ModemGameToPlay) { - case (MODEM_NULL_HOST): - case (MODEM_NULL_JOIN): - status = Reconnect_Null_Modem(); - break; - - case (MODEM_DIALER): - modemstatus = NullModem.Get_Modem_Status(); - if ( (modemstatus & CD_SET) ) { - //Smart_Printf( "Dial Modem connection error! Attempting reconnect....\n" ); - status = Reconnect_Null_Modem(); - } else { - status = Dial_Modem( DialSettings, true ); - } - break; - - case (MODEM_ANSWERER): - modemstatus = NullModem.Get_Modem_Status(); - if ( (modemstatus & CD_SET) ) { - //Smart_Printf( "Answer Modem connection error! Attempting reconnect....\n" ); - status = Reconnect_Null_Modem(); - } else { - status = Answer_Modem( DialSettings, true ); - } - break; - } - - return( status ); -} - - -/*************************************************************************** - * Reconnect_Null_Modem -- allows user to reconnect * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 = failure to connect; 1 = connect OK * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -static int Reconnect_Null_Modem( void ) -{ - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /*........................................................................ - Dialog variables - ........................................................................*/ - bool process = true; // process while true - KeyNumType input; - - int retval; - unsigned long starttime; - unsigned long lastmsgtime; - int packetlen; - - int x,y,width,height; // dialog dimensions - char buffer[80*3]; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - - /* - ** Determine the dimensions of the text to be used for the dialog box. - ** These dimensions will control how the dialog box looks. - */ - strcpy( buffer, Text_String( TXT_NULL_CONNERR_CHECK_CABLES ) ); - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(buffer, 200, width, height); - - width = MAX(width, 50); - width += 40; - height += 60; - - x = (320 - width) / 2; - y = (200 - height) / 2; - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8)) >> 1), - y + height - (FontHeight + FontYSpacing + 2) - 5); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - process = true; - - /* - ............................ Create the list ............................. - */ - commands = &cancelbtn; - - commands->Flag_List_To_Redraw(); - - /* - ............................ Draw the dialog ............................. - */ - Hide_Mouse(); - - Dialog_Box(x, y, width, height); - Draw_Caption(TXT_NONE, x, y, width); - - Fancy_Text_Print(buffer, x + 20, y + 25, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - commands->Draw_All(); - Show_Mouse(); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - starttime = lastmsgtime = TickCount.Time(); - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - commands->Draw_All(); - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - retval = false; - process = false; - break; - - default: - break; - } - /*..................................................................... - Service the connection. - .....................................................................*/ - NullModem.Service(); - - /*..................................................................... - Resend our message if it's time - .....................................................................*/ - if (TickCount.Time() - starttime > PACKET_RETRANS_TIME) { - starttime = TickCount.Time(); - SendPacket.Command = SERIAL_CONNECT; - SendPacket.ID = MPlayerLocalID; - //Smart_Printf( "Sending a SERIAL_CONNECT packet !!!!!!!!\n" ); - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); - } - - /*..................................................................... - Check for an incoming message - .....................................................................*/ - if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { - - lastmsgtime = TickCount.Time(); - - if (ReceivePacket.Command == SERIAL_CONNECT) { - //Smart_Printf( "Received a SERIAL_CONNECT packet !!!!!!!!\n" ); - - // are we getting our own packets back?? - - if (ReceivePacket.ID == MPlayerLocalID) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - retval = false; - process = false; - break; - } - - /*............................................................... - OK, we got our message; now we have to make certain the other - guy gets his, so send him one with an ACK required. - ...............................................................*/ - SendPacket.Command = SERIAL_CONNECT; - SendPacket.ID = MPlayerLocalID; - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 60) - NullModem.Service(); - retval = true; - process = false; - } - } - - // - // timeout if we do not get any packets - // - if (TickCount.Time() - lastmsgtime > PACKET_CANCEL_TIMEOUT) { - retval = false; - process = false; - } - - } /* end of while */ - - return( retval ); - -} - - -/*********************************************************************************************** - * Destroy_Null_Connection -- destroys the given connection * - * * - * Call this routine when a connection goes bad, or another player signs off. * - * * - * INPUT: * - * id connection ID to destroy * - * error 0 = user signed off; 1 = connection error * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/31/1995 DRD : Created. * - *=============================================================================================*/ -void Destroy_Null_Connection(int id, int error) -{ - int i,j,idx; - HousesType house; - HouseClass *housep; - char txt[80]; - - - if ( MPlayerCount == 1 ) { - return; - } - - // find index for id - - idx = -1; - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == (unsigned char)id) { - idx = i; - break; - } - } - - if (idx == -1) { - return; - } - - /*------------------------------------------------------------------------ - Create a message to display to the user - ------------------------------------------------------------------------*/ - txt[0] = '\0'; - if (error == 1) { - sprintf(txt,Text_String(TXT_CONNECTION_LOST), MPlayerNames[idx] ); - } - else if (error == 0) { - sprintf(txt,Text_String(TXT_LEFT_GAME), MPlayerNames[idx] ); - } - else if (error == -1) { - NullModem.Delete_Connection(); - } - - if (strlen(txt)) { - Messages.Add_Message (txt, - MPlayerTColors[MPlayerID_To_ColorIndex((unsigned char)id)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - } - - for (i = 0; i < MPlayerCount; i++) { - if (MPlayerID[i] == (unsigned char)id) { - /*.................................................................. - Turn the player's house over to the computer's AI - ..................................................................*/ - house = MPlayerHouses[i]; - housep = HouseClass::As_Pointer (house); - housep->IsHuman = false; - - /*.................................................................. - Move arrays back by one - ..................................................................*/ - for (j = i; j < MPlayerCount - 1; j++) { - MPlayerID[j] = MPlayerID[j + 1]; - MPlayerHouses[j] = MPlayerHouses[j + 1]; - strcpy (MPlayerNames[j], MPlayerNames[j+1]); - TheirProcessTime[j] = TheirProcessTime[j+1]; - } - } - } - - MPlayerCount--; - - /*------------------------------------------------------------------------ - If we're the last player left, tell the user. - ------------------------------------------------------------------------*/ - if (MPlayerCount == 1) { - sprintf(txt,"%s",Text_String(TXT_JUST_YOU_AND_ME)); - Messages.Add_Message (txt, - MPlayerTColors[MPlayerID_To_ColorIndex((unsigned char)id)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); - Map.Flag_To_Redraw(false); - } - -} /* end of Destroy_Null_Connection */ - - -/*************************************************************************** - * Select_Serial_Dialog -- Serial Communications menu dialog * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * GAME_MODEM user wants to play a modem game * - * GAME_NULL_MODEM user wants to play a null-modem game * - * GAME_NORMAL user hit Cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -GameType Select_Serial_Dialog( void ) -{ - int rc; -// int value, i; - int com = -1, baud = -1; - int error = 0; - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 160 *factor; // dialog width - int d_dialog_h = 94 *factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord -// D_DIALOG_Y = ((200 - D_DIALOG_H) / 2), // dialog y-coord - int d_dialog_y = ((136*factor - d_dialog_h) / 2); // dialog y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 11*factor; // ht of 6-pt text - int d_margin = 7; // margin width/height - - int d_dial_w = 90 *factor; - int d_dial_h = 9 *factor; - int d_dial_x = d_dialog_cx - d_dial_w / 2; - int d_dial_y = d_dialog_y + d_margin + d_txt6_h + d_margin; - - int d_answer_w = 90 *factor; - int d_answer_h = 9 *factor; - int d_answer_x = d_dialog_cx - d_answer_w / 2; - int d_answer_y = d_dial_y + d_dial_h + 2; - - int d_nullmodem_w = 90 *factor; - int d_nullmodem_h = 9 *factor; - int d_nullmodem_x = d_dialog_cx - d_nullmodem_w / 2; - int d_nullmodem_y = d_answer_y + d_answer_h + 2; - - int d_settings_w = 90 *factor; - int d_settings_h = 9 *factor; - int d_settings_x = d_dialog_cx - d_settings_w / 2; - int d_settings_y = d_nullmodem_y + d_nullmodem_h + 2; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50 *factor; -#else - int d_cancel_w = 40 *factor; -#endif - int d_cancel_h = 9 *factor; - int d_cancel_x = d_dialog_cx - d_cancel_w / 2; - int d_cancel_y = d_settings_y + d_settings_h + d_margin; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_DIAL = 100, - BUTTON_ANSWER, - BUTTON_NULLMODEM, - BUTTON_SETTINGS, - BUTTON_CANCEL, - - NUM_OF_BUTTONS = 5, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - KeyNumType input; - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - int tabs[] = {77 * factor}; // tabs for player list box - GameType retval; // return value - - int selection; - bool pressed; - int curbutton; - TextButtonClass *buttons[NUM_OF_BUTTONS]; - - SerialSettingsType *settings; - bool selectsettings = false; - - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - TextButtonClass dialbtn(BUTTON_DIAL, TXT_DIAL_MODEM, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_dial_x, d_dial_y, d_dial_w, d_dial_h); - - TextButtonClass answerbtn(BUTTON_ANSWER, TXT_ANSWER_MODEM, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_answer_x, d_answer_y, d_answer_w, d_answer_h); - - TextButtonClass nullmodembtn(BUTTON_NULLMODEM, TXT_NULL_MODEM, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_nullmodem_x, d_nullmodem_y, d_nullmodem_w, d_nullmodem_h); - - TextButtonClass settingsbtn(BUTTON_SETTINGS, TXT_SETTINGS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_settings_x, d_settings_y, d_settings_w, d_settings_h); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /*........................................................................ - Read the CC.INI file to extract default serial settings, scenario numbers - & descriptions, and the phone list. - ........................................................................*/ - Read_MultiPlayer_Settings (); - - if (SerialDefaults.Port == 0 || - SerialDefaults.IRQ == -1 || - SerialDefaults.Baud == -1) { - selectsettings = true; - } else { - if ( NullModem.Detect_Port( &SerialDefaults ) != PORT_VALID ) { - selectsettings = true; - } - } - - /* - ............................ Create the list ............................. - */ - commands = &dialbtn; - answerbtn.Add_Tail(*commands); - nullmodembtn.Add_Tail(*commands); - settingsbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - - /* - ......................... Fill array of button ptrs ...................... - */ - curbutton = 0; - buttons[0] = &dialbtn; - buttons[1] = &answerbtn; - buttons[2] = &nullmodembtn; - buttons[3] = &settingsbtn; - buttons[4] = &cancelbtn; - buttons[curbutton]->Turn_On(); - - Keyboard::Clear(); - - Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - -Debug_Smart_Print = true; - - MPlayerLocalID = 0xff; // set to invalid value - - /* - -------------------------- Main Processing Loop -------------------------- - */ - display = REDRAW_ALL; - process = true; - pressed = false; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - /* - ..................... Refresh the backdrop ...................... - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - /* - ..................... Draw the background ....................... - */ - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /* - ..................... Redraw the buttons ....................... - */ - commands->Draw_All(); - /* - ....................... Draw the labels ......................... - */ - Draw_Caption (TXT_SELECT_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ............................ Process input ............................ - */ - switch (input) { - case (BUTTON_DIAL | KN_BUTTON): - selection = BUTTON_DIAL; - pressed = true; - break; - - case (BUTTON_ANSWER | KN_BUTTON): - selection = BUTTON_ANSWER; - pressed = true; - break; - - case (BUTTON_NULLMODEM | KN_BUTTON): - selection = BUTTON_NULLMODEM; - pressed = true; - break; - - case (BUTTON_SETTINGS | KN_BUTTON): - selection = BUTTON_SETTINGS; - pressed = true; - break; - - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - selection = BUTTON_CANCEL; - pressed = true; - break; - - case (KN_UP): - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton--; - if (curbutton < 0) - curbutton = (NUM_OF_BUTTONS - 1); - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case (KN_DOWN): - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton++; - if (curbutton > (NUM_OF_BUTTONS - 1) ) - curbutton = 0; - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - break; - - case (KN_RETURN): - selection = curbutton + BUTTON_DIAL; - pressed = true; - break; - - default: - break; - } - - if (pressed) { - // - // to make sure the selection is correct in case they used the mouse - // - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - curbutton = selection - BUTTON_DIAL; - buttons[curbutton]->Turn_On(); - buttons[curbutton]->IsPressed = true; - buttons[curbutton]->Draw_Me(true); - - switch (selection) { - case (BUTTON_DIAL): - - if (selectsettings) { - CCMessageBox().Process(TXT_SELECT_SETTINGS); - } - - /* - ** Remote-connect - */ - else if ( Phone_Dialog() ) { - if (PhoneBook[CurPhoneIdx]->Settings.Port == 0) { - settings = &SerialDefaults; - } else { - settings = &(PhoneBook[CurPhoneIdx]->Settings); - } - - if (SerialPort){ - delete SerialPort; - } - SerialPort = new WinModemClass; - - if ( Init_Null_Modem( settings ) ) { - - if (settings->CallWaitStringIndex == CALL_WAIT_CUSTOM) { - strcpy( DialString, settings->CallWaitString ); - } else { - strcpy( DialString, - CallWaitStrings[ settings->CallWaitStringIndex ] ); - } - strcat( DialString, PhoneBook[ CurPhoneIdx ]->Number ); - - if ( Dial_Modem( settings, false ) ) { - ModemGameToPlay = MODEM_DIALER; - if ( Com_Scenario_Dialog() ) { - retval = GAME_MODEM; - process = false; - } - } - - if (process) { // restore to default - NullModem.Change_IRQ_Priority( 0 ); - } - } else { - CCMessageBox().Process(TXT_SELECT_SETTINGS); - } - } - - if (process) { - buttons[curbutton]->IsPressed = false; - buttons[curbutton]->Flag_To_Redraw(); - } - - display = REDRAW_ALL; - break; - - case (BUTTON_ANSWER): - - if (selectsettings) { - CCMessageBox().Process(TXT_SELECT_SETTINGS); - } else { - /* - ** Remote-connect - */ - settings = &SerialDefaults; - - if (SerialPort){ - delete SerialPort; - } - SerialPort = new WinModemClass; - - if ( Init_Null_Modem( settings ) ) { - if ( Answer_Modem( settings, false ) ) { - ModemGameToPlay = MODEM_ANSWERER; - if ( Com_Show_Scenario_Dialog() ) { - retval = GAME_MODEM; - process = false; - } - } - - if (process) { // restore to default - NullModem.Change_IRQ_Priority( 0 ); - } - } else { - CCMessageBox().Process(TXT_SELECT_SETTINGS); - } - } - - if (process) { - buttons[curbutton]->IsPressed = false; - buttons[curbutton]->Flag_To_Redraw(); - } - - display = REDRAW_ALL; - break; - - case (BUTTON_NULLMODEM): - - if (selectsettings) { - CCMessageBox().Process(TXT_SELECT_SETTINGS); - } else { - /* - ** Otherwise, remote-connect; save values if we're recording - */ - - if (SerialPort){ - delete SerialPort; - } - SerialPort = new WinNullModemClass; - - if ( Init_Null_Modem( &SerialDefaults ) ) { - rc = Test_Null_Modem(); - switch (rc) { - case (1): - ModemGameToPlay = MODEM_NULL_HOST; - if ( Com_Scenario_Dialog() ) { - retval = GAME_NULL_MODEM; - process = false; - } - break; - - case (2): - ModemGameToPlay = MODEM_NULL_JOIN; - if ( Com_Show_Scenario_Dialog() ) { - retval = GAME_NULL_MODEM; - process = false; - } - break; - - case (3): - CCMessageBox().Process( TXT_MODEM_OR_LOOPBACK ); - break; - } - - if (process) { // restore to default - NullModem.Change_IRQ_Priority( 0 ); - } - } else { - CCMessageBox().Process(TXT_SELECT_SETTINGS); - } - } - - if (process) { - buttons[curbutton]->IsPressed = false; - buttons[curbutton]->Flag_To_Redraw(); - } - - display = REDRAW_ALL; - break; - - case (BUTTON_SETTINGS): - if ( Com_Settings_Dialog( &SerialDefaults ) ) { - Write_MultiPlayer_Settings (); - - selectsettings = true; - - if (SerialDefaults.Port != 0 && - SerialDefaults.IRQ != -1 && - SerialDefaults.Baud != -1) { - if ( NullModem.Detect_Port( &SerialDefaults ) == PORT_VALID) { - selectsettings = false; - } - } - } - - buttons[curbutton]->IsPressed = false; - buttons[curbutton]->Flag_To_Redraw(); - display = REDRAW_ALL; - break; - - case (BUTTON_CANCEL): - retval = GAME_NORMAL; - process = false; - break; - } - - pressed = false; - } - } /* end of while */ - -#if 0 - if (retval == GAME_NORMAL) { - Debug_Smart_Print = false; - } -#endif - -Debug_Smart_Print = false; - - return( retval ); -} - - - - -/*********************************************************************************************** - * Advanced_Modem_Settings -- Allows to user to set additional modem settings * - * * - * * - * * - * INPUT: current settings * - * * - * OUTPUT: modified settings * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 12/16/96 2:29PM ST : Created * - *=============================================================================================*/ -Advanced_Modem_Settings (SerialSettingsType *settings) -{ - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 340; // dialog width - int d_dialog_h = 170; // dialog height - int d_dialog_x = 320 - d_dialog_w/2; // dialog x-coord - int d_dialog_y = 200 - d_dialog_h/ 2; // dialog y-coord - - - int d_compression_w = 50; - int d_compression_h = 18; - int d_compression_x = d_dialog_x + d_dialog_w/2 +40; - int d_compression_y = d_dialog_y + 30; - - int d_errorcorrection_w = 50; - int d_errorcorrection_h = 18; - int d_errorcorrection_x = d_dialog_x + d_dialog_w/2 +40; - int d_errorcorrection_y = d_dialog_y + 52; - - int d_hardwareflowcontrol_w = 50; - int d_hardwareflowcontrol_h = 18; - int d_hardwareflowcontrol_x = d_dialog_x + d_dialog_w/2 +40; - int d_hardwareflowcontrol_y = d_dialog_y + 74; - - int d_default_w = 100; - int d_default_h = 18; - int d_default_x = d_dialog_x + d_dialog_w / 2 - d_default_w / 2; - int d_default_y = d_dialog_y + 110; - - int d_ok_w = 100; - int d_ok_h = 18; - int d_ok_x = d_dialog_x + d_dialog_w/2 - d_ok_w / 2; - int d_ok_y = d_dialog_y + d_dialog_h - 24; - - enum { - BUTTON_COMPRESSION = 100, - BUTTON_ERROR_CORRECTION, - BUTTON_HARDWARE_FLOW_CONTROL, - BUTTON_DEFAULT, - BUTTON_OK, - }; - - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND, - } RedrawType; - - /* - ** Yes/No strings - */ - char compress_text [16]; - char correction_text [16]; - char flowcontrol_text[16]; - - - /* - ** Initialise the button text - */ - strcpy (compress_text, settings->Compression ? Text_String (TXT_ON) : Text_String (TXT_OFF) ); - strcpy (correction_text, settings->ErrorCorrection ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - strcpy (flowcontrol_text, settings->HardwareFlowControl ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - - - /* - ** Create the buttons - */ - TextButtonClass compressionbutton(BUTTON_COMPRESSION, compress_text, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_compression_x, d_compression_y, d_compression_w, d_compression_h); - - TextButtonClass errorcorrectionbutton(BUTTON_ERROR_CORRECTION, correction_text, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_errorcorrection_x, d_errorcorrection_y, d_errorcorrection_w, d_errorcorrection_h); - - TextButtonClass hardwareflowcontrolbutton(BUTTON_HARDWARE_FLOW_CONTROL, flowcontrol_text, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_hardwareflowcontrol_x, d_hardwareflowcontrol_y, d_hardwareflowcontrol_w, d_hardwareflowcontrol_h); - - TextButtonClass defaultbutton(BUTTON_DEFAULT, TXT_DEFAULT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_default_x, d_default_y, d_default_w, d_default_h); - - TextButtonClass okbutton(BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ok_x, d_ok_y, d_ok_w, d_ok_h); - - - /* - ** Misc. variables. - */ - RedrawType display = REDRAW_ALL; // redraw level - BOOL process = true; // process while true - KeyNumType input; - GadgetClass *commands; // button list - - - commands = &okbutton; - defaultbutton.Add_Tail(*commands); - compressionbutton.Add_Tail(*commands); - errorcorrectionbutton.Add_Tail(*commands); - hardwareflowcontrolbutton.Add_Tail(*commands); - - - /* - ** Main process loop - */ - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - // init font variables - - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_MODEM_INITIALISATION, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print( TXT_DATA_COMPRESSION, - d_compression_x - 26, d_compression_y + 2, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print( TXT_ERROR_CORRECTION, - d_errorcorrection_x - 26, d_errorcorrection_y +2, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print( TXT_HARDWARE_FLOW_CONTROL, - d_hardwareflowcontrol_x -26, d_hardwareflowcontrol_y +2, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - compressionbutton.Flag_To_Redraw(); - errorcorrectionbutton.Flag_To_Redraw(); - hardwareflowcontrolbutton.Flag_To_Redraw(); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - case (BUTTON_COMPRESSION | KN_BUTTON): - settings->Compression = settings->Compression ^ 1; - strcpy (compress_text, settings->Compression ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - break; - - case (BUTTON_ERROR_CORRECTION | KN_BUTTON): - settings->ErrorCorrection = settings->ErrorCorrection ^ 1; - strcpy (correction_text, settings->ErrorCorrection ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - break; - - case (BUTTON_HARDWARE_FLOW_CONTROL | KN_BUTTON): - settings->HardwareFlowControl = settings->HardwareFlowControl ^ 1; - strcpy (flowcontrol_text, settings->HardwareFlowControl ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - break; - - case (BUTTON_DEFAULT | KN_BUTTON): - settings->Compression = false; - settings->ErrorCorrection = false; - settings->HardwareFlowControl = true; - - strcpy (compress_text, settings->Compression ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - - strcpy (correction_text, settings->ErrorCorrection ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - - strcpy (flowcontrol_text, settings->HardwareFlowControl ? - Text_String (TXT_ON) : Text_String (TXT_OFF) ); - - if (display < REDRAW_BUTTONS) display = REDRAW_BUTTONS; - break; - - case (BUTTON_OK | KN_BUTTON): - process = false; - break; - } - } -} - - - - -/*************************************************************************** - * Com_Settings_Dialog -- Lets user select serial port settings * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Settings ³ * - * ³ ³ * - * ³ Port:____ IRQ:__ Baud:______ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ³ ³ ³ ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ ³ * - * ³ Initialization: [Add] [Delete] ³ * - * ³ _____________________________ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ ³ * - * ³ Call Waiting: ³ * - * ³ _______________ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ [Tone Dialing] ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ [Pulse Dialing] ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * settings ptr to SerialSettingsType structure * - * * - * OUTPUT: * - * true = OK, false = Cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -static int Com_Settings_Dialog( SerialSettingsType *settings ) -{ -/* ###Change collision detected! C:\PROJECTS\CODE\NULLDLG.CPP... */ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 301 *factor; // dialog width - int d_dialog_h = 200 *factor; // dialog height - int d_dialog_x = ((320 *factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200 *factor - d_dialog_h) / 2); // dialog y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 6 *factor +1; // ht of 6-pt text - int d_margin = 5 *factor; // margin width/height - -#ifdef EDIT_IRQ - int d_portlist_w = 80 *factor; - int d_portlist_h = 35 *factor; - int d_portlist_x = d_dialog_x + (d_dialog_w / 6) - (d_portlist_w / 2); - int d_portlist_y = d_dialog_y + ((d_margin + d_txt6_h) * 2) + d_margin + 10 *factor; - - int d_port_w = ((PORTBUF_MAX - 1) * 6 *factor) + 4 *factor; - int d_port_h = 9 *factor; - int d_port_x = d_portlist_x + 31 *factor; - int d_port_y = d_portlist_y - d_margin - d_txt6_h; - - - int d_irqlist_w = 80 *factor; - int d_irqlist_h = 35 *factor; - int d_irqlist_x = d_dialog_x + (d_dialog_w / 2) - (d_irqlist_w / 2); - int d_irqlist_y = d_portlist_y; - - int d_irq_w = ((IRQBUF_MAX - 1) * 6 *factor) + 3 *factor; - int d_irq_h = 9 *factor; - int d_irq_x = d_irqlist_x + 25 *factor; - int d_irq_y = d_irqlist_y - d_margin - d_txt6_h; - - int d_baudlist_w = 80 *factor; - int d_baudlist_h = 35 *factor; - int d_baudlist_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_baudlist_w / 2); - int d_baudlist_y = d_portlist_y; - - int d_baud_w = ((BAUDBUF_MAX - 1) * 6 *factor) + 3 *factor; - int d_baud_h = 9 *factor; - int d_baud_x = d_baudlist_x + 31 *factor; - int d_baud_y = d_baudlist_y - d_margin - d_txt6_h; - -#endif //EDIT_IRQ - int d_initstrlist_w = ((INITSTRBUF_MAX - 1) * 6 *factor) + 8 + 3 *factor; - int d_initstrlist_h = 21 *factor; - int d_initstrlist_x = d_dialog_cx - (d_initstrlist_w / 2); - int d_initstrlist_y = d_dialog_y + ((d_margin + d_txt6_h) * 2) + d_margin + 10 *factor + - 35*factor + - ((d_margin + d_txt6_h) * 2) + d_margin + 4 *factor; - - int d_initstr_w = ((INITSTRBUF_MAX - 1) * 6 *factor) + 3 *factor; - int d_initstr_h = 9 *factor; - int d_initstr_x = d_initstrlist_x; - int d_initstr_y = d_initstrlist_y - d_margin - d_txt6_h; - -#ifndef EDIT_IRQ - int d_portlist_w = 80 *factor + 80; - int d_portlist_h = 35 *factor; - int d_portlist_x = d_initstrlist_x; - int d_portlist_y = d_dialog_y + ((d_margin + d_txt6_h) * 2) + d_margin + 10 *factor; - - int d_port_w = d_portlist_w; - int d_port_h = 9 *factor; - int d_port_x = d_portlist_x; // + 31 *factor; - int d_port_y = d_portlist_y - d_margin - d_txt6_h; - - int d_baudlist_w = 80 *factor; - int d_baudlist_h = 35 *factor; - int d_baudlist_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_baudlist_w / 2); - d_baudlist_x -= 32; - //int d_baudlist_x = d_portlist_x + d_portlist_w + 20 * factor; - int d_baudlist_y = d_portlist_y; - - int d_baud_w = ((BAUDBUF_MAX - 1) * 6 *factor) + 3 *factor; - int d_baud_h = 9 *factor; - int d_baud_x = d_baudlist_x + 31 *factor; - int d_baud_y = d_baudlist_y - d_margin - d_txt6_h; - - int d_inittype_w = 30*factor; - int d_inittype_h = 9*factor; - int d_inittype_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_inittype_w / 2); - int d_inittype_y = d_baud_y + 20*factor; - -#endif //EDIT_IRQ - - int d_add_w = 45 *factor; - int d_add_h = 9 *factor; -#ifdef FRENCH - int d_add_x = (d_dialog_cx - (d_add_w / 2))+34*factor; -#else - int d_add_x = d_dialog_cx - (d_add_w / 2); -#endif - int d_add_y = d_initstr_y - d_add_h - 3*factor; - - int d_delete_w = 45 *factor; - int d_delete_h = 9 *factor; - -#ifdef FRENCH - int d_delete_x = 14*factor + d_dialog_x + ((d_dialog_w * 3) / 4) - (d_delete_w / 2); -#else - int d_delete_x = d_dialog_x + ((d_dialog_w * 3) / 4) - (d_delete_w / 2); -#endif - int d_delete_y = d_initstr_y - d_add_h - 3 *factor; - - int d_cwaitstrlist_w = (((CWAITSTRBUF_MAX - 1) + 9) * 6 *factor) + 3 *factor; - int d_cwaitstrlist_h = 27 *factor; - int d_cwaitstrlist_x = d_initstrlist_x; - int d_cwaitstrlist_y = d_initstrlist_y + d_initstrlist_h + ((d_margin + d_txt6_h) * 2) + 2 *factor; - - int d_cwaitstr_w = ((CWAITSTRBUF_MAX - 1) * 6 *factor) + 3 *factor; - int d_cwaitstr_h = 9 *factor; - int d_cwaitstr_x = d_cwaitstrlist_x; - int d_cwaitstr_y = d_cwaitstrlist_y - d_margin - d_txt6_h; - - int d_tone_w = 80 *factor; - int d_tone_h = 9 *factor; - int d_tone_x = d_dialog_x + ((d_dialog_w * 3) / 4) - (d_tone_w / 2); - int d_tone_y = d_cwaitstrlist_y; - - int d_pulse_w = 80 *factor; - int d_pulse_h = 9 *factor; - int d_pulse_x = d_dialog_x + ((d_dialog_w * 3) / 4) - (d_pulse_w / 2); - int d_pulse_y = d_tone_y + d_tone_h + d_margin; - - int d_save_w = 40 *factor; - int d_save_h = 9 *factor; - int d_save_x = d_dialog_x + (d_dialog_w / 5) - (d_save_w / 2); - int d_save_y = d_dialog_y + d_dialog_h - d_save_h - d_margin - 2 *factor; - -#if (GERMAN | FRENCH) - int d_cancel_w = 50 *factor; -#else - int d_cancel_w = 40 *factor; -#endif - int d_cancel_h = 9 *factor; - int d_cancel_x = d_dialog_x + ((d_dialog_w * 4) / 5) - (d_cancel_w / 2); - int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin - 2 *factor; - -#if (GERMAN | FRENCH) - int d_advanced_w = 50*factor; -#else - int d_advanced_w = 40*factor; -#endif - int d_advanced_h = 9*factor; - int d_advanced_x = d_dialog_x + ((d_dialog_w) / 2) - (d_advanced_w / 2); - int d_advanced_y = d_dialog_y + d_dialog_h - d_advanced_h - d_margin - 2 *factor; - - - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_PORT = 100, - BUTTON_PORTLIST, - BUTTON_IRQ, - BUTTON_IRQLIST, - BUTTON_BAUD, - BUTTON_BAUDLIST, - BUTTON_INITSTR, - BUTTON_INITSTRLIST, - BUTTON_ADD, - BUTTON_DELETE, - BUTTON_CWAITSTR, - BUTTON_CWAITSTRLIST, - BUTTON_TONE, - BUTTON_PULSE, - BUTTON_SAVE, - BUTTON_ADVANCED, - BUTTON_INITTYPE, - BUTTON_CANCEL, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - static char *portname[4] = { - "COM1 - 3F8", - "COM2 - 2F8", - "COM3 - 3E8", - "COM4 - 2E8" - }; - - static char custom_port[10 + MODEM_NAME_MAX] = {"CUSTOM - ????"}; - -#ifdef EDIT_IRQ - static char *irqname[5] = { - "2 / 9", - "3 - [COM2 & 4]", - "4 - [COM1 & 3]", - "5", - "CUSTOM - ??" - }; - - static int _irqidx[4] = { - 2, - 1, - 2, - 1 - }; -#endif // EDIT_IRQ - - static char modemnames[10][MODEM_NAME_MAX]; - - static char *baudname[5] = { - "14400", - "19200", - "28800", - "38400", - "57600", - }; - - static char *init_types[2] = { - "Normal", - "Full", - }; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - BOOL process = true; // process while true - KeyNumType input; - char * item; // general-purpose string - char * temp; // general-purpose string - - char portbuf[ PORTBUF_MAX ] = {0}; // buffer for port -#ifdef EDIT_IRQ - char irqbuf[ IRQBUF_MAX ] = {0}; // buffer for irq -#endif //EDIT_IRQ - char baudbuf[ BAUDBUF_MAX ] = {0}; // buffer for baud - char initstrbuf[ INITSTRBUF_MAX ] = {0}; // buffer for init string - char cwaitstrbuf[ CWAITSTRBUF_MAX ] = {0}; // buffer for call waiting string - - int port_index = 1; // index of currently-selected port (default = com2) - int port_custom_index = 4; //index of custom entry in port list -#ifdef EDIT_IRQ - int irq_index = 1; // index of currently-selected irq (default = 3) -#endif //EDIT_IRQ - int baud_index = 1; // index of currently-selected baud (default = 19200) - int initstr_index = 0; // index of currently-selected modem init (default = "ATZ") - int cwaitstr_index = CALL_WAIT_CUSTOM; // index of currently-selected call waiting (default = "") - int rc = 0; // -1 = user cancelled, 1 = New - int i; // loop counter - int pos; - int len; - int firsttime = 1; - SerialSettingsType tempsettings; - DetectPortType dpstatus; - char init_text[32]; - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - EditClass port_edt (BUTTON_PORT, - portbuf, PORTBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_port_x, d_port_y, d_port_w, d_port_h, EditClass::ALPHANUMERIC); - - ListClass portlist(BUTTON_PORTLIST, - d_portlist_x, d_portlist_y, d_portlist_w, d_portlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - -#ifdef EDIT_IRQ - EditClass irq_edt (BUTTON_IRQ, - irqbuf, IRQBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_irq_x, d_irq_y, d_irq_w, d_irq_h, EditClass::NUMERIC); - - ListClass irqlist(BUTTON_IRQLIST, - d_irqlist_x, d_irqlist_y, d_irqlist_w, d_irqlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); -#endif //EDIT_IRQ - - EditClass baud_edt (BUTTON_BAUD, - baudbuf, BAUDBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_baud_x, d_baud_y, d_baud_w, d_baud_h, EditClass::NUMERIC); - - ListClass baudlist(BUTTON_BAUDLIST, - d_baudlist_x, d_baudlist_y, d_baudlist_w, d_baudlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - EditClass initstr_edt (BUTTON_INITSTR, - initstrbuf, INITSTRBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_initstr_x, d_initstr_y, d_initstr_w, d_initstr_h, EditClass::ALPHANUMERIC); - - ListClass initstrlist(BUTTON_INITSTRLIST, - d_initstrlist_x, d_initstrlist_y, d_initstrlist_w, d_initstrlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - TextButtonClass addbtn(BUTTON_ADD, TXT_ADD, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#ifdef FRENCH -// d_add_x, d_add_y); -//#else - d_add_x, d_add_y, d_add_w, d_add_h); -//#endif - - TextButtonClass deletebtn(BUTTON_DELETE, TXT_DELETE_BUTTON, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#ifdef FRENCH -// d_delete_x, d_delete_y); -//#else - d_delete_x, d_delete_y, d_delete_w, d_delete_h); -//#endif - - EditClass cwaitstr_edt (BUTTON_CWAITSTR, - cwaitstrbuf, CWAITSTRBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_cwaitstr_x, d_cwaitstr_y, d_cwaitstr_w, d_cwaitstr_h, EditClass::ALPHANUMERIC); - - ListClass cwaitstrlist(BUTTON_CWAITSTRLIST, - d_cwaitstrlist_x, d_cwaitstrlist_y, d_cwaitstrlist_w, d_cwaitstrlist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - TextButtonClass tonebtn(BUTTON_TONE, TXT_TONE_BUTTON, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_tone_x, d_tone_y, d_tone_w, d_tone_h); - - TextButtonClass pulsebtn(BUTTON_PULSE, TXT_PULSE_BUTTON, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_pulse_x, d_pulse_y, d_pulse_w, d_pulse_h); - - TextButtonClass savebtn(BUTTON_SAVE, TXT_SAVE_BUTTON, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_save_x, d_save_y); -//#else - d_save_x, d_save_y, d_save_w, d_save_h); -//#endif - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif -#if (0) - TextButtonClass inittypebutton(BUTTON_INITTYPE, init_text, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_inittype_x, d_inittype_y, d_inittype_w, d_inittype_h); -#endif //(0) - - TextButtonClass advancedbutton(BUTTON_ADVANCED, TXT_ADVANCED, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_advanced_x, d_advanced_y, d_advanced_w, d_advanced_h); - - /* - ----------------------------- Various Inits ------------------------------ - */ - memcpy( &tempsettings, settings, sizeof(SerialSettingsType) ); - - strcpy (init_text, init_types[tempsettings.Init]); - - if (tempsettings.Port == 0) { - tempsettings.Port = 0x2f8; - } - - if (tempsettings.IRQ == -1) { - tempsettings.IRQ = 3; - } - - if (tempsettings.Baud == -1) { - tempsettings.Baud = 19200; - } - - /*........................................................................ - Set the current indices - ........................................................................*/ - -#ifdef EDIT_IRQ - switch ( tempsettings.IRQ ) { - case ( 2 ): - irq_index = 0; - strcpy (irqbuf, "2"); - break; - - case ( 3 ): - irq_index = 1; - strcpy (irqbuf, "3"); - break; - - case ( 4 ): - irq_index = 2; - strcpy (irqbuf, "4"); - break; - - case ( 5 ): - irq_index = 3; - strcpy (irqbuf, "5"); - break; - - default: - irq_index = 4; - sprintf (irqbuf, "%d", tempsettings.IRQ); - temp = strchr( irqname[4], '-' ); - if ( temp ) { - pos = (int)(temp - irqname[4]) + 2; - len = strlen( irqbuf ); - strncpy( irqname[4] + pos, irqbuf, len ); - *(irqname[4] + pos + len) = 0; - } - break; - } -#endif //EDIT_IRQ - - if (tempsettings.Baud == 14400) { - baud_index = 0; - } else { - if (tempsettings.Baud == 19200) { - baud_index = 1; - } else { - if (tempsettings.Baud == 28800) { - baud_index = 2; - } else { - if (tempsettings.Baud == 38400) { - baud_index = 3; - } else { - baud_index = 4; - } - } - } - } - - sprintf (baudbuf, "%d", tempsettings.Baud); - - /*........................................................................ - Set up the port list box & edit box - ........................................................................*/ - for (i = 0; i < 4; i++) { - portlist.Add_Item( portname[ i ] ); - } - - /* - ** Loop through the first 10 possible modem entries in the registry. Frankly, its just - ** tough luck if the user has more than 10 modems attached! - */ - if (ModemRegistry) { - delete ModemRegistry; - } - int modems_found = 0; - for (i=0 ; i<10 ; i++) { - ModemRegistry = new ModemRegistryEntryClass (i); - if (ModemRegistry->Get_Modem_Name()) { - strncpy (modemnames[modems_found], ModemRegistry->Get_Modem_Name(), MODEM_NAME_MAX); - portlist.Add_Item( modemnames [modems_found++] ); - port_custom_index ++; - } - delete ModemRegistry; - } - ModemRegistry = NULL; - - portlist.Add_Item ( custom_port ); - - - /* - ** Work out the current port index - */ - port_index = -1; - - if (tempsettings.ModemName[0]) { - for ( i=0 ; i= REDRAW_BACKGROUND) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - // init font variables - - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_SETTINGS, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print( TXT_PORT_COLON, - d_port_x - 3, d_port_y + 1 *factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - -#ifdef EDIT_IRQ - Fancy_Text_Print( TXT_IRQ_COLON, - d_irq_x - 3, d_irq_y + 1 *factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); -#endif //EDIT_IRQ - - Fancy_Text_Print( TXT_BAUD_COLON, - d_baud_x - 3, d_baud_y + 1 *factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print( TXT_INIT_STRING, - d_initstr_x, d_initstr_y - d_txt6_h - 3 *factor, - CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print( TXT_CWAIT_STRING, - d_cwaitstr_x, d_cwaitstr_y - d_txt6_h - 3 *factor, - CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); -#if (0) - Fancy_Text_Print ( "Modem Init", - d_inittype_x, d_inittype_y - d_txt6_h - d_margin, - CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); -#endif //(0) - } - - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - cancelbtn.Flag_To_Redraw(); - port_edt.Flag_To_Redraw(); - portlist.Flag_To_Redraw(); -#ifdef EDIT_IRQ - irq_edt.Flag_To_Redraw(); - irqlist.Flag_To_Redraw(); -#endif // EDIT_IRQ - baud_edt.Flag_To_Redraw(); - baudlist.Flag_To_Redraw(); - //inittypebutton.Flag_To_Redraw(); - advancedbutton.Flag_To_Redraw(); - initstr_edt.Flag_To_Redraw(); - initstrlist.Flag_To_Redraw(); - addbtn.Flag_To_Redraw(); - deletebtn.Flag_To_Redraw(); - cwaitstr_edt.Flag_To_Redraw(); - cwaitstrlist.Flag_To_Redraw(); - tonebtn.Flag_To_Redraw(); - pulsebtn.Flag_To_Redraw(); - savebtn.Flag_To_Redraw(); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - if ( firsttime ) { - port_edt.Set_Focus(); - port_edt.Flag_To_Redraw(); - input = commands->Input(); - firsttime = 0; - } - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { -#if (0) - case (BUTTON_INITTYPE | KN_BUTTON): - tempsettings.Init = !tempsettings.Init; - strcpy (init_text, init_types[tempsettings.Init]); - inittypebutton.Flag_To_Redraw(); - break; - - -#endif //(0) - - case (BUTTON_ADVANCED | KN_BUTTON): - Advanced_Modem_Settings (&tempsettings); - display = REDRAW_ALL; - break; - - - case (BUTTON_PORT | KN_BUTTON): - item = (char *)portlist.Current_Item(); - if (port_index < 4) { - temp = strchr( item, ' ' ); - if ( !temp ) { - strncpy( portbuf, item, PORTBUF_MAX ); - } else { - pos = (int)(temp - item); - strncpy( portbuf, item, pos ); - portbuf[pos] = 0; - } - port_edt.Set_Text( portbuf, PORTBUF_MAX ); - port_edt.Flag_To_Redraw(); -#ifdef EDIT_IRQ - irq_edt.Set_Focus(); - irq_edt.Flag_To_Redraw(); -#endif //EDIT_IRQ - } else { - strupr( portbuf ); - if ( stricmp(portbuf, "3F8") == 0 ) { - port_index = 0; - portlist.Set_Selected_Index( port_index ); - strcpy (portbuf, "COM1"); - display = REDRAW_BUTTONS; - } - else if ( stricmp(portbuf, "2F8") == 0 ) { - port_index = 1; - portlist.Set_Selected_Index( port_index ); - strcpy (portbuf, "COM2"); - display = REDRAW_BUTTONS; - } - else if ( stricmp(portbuf, "3E8") == 0 ) { - port_index = 2; - portlist.Set_Selected_Index( port_index ); - strcpy (portbuf, "COM3"); - display = REDRAW_BUTTONS; - } - else if ( stricmp(portbuf, "2E8") == 0 ) { - port_index = 3; - portlist.Set_Selected_Index( port_index ); - strcpy (portbuf, "COM4"); - display = REDRAW_BUTTONS; - } - else if ( strncmp(portbuf, "COM", 3) == 0 ) { - display = REDRAW_BUTTONS; - - switch ( (portbuf[3] - '0') ) { - case 1: - port_index = 0; - break; - - case 2: - port_index = 1; - break; - - case 3: - port_index = 2; - break; - - case 4: - port_index = 3; - break; - - default: - if (portbuf[3] <= '9' && portbuf[3] >'0') { - portbuf[4] = 0; - port_index = port_custom_index; - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - len = strlen( portbuf ); - strncpy( item + pos, portbuf, len ); - *(item + pos + len) = 0; - display = REDRAW_BUTTONS; - } - break; - } - CCMessageBox().Process( TXT_INVALID_PORT_ADDRESS ); - port_edt.Set_Focus(); - display = REDRAW_ALL; - break; - } - - portlist.Set_Selected_Index( port_index ); - } else { - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - len = strlen( portbuf ); - strncpy( item + pos, portbuf, len ); - *(item + pos + len) = 0; - display = REDRAW_BUTTONS; - } - } - -#ifdef EDIT_IRQ - if (display == REDRAW_BUTTONS) { - irq_edt.Set_Focus(); - irq_edt.Flag_To_Redraw(); - } -#endif //EDIT_IRQ - } - break; - - case (BUTTON_PORTLIST | KN_BUTTON): - if (portlist.Current_Index() != port_index) { - port_index = portlist.Current_Index(); - item = (char *)portlist.Current_Item(); - if (port_index < 4) { - temp = strchr( item, ' ' ); - if ( !temp ) { - strncpy( portbuf, item, PORTBUF_MAX ); - } else { - pos = (int)(temp - item); - strncpy( portbuf, item, pos ); - portbuf[pos] = 0; - } - port_edt.Clear_Focus(); - - // auto select the irq for port - -#ifdef EDIT_IRQ - irq_index = _irqidx[ port_index ]; - irqlist.Set_Selected_Index( irq_index ); - item = (char *)irqlist.Current_Item(); - temp = strchr( item, ' ' ); - if ( !temp ) { - strncpy( irqbuf, item, 2 ); - } else { - pos = (int)(temp - item); - strncpy( irqbuf, item, pos ); - irqbuf[pos] = 0; - } - irq_edt.Clear_Focus(); -#endif //EDIT_IRQ - } else { - if (port_index == port_custom_index) { - /* - ** This is the custom entry - */ - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - if ( *(item + pos) == '?' ) { - portbuf[0] = 0; - } else { - strncpy( portbuf, item + pos, PORTBUF_MAX ); - } - } - port_edt.Set_Focus(); - }else{ - /* - ** Must be a modem name entry so just copy iy - */ - strncpy (portbuf, item, PORTBUF_MAX); - } - - } - port_edt.Set_Text( portbuf, PORTBUF_MAX ); - display = REDRAW_BUTTONS; - } else { - if (port_index < port_custom_index) { - port_edt.Clear_Focus(); - } else { - port_edt.Set_Focus(); - } - display = REDRAW_BUTTONS; - } - break; - -#ifdef EDIT_IRQ - case (BUTTON_IRQ | KN_BUTTON): - item = (char *)irqlist.Current_Item(); - if (irq_index < 4) { - temp = strchr( item, ' ' ); - if ( !temp ) { - strncpy( irqbuf, item, IRQBUF_MAX ); - } else { - pos = (int)(temp - item); - strncpy( irqbuf, item, pos ); - irqbuf[pos] = 0; - } - irq_edt.Set_Text( irqbuf, IRQBUF_MAX ); - irq_edt.Flag_To_Redraw(); - } else { - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - len = strlen( irqbuf ); - strncpy( item + pos, irqbuf, len ); - *(item + pos + len) = 0; - display = REDRAW_BUTTONS; - } - } - baud_edt.Set_Focus(); - baud_edt.Flag_To_Redraw(); - break; - - case (BUTTON_IRQLIST | KN_BUTTON): - if (irqlist.Current_Index() != irq_index) { - irq_index = irqlist.Current_Index(); - item = (char *)irqlist.Current_Item(); - if (irq_index < 4) { - temp = strchr( item, ' ' ); - if ( !temp ) { - strncpy( irqbuf, item, IRQBUF_MAX ); - } else { - pos = (int)(temp - item); - strncpy( irqbuf, item, pos ); - irqbuf[pos] = 0; - } - irq_edt.Clear_Focus(); - } else { - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - if ( *(item + pos) == '?' ) { - irqbuf[0] = 0; - } else { - strncpy( irqbuf, item + pos, IRQBUF_MAX ); - } - } - irq_edt.Set_Focus(); - } - irq_edt.Set_Text( irqbuf, IRQBUF_MAX ); - } else { - if (irq_index < 4) { - irq_edt.Clear_Focus(); - } else { - irq_edt.Set_Focus(); - } - } - display = REDRAW_BUTTONS; - break; -#endif //EDIT_IRQ - - case (BUTTON_BAUD | KN_BUTTON): - item = (char *)baudlist.Current_Item(); - strncpy( baudbuf, item, BAUDBUF_MAX ); - baud_edt.Set_Text( baudbuf, BAUDBUF_MAX ); - initstr_edt.Set_Focus(); - initstr_edt.Flag_To_Redraw(); - display = REDRAW_BUTTONS; - break; - - case (BUTTON_BAUDLIST | KN_BUTTON): - if (baudlist.Current_Index() != baud_index) { - baud_index = baudlist.Current_Index(); - item = (char *)baudlist.Current_Item(); - strncpy( baudbuf, item, BAUDBUF_MAX ); - baud_edt.Set_Text( baudbuf, BAUDBUF_MAX ); - baud_edt.Clear_Focus(); - display = REDRAW_BUTTONS; - } - break; - -#if 0 - case (BUTTON_INITSTR | KN_BUTTON): - strupr( initstrbuf ); - strncpy( InitStrings[ initstr_index ], initstrbuf, INITSTRBUF_MAX ); - Build_Init_String_Listbox(&initstrlist, &initstr_edt, initstrbuf, - &initstr_index); - cwaitstr_edt.Set_Focus(); - cwaitstr_edt.Flag_To_Redraw(); - display = REDRAW_BUTTONS; - break; -#endif - - case (BUTTON_INITSTRLIST | KN_BUTTON): - if (initstrlist.Current_Index() != initstr_index) { - initstr_index = initstrlist.Current_Index(); - item = (char *)initstrlist.Current_Item(); - strncpy( initstrbuf, item, INITSTRBUF_MAX ); - initstr_edt.Set_Text( initstrbuf, INITSTRBUF_MAX ); - } - initstr_edt.Set_Focus(); - initstr_edt.Flag_To_Redraw(); - display = REDRAW_BUTTONS; - break; - - /*------------------------------------------------------------------ - Add a new InitString entry - ------------------------------------------------------------------*/ - case (BUTTON_ADD | KN_BUTTON): - - item = new char[ INITSTRBUF_MAX ]; - memset (item, 0, INITSTRBUF_MAX); - - strupr ( initstrbuf ); - strncpy ( item, initstrbuf, INITSTRBUF_MAX-1 ); - - InitStrings.Add ( item ); - Build_Init_String_Listbox (&initstrlist, &initstr_edt, initstrbuf, - &initstr_index); - /*............................................................ - Set the current listbox index to the newly-added item. - ............................................................*/ - for (i = 0; i < InitStrings.Count(); i++) { - if (item == InitStrings[i]) { - initstr_index = i; - strcpy( initstrbuf, InitStrings[ initstr_index ] ); - initstr_edt.Set_Text( initstrbuf, INITSTRBUF_MAX ); - initstrlist.Set_Selected_Index( initstr_index ); - } - } - initstr_edt.Set_Focus(); - initstr_edt.Flag_To_Redraw(); - display = REDRAW_BUTTONS; - break; - - /*------------------------------------------------------------------ - Delete the current InitString entry - ------------------------------------------------------------------*/ - case (BUTTON_DELETE | KN_BUTTON): - - if ( InitStrings.Count() && initstr_index != -1) { - InitStrings.Delete( initstr_index ); - Build_Init_String_Listbox(&initstrlist, &initstr_edt, initstrbuf, - &initstr_index); - } - break; - - case (BUTTON_CWAITSTR | KN_BUTTON): - item = (char *)cwaitstrlist.Current_Item(); - if (cwaitstr_index < 3) { - } else { - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - len = strlen( cwaitstrbuf ); - strncpy( item + pos, cwaitstrbuf, len ); - *(item + pos + len) = 0; - display = REDRAW_BUTTONS; - } - } - break; - - case (BUTTON_CWAITSTRLIST | KN_BUTTON): - if (cwaitstrlist.Current_Index() != cwaitstr_index) { - cwaitstr_index = cwaitstrlist.Current_Index(); - item = (char *)cwaitstrlist.Current_Item(); - if (cwaitstr_index < 3) { - strncpy( cwaitstrbuf, item, CWAITSTRBUF_MAX ); - cwaitstr_edt.Clear_Focus(); - } else { - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - strncpy( cwaitstrbuf, item + pos, CWAITSTRBUF_MAX ); - } - cwaitstr_edt.Set_Focus(); - } - cwaitstr_edt.Set_Text( cwaitstrbuf, CWAITSTRBUF_MAX ); - } else { - if (cwaitstr_index < 3) { - cwaitstr_edt.Clear_Focus(); - } else { - cwaitstr_edt.Set_Focus(); - } - } - display = REDRAW_BUTTONS; - break; - - case (BUTTON_TONE | KN_BUTTON): - tempsettings.DialMethod = DIAL_TOUCH_TONE; - tonebtn.Turn_On(); - pulsebtn.Turn_Off(); - break; - - case (BUTTON_PULSE | KN_BUTTON): - tempsettings.DialMethod = DIAL_PULSE; - tonebtn.Turn_Off(); - pulsebtn.Turn_On(); - break; - - /*------------------------------------------------------------------ - SAVE: save the com settings - ------------------------------------------------------------------*/ - case (KN_RETURN): - case (BUTTON_SAVE | KN_BUTTON): - switch (port_index) { - case ( 0 ): - tempsettings.Port = 0x3f8; - tempsettings.ModemName[0] = 0; - break; - - case ( 1 ): - tempsettings.Port = 0x2f8; - tempsettings.ModemName[0] = 0; - break; - - case ( 2 ): - tempsettings.Port = 0x3e8; - tempsettings.ModemName[0] = 0; - break; - - case ( 3 ): - tempsettings.Port = 0x2e8; - tempsettings.ModemName[0] = 0; - break; - - default: - if (port_index == port_custom_index) { - strncpy ( tempsettings.ModemName, portbuf, MODEM_NAME_MAX ); - tempsettings.Port = 1; - } else { - /* - ** Must be a modem name index - */ - strcpy (tempsettings.ModemName, portlist.Current_Item()); - tempsettings.Port = 1; - } - break; - } - -#ifdef EDIT_IRQ - switch (irq_index) { - case ( 0 ): - tempsettings.IRQ = 2; - break; - - case ( 1 ): - tempsettings.IRQ = 3; - break; - - case ( 2 ): - tempsettings.IRQ = 4; - break; - - case ( 3 ): - tempsettings.IRQ = 5; - break; - - default: - sscanf( irqbuf, "%d", &tempsettings.IRQ ); - break; - } -#endif //EDIT_IRQ - - sscanf( baudbuf, "%d", &tempsettings.Baud ); - - tempsettings.InitStringIndex = initstr_index; - tempsettings.CallWaitStringIndex = cwaitstr_index; - - item = CallWaitStrings[ CALL_WAIT_CUSTOM ]; - temp = strchr( item, '-' ); - if ( temp ) { - pos = (int)(temp - item) + 2; - strncpy( cwaitstrbuf, item + pos, CWAITSTRBUF_MAX ); - } else { - cwaitstrbuf[ 0 ] = 0; - } - - strncpy( tempsettings.CallWaitString, cwaitstrbuf, CWAITSTRBUF_MAX ); - - dpstatus = NullModem.Detect_Port( &tempsettings ); - - if (dpstatus == PORT_VALID) { - process = false; - rc = true; - } - else if (dpstatus == PORT_INVALID) { - CCMessageBox().Process( TXT_INVALID_SETTINGS ); - firsttime = 1; - display = REDRAW_ALL; - } - else if (dpstatus == PORT_IRQ_INUSE) { - CCMessageBox().Process( TXT_IRQ_ALREADY_IN_USE ); - firsttime = 1; - display = REDRAW_ALL; - } - break; - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF, bail out with error code - ------------------------------------------------------------------*/ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - process = false; - rc = false; - break; - } - - } /* end of while */ - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - /*------------------------------------------------------------------------ - Save values into the Settings structure - ------------------------------------------------------------------------*/ - if (rc) { - memcpy( settings, &tempsettings, sizeof(SerialSettingsType) ); - } - - return(rc); - -} /* end of Com_Settings_Dialog */ - - -/*************************************************************************** - * Build_Init_String_Listbox -- [re]builds the initstring listbox * - * * - * This routine rebuilds the initstring list box from scratch; it also * - * updates the contents of the initstring edit field. * - * * - * INPUT: * - * list ptr to list box * - * edit ptr to edit box * - * buf ptr to buffer for initstring * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/08/1995 DRD : Created. * - *=========================================================================*/ -static void Build_Init_String_Listbox (ListClass *list, EditClass *edit, char *buf, int *index) -{ - int i, curidx; - char *item; - - - curidx = *index; - - /*........................................................................ - Clear the list - ........................................................................*/ - while (list->Count()) { - item = (char *)(list->Get_Item(0)); - list->Remove_Item(item); - delete [] item; - } - - /* - ** Now sort the init string list by name then number - */ - qsort ((void *)(&InitStrings[0]), InitStrings.Count(), sizeof(char *), Init_String_Compare); - - /*........................................................................ - Build the list - ........................................................................*/ - for (i = 0; i < InitStrings.Count(); i++) { - item = new char[ INITSTRBUF_MAX ]; - strcpy( item, InitStrings[i] ); - list->Add_Item(item); - } - list->Flag_To_Redraw(); - - /*........................................................................ - Init the current phone book index - ........................................................................*/ - if (list->Count() == 0 || curidx < -1) { - curidx = -1; - } else { - if (curidx >= list->Count() ) { - curidx = 0; - } - } - - /*........................................................................ - Fill in initstring edit buffer - ........................................................................*/ - if (curidx > -1) { - strcpy (buf, InitStrings[ curidx ]); - edit->Set_Text (buf, INITSTRBUF_MAX ); - list->Set_Selected_Index( curidx ); - } - - *index = curidx; -} - - -/*************************************************************************** - * Init_String_Compare -- for qsort * - * * - * INPUT: * - * p1,p2 ptrs to elements to compare * - * * - * OUTPUT: * - * 0 = same, -1 = (*p1) goes BEFORE (*p2), 1 = (*p1) goes AFTER (*p2) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/08/1995 DRD : Created. * - *=========================================================================*/ -static int Init_String_Compare (const void *p1, const void *p2) -{ - return( strcmp( *((char **)p1), *((char **)p2) ) ); -} - - -/*********************************************************************************************** - * Com_Scenario_Dialog -- Serial game scenario selection dialog * - * * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Serial Game ³ * - * ³ ³ * - * ³ Your Name: __________ House: [GDI] [NOD] ³ * - * ³ Credits: ______ Desired Color: [ ][ ][ ][ ] ³ * - * ³ Opponent: Name ³ * - * ³ ³ * - * ³ Scenario ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * - * ³ ³ Hell's Kitchen ³³ ³ * - * ³ ³ Heaven's Gate ÃÄ´ ³ * - * ³ ³ ... ³ ³ ³ * - * ³ ³ ÃÄ´ ³ * - * ³ ³ ³³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * - * ³ [ Bases ] [ Crates ] ³ * - * ³ [ Tiberium ] [ AI Players ] ³ * - * ³ ³ * - * ³ [OK] [Cancel] ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ [Send Message] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = success, false = cancel * - * * - * WARNINGS: * - * MPlayerName & MPlayerGameName must contain this player's name. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -#define TXT_HOST_INTERNET_GAME 4567+1 -#define TXT_JOIN_INTERNET_GAME 4567+2 -int Com_Scenario_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 290*factor; // dialog width - int d_dialog_h = 190*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // dialog y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 6*factor+1; // ht of 6-pt text - int d_margin1 = 5*factor; // margin width/height - int d_margin2 = 2*factor; // margin width/height - - int d_name_w = 70*factor; - int d_name_h = 9*factor; - int d_name_x = d_dialog_x + 108*factor; - int d_name_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h + d_margin1; - - int d_credits_w = ((CREDITSBUF_MAX - 1) * 6*factor) + 3*factor; - int d_credits_h = 9*factor; - int d_credits_x = d_name_x; - int d_credits_y = d_name_y + d_name_h + d_margin2; - - int d_gdi_w = 30*factor; - int d_gdi_h = 9*factor; - int d_gdi_x = d_dialog_cx + (d_dialog_w / 4); - int d_gdi_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h + d_margin1; - - int d_nod_w = 30*factor; - int d_nod_h = 9*factor; - int d_nod_x = d_gdi_x + d_gdi_w + (d_margin1 / 2); - int d_nod_y = d_gdi_y; - - int d_color_w = 10*factor; - int d_color_h = 9*factor; - int d_color_y = d_gdi_y + d_gdi_h + d_margin2; - - int d_opponent_x = d_name_x; - int d_opponent_y = d_color_y + d_color_h + d_margin2; - - int d_scenariolist_w = 182*factor; - int d_scenariolist_h = 27*factor; - int d_scenariolist_x = d_dialog_cx - (d_scenariolist_w / 2); - int d_scenariolist_y = d_opponent_y + d_txt6_h + 3*factor + d_txt6_h; - - // d_count_x is calculated below after other enums - int d_count_w = 25*factor; - int d_count_h = 7*factor; - int d_count_y = d_scenariolist_y + d_scenariolist_h + d_margin2; - - // d_level_x is calculated below after other enums - int d_level_w = 25*factor; - int d_level_h = 7*factor; - int d_level_y = d_count_y; - -#if (GERMAN | FRENCH) - int d_bases_w = 120*factor;//BGA:100; -#else - int d_bases_w = 110*factor; -#endif - int d_bases_h = 9*factor; - int d_bases_x = d_dialog_cx - d_bases_w - d_margin2; - int d_bases_y = d_count_y + d_count_h + d_margin2; - -#if (GERMAN | FRENCH) - int d_goodies_w = 120*factor; -#else - int d_goodies_w = 110*factor; -#endif - int d_goodies_h = 9*factor; - int d_goodies_x = d_dialog_cx + d_margin2; - int d_goodies_y = d_bases_y; - - int d_count_x = d_dialog_cx - d_count_w - ((2 * 6*factor) + 3*factor) - - ((d_bases_w - ((13 * 6*factor) + 3*factor + d_count_w)) / 2) - d_margin2; - - int d_level_x = d_dialog_cx + (11 * 6*factor) - + ((d_goodies_w - ((13 * 6*factor) + 3*factor + d_level_w)) / 2) + d_margin2; - -#if (GERMAN | FRENCH) - int d_tiberium_w = 120*factor; -#else - int d_tiberium_w = 110*factor; -#endif - int d_tiberium_h = 9*factor; - int d_tiberium_x = d_dialog_cx - d_bases_w - d_margin2; - int d_tiberium_y = d_bases_y + d_bases_h + d_margin2; - -#if (GERMAN | FRENCH) - int d_ghosts_w = 120*factor; -#else - int d_ghosts_w = 110*factor; -#endif - int d_ghosts_h = 9*factor; - int d_ghosts_x = d_dialog_cx + d_margin2; - int d_ghosts_y = d_tiberium_y; - - int d_ok_w = 45*factor; - int d_ok_h = 9*factor; - int d_ok_x = d_tiberium_x + (d_tiberium_w / 2) - (d_ok_w / 2); - int d_ok_y = d_tiberium_y + d_tiberium_h + d_margin1; - - int d_cancel_w = 45*factor; - int d_cancel_h = 9*factor; - int d_cancel_x = d_ghosts_x + (d_ghosts_w / 2) - (d_cancel_w / 2); - int d_cancel_y = d_tiberium_y + d_tiberium_h + d_margin1; - - int d_message_w = d_dialog_w - (d_margin1 * 2); - int d_message_h = 34*factor; - int d_message_x = d_dialog_x + d_margin1; - int d_message_y = d_cancel_y + d_cancel_h + d_margin1; - - int d_send_w = 80*factor; - int d_send_h = 9*factor; - int d_send_x = d_dialog_cx - (d_send_w / 2); - int d_send_y = d_message_y + d_message_h + d_margin2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_NAME = 100, - BUTTON_GDI, - BUTTON_NOD, - BUTTON_CREDITS, - BUTTON_SCENARIOLIST, - BUTTON_COUNT, - BUTTON_LEVEL, - BUTTON_BASES, - BUTTON_TIBERIUM, - BUTTON_GOODIES, - BUTTON_GHOSTS, - BUTTON_OK, - BUTTON_CANCEL, - BUTTON_SEND, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_MESSAGE, - REDRAW_COLORS, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - KeyNumType input; - - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - char credbuf[CREDITSBUF_MAX]; // for credit edit box - int old_cred; // old value in credits buffer - int transmit; // 1 = re-transmit new game options - int cbox_x[] = { d_gdi_x, - d_gdi_x + d_color_w, - d_gdi_x + (d_color_w * 2), - d_gdi_x + (d_color_w * 3), - d_gdi_x + (d_color_w * 4), - d_gdi_x + (d_color_w * 5)}; - int parms_received = 0; // 1 = game options received - int changed = 0; // 1 = user has changed an option - - int rc; - int recsignedoff = false; - int i; - int version; - char txt[80]; - unsigned long starttime; - unsigned long timingtime; - unsigned long lastmsgtime; - unsigned long lastredrawtime; - unsigned long transmittime = 0; - unsigned long theirresponsetime; - int packetlen; - static int first_time = 1; - bool oppscorescreen = false; - bool gameoptions = false; - EventClass *event; // event ptr - unsigned long msg_timeout = 1200; // init to 20 seconds - - int message_length; - int sent_so_far; - unsigned short magic_number; - unsigned short crc; - bool ready_to_go = false; - CountDownTimerClass ready_time; - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - EditClass name_edt (BUTTON_NAME, - namebuf, MPLAYER_NAME_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); - - TextButtonClass gdibtn(BUTTON_GDI, TXT_G_D_I, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_gdi_x, d_gdi_y, d_gdi_w, d_gdi_h); - - TextButtonClass nodbtn(BUTTON_NOD, TXT_N_O_D, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_nod_x, d_nod_y, d_nod_w, d_nod_h); - - EditClass credit_edt (BUTTON_CREDITS, - credbuf, CREDITSBUF_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_credits_x, d_credits_y, d_credits_w, d_credits_h, EditClass::ALPHANUMERIC); - - ListClass scenariolist(BUTTON_SCENARIOLIST, - d_scenariolist_x, d_scenariolist_y, d_scenariolist_w, d_scenariolist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - GaugeClass countgauge (BUTTON_COUNT, - d_count_x, d_count_y, d_count_w, d_count_h); - - GaugeClass levelgauge (BUTTON_LEVEL, - d_level_x, d_level_y, d_level_w, d_level_h); - - TextButtonClass basesbtn(BUTTON_BASES, TXT_BASES_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_bases_x, d_bases_y, d_bases_w, d_bases_h); - - TextButtonClass tiberiumbtn(BUTTON_TIBERIUM, TXT_TIBERIUM_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_tiberium_x, d_tiberium_y, d_tiberium_w, d_tiberium_h); - - TextButtonClass goodiesbtn(BUTTON_GOODIES, TXT_CRATES_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_goodies_x, d_goodies_y, d_goodies_w, d_goodies_h); - - TextButtonClass ghostsbtn(BUTTON_GHOSTS, TXT_AI_PLAYERS_OFF, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ghosts_x, d_ghosts_y, d_ghosts_w, d_ghosts_h); - - TextButtonClass okbtn(BUTTON_OK, TXT_OK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_ok_x, d_ok_y, d_ok_w, d_ok_h); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - TextButtonClass sendbtn(BUTTON_SEND, TXT_SEND_MESSAGE, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_send_x, d_send_y); -//#else - d_send_x, d_send_y, d_send_w, d_send_h); -//#endif - - /* - ------------------------- Build the button list -------------------------- - */ - commands = &name_edt; - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - credit_edt.Add_Tail(*commands); - scenariolist.Add_Tail(*commands); - countgauge.Add_Tail(*commands); - levelgauge.Add_Tail(*commands); - basesbtn.Add_Tail(*commands); - tiberiumbtn.Add_Tail(*commands); - goodiesbtn.Add_Tail(*commands); - ghostsbtn.Add_Tail(*commands); - okbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - sendbtn.Add_Tail(*commands); - - /* - ----------------------------- Various Inits ------------------------------ - */ - /*........................................................................ - Init player name & house - ........................................................................*/ - MPlayerColorIdx = MPlayerPrefColor; // init my preferred color - strcpy (namebuf, MPlayerName); // set my name - name_edt.Set_Text(namebuf,MPLAYER_NAME_MAX); - name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); - - if (MPlayerHouse==HOUSE_GOOD) { - gdibtn.Turn_On(); - } else { - nodbtn.Turn_On(); - } - - /*........................................................................ - Init scenario values, only the first time through - ........................................................................*/ - if (first_time) { - MPlayerCredits = 3000; // init credits & credit buffer - MPlayerBases = 1; // init scenario parameters - MPlayerTiberium = 0; - MPlayerGoodies = 0; - MPlayerGhosts = 0; - Special.IsCaptureTheFlag = 0; - MPlayerUnitCount = (MPlayerCountMax[MPlayerBases] + MPlayerCountMin[MPlayerBases]) / 2; - first_time = 0; - } - - /*........................................................................ - Init button states - ........................................................................*/ - if (MPlayerBases) { - basesbtn.Turn_On(); - basesbtn.Set_Text(TXT_BASES_ON); - } - if (MPlayerTiberium) { - tiberiumbtn.Turn_On(); - tiberiumbtn.Set_Text(TXT_TIBERIUM_ON); - } - if (MPlayerGoodies) { - goodiesbtn.Turn_On(); - goodiesbtn.Set_Text(TXT_CRATES_ON); - } - if (MPlayerGhosts) { - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_AI_PLAYERS_ON); - } - if (Special.IsCaptureTheFlag) { - MPlayerGhosts = 0; - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_CAPTURE_THE_FLAG); - } - - sprintf(credbuf, "%d", MPlayerCredits); - credit_edt.Set_Text(credbuf, CREDITSBUF_MAX); - old_cred = MPlayerCredits; - - levelgauge.Set_Maximum(MPLAYER_BUILD_LEVEL_MAX - 1); - levelgauge.Set_Value(BuildLevel - 1); - - countgauge.Set_Maximum(MPlayerCountMax[MPlayerBases] - MPlayerCountMin[MPlayerBases]); - countgauge.Set_Value(MPlayerUnitCount - MPlayerCountMin[MPlayerBases]); - - /*........................................................................ - Init other scenario parameters - ........................................................................*/ - Special.IsTGrowth = MPlayerTiberium; - Special.IsTSpread = MPlayerTiberium; - transmit = 1; - - /*........................................................................ - Init scenario description list box - ........................................................................*/ - for (i = 0; i < MPlayerScenarios.Count(); i++) { - scenariolist.Add_Item (strupr(MPlayerScenarios[i])); - } - ScenarioIdx = 0; // 1st scenario is selected - - /*........................................................................ - Init random-number generator, & create a seed to be used for all random - numbers from here on out - ........................................................................*/ - randomize(); - Seed = rand(); - - /*........................................................................ - Init the message display system - ........................................................................*/ - Messages.Init (d_message_x + 2*factor, d_message_y + 2*factor, 4, MAX_MESSAGE_LENGTH, d_txt6_h); - - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - extern char ModemRXString[]; - - if (strlen(ModemRXString) > 36) - ModemRXString[36] = 0; - - if (strlen(ModemRXString) > 0) - Messages.Add_Message (ModemRXString, CC_TAN, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, 0, 0); - - ModemRXString[0] = '\0'; - - /* - ---------------------------- Init Mono Output ---------------------------- - */ - #if(SHOW_MONO) - NullModem.Configure_Debug(sizeof (CommHeaderType),sizeof (SerialCommandType), - SerialPacketNames, 106); - NullModem.Mono_Debug_Print(1); - #endif - - /* - ---------------------------- Processing loop ----------------------------- - */ - NullModem.Reset_Response_Time(); // clear response time - theirresponsetime = 10000; // initialize to an invalid value - timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); - while (Get_Mouse_State() > 0) Show_Mouse(); - - - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - // init font variables - - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ -#ifdef FORCE_WINSOCK - if (Winsock.Get_Connected()){ - Draw_Caption (TXT_HOST_INTERNET_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - }else{ - Draw_Caption (TXT_HOST_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - } -#else - Draw_Caption (TXT_HOST_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); -#endif //FORCE_WINSOCK - - Fancy_Text_Print(TXT_YOUR_NAME, - d_name_x - 5*factor, d_name_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_SIDE_COLON, - d_gdi_x - 5*factor, d_gdi_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print (TXT_START_CREDITS_COLON, d_credits_x - 5*factor, d_credits_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_COLOR_COLON, - cbox_x[0] - 5*factor, d_color_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_SCENARIOS, - d_scenariolist_x + (d_scenariolist_w / 2), - d_scenariolist_y - d_txt6_h, - CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print (TXT_COUNT, d_count_x - 3*factor, d_count_y, CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); - - Fancy_Text_Print (TXT_LEVEL, d_level_x - 3*factor, d_level_y, CC_GREEN, TBLACK, - TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); - } - - /*.................................................................. - Draw the color boxes - ..................................................................*/ - if (display >= REDRAW_COLORS) { - for (i = 0; i < MAX_MPLAYER_COLORS; i++) { - LogicPage->Fill_Rect (cbox_x[i] + 1*factor, d_color_y + 1*factor, - cbox_x[i] + 1*factor + d_color_w - 2*factor, d_color_y + 1*factor + d_color_h - 2*factor, - MPlayerGColors[i]); - - if (i == MPlayerColorIdx) { - Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, - BOXSTYLE_GREEN_DOWN, false); - } else { - Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, - BOXSTYLE_GREEN_RAISED, false); - } - } - } - - /*.................................................................. - Draw the message: - - Erase an old message first - ..................................................................*/ - if (display >= REDRAW_MESSAGE) { - Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, - BOXSTYLE_GREEN_BORDER, true); - Messages.Draw(); - - LogicPage->Fill_Rect (d_dialog_x + 2*factor, - d_opponent_y, - d_dialog_x + d_dialog_w - 4*factor, - d_opponent_y + d_txt6_h, - BLACK); - - if (parms_received) { - if (oppscorescreen) { - sprintf(txt,"%s",Text_String(TXT_WAITING_FOR_OPPONENT)); - - int txtwidth = String_Pixel_Width( txt ); - - Fancy_Text_Print (txt, d_dialog_cx - (txtwidth / 2), - d_opponent_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } else { - Fancy_Text_Print (TXT_OPPONENT_COLON, d_opponent_x - 3*factor, - d_opponent_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (TheirHouse == HOUSE_GOOD) { - sprintf(txt,"%s %s",TheirName,Text_String(TXT_G_D_I)); - } else { - sprintf(txt,"%s %s",TheirName,Text_String(TXT_N_O_D)); - } - - Fancy_Text_Print (txt, d_opponent_x, - d_opponent_y, MPlayerTColors[TheirColor], TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - } - - sprintf( txt, "%d ", MPlayerUnitCount ); - Fancy_Text_Print (txt, d_count_x + d_count_w + 3*factor, - d_count_y, CC_GREEN, BLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { - sprintf(txt, "%d ", BuildLevel); - } else { - sprintf(txt, "**"); - } - Fancy_Text_Print (txt, d_level_x + d_level_w + 3*factor, - d_level_y, CC_GREEN, BLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Flag_List_To_Redraw(); - } - - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - /*------------------------------------------------------------------ - User clicks on a color button - ------------------------------------------------------------------*/ - case KN_LMOUSE: - if (_Kbd->MouseQX > cbox_x[0] && - _Kbd->MouseQX < (cbox_x[MAX_MPLAYER_COLORS - 1] + d_color_w) && - _Kbd->MouseQY > d_color_y && - _Kbd->MouseQY < (d_color_y + d_color_h)) { - if (!ready_to_go){ - MPlayerPrefColor = (_Kbd->MouseQX - cbox_x[0]) / d_color_w; - MPlayerColorIdx = MPlayerPrefColor; - display = REDRAW_COLORS; - - name_edt.Set_Color (MPlayerTColors[MPlayerColorIdx]); - name_edt.Flag_To_Redraw(); - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - changed = 1; - } - } - break; - - /*------------------------------------------------------------------ - User edits the name field; retransmit new game options - ------------------------------------------------------------------*/ - case (BUTTON_NAME | KN_BUTTON): - if (!ready_to_go){ - credit_edt.Clear_Focus(); - credit_edt.Flag_To_Redraw(); - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - changed = 1; - } - break; - - /*------------------------------------------------------------------ - House Buttons: set the player's desired House - ------------------------------------------------------------------*/ - case (BUTTON_GDI | KN_BUTTON): - if (!ready_to_go){ - MPlayerHouse = HOUSE_GOOD; - gdibtn.Turn_On(); - nodbtn.Turn_Off(); - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - case (BUTTON_NOD | KN_BUTTON): - if (!ready_to_go){ - MPlayerHouse = HOUSE_BAD; - gdibtn.Turn_Off(); - nodbtn.Turn_On(); - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - User edits the credits value; retransmit new game options - ------------------------------------------------------------------*/ - case (BUTTON_CREDITS | KN_BUTTON): - if (!ready_to_go){ - name_edt.Clear_Focus(); - name_edt.Flag_To_Redraw(); - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - New Scenario selected. - ------------------------------------------------------------------*/ - case (BUTTON_SCENARIOLIST | KN_BUTTON): - if (scenariolist.Current_Index() != ScenarioIdx && !ready_to_go) { - ScenarioIdx = scenariolist.Current_Index(); - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - User adjusts max # units - ------------------------------------------------------------------*/ - case (BUTTON_COUNT | KN_BUTTON): - if (!ready_to_go){ - MPlayerUnitCount = countgauge.Get_Value() + MPlayerCountMin[MPlayerBases]; - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - User adjusts build level - ------------------------------------------------------------------*/ - case (BUTTON_LEVEL | KN_BUTTON): - if (!ready_to_go){ - BuildLevel = levelgauge.Get_Value() + 1; - if (BuildLevel > MPLAYER_BUILD_LEVEL_MAX) // if it's pegged, max it out - BuildLevel = MPLAYER_BUILD_LEVEL_MAX; - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - Toggle bases - ------------------------------------------------------------------*/ - case (BUTTON_BASES | KN_BUTTON): - if (!ready_to_go){ - if (MPlayerBases) { - MPlayerBases = 0; - basesbtn.Turn_Off(); - basesbtn.Set_Text(TXT_BASES_OFF); - MPlayerUnitCount = Fixed_To_Cardinal (MPlayerCountMax[0]-MPlayerCountMin[0], - Cardinal_To_Fixed(MPlayerCountMax[1]-MPlayerCountMin[1], - MPlayerUnitCount-MPlayerCountMin[1])) + MPlayerCountMin[0]; - } else { - MPlayerBases = 1; - basesbtn.Turn_On(); - basesbtn.Set_Text(TXT_BASES_ON); - MPlayerUnitCount = Fixed_To_Cardinal (MPlayerCountMax[1]-MPlayerCountMin[1], - Cardinal_To_Fixed(MPlayerCountMax[0]-MPlayerCountMin[0], - MPlayerUnitCount-MPlayerCountMin[0])) + MPlayerCountMin[1]; - } - MPlayerCredits = atoi(credbuf); - countgauge.Set_Maximum(MPlayerCountMax[MPlayerBases] - MPlayerCountMin[MPlayerBases]); - countgauge.Set_Value(MPlayerUnitCount - MPlayerCountMin[MPlayerBases]); - strcpy (MPlayerName, namebuf); - transmit = 1; - display = REDRAW_ALL; - } - break; - - /*------------------------------------------------------------------ - Toggle tiberium - ------------------------------------------------------------------*/ - case (BUTTON_TIBERIUM | KN_BUTTON): - if (!ready_to_go){ - if (MPlayerTiberium) { - MPlayerTiberium = 0; - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - tiberiumbtn.Turn_Off(); - tiberiumbtn.Set_Text(TXT_TIBERIUM_OFF); - } else { - MPlayerTiberium = 1; - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - tiberiumbtn.Turn_On(); - tiberiumbtn.Set_Text(TXT_TIBERIUM_ON); - } - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - Toggle goodies - ------------------------------------------------------------------*/ - case (BUTTON_GOODIES | KN_BUTTON): - if (!ready_to_go){ - if (MPlayerGoodies) { - MPlayerGoodies = 0; - goodiesbtn.Turn_Off(); - goodiesbtn.Set_Text(TXT_CRATES_OFF); - } else { - MPlayerGoodies = 1; - goodiesbtn.Turn_On(); - goodiesbtn.Set_Text(TXT_CRATES_ON); - } - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - Toggle ghosts - ------------------------------------------------------------------*/ - case (BUTTON_GHOSTS | KN_BUTTON): - if (!ready_to_go){ - if (!MPlayerGhosts && !Special.IsCaptureTheFlag) { // ghosts OFF => ghosts ON - MPlayerGhosts = 1; - Special.IsCaptureTheFlag = 0; - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_AI_PLAYERS_ON); - } - else if (MPlayerGhosts) { // ghosts ON => capture-flag - MPlayerGhosts = 0; - Special.IsCaptureTheFlag = 1; - ghostsbtn.Turn_On(); - ghostsbtn.Set_Text(TXT_CAPTURE_THE_FLAG); - } - else if (Special.IsCaptureTheFlag) { // capture-flag => AI OFF - MPlayerGhosts = 0; - Special.IsCaptureTheFlag = 0; - ghostsbtn.Turn_Off(); - ghostsbtn.Set_Text(TXT_AI_PLAYERS_OFF); - } - MPlayerCredits = atoi(credbuf); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - OK: exit loop with true status - ------------------------------------------------------------------*/ - case (BUTTON_OK | KN_BUTTON): - if (!ready_to_go){ - // - // make sure we got a game options packet from the other player - // - if (gameoptions) { - //rc = true; - //process = false; - - // force transmitting of game options packet one last time - - - - SendPacket.Command = SERIAL_READY_TO_GO; - SendPacket.ID = ModemGameToPlay; - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - - while ( ( NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - NullModem.Service(); - Keyboard::Check(); //Make sure the message loop gets called - } - - ready_to_go = true; - ready_time.Set(120, true); - - transmit = 1; - transmittime = 0; - - } else { - CCMessageBox().Process (TXT_ONLY_ONE,TXT_OOPS,NULL); - display = REDRAW_ALL; - } - } - break; - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF, bail out with error code - ------------------------------------------------------------------*/ - case (KN_ESC): - if (!ready_to_go){ - if (Messages.Get_Edit_Buf() != NULL) { - Messages.Input(input); - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - break; - } - } - case (BUTTON_CANCEL | KN_BUTTON): - if (!ready_to_go){ - process = false; - rc = false; - } - break; - - /*------------------------------------------------------------------ - Default: manage the inter-player messages - ------------------------------------------------------------------*/ - default: - if (ready_to_go) break; - - /*............................................................... - F4/SEND/'M' = send a message - ...............................................................*/ - if (Messages.Get_Edit_Buf()==NULL) { - if (input == KN_M || input==(BUTTON_SEND | KN_BUTTON) || - input == KN_F4) { - memset (txt, 0, 80); - - strcpy(txt,Text_String(TXT_MESSAGE)); // "Message:" - - Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, d_message_w-70*factor); - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - - credit_edt.Clear_Focus(); - credit_edt.Flag_To_Redraw(); - name_edt.Clear_Focus(); - name_edt.Flag_To_Redraw(); - - break; - } - } else { - if ( input == (BUTTON_SEND | KN_BUTTON) ) { - input = KN_RETURN; - } - } - - /*............................................................... - Manage the message system (get rid of old messages) - ...............................................................*/ - if (Messages.Manage()) { - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } - - /*............................................................... - Service keyboard input for any message being edited. - ...............................................................*/ - i = Messages.Input(input); - - /*............................................................... - If 'Input' returned 1, it means refresh the message display. - ...............................................................*/ - if (i==1) { - Messages.Draw(); - } - - /*............................................................... - If 'Input' returned 2, it means redraw the message display. - ...............................................................*/ - else if (i==2) { - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } - - /*............................................................... - If 'input' returned 3, it means send the current message. - ...............................................................*/ - else if (i==3) { - long actual_message_size; - char *the_string; - - sent_so_far = 0; - magic_number = MESSAGE_HEAD_MAGIC_NUMBER; - message_length = strlen(Messages.Get_Edit_Buf()); - crc = (unsigned short) - (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) &0xffff); - - while (sent_so_far < message_length){ - - SendPacket.Command = SERIAL_MESSAGE; - strcpy (SendPacket.Name, MPlayerName); - SendPacket.ID = Build_MPlayerID(MPlayerColorIdx, MPlayerHouse); - memcpy (SendPacket.Message, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); - - /* - ** Steve I's stuff for splitting message on word boundries - */ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - - /* Start at the end of the message and find a space with 10 chars. */ - the_string = SendPacket.Message; - while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && - the_string[actual_message_size] != ' '){ - --actual_message_size; - } - if ( the_string[actual_message_size] == ' ' ){ - - /* Now delete the extra characters after the space (they musnt print) */ - for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ - the_string[i + actual_message_size] = 0xff; - } - }else{ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - } - - *(SendPacket.Message + COMPAT_MESSAGE_LENGTH-5) = 0; - *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-4)) = magic_number; - *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-2)) = crc; - - /*.................................................................. - Send the message - ..................................................................*/ - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - NullModem.Service(); - - /*.................................................................. - Add the message to our own screen - ..................................................................*/ - sprintf(txt, Text_String (TXT_FROM), MPlayerName, SendPacket.Message); - Messages.Add_Message (txt, MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); - - magic_number++; - sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; - } - - if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; - } /* end of send message */ - - } /* end of input processing */ - - /*--------------------------------------------------------------------- - Detect editing of the credits buffer, transmit new values to players - ---------------------------------------------------------------------*/ - if (atoi(credbuf) != old_cred) { - old_cred = Bound(atoi(credbuf), 0, 9999); - MPlayerCredits = old_cred; - transmit = 1; - sprintf(credbuf, "%d", MPlayerCredits); - credit_edt.Set_Text(credbuf, CREDITSBUF_MAX); - } - - /*--------------------------------------------------------------------- - Detect editing of the name buffer, transmit new values to players - ---------------------------------------------------------------------*/ - if (strcmp (namebuf, MPlayerName)) { - strcpy (MPlayerName, namebuf); - transmit = 1; - changed = 1; - } - - /*--------------------------------------------------------------------- - If our Transmit flag is set, we need to send out a game option packet. - This message requires an ACK. The first time through the loop, transmit - should be set, so we send out our default options; we'll then send - any changes we make to the defaults. - ---------------------------------------------------------------------*/ - if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { - SendPacket.Command = SERIAL_GAME_OPTIONS; - strcpy (SendPacket.Name, MPlayerName); -#ifdef PATCH - if (IsV107) { - SendPacket.Version = 1; - } else { - SendPacket.Version = 2; - } -#else - SendPacket.Version = Version_Number(); -#endif - SendPacket.House = MPlayerHouse; - SendPacket.Color = MPlayerColorIdx; - - SendPacket.Scenario = MPlayerFilenum[ScenarioIdx]; - - SendPacket.Credits = MPlayerCredits; - SendPacket.IsBases = MPlayerBases; - SendPacket.IsTiberium = MPlayerTiberium; - SendPacket.IsGoodies = MPlayerGoodies; - SendPacket.IsGhosties = MPlayerGhosts; - SendPacket.BuildLevel = BuildLevel; - SendPacket.UnitCount = MPlayerUnitCount; - SendPacket.Seed = Seed; - SendPacket.Special = Special; - SendPacket.GameSpeed = Options.GameSpeed; - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - transmittime = TickCount.Time(); - transmit = 0; - - starttime = TickCount.Time(); - while ( ( NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - NullModem.Service(); - Keyboard::Check(); //Make sure the message loop gets called - } - } - - // - // send a timing packet if enough time has gone by. - // - if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { - SendPacket.Command = SERIAL_TIMING; - SendPacket.ResponseTime = NullModem.Response_Time(); - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); - timingtime = TickCount.Time(); - } - - /*--------------------------------------------------------------------- - Check for an incoming message - ---------------------------------------------------------------------*/ - while (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { -// Smart_Printf( "received packet of length %d\n", packetlen ); - - lastmsgtime = TickCount.Time(); - msg_timeout = 600; // reset timeout value to 10 seconds - // (only the 1st time through is 20 seconds) - - // are we getting our own packets back?? - - if (ReceivePacket.Command >= SERIAL_CONNECT && - ReceivePacket.Command < SERIAL_LAST_COMMAND && - ReceivePacket.Command != SERIAL_MESSAGE && - ReceivePacket.ID == ModemGameToPlay) { - - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - break; - } - - event = (EventClass *)&ReceivePacket; - if (event->Type <= EventClass::FRAMEINFO) { - if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { - lastredrawtime = TickCount.Time(); - oppscorescreen = true; - -if (display != REDRAW_ALL) { - display = REDRAW_MESSAGE; -} - -// display = REDRAW_MESSAGE; - parms_received = 1; - } - } else { - switch ( ReceivePacket.Command ) { - /*.................................................................. - Sign-off: Give the other machine time to receive my ACK, display a - message, and exit. - ..................................................................*/ - case (SERIAL_SIGN_OFF): -// Smart_Printf( "received sign off\n" ); - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 60) - NullModem.Service(); - CCMessageBox().Process(TXT_USER_SIGNED_OFF); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - recsignedoff = true; - break; - - /*.................................................................. - Game Options: Store the other machine's name, color & house; - If they've picked the same color as myself, re-transmit my settings - to force him to choose a different color. (Com_Show_Scenario_Dialog - is responsible for ensuring the colors are different.) - ..................................................................*/ - case (SERIAL_GAME_OPTIONS): -// Smart_Printf( "received game options\n" ); - oppscorescreen = false; - gameoptions = true; - strcpy (TheirName, ReceivePacket.Name); - TheirColor = ReceivePacket.Color; - TheirHouse = ReceivePacket.House; - transmit = 1; - - parms_received = 1; -if (display != REDRAW_ALL) { - display = REDRAW_MESSAGE; -} -// display = REDRAW_MESSAGE; - - /*............................................................... - Check the version number of the other system. - ...............................................................*/ -#ifdef PATCH - if (IsV107) { - version = 1; - } else { - version = 2; - } -#else - version = Version_Number(); -#endif - if (ReceivePacket.Version > version) { - CCMessageBox().Process (TXT_YOURGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } else { - if (ReceivePacket.Version < version) { - CCMessageBox().Process (TXT_DESTGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } - } - break; - - /*.................................................................. - Incoming message: add to our list - ..................................................................*/ - case (SERIAL_MESSAGE): -// Smart_Printf( "received serial message\n" ); - oppscorescreen = false; - sprintf(txt, Text_String (TXT_FROM), ReceivePacket.Name, - ReceivePacket.Message); - magic_number = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-4)); - crc = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-2)); - Messages.Add_Message (txt, - MPlayerTColors[MPlayerID_To_ColorIndex(ReceivePacket.ID)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); -if (display != REDRAW_ALL) { - display = REDRAW_MESSAGE; -} -// display = REDRAW_MESSAGE; - break; - - // - // get their response time - // - case (SERIAL_TIMING): -// Smart_Printf( "received timing\n" ); - oppscorescreen = false; - theirresponsetime = ReceivePacket.ResponseTime; - - if ( !gameoptions ) { - - // retransmit of game options packet again - transmit = 1; - } - break; - - // - // print msg waiting for opponent - // - case (SERIAL_SCORE_SCREEN): -// Smart_Printf( "received score screen\n" ); - oppscorescreen = true; -if (display != REDRAW_ALL) { - display = REDRAW_MESSAGE; -} -// display = REDRAW_MESSAGE; - parms_received = 1; - break; - - default: -// Smart_Printf( "received unknown command %X\n", ReceivePacket.Command ); - break; - } - } - } - - // if we haven't received a msg for 10 seconds exit - - if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - } - - /*--------------------------------------------------------------------- - Service the connection - ---------------------------------------------------------------------*/ - NullModem.Service(); - - /* - ** If user has clicked 'GO' and the timeout has elapsed then quit the loop - */ - if ( ready_to_go && ready_time.Time() == 0 ){ - rc = 1; - process = false; - } - - } /* end of while */ - - /*------------------------------------------------------------------------ - Sort player ID's, so we can execute commands in the same order on both - machines. - ------------------------------------------------------------------------*/ - if (rc) { - /*..................................................................... - Set the number of players in this game, and my ID - .....................................................................*/ - MPlayerCount = 2; - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - TheirID = Build_MPlayerID (TheirColor,TheirHouse); - - /*..................................................................... - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - .....................................................................*/ - if (TheirID < MPlayerLocalID) { - MPlayerID[0] = TheirID; - MPlayerID[1] = MPlayerLocalID; - strcpy (MPlayerNames[0], TheirName); - strcpy (MPlayerNames[1], MPlayerName); - } else { - MPlayerID[0] = MPlayerLocalID; - MPlayerID[1] = TheirID; - strcpy (MPlayerNames[0], MPlayerName); - strcpy (MPlayerNames[1], TheirName); - } - - /*..................................................................... - Get the scenario filename - .....................................................................*/ - Scenario = MPlayerFilenum[ScenarioIdx]; - - /*..................................................................... - Send all players the GO packet. - .....................................................................*/ - SendPacket.Command = SERIAL_GO; - SendPacket.ResponseTime = NullModem.Response_Time(); - if ( theirresponsetime == 10000 ) { -// Mono_Clear_Screen(); -// Smart_Printf( "Did not receive their response time!!!!!!!\n" ); -// Get_Key(); - } else { - if (SendPacket.ResponseTime < theirresponsetime) { - SendPacket.ResponseTime = theirresponsetime; - } - } - - // - // calculated one way delay for a packet and overall delay to execute - // a packet - // - MPlayerMaxAhead = MAX( (SendPacket.ResponseTime / 8), 2); -char flip[128]; -sprintf (flip, "C&C95 - MaxAhead set to %d frames\n", MPlayerMaxAhead); -CCDebugString (flip); - - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while ( ( NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - NullModem.Service(); - Keyboard::Check(); //Make sure the message loop gets called - } - - // clear queue to keep from doing any resends - NullModem.Init_Send_Queue(); - - } else { - if ( !recsignedoff ) { - /*..................................................................... - Broadcast my sign-off over my network - .....................................................................*/ - SendPacket.Command = SERIAL_SIGN_OFF; - SendPacket.Color = MPlayerLocalID; // use Color for ID - SendPacket.ID = ModemGameToPlay; - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while ( (NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) )){ - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { - - // are we getting our own packets back?? - - if (ReceivePacket.Command == SERIAL_SIGN_OFF - && ReceivePacket.ID == ModemGameToPlay) { - - // exit while - break; - } - } - - NullModem.Service(); - } - } - - Shutdown_Modem(); - } - - /*------------------------------------------------------------------------ - Clear all lists - ------------------------------------------------------------------------*/ - while (scenariolist.Count()) { - scenariolist.Remove_Item(scenariolist.Get_Item(0)); - } - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - /*------------------------------------------------------------------------ - Save any changes made to our options - ------------------------------------------------------------------------*/ - if (changed) { - Write_MultiPlayer_Settings (); - } - - return(rc); - -} /* end of Com_Scenario_Dialog */ - - -/*********************************************************************************************** - * Com_Show_Scenario_Dialog -- Serial game scenario selection dialog * - * * - * * - * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * - * ³ Serial Game ³ * - * ³ ³ * - * ³ Your Name: __________ ³ * - * ³ House: [GDI] [NOD] ³ * - * ³ Desired Color: [ ][ ][ ][ ] ³ * - * ³ ³ * - * ³ Opponent: Name ³ * - * ³ Scenario: Description ³ * - * ³ Credits: xxxx ³ * - * ³ Bases: ON ³ * - * ³ Crates: ON ³ * - * ³ Tiberium: ON ³ * - * ³ Ghosts: ON ³ * - * ³ ³ * - * ³ [Cancel] ³ * - * ³ ³ * - * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * - * ³ ³ ³ ³ * - * ³ ³ ³ ³ * - * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * - * ³ [Send Message] ³ * - * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = success, false = cancel * - * * - * WARNINGS: * - * MPlayerName & MPlayerGameName must contain this player's name. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -int Com_Show_Scenario_Dialog(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 306*factor; // dialog width - int d_dialog_h = 187*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200*factor - d_dialog_h) / 2); // dialog y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 6*factor+1; // ht of 6-pt text - int d_margin1 = 5*factor; // margin width/height - int d_margin2 = 2*factor; // margin width/height - - int d_name_w = 70*factor; - int d_name_h = 9*factor; - int d_name_x = d_dialog_cx; - int d_name_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h; - - int d_gdi_w = 30*factor; - int d_gdi_h = 9*factor; - int d_gdi_x = d_dialog_cx; - int d_gdi_y = d_name_y + d_name_h + d_margin2; - - int d_nod_w = 30*factor; - int d_nod_h = 9*factor; - int d_nod_x = d_gdi_x + d_gdi_w + d_margin2; - int d_nod_y = d_gdi_y; - - int d_color_w = 10*factor; - int d_color_h = 9*factor; - int d_color_y = d_gdi_y + d_gdi_h + d_margin2; - - int d_opponent_y = d_color_y + d_color_h + d_margin1; - int d_scenario_y = d_opponent_y + d_txt6_h; - int d_credits_y = d_scenario_y + d_txt6_h; - int d_count_y = d_credits_y + d_txt6_h; - int d_level_y = d_count_y + d_txt6_h; - int d_bases_y = d_level_y + d_txt6_h; - int d_goodies_y = d_bases_y + d_txt6_h; - int d_tiberium_y = d_goodies_y + d_txt6_h; - int d_ghosts_y = d_tiberium_y + d_txt6_h; - - int d_cancel_w = 45*factor; - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx - (d_cancel_w / 2); - int d_cancel_y = d_ghosts_y + d_txt6_h + d_margin1; - - int d_message_w = d_dialog_w - (d_margin1 * 2); - int d_message_h = 34*factor; - int d_message_x = d_dialog_x + d_margin1; - int d_message_y = d_cancel_y + d_cancel_h + d_margin1; - - int d_send_w = 80*factor; - int d_send_h = 9*factor; - int d_send_x = d_dialog_cx - (d_send_w / 2); - int d_send_y = d_message_y + d_message_h + d_margin2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_NAME = 100, - BUTTON_GDI, - BUTTON_NOD, - BUTTON_CANCEL, - BUTTON_SEND, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_MESSAGE, - REDRAW_COLORS, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - BOOL process = true; // process while true - KeyNumType input; - - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - int transmit; // 1 = re-transmit new game options - int first; // 1 = no packets received yet - int cbox_x[] = { d_dialog_cx, - d_dialog_cx + d_color_w, - d_dialog_cx + (d_color_w * 2), - d_dialog_cx + (d_color_w * 3), - d_dialog_cx + (d_color_w * 4), - d_dialog_cx + (d_color_w * 5)}; - int parms_received = 0; // 1 = game options received - int changed = 0; // 1 = user has changed an option - - int rc; - int recsignedoff = 0; - int i; - int version; - char txt[80]; - unsigned long starttime; - unsigned long timingtime; - unsigned long lastmsgtime; - unsigned long lastredrawtime; - unsigned long transmittime = 0; - int packetlen; - bool oppscorescreen = false; - bool gameoptions = false; - EventClass *event; // event ptr - unsigned long msg_timeout = 1200; // init to 20 seconds - - int message_length; - int sent_so_far; - unsigned short magic_number; - unsigned short crc; - bool ready_to_go = false; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - EditClass name_edt (BUTTON_NAME, - namebuf, MPLAYER_NAME_MAX, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); - - TextButtonClass gdibtn(BUTTON_GDI, TXT_G_D_I, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_gdi_x, d_gdi_y, d_gdi_w, d_gdi_h); - - TextButtonClass nodbtn(BUTTON_NOD, TXT_N_O_D, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_nod_x, d_nod_y, d_nod_w, d_nod_h); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - TextButtonClass sendbtn(BUTTON_SEND, TXT_SEND_MESSAGE, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_send_x, d_send_y); -//#else - d_send_x, d_send_y, d_send_w, d_send_h); -//#endif - - /* - ------------------------- Build the button list -------------------------- - */ - commands = &name_edt; - gdibtn.Add_Tail(*commands); - nodbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - sendbtn.Add_Tail(*commands); - - /* - ----------------------------- Various Inits ------------------------------ - */ - /*........................................................................ - Init player name & house - ........................................................................*/ - MPlayerColorIdx = MPlayerPrefColor; // init my preferred color - strcpy (namebuf, MPlayerName); // set my name - name_edt.Set_Text(namebuf,MPLAYER_NAME_MAX); - name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); - - if (MPlayerHouse==HOUSE_GOOD) { - gdibtn.Turn_On(); - } else { - nodbtn.Turn_On(); - } - - Fancy_Text_Print("", 0, 0, CC_GREEN, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - transmit = 1; - first = 1; - - /*........................................................................ - Init the message display system - ........................................................................*/ - Messages.Init (d_message_x + 2*factor, d_message_y + 2*factor, 4, MAX_MESSAGE_LENGTH, d_txt6_h); - - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - extern char ModemRXString[]; - - if (strlen(ModemRXString) > 36) - ModemRXString[36] = 0; - - if (strlen(ModemRXString) > 0) - Messages.Add_Message (ModemRXString, CC_TAN, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, 0, 0); - - ModemRXString[0] = '\0'; - - /* - ---------------------------- Init Mono Output ---------------------------- - */ - #if(SHOW_MONO) - NullModem.Configure_Debug(sizeof (CommHeaderType),sizeof (SerialCommandType), - SerialPacketNames, 106); - NullModem.Mono_Debug_Print(1); - #endif - - /* - ---------------------------- Processing loop ----------------------------- - */ - NullModem.Reset_Response_Time(); // clear response time - timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); - while (Get_Mouse_State() > 0) Show_Mouse(); - - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ -#ifdef FORCE_WINSOCK - if (Winsock.Get_Connected()){ - Draw_Caption (TXT_JOIN_INTERNET_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - }else{ - Draw_Caption (TXT_JOIN_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); - } -#else - Draw_Caption (TXT_JOIN_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); -#endif //FORCE_WINSOCK - - Fancy_Text_Print(TXT_YOUR_NAME, - d_name_x - 5*factor, d_name_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_SIDE_COLON, - d_gdi_x - 5*factor, d_gdi_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print(TXT_COLOR_COLON, - cbox_x[0] - 5*factor, d_color_y + 1*factor, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - } - - /*.................................................................. - Draw the color boxes - ..................................................................*/ - if (display >= REDRAW_COLORS) { - for (i = 0; i < MAX_MPLAYER_COLORS; i++) { - LogicPage->Fill_Rect (cbox_x[i] + 1*factor, d_color_y + 1*factor, - cbox_x[i] + 1*factor + d_color_w - 2*factor, d_color_y + 1*factor + d_color_h - 2*factor, - MPlayerGColors[i]); - - if (i == MPlayerColorIdx) { - Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, - BOXSTYLE_GREEN_DOWN, false); - } else { - Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, - BOXSTYLE_GREEN_RAISED, false); - } - } - } - - /*.................................................................. - Draw the message: - - Erase an old message first - ..................................................................*/ - if (display >= REDRAW_MESSAGE) { - Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, - BOXSTYLE_GREEN_BORDER, true); - Messages.Draw(); - - LogicPage->Fill_Rect( d_dialog_x + 2*factor, - d_opponent_y, - d_dialog_x + d_dialog_w - 4*factor, - d_ghosts_y + d_txt6_h, - BLACK); - - if (parms_received) { - if (oppscorescreen) { - sprintf(txt,"%s",Text_String(TXT_WAITING_FOR_OPPONENT)); - - int txtwidth = String_Pixel_Width( txt ); - - Fancy_Text_Print (txt, d_dialog_cx - (txtwidth / 2), - d_opponent_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } else { - /*............................................................ - Opponent's name - ............................................................*/ - Fancy_Text_Print (TXT_OPPONENT_COLON, d_dialog_cx - 3*factor, - d_opponent_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (TheirHouse == HOUSE_GOOD) { - sprintf(txt,"%s %s",TheirName,Text_String(TXT_G_D_I)); - } else { - sprintf(txt,"%s %s",TheirName,Text_String(TXT_N_O_D)); - } - - Fancy_Text_Print (txt, d_dialog_cx, - d_opponent_y, MPlayerTColors[TheirColor], TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Scenario description - ............................................................*/ - Fancy_Text_Print (TXT_SCENARIO_COLON, d_dialog_cx - 3*factor, - d_scenario_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (ScenarioIdx != -1) { - sprintf(txt,"%s", MPlayerScenarios[ScenarioIdx]); - - Fancy_Text_Print (txt, d_dialog_cx, - d_scenario_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } else { - strcpy(txt,Text_String(TXT_NOT_FOUND)); - - Fancy_Text_Print (txt, d_dialog_cx, - d_scenario_y, RED, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - - /*............................................................ - Credits - ............................................................*/ - Fancy_Text_Print (TXT_START_CREDITS_COLON, d_dialog_cx - 3*factor, - d_credits_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - sprintf(txt,"%d",MPlayerCredits); - Fancy_Text_Print (txt, d_dialog_cx, - d_credits_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Count - ............................................................*/ - - Fancy_Text_Print (TXT_COUNT, d_dialog_cx - 3*factor, - d_count_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - sprintf( txt, "%d ", MPlayerUnitCount ); - Fancy_Text_Print (txt, d_dialog_cx, - d_count_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Level - ............................................................*/ - - Fancy_Text_Print (TXT_LEVEL, d_dialog_cx - 3*factor, - d_level_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { - sprintf(txt, "%d ", BuildLevel); - } else { - sprintf(txt, "**"); - } - Fancy_Text_Print (txt, d_dialog_cx, - d_level_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Bases status - ............................................................*/ - Fancy_Text_Print (TXT_BASES_COLON, d_dialog_cx - 3*factor, - d_bases_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (MPlayerBases) { - strcpy(txt,Text_String(TXT_ON)); - } else { - strcpy(txt,Text_String(TXT_OFF)); - } - Fancy_Text_Print (txt, d_dialog_cx, - d_bases_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Tiberium status - ............................................................*/ - Fancy_Text_Print (TXT_TIBERIUM_COLON, d_dialog_cx - 3*factor, - d_tiberium_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (MPlayerTiberium) { - strcpy(txt,Text_String(TXT_ON)); - } else { - strcpy(txt,Text_String(TXT_OFF)); - } - Fancy_Text_Print (txt, d_dialog_cx, - d_tiberium_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Goodies status - ............................................................*/ - Fancy_Text_Print (TXT_CRATES_COLON, d_dialog_cx - 3*factor, - d_goodies_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (MPlayerGoodies) { - strcpy(txt,Text_String(TXT_ON)); - } else { - strcpy(txt,Text_String(TXT_OFF)); - } - Fancy_Text_Print (txt, d_dialog_cx, - d_goodies_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................ - Capture the flag or AI player ON/OFF - ............................................................*/ - if ( Special.IsCaptureTheFlag ) { - strcpy( txt, Text_String( TXT_CAPTURE_THE_FLAG ) ); - strcat( txt, ":" ); - Fancy_Text_Print (txt, d_dialog_cx - 3*factor, - d_ghosts_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - strcpy(txt,Text_String(TXT_ON)); - Fancy_Text_Print (txt, d_dialog_cx, - d_ghosts_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } else { - /*............................................................ - Ghost player status - ............................................................*/ - Fancy_Text_Print (TXT_AI_PLAYERS_COLON, d_dialog_cx - 3*factor, - d_ghosts_y, CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - if (MPlayerGhosts) { - strcpy(txt,Text_String(TXT_ON)); - } else { - strcpy(txt,Text_String(TXT_OFF)); - } - Fancy_Text_Print (txt, d_dialog_cx, - d_ghosts_y, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - } - } - } - - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Flag_List_To_Redraw(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - /*------------------------------------------------------------------ - User clicks on a color button - ------------------------------------------------------------------*/ - case KN_LMOUSE: - if (_Kbd->MouseQX > cbox_x[0] && - _Kbd->MouseQX < (cbox_x[MAX_MPLAYER_COLORS - 1] + d_color_w) && - _Kbd->MouseQY > d_color_y && - _Kbd->MouseQY < (d_color_y + d_color_h)) { - if (!ready_to_go){ - /*......................................................... - Compute my preferred color as the one I clicked on. - .........................................................*/ - MPlayerPrefColor = (_Kbd->MouseQX - cbox_x[0]) / d_color_w; - changed = 1; - /*......................................................... - If 'TheirColor' is set to the other player's color, make - sure we can't pick that color. - .........................................................*/ - if (parms_received) { - if (MPlayerPrefColor == TheirColor) - break; - } - MPlayerColorIdx = MPlayerPrefColor; - - name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); - name_edt.Flag_To_Redraw(); - display = REDRAW_COLORS; - strcpy (MPlayerName, namebuf); - transmit = 1; - } - } - break; - - /*------------------------------------------------------------------ - House Buttons: set the player's desired House - ------------------------------------------------------------------*/ - case (BUTTON_GDI | KN_BUTTON): - if (!ready_to_go){ - MPlayerHouse = HOUSE_GOOD; - gdibtn.Turn_On(); - nodbtn.Turn_Off(); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - case (BUTTON_NOD | KN_BUTTON): - if (!ready_to_go){ - MPlayerHouse = HOUSE_BAD; - gdibtn.Turn_Off(); - nodbtn.Turn_On(); - strcpy (MPlayerName, namebuf); - transmit = 1; - } - break; - - /*------------------------------------------------------------------ - User edits the name value; retransmit - ------------------------------------------------------------------*/ - case (BUTTON_NAME | KN_BUTTON): - if (!ready_to_go){ - strcpy (MPlayerName, namebuf); - transmit = 1; - changed = 1; - } - break; - - /*------------------------------------------------------------------ - CANCEL: send a SIGN_OFF, bail out with error code - ------------------------------------------------------------------*/ - case (KN_ESC): - if (!ready_to_go){ - if (Messages.Get_Edit_Buf() != NULL) { - Messages.Input(input); - display = REDRAW_MESSAGE; - break; - } - } - case (BUTTON_CANCEL | KN_BUTTON): - if (!ready_to_go){ - process = false; - rc = false; - } - break; - - /*------------------------------------------------------------------ - Default: manage the inter-player messages - ------------------------------------------------------------------*/ - default: - if (!ready_to_go){ - - /*............................................................... - F4/SEND/'M' = send a message - ...............................................................*/ - if (Messages.Get_Edit_Buf()==NULL) { - if (input == KN_M || input==(BUTTON_SEND | KN_BUTTON) || - input == KN_F4) { - memset (txt, 0, 80); - - strcpy(txt,Text_String(TXT_MESSAGE)); // "Message:" - - Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, d_message_w-70*factor); - display = REDRAW_MESSAGE; - - name_edt.Clear_Focus(); - name_edt.Flag_To_Redraw(); - - break; - } - } else { - if ( input == (BUTTON_SEND | KN_BUTTON) ) { - input = KN_RETURN; - } - } - - /*............................................................... - Manage the message system (get rid of old messages) - ...............................................................*/ - if (Messages.Manage()) { - display = REDRAW_MESSAGE; - } - - /*............................................................... - Re-draw the messages & service keyboard input for any message - being edited. - ...............................................................*/ - i = Messages.Input(input); - - /*............................................................... - If 'Input' returned 1, it means refresh the message display. - ...............................................................*/ - if (i==1) { - Messages.Draw(); - } else { - - /*............................................................... - If 'Input' returned 2, it means redraw the message display. - ...............................................................*/ - if (i==2) { - display = REDRAW_MESSAGE; - } else { - - /*............................................................... - If 'input' returned 3, it means send the current message. - ...............................................................*/ - if (i==3) { - long actual_message_size; - char *the_string; - - sent_so_far = 0; - magic_number = MESSAGE_HEAD_MAGIC_NUMBER; - message_length = strlen(Messages.Get_Edit_Buf()); - crc = (unsigned short) - (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) &0xffff); - - while (sent_so_far < message_length){ - SendPacket.Command = SERIAL_MESSAGE; - strcpy (SendPacket.Name, MPlayerName); - SendPacket.ID = Build_MPlayerID(MPlayerColorIdx, MPlayerHouse); - memcpy (SendPacket.Message, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); - - /* - ** Steve I's stuff for splitting message on word boundries - */ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - - /* Start at the end of the message and find a space with 10 chars. */ - the_string = GPacket.Message.Buf; - while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && - the_string[actual_message_size] != ' '){ - --actual_message_size; - } - if ( the_string[actual_message_size] == ' ' ){ - - /* Now delete the extra characters after the space (they musnt print) */ - for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ - the_string[i + actual_message_size] = 0xff; - } - }else{ - actual_message_size = COMPAT_MESSAGE_LENGTH - 5; - } - - *(SendPacket.Message + COMPAT_MESSAGE_LENGTH-5) = 0; - *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-4)) = magic_number; - *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-2)) = crc; - - /*.................................................................. - Send the message - ..................................................................*/ - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - NullModem.Service(); - - /*.................................................................. - Add the message to our own screen - ..................................................................*/ - sprintf(txt, Text_String (TXT_FROM), MPlayerName, SendPacket.Message); - Messages.Add_Message (txt, MPlayerTColors[MPlayerColorIdx], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); - - magic_number++; - sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; - } - display = REDRAW_MESSAGE; - } - } - } - } - break; - } - - /*--------------------------------------------------------------------- - Detect editing of the name buffer, transmit new values to players - ---------------------------------------------------------------------*/ - if (strcmp (namebuf, MPlayerName)) { - strcpy (MPlayerName, namebuf); - transmit = 1; - changed = 1; - } - - /*--------------------------------------------------------------------- - If our Transmit flag is set, we need to send out a game option packet - ---------------------------------------------------------------------*/ - if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { - SendPacket.Command = SERIAL_GAME_OPTIONS; - strcpy (SendPacket.Name, MPlayerName); -#ifdef PATCH - if (IsV107) { - SendPacket.Version = 1; - } else { - SendPacket.Version = 2; - } -#else - SendPacket.Version = Version_Number(); -#endif - SendPacket.House = MPlayerHouse; - SendPacket.Color = MPlayerColorIdx; - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - transmittime = TickCount.Time(); - transmit = 0; - } - - // - // send a timing packet if enough time has gone by. - // - if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { - SendPacket.Command = SERIAL_TIMING; - SendPacket.ResponseTime = NullModem.Response_Time(); - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); - timingtime = TickCount.Time(); - } - - /*--------------------------------------------------------------------- - Check for an incoming message - ---------------------------------------------------------------------*/ - if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { -// Smart_Printf( "received packet of length %d\n", packetlen ); - - lastmsgtime = TickCount.Time(); - - msg_timeout = 600; - - // are we getting our own packets back?? - - if (ReceivePacket.Command >= SERIAL_CONNECT && - ReceivePacket.Command < SERIAL_LAST_COMMAND && - ReceivePacket.Command != SERIAL_MESSAGE && - ReceivePacket.ID == ModemGameToPlay) { - - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - break; - } - - event = (EventClass *)&ReceivePacket; - if (event->Type <= EventClass::FRAMEINFO) { - if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { - lastredrawtime = TickCount.Time(); - oppscorescreen = true; - display = REDRAW_MESSAGE; - parms_received = 1; - } - } else { - switch ( ReceivePacket.Command ) { - - /* - ** Once the host is ready to go, we can no longer change game options. - */ - case SERIAL_READY_TO_GO: - ready_to_go = true; - break; - - /*.................................................................. - Other system signs off: Give it time to receive my ACK, then show - a message. - ..................................................................*/ - case (SERIAL_SIGN_OFF): - starttime = TickCount.Time(); - while ( (TickCount.Time() - starttime) < 60) - NullModem.Service(); - CCMessageBox().Process(TXT_USER_SIGNED_OFF); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - recsignedoff = true; - break; - - /*.................................................................. - Game Options: Store all options; check my color & game version. - ..................................................................*/ - case (SERIAL_GAME_OPTIONS): - oppscorescreen = false; - gameoptions = true; - display = REDRAW_MESSAGE; - parms_received = 1; - - strcpy (TheirName, ReceivePacket.Name); - TheirColor = ReceivePacket.Color; - TheirHouse = ReceivePacket.House; - - /*............................................................... - Make sure I don't have the same color as the other guy. - ...............................................................*/ - if (MPlayerColorIdx == TheirColor) { - - // force transmitting of game options packet - - transmit = 1; - transmittime = 0; - - MPlayerColorIdx = TheirColor + 1; - if (MPlayerColorIdx >= 6) - MPlayerColorIdx = 0; - name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); - name_edt.Flag_To_Redraw(); - display = REDRAW_COLORS; - } - - /*............................................................... - Save scenario settings. - ...............................................................*/ - MPlayerCredits = ReceivePacket.Credits; - MPlayerBases = ReceivePacket.IsBases; - MPlayerTiberium = ReceivePacket.IsTiberium; - MPlayerGoodies = ReceivePacket.IsGoodies; - MPlayerGhosts = ReceivePacket.IsGhosties; - BuildLevel = ReceivePacket.BuildLevel; - MPlayerUnitCount = ReceivePacket.UnitCount; - Seed = ReceivePacket.Seed; - Special = ReceivePacket.Special; - Options.GameSpeed = ReceivePacket.GameSpeed; - - if (MPlayerTiberium) { - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - } else { - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - } - - /*............................................................... - Find the index of the scenario number; if it's not found, leave - it at -1. - ...............................................................*/ - ScenarioIdx = -1; - for (i = 0; i < MPlayerFilenum.Count(); i++) { - if (ReceivePacket.Scenario == MPlayerFilenum[i]) - ScenarioIdx = i; - } - - /*............................................................... - Check our version numbers; if they're incompatible, sign off. - ...............................................................*/ -#ifdef PATCH - if (IsV107) { - version = 1; - } else { - version = 2; - } -#else - version = Version_Number(); -#endif - if (ReceivePacket.Version > version) { - CCMessageBox().Process (TXT_YOURGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } else { - if (ReceivePacket.Version < version) { - CCMessageBox().Process (TXT_DESTGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } - } - - /*............................................................... - If this is the first game-options packet we've received, transmit - our options to him. - ...............................................................*/ - if (first) { - first = 0; - - // force transmitting of game options packet - - transmit = 1; - transmittime = 0; - } - break; - - /*.................................................................. - GO: Exit this routine with a success code. - ..................................................................*/ - case (SERIAL_GO): - // - // calculated one way delay for a packet and overall delay - // to execute a packet - // - MPlayerMaxAhead = MAX( (ReceivePacket.ResponseTime / 8), 2); -char flip[128]; -sprintf (flip, "C&C95 - MaxAhead set to %d frames\n", MPlayerMaxAhead); -CCDebugString (flip); - - process = false; - rc = true; - break; - - /*.................................................................. - Incoming message: add to our list - ..................................................................*/ - case (SERIAL_MESSAGE): - oppscorescreen = false; - sprintf(txt, Text_String (TXT_FROM), ReceivePacket.Name, - ReceivePacket.Message); - magic_number = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-4)); - crc = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-2)); - Messages.Add_Message (txt, MPlayerTColors[MPlayerID_To_ColorIndex(ReceivePacket.ID)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); - display = REDRAW_MESSAGE; - break; - - // - // throw away timing packet - // - case (SERIAL_TIMING): - oppscorescreen = false; - break; - - // - // print msg waiting for opponent - // - case (SERIAL_SCORE_SCREEN): -// Smart_Printf( "received score screen\n" ); - oppscorescreen = true; - display = REDRAW_MESSAGE; - parms_received = 1; - break; - - default: - break; - } - } - } - - // if we haven't received a msg for 10 seconds exit - - //if ( ((TickCount.Time() - lastmsgtime) > msg_timeout) || - //(Winsock.Get_Connected() && Winsock.Get_Connection_Status == TcpipManagerClass::CONNECTION_LOST)) { - - if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - } - - - - - /*--------------------------------------------------------------------- - Service the connection - ---------------------------------------------------------------------*/ - NullModem.Service(); - - } /* end of while */ - - /*------------------------------------------------------------------------ - Sort player ID's, so we can execute commands in the same order on both - machines. - ------------------------------------------------------------------------*/ - if (rc) { - /*..................................................................... - Set the number of players in this game, and my ID - .....................................................................*/ - MPlayerCount = 2; - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - TheirID = Build_MPlayerID (TheirColor,TheirHouse); - - /*..................................................................... - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - .....................................................................*/ - if (TheirID < MPlayerLocalID) { - MPlayerID[0] = TheirID; - MPlayerID[1] = MPlayerLocalID; - strcpy (MPlayerNames[0], TheirName); - strcpy (MPlayerNames[1], MPlayerName); - } else { - MPlayerID[0] = MPlayerLocalID; - MPlayerID[1] = TheirID; - strcpy (MPlayerNames[0], MPlayerName); - strcpy (MPlayerNames[1], TheirName); - } - - /*..................................................................... - Get the scenario filename - .....................................................................*/ - Scenario = MPlayerFilenum[ScenarioIdx]; - - starttime = TickCount.Time(); - while ( ( NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - NullModem.Service(); - Keyboard::Check(); //Make sure the message loop gets called - } - - // clear queue to keep from doing any resends - NullModem.Init_Send_Queue(); - - } else { - if ( !recsignedoff ) { - /*..................................................................... - Broadcast my sign-off over my network - .....................................................................*/ - SendPacket.Command = SERIAL_SIGN_OFF; - SendPacket.Color = MPlayerLocalID; // use Color for ID - SendPacket.ID = ModemGameToPlay; - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while ( (NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) )){ - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { - - // are we getting our own packets back?? - - if (ReceivePacket.Command == SERIAL_SIGN_OFF - && ReceivePacket.ID == ModemGameToPlay) { - - // exit while - break; - } - } - - NullModem.Service(); - } - } - - Shutdown_Modem(); - } - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - /*------------------------------------------------------------------------ - Save any changes made to our options - ------------------------------------------------------------------------*/ - if (changed) { - Write_MultiPlayer_Settings (); - } - - return(rc); - -} /* end of Com_Show_Scenario_Dialog */ - - - -/*************************************************************************** - * Phone_Dialog -- Lets user edit phone directory & dial * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * true = dial the current phone book entry, false = cancel. * - * * - * WARNINGS: * - * Serial options must have been read from CC.INI. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -static int Phone_Dialog (void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 280 *factor; // dialog width - int d_dialog_h = 150 *factor; // dialog height - int d_dialog_x = ((320 *factor - d_dialog_w) / 2); // dialog x-coord - int d_dialog_y = ((200 *factor- d_dialog_h) / 2); // dialog y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 11 *factor; // ht of 6-pt text - int d_margin = 7 *factor; // margin width/height - - int d_phonelist_w = 268 *factor; - int d_phonelist_h = 87 *factor; - int d_phonelist_x = d_dialog_cx - (d_phonelist_w / 2); - int d_phonelist_y = d_dialog_y + d_margin + d_txt6_h + 11*factor; - - int d_add_w = 45*factor; - int d_add_h = 9*factor; - int d_add_x = d_dialog_cx - (d_add_w / 2) - d_margin - d_add_w; - int d_add_y = d_phonelist_y + d_phonelist_h + d_margin; - - int d_edit_w = 45*factor; - int d_edit_h = 9*factor; - int d_edit_x = d_dialog_cx - (d_edit_w / 2); - int d_edit_y = d_phonelist_y + d_phonelist_h + d_margin; - - int d_delete_w = 45*factor; - int d_delete_h = 9*factor; - int d_delete_x = d_dialog_cx + (d_delete_w / 2) + d_margin; - int d_delete_y = d_phonelist_y + d_phonelist_h + d_margin; - - int d_numedit_w = ( (PhoneEntryClass::PHONE_MAX_NUM - 1) * 6*factor) + 3*factor; - int d_numedit_h = 9*factor; - int d_numedit_x = d_dialog_cx - (d_numedit_w / 2); - int d_numedit_y = d_add_y + d_add_h + d_margin; - - int d_dial_w = 45*factor; - int d_dial_h = 9*factor; - int d_dial_x = d_dialog_cx - (d_numedit_w / 2) - d_margin - d_dial_w; - int d_dial_y = d_add_y + d_add_h + d_margin; - - int d_cancel_w = 45*factor; - int d_cancel_h = 9*factor; - int d_cancel_x = d_dialog_cx + (d_numedit_w / 2) + d_margin; - int d_cancel_y = d_add_y + d_add_h + d_margin; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_PHONELIST = 100, - BUTTON_ADD, - BUTTON_EDIT, - BUTTON_DELETE, - BUTTON_DIAL, - BUTTON_CANCEL, - BUTTON_NUMEDIT, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - BOOL process = true; // process while true - KeyNumType input; - - char phone_num[ PhoneEntryClass::PHONE_MAX_NUM ] = { 0 }; // buffer for editing phone # - int rc; - int i; - int tabs[] = {123*factor, 207*factor}; // tabs for list box - char *item; // for removing items from list box - PhoneEntryClass *p_entry; // for creating / editing phonebook entries - int changed = 0; // 1 = save changes to INI file - int firsttime = 0; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - void const *up_button; - void const *down_button; - - if (InMainLoop){ - up_button = Hires_Retrieve("BTN-UP.SHP"); - down_button = Hires_Retrieve("BTN-DN.SHP"); - }else{ - up_button = Hires_Retrieve("BTN-UP2.SHP"); - down_button = Hires_Retrieve("BTN-DN2.SHP"); - } - - - ListClass phonelist(BUTTON_PHONELIST, - d_phonelist_x, d_phonelist_y, d_phonelist_w, d_phonelist_h, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - up_button, - down_button); - - TextButtonClass addbtn(BUTTON_ADD, TXT_ADD, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#ifdef FRENCH -// d_add_x-4, d_add_y); -//#else - d_add_x, d_add_y, d_add_w, d_add_h); -//#endif - - TextButtonClass editbtn(BUTTON_EDIT, TXT_EDIT, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_edit_x, d_edit_y, d_edit_w, d_edit_h); - - TextButtonClass deletebtn(BUTTON_DELETE, TXT_DELETE_BUTTON, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#ifdef FRENCH -// d_delete_x, d_delete_y); -//#else - d_delete_x, d_delete_y, d_delete_w, d_delete_h); -//#endif - - TextButtonClass dialbtn(BUTTON_DIAL, TXT_DIAL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -/* ###Change collision detected! C:\PROJECTS\CODE\NULLDLG.CPP... */ - d_dial_x, d_dial_y, d_dial_w, d_dial_h); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, -//#if (GERMAN | FRENCH) -// d_cancel_x, d_cancel_y); -//#else - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); -//#endif - - EditClass numedit (BUTTON_NUMEDIT, - phone_num, PhoneEntryClass::PHONE_MAX_NUM, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_numedit_x, d_numedit_y, d_numedit_w, d_numedit_h, EditClass::ALPHANUMERIC); - - /* - ------------------------- Build the button list -------------------------- - */ - commands = &phonelist; - addbtn.Add_Tail(*commands); - editbtn.Add_Tail(*commands); - deletebtn.Add_Tail(*commands); - dialbtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - numedit.Add_Tail(*commands); - dialbtn.Turn_On(); - - /* - ----------------------------- Various Inits ------------------------------ - */ - /*........................................................................ - Fill in the phone directory list box - ........................................................................*/ - phonelist.Set_Tabs(tabs); - Build_Phone_Listbox(&phonelist, &numedit, phone_num); - - if (CurPhoneIdx == -1) { - firsttime = 1; - } - - /* - ---------------------------- Processing loop ----------------------------- - */ - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - // init font variables - - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_PHONE_LIST, d_dialog_x, d_dialog_y, d_dialog_w); - } - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - phonelist.Flag_To_Redraw(); - addbtn.Flag_To_Redraw(); - editbtn.Flag_To_Redraw(); - deletebtn.Flag_To_Redraw(); - dialbtn.Flag_To_Redraw(); - cancelbtn.Flag_To_Redraw(); - numedit.Flag_To_Redraw(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - if ( firsttime ) { - numedit.Set_Focus(); - numedit.Flag_To_Redraw(); - input = commands->Input(); - firsttime = 0; - } - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - /*------------------------------------------------------------------ - New phone listing selected. - ------------------------------------------------------------------*/ - case (BUTTON_PHONELIST | KN_BUTTON): - /*............................................................... - Detect a change in the selected item; update CurPhoneIdx, and - the edit box buffer. - ...............................................................*/ - if (phonelist.Current_Index() != CurPhoneIdx) { - CurPhoneIdx = phonelist.Current_Index(); - strcpy (phone_num, PhoneBook[CurPhoneIdx]->Number); - numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); - changed = 1; - } - break; - - /*------------------------------------------------------------------ - Add a new entry - ------------------------------------------------------------------*/ - case (BUTTON_ADD | KN_BUTTON): - - /*............................................................... - Allocate a new phone book entry - ...............................................................*/ - p_entry = new PhoneEntryClass(); - p_entry->Name[0] = 0; - p_entry->Number[0] = 0; - p_entry->Settings.Port = 0; - p_entry->Settings.IRQ = -1; - p_entry->Settings.Baud = -1; - p_entry->Settings.DialMethod = DIAL_TOUCH_TONE; - p_entry->Settings.InitStringIndex = 0; - p_entry->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; - p_entry->Settings.CallWaitString[0] = 0; - - /*............................................................... - Invoke the entry editor; if user clicks Save, add the new entry - to the list, and rebuild the list box. - ...............................................................*/ - if ( Edit_Phone_Dialog( p_entry ) ) { - PhoneBook.Add (p_entry); - Build_Phone_Listbox( &phonelist, &numedit, phone_num ); - /*............................................................ - Set the current listbox index to the newly-added item. - ............................................................*/ - for (i = 0; i < PhoneBook.Count(); i++) { - if (p_entry == PhoneBook[i]) { - CurPhoneIdx = i; - strcpy (phone_num, PhoneBook[CurPhoneIdx]->Number); - numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); - phonelist.Set_Selected_Index( CurPhoneIdx ); - } - } - changed = 1; - } else { - - /*............................................................... - If the user clicked Cancel, delete the entry & keep looping. - ...............................................................*/ - delete p_entry; - } - display = REDRAW_ALL; - break; - - /*------------------------------------------------------------------ - Edit the current entry - ------------------------------------------------------------------*/ - case (BUTTON_EDIT | KN_BUTTON): - - /*............................................................... - Do nothing if no entry is selected. - ...............................................................*/ - if (CurPhoneIdx==-1) - break; - - /*............................................................... - Allocate a new entry & copy the currently-selected entry into it - ...............................................................*/ - p_entry = new PhoneEntryClass(); - (*p_entry) = (*PhoneBook[CurPhoneIdx]); - - /*............................................................... - Pass the new entry to the entry editor; if the user selects OK, - copy the data back into our phone book. Rebuild the list so - the changes show up in the list box. - ...............................................................*/ - if ( Edit_Phone_Dialog( p_entry ) ) { - (*PhoneBook[CurPhoneIdx]) = (*p_entry); - Build_Phone_Listbox(&phonelist, &numedit, phone_num); - /*............................................................ - Set the current listbox index to the newly-added item. - ............................................................*/ - for (i = 0; i < PhoneBook.Count(); i++) { - if (PhoneBook[CurPhoneIdx] == PhoneBook[i]) { - CurPhoneIdx = i; - strcpy (phone_num, PhoneBook[CurPhoneIdx]->Number); - numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); - phonelist.Set_Selected_Index( CurPhoneIdx ); - } - } - changed = 1; - } - delete p_entry; - display = REDRAW_ALL; - break; - - /*------------------------------------------------------------------ - Delete the current entry - ------------------------------------------------------------------*/ - case (BUTTON_DELETE | KN_BUTTON): - - /*............................................................... - Do nothing if no entry is selected. - ...............................................................*/ - if (CurPhoneIdx == -1) - break; - - /*............................................................... - Delete the current item & rebuild the phone listbox - ...............................................................*/ - PhoneBook.Delete (CurPhoneIdx); - Build_Phone_Listbox(&phonelist, &numedit, phone_num); - - if (CurPhoneIdx == -1) { - *phone_num = 0; - numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); - } - changed = 1; - break; - - /*------------------------------------------------------------------ - Dial the current number - ------------------------------------------------------------------*/ - case (KN_RETURN): - dialbtn.IsPressed = true; - dialbtn.Draw_Me(true); - // fall thru - - case (BUTTON_DIAL | KN_BUTTON): - - /*............................................................... - If no item is selected, just dial the number in the phone # - edit box: - - Create a new phone entry - - Copy the phone number into it - - Set settings to defaults - ...............................................................*/ - if (CurPhoneIdx == -1 || - strcmp( PhoneBook[CurPhoneIdx]->Number, phone_num) ) { - - if ( strlen(phone_num) == 0) { // do not dial - dialbtn.IsPressed = false; - dialbtn.Flag_To_Redraw(); - break; - } - - p_entry = new PhoneEntryClass(); - strcpy( p_entry->Name, "NONAME" ); - strcpy( p_entry->Number, phone_num); - p_entry->Settings.Port = 0; - p_entry->Settings.IRQ = -1; - p_entry->Settings.Baud = -1; - p_entry->Settings.DialMethod = DIAL_TOUCH_TONE; - p_entry->Settings.InitStringIndex = 0; - p_entry->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; - p_entry->Settings.CallWaitString[0] = 0; - - PhoneBook.Add (p_entry); - Build_Phone_Listbox(&phonelist, &numedit, phone_num); - /*............................................................ - Set the current listbox index to the newly-added item. - ............................................................*/ - for (i = 0; i < PhoneBook.Count(); i++) { - if (p_entry == PhoneBook[i]) { - CurPhoneIdx = i; - } - } - changed = 1; - } - - process = false; - rc = true; - break; - - /*------------------------------------------------------------------ - CANCEL: bail out - ------------------------------------------------------------------*/ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - process = false; - rc = false; - break; - } - - } /* end of while */ - - /*------------------------------------------------------------------------ - Save any changes we've made to the phone list or settings - ------------------------------------------------------------------------*/ - if (changed) { - Write_MultiPlayer_Settings (); - } - - /*------------------------------------------------------------------------ - Clear the list box - ------------------------------------------------------------------------*/ - while (phonelist.Count()) { - item = (char *)phonelist.Get_Item(0); - phonelist.Remove_Item(item); - delete [] item; - } - - return(rc); - -} /* end of Phone_Dialog */ - - -/*************************************************************************** - * Build_Phone_Listbox -- [re]builds the phone entry listbox * - * * - * This routine rebuilds the phone list box from scratch; it also updates * - * the contents of the phone # edit field. * - * * - * INPUT: * - * list ptr to list box * - * edit ptr to edit box * - * buf ptr to buffer for phone # * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -static void Build_Phone_Listbox (ListClass *list, EditClass *edit, char *buf) -{ - int i; - char *item; - char phonename[21]; - char phonenum[15]; - - /*........................................................................ - Clear the list - ........................................................................*/ - while (list->Count()) { - item = (char *)(list->Get_Item(0)); - list->Remove_Item(item); - delete [] item; - } - - /* - ** Now sort the phone list by name then number - */ - qsort ((void *)(&PhoneBook[0]), PhoneBook.Count(), sizeof(class PhoneEntryClass *), Phone_Compare); - - /*........................................................................ - Build the list - ........................................................................*/ - for (i = 0; i < PhoneBook.Count(); i++) { - item = new char[80]; - if ( !(strlen( PhoneBook[i]->Name )) ) { - strcpy( phonename, " " ); - } else { - strncpy( phonename, PhoneBook[i]->Name, 20 ); - phonename[21] = 0; - } - - if ( !(strlen( PhoneBook[i]->Number )) ) { - strcpy( phonenum, " " ); - } else { - if ( strlen( PhoneBook[i]->Number ) < 14) { - strcpy( phonenum, PhoneBook[i]->Number ); - } else { - strncpy( phonenum, PhoneBook[i]->Number, 12 ); - phonenum[12] = 0; - strcat( phonenum, "..." ); - } - } - - if (PhoneBook[i]->Settings.Baud != -1) { - sprintf(item,"%s\t%s\t%d", phonename, phonenum, - PhoneBook[i]->Settings.Baud); - } else { - sprintf(item,"%s\t%s\t[%s]", phonename, phonenum, - Text_String(TXT_DEFAULT)); - } - list->Add_Item(item); - } - list->Flag_To_Redraw(); - - /*........................................................................ - Init the current phone book index - ........................................................................*/ - if (list->Count() == 0 || CurPhoneIdx < -1) { - CurPhoneIdx = -1; - } else { - if (CurPhoneIdx >= list->Count() ) { - CurPhoneIdx = 0; - } - } - - /*........................................................................ - Fill in phone number edit buffer - ........................................................................*/ - if (CurPhoneIdx > -1) { - strcpy (buf, PhoneBook[CurPhoneIdx]->Number); - edit->Set_Text (buf, PhoneEntryClass::PHONE_MAX_NUM ); - list->Set_Selected_Index( CurPhoneIdx ); - } -} - - -/*************************************************************************** - * Phone_Compare -- for qsort * - * * - * INPUT: * - * p1,p2 ptrs to elements to compare * - * * - * OUTPUT: * - * 0 = same, -1 = (*p1) goes BEFORE (*p2), 1 = (*p1) goes AFTER (*p2) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=========================================================================*/ -static int Phone_Compare (const void *p1, const void *p2) -{ - class PhoneEntryClass *pe1,*pe2; - int result; - - pe1 = *((class PhoneEntryClass **)p1); - pe2 = *((class PhoneEntryClass **)p2); - - result = strcmp( pe1->Name, pe2->Name ); - - // if strings are equal then check the phone number - - if ( !result ) { - result = strcmp( pe1->Number, pe2->Number ); - } - - return(result); -} - - -/*************************************************************************** - * Edit_Phone_Dialog -- lets user edit a phone book entry * - * * - * INPUT: * - * phone entry to edit * - * * - * OUTPUT: * - * true = OK, false = cancel * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/29/1995 BRR : Created. * - *=========================================================================*/ -static int Edit_Phone_Dialog (PhoneEntryClass *phone) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - /*........................................................................ - Dialog & button dimensions - ........................................................................*/ - int d_dialog_w = 230 *factor; // dialog width - int d_dialog_h = 105*factor; // dialog height - int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord -// D_DIALOG_Y = ((200 - D_DIALOG_H) / 2); // dialog y-coord - int d_dialog_y = ((136*factor - d_dialog_h) / 2); // dialog y-coord - int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord - - int d_txt6_h = 11 *factor; // ht of 6-pt text - int d_margin = 7 *factor; // margin width/height - - int d_name_w = ( (PhoneEntryClass::PHONE_MAX_NAME - 1) * 6) + 3 *factor; - int d_name_h = 9 *factor; - int d_name_x = d_dialog_x + (((d_dialog_w - d_name_w) * 3) / 4) - 5 *factor; - int d_name_y = d_dialog_y + 25 *factor; - - int d_number_w = ( (PhoneEntryClass::PHONE_MAX_NUM - 1) * 6) + 3 *factor; - int d_number_h = 9 *factor; - int d_number_x = d_dialog_x + (((d_dialog_w - d_number_w) * 3) / 4) - 5 *factor; - int d_number_y = d_name_y + d_name_h + d_margin; - -#if (GERMAN | FRENCH) - int d_default_w = 130 *factor; -#else - int d_default_w = 104 *factor; -#endif - int d_default_h = 9 *factor; - int d_default_x = d_dialog_cx - (d_default_w / 2); - int d_default_y = d_number_y + d_number_h + d_margin; - -#if (GERMAN | FRENCH) - int d_custom_w = 130 *factor; -#else - int d_custom_w = 100 *factor; -#endif - int d_custom_h = 9 *factor; - int d_custom_x = d_dialog_cx - (d_default_w / 2); - int d_custom_y = d_default_y + d_default_h + d_margin; - -#if (GERMAN | FRENCH) - int d_save_w = 55 *factor; -#else - int d_save_w = 45 *factor; -#endif - int d_save_h = 9 *factor; - int d_save_x = d_dialog_cx - d_margin - d_save_w; - int d_save_y = d_dialog_y + d_dialog_h - d_margin - d_save_h; - -#if (GERMAN | FRENCH) - int d_cancel_w = 55 *factor; -#else - int d_cancel_w = 45 *factor; -#endif - int d_cancel_h = 9 *factor; - int d_cancel_x = d_dialog_cx + d_margin; - int d_cancel_y = d_dialog_y + d_dialog_h - d_margin - d_cancel_h; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_NAME = 100, - BUTTON_NUMBER, - BUTTON_DEFAULT, - BUTTON_CUSTOM, - BUTTON_SAVE, - BUTTON_CANCEL, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - BOOL process = true; // process while true - KeyNumType input; - - char namebuf[PhoneEntryClass::PHONE_MAX_NAME] = { 0 }; // buffer for editing name - char numbuf[PhoneEntryClass::PHONE_MAX_NUM] = { 0 }; // buffer for editing phone # - int rc; - SerialSettingsType settings; - int custom = 0; - int firsttime = 1; - - /*........................................................................ - Buttons - ........................................................................*/ - GadgetClass *commands; // button list - - EditClass nameedit (BUTTON_NAME, - namebuf, PhoneEntryClass::PHONE_MAX_NAME, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); - - EditClass numedit (BUTTON_NUMBER, - numbuf, PhoneEntryClass::PHONE_MAX_NUM, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_number_x, d_number_y, d_number_w, d_number_h, EditClass::ALPHANUMERIC); - - TextButtonClass defaultbtn(BUTTON_DEFAULT, TXT_DEFAULT_SETTINGS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_default_x, d_default_y, d_default_w, d_default_h); - - TextButtonClass custombtn(BUTTON_CUSTOM, TXT_CUSTOM_SETTINGS, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_custom_x, d_custom_y, d_custom_w, d_custom_h); - - TextButtonClass savebtn(BUTTON_SAVE, TXT_SAVE_BUTTON, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_save_x, d_save_y, d_save_w, d_save_h); - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); - - /* - ------------------------- Build the button list -------------------------- - */ - commands = &nameedit; - numedit.Add_Tail(*commands); - defaultbtn.Add_Tail(*commands); - custombtn.Add_Tail(*commands); - savebtn.Add_Tail(*commands); - cancelbtn.Add_Tail(*commands); - - /* - ----------------------------- Various Inits ------------------------------ - */ - /*........................................................................ - Init the settings; if the phone entry is set to use defaults, init our - settings to sensible values (in case we invoke the setting editor); - otherwise, copy the entry's settings. - ........................................................................*/ - if (phone->Settings.Port == 0 || phone->Settings.IRQ == -1 || - phone->Settings.Baud == -1) { - settings = SerialDefaults; - defaultbtn.Turn_On(); - custom = false; - } else { - settings = phone->Settings; - custombtn.Turn_On(); - custom = true; - } - - strcpy (namebuf, phone->Name); - nameedit.Set_Text (namebuf, PhoneEntryClass::PHONE_MAX_NAME); - - strcpy (numbuf, phone->Number); - numedit.Set_Text (numbuf, PhoneEntryClass::PHONE_MAX_NUM); - - /* - ---------------------------- Processing loop ----------------------------- - */ - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - if (display >= REDRAW_BACKGROUND) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - - Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); - - // init font variables - - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - /*............................................................... - Dialog & Field labels - ...............................................................*/ - Draw_Caption (TXT_PHONE_LISTING, d_dialog_x, d_dialog_y, d_dialog_w); - - Fancy_Text_Print (TXT_NAME_COLON, - d_name_x - 5, d_name_y + 1, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Fancy_Text_Print (TXT_NUMBER_COLON, - d_number_x - 5, d_number_y + 1, - CC_GREEN, TBLACK, - TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - } - /* - .......................... Redraw buttons .......................... - */ - if (display >= REDRAW_BUTTONS) { - commands->Flag_List_To_Redraw(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - /* - ........................... Get user input ............................ - */ - input = commands->Input(); - - if ( firsttime ) { - nameedit.Set_Focus(); - nameedit.Flag_To_Redraw(); - input = commands->Input(); - firsttime = 0; - } - - /* - ---------------------------- Process input ---------------------------- - */ - switch (input) { - case (BUTTON_NAME | KN_BUTTON): - numedit.Set_Focus(); - numedit.Flag_To_Redraw(); - break; - -// case (BUTTON_NUMBER | KN_BUTTON): -// nameedit.Clear_Focus(); -// nameedit.Flag_To_Redraw(); -// break; - - /*------------------------------------------------------------------ - Use Default Serial Settings - ------------------------------------------------------------------*/ - case (BUTTON_DEFAULT | KN_BUTTON): - custombtn.Turn_Off(); - defaultbtn.Turn_On(); - custom = 0; - break; - - /*------------------------------------------------------------------ - Use Custom Serial Settings - ------------------------------------------------------------------*/ - case (BUTTON_CUSTOM | KN_BUTTON): - if (Com_Settings_Dialog (&settings)) { - custombtn.Turn_On(); - defaultbtn.Turn_Off(); - } - custom = 1; - display = REDRAW_ALL; - break; - - /*------------------------------------------------------------------ - CANCEL: bail out - ------------------------------------------------------------------*/ - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - process = false; - rc = false; - break; - - /*------------------------------------------------------------------ - Save: save changes - ------------------------------------------------------------------*/ - case (KN_RETURN): - case (BUTTON_SAVE | KN_BUTTON): - process = false; - rc = true; - break; - } - - } /* end of while */ - - /*------------------------------------------------------------------------ - If 'Save', save all current settings - ------------------------------------------------------------------------*/ - if (rc) { - strcpy( phone->Name, strupr( namebuf ) ); - - // if nothing was entered then make if NONAME - - if ( !(phone->Name[0]) ) { - strcpy( phone->Name, "NONAME" ); - } - - strcpy( phone->Number, strupr( numbuf ) ); - - if (custom) { - phone->Settings = settings; - } else { - phone->Settings.Port = 0; - phone->Settings.IRQ = -1; - phone->Settings.Baud = -1; - phone->Settings.DialMethod = DIAL_TOUCH_TONE; - phone->Settings.InitStringIndex = 0; - phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; - phone->Settings.CallWaitString[0] = 0; - } - } - - return(rc); - - -} /* end of Edit_Phone_Dialog */ - - -static bool Dial_Modem( SerialSettingsType *settings, bool reconnect ) -{ - bool connected = false; - DialStatusType dialstatus; - int modemstatus; - - /* - ** Turn modem servicing off in the callback routine. - */ - ModemService = false; - - // save for later to reconnect - - DialSettings = settings; - - modemstatus = NullModem.Get_Modem_Status(); - if (reconnect) { - if ( (modemstatus & CD_SET) ) { - connected = true; - ModemService = true; - return( connected ); - } - } else { - if ( (modemstatus & CD_SET) ) { - NullModem.Hangup_Modem(); - ModemService = false; - } - } - - NullModem.Setup_Modem_Echo( Modem_Echo ); - - modemstatus = NullModem.Detect_Modem( settings, reconnect ); - if ( !modemstatus ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - - /* - ** If our first attempt to detect the modem failed, and we're at - ** 14400 or 28800, bump up to the next baud rate & try again. - */ - switch (settings->Baud) { - - case 14400: - settings->Baud = 19200; - Shutdown_Modem(); - Init_Null_Modem(settings); - NullModem.Setup_Modem_Echo( Modem_Echo ); - modemstatus = NullModem.Detect_Modem( settings, reconnect ); - if ( !modemstatus ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); - ModemService = true; - return( connected ); - } - break; - - case 28800: - settings->Baud = 38400; - Shutdown_Modem(); - Init_Null_Modem(settings); - NullModem.Setup_Modem_Echo( Modem_Echo ); - modemstatus = NullModem.Detect_Modem( settings, reconnect ); - if ( !modemstatus ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); - ModemService = true; - return( connected ); - } - break; - - default: - CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); - ModemService = true; - return( connected ); - - } - } - else if ( modemstatus == -1 ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - CCMessageBox().Process( TXT_ERROR_IN_INITSTRING ); - ModemService = true; - return( connected ); - } - - - /* - ** Completely disable audio. This is required for MWave devices - */ - ThemeType old_theme = THEME_NONE; - if (SoundOn){ - old_theme = Theme.What_Is_Playing(); - Theme.Stop(); - CountDownTimerClass wait; - Call_Back(); - wait.Set (60,true); - while ( wait.Time() ) { - Call_Back(); - } - Sound_End(); - Call_Back(); - wait.Set (60,true); - while ( wait.Time() ) { - Call_Back(); - } - SoundOn = 0; - } - - dialstatus = NullModem.Dial_Modem( DialString, settings->DialMethod, reconnect ); - - if (reconnect) { - /* - --------------------------- Redraw the display --------------------------- - */ - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); - } - - switch ( dialstatus ) { - case DIAL_CONNECTED: - connected = true; - break; - - case DIAL_NO_CARRIER: - CCMessageBox().Process(TXT_NO_CARRIER); - connected = false; - break; - - case DIAL_BUSY: - CCMessageBox().Process(TXT_LINE_BUSY); - connected = false; - break; - - case DIAL_ERROR: - CCMessageBox().Process(TXT_NUMBER_INVALID); - connected = false; - break; - - case DIAL_NO_DIAL_TONE: - CCMessageBox().Process(TXT_NO_DIAL_TONE); - connected = false; - break; - - case DIAL_CANCELED: - NullModem.Hangup_Modem(); - ModemService = false; - CCMessageBox().Process(TXT_DIALING_CANCELED); - connected = false; - break; - } - - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - - /* - ** Restore audio capability - */ - SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 ); - if (SoundOn){ - Theme.Play_Song (old_theme); - } - - ModemService = true; - return( connected ); - -} /* end of Dial_Modem */ - - -static bool Answer_Modem( SerialSettingsType *settings, bool reconnect ) -{ - bool connected = false; - DialStatusType dialstatus; - int modemstatus; - -/* ###Change collision detected! C:\PROJECTS\CODE\NULLDLG.CPP... */ - /* - ** Turn modem servicing off in the callback routine. - */ - ModemService = false; - - // save for later to reconnect - - DialSettings = settings; - - modemstatus = NullModem.Get_Modem_Status(); - if (reconnect) { - if ( (modemstatus & CD_SET) ) { - connected = true; - ModemService = true; - return( connected ); - } - } else { - if ( (modemstatus & CD_SET) ) { - NullModem.Hangup_Modem(); - ModemService = false; - } - } - - NullModem.Setup_Modem_Echo( Modem_Echo ); - - modemstatus = NullModem.Detect_Modem( settings, reconnect ); - if ( !modemstatus ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - - /* - ** If our first attempt to detect the modem failed, and we're at - ** 14400 or 28800, bump up to the next baud rate & try again. - */ - switch (settings->Baud) { - - case 14400: - settings->Baud = 19200; - Shutdown_Modem(); - Init_Null_Modem(settings); - NullModem.Setup_Modem_Echo( Modem_Echo ); - modemstatus = NullModem.Detect_Modem( settings, reconnect ); - if ( !modemstatus ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); - ModemService = true; - return( connected ); - } - break; - - case 28800: - settings->Baud = 38400; - Shutdown_Modem(); - Init_Null_Modem(settings); - NullModem.Setup_Modem_Echo( Modem_Echo ); - modemstatus = NullModem.Detect_Modem( settings, reconnect ); - if ( !modemstatus ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); - ModemService = true; - return( connected ); - } - break; - - default: - CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); - ModemService = true; - return( connected ); - } - - } - else if ( modemstatus == -1 ) { - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - CCMessageBox().Process( TXT_ERROR_IN_INITSTRING ); - ModemService = true; - return( connected ); - } - - /* - ** Completely disable audio. This is required for MWave devices - */ - ThemeType old_theme = THEME_NONE; - if (SoundOn){ - old_theme = Theme.What_Is_Playing(); - Theme.Stop(); - CountDownTimerClass wait; - Call_Back(); - wait.Set (60,true); - while ( wait.Time() ) { - Call_Back(); - } - Sound_End(); - Call_Back(); - wait.Set (60,true); - while ( wait.Time() ) { - Call_Back(); - } - SoundOn = 0; - } - - dialstatus = NullModem.Answer_Modem( reconnect ); - - switch ( dialstatus ) { - case DIAL_CONNECTED: - connected = true; - break; - - case DIAL_NO_CARRIER: - CCMessageBox().Process(TXT_NO_CARRIER); - connected = false; - break; - - case DIAL_BUSY: - CCMessageBox().Process(TXT_LINE_BUSY); - connected = false; - break; - - case DIAL_ERROR: - CCMessageBox().Process(TXT_NUMBER_INVALID); - connected = false; - break; - - case DIAL_NO_DIAL_TONE: - CCMessageBox().Process(TXT_NO_DIAL_TONE); - connected = false; - break; - - case DIAL_CANCELED: - CCMessageBox().Process(TXT_ANSWERING_CANCELED); - connected = false; - break; - } - - NullModem.Remove_Modem_Echo(); - NullModem.Print_EchoBuf(); - NullModem.Reset_EchoBuf(); - - /* - ** Restore audio capability - */ - SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 ); - if (SoundOn){ - Theme.Play_Song (old_theme); - } - - ModemService = true; - return( connected ); - -} /* end of Answer_Modem */ - - -static void Modem_Echo( char c ) -{ - if (NullModem.EchoCount < (NullModem.EchoSize - 1) ) { - *(NullModem.EchoBuf + NullModem.EchoCount) = c; - *(NullModem.EchoBuf + NullModem.EchoCount + 1) = 0; - NullModem.EchoCount++; - } else { - //Smart_Printf( "Echo buffer full!!!\n" ); - } - -} /* end of Modem_Echo */ - - -void Smart_Printf( char *format, ... ) -{ - va_list arglist; - char buf[501]; - - - va_start(arglist,format); - vsprintf(buf,format,arglist); - va_end(arglist); - - if (Debug_Smart_Print) { - if (Special.IsMonoEnabled) { -// Mono_Set_Cursor(0,0); - Mono_Printf("%s",buf); - } else { -// Mono_Printf("%s",buf); - printf("%s",buf); - } - } else { - if (Debug_Heap_Dump) { - printf("%s",buf); - } - } -} - - -void Hex_Dump_Data( char *buffer, int length ) -{ - int i; - int offset = 0; - char buff[10]; - char ptr[16]; - char c; - - - while (length >= 16) { - memcpy( ptr, (buffer + offset), 16); - - Smart_Printf("%05lX ", offset); - - for (i = 0; i < 16; i++) { - - c = ptr[i]; - itoh(c, buff); - - if (!(i & 0x3) && i) { - Smart_Printf("³ "); - } - - Smart_Printf("%s ", buff); - } - - Smart_Printf(" "); - - for (i = 0; i < 16; i++) { - c = ptr[i]; - - if (c && ((c < 7) || (c > 11)) && (c != 13)) { - Smart_Printf("%c", c); - } else { - Smart_Printf("."); - } - } - - Smart_Printf("\n"); - - offset += 16; - length -= 16; - } - - if (length) { - memcpy( ptr, (buffer + offset), 16); - - Smart_Printf("%05lX ", offset); - - for (i = 0; i < 16; i++) { - if (i < length) { - c = ptr[i]; - itoh(c, buff); - if (!(i & 0x3) && i) { - Smart_Printf("³ "); - } - Smart_Printf("%s ", buff); - } else { - if (!(i & 0x3) && i) { - Smart_Printf(" "); - } - Smart_Printf(" "); - } - } - - Smart_Printf(" "); - - for (i = 0; i < length; i++) { - - c = ptr[i]; - - if (c && ((c < 7) || (c > 11)) && (c != 13)) { - Smart_Printf("%c", c); - } else { - Smart_Printf("."); - } - } - - Smart_Printf("\n"); - } - -} /* end of Hex_Dump_Data */ - - -void itoh( int i, char *s) -{ - - int nibble, loop; - -// *s++ = '0'; -// *s++ = 'x'; - - if (i == 0) { - *s++ = '0'; - *s++ = '0'; - } else { - for (loop = 1; loop >= 0; loop--) { - nibble = (i >> (loop << 2)) & 0x000F; - - /* decimal range */ - if (nibble < 10) { - *s++ = '0' + nibble; - } else { - *s++ = 'A' + (nibble - 10); - } - } - } - *s = 0; /* null terminate it */ -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if (0) - -int Com_Fake_Scenario_Dialog(void) -{ - bool display = true; // redraw level - bool process = true; // process while true - - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - int transmit; // 1 = re-transmit new game options - int parms_received = 1; // 1 = game options received - int changed = 0; // 1 = user has changed an option - - int rc; - int recsignedoff = false; - int version; - unsigned long starttime; - unsigned long timingtime; - unsigned long lastmsgtime; - unsigned long lastredrawtime; - unsigned long transmittime = 0; - unsigned long theirresponsetime; - int packetlen; - bool oppscorescreen = false; - bool gameoptions = false; - EventClass *event; // event ptr - unsigned long msg_timeout = 60*60; // init to 60 seconds - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /*........................................................................ - Dialog variables - ........................................................................*/ - TextButtonClass * buttons = 0; - - KeyNumType input; - - int x,y; - int width=0; - int height=0; - char text_buffer[80*3]; - - const char *current_status_string = Text_String(TXT_WINSOCK_CONNECTING); - strcpy(text_buffer, current_status_string); - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - - Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height); - - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (SeenBuff.Get_Width() - width) / 2; - y = (SeenBuff.Get_Height() - height) / 2; - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1), - y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); - - Set_Logic_Page(SeenBuff); - buttons = &cancelbtn; - - buttons->Flag_List_To_Redraw(); - process = true; - - /*........................................................................ - Init other scenario parameters - ........................................................................*/ - Special.IsTGrowth = MPlayerTiberium; - Special.IsTSpread = MPlayerTiberium; - transmit = 1; - - /*........................................................................ - Init random-number generator, & create a seed to be used for all random - numbers from here on out - ........................................................................*/ - randomize(); - //Seed = rand(); - - /* - ---------------------------- Processing loop ----------------------------- - */ - NullModem.Reset_Response_Time(); // clear response time - theirresponsetime = 10000; // initialize to an invalid value - timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); - - - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=true; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - /* - ..................... Draw the background ....................... - */ - Dialog_Box(x, y, width, height); - /* - ....................... Draw the labels ......................... - */ - Draw_Caption(TXT_NONE, x, y, width); - - Fancy_Text_Print(text_buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - buttons->Draw_All(); - Show_Mouse(); - display = false; - } - - /* - ............................ Process input ............................ - */ - input = buttons->Input(); - switch (input) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - process = false; - rc = false; - break; - - default: - break; - } - - - /*--------------------------------------------------------------------- - If our Transmit flag is set, we need to send out a game option packet. - This message requires an ACK. The first time through the loop, transmit - should be set, so we send out our default options; we'll then send - any changes we make to the defaults. - ---------------------------------------------------------------------*/ - if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { - SendPacket.Command = SERIAL_GAME_OPTIONS; - strcpy (SendPacket.Name, MPlayerName); -#ifdef PATCH - if (IsV107) { - SendPacket.Version = 1; - } else { - SendPacket.Version = 2; - } -#else - SendPacket.Version = Version_Number(); -#endif - SendPacket.House = MPlayerHouse; - SendPacket.Color = MPlayerColorIdx; - - SendPacket.Scenario = MPlayerFilenum[ScenarioIdx]; - - SendPacket.Credits = MPlayerCredits; - SendPacket.IsBases = MPlayerBases; - SendPacket.IsTiberium = MPlayerTiberium; - SendPacket.IsGoodies = MPlayerGoodies; - SendPacket.IsGhosties = MPlayerGhosts; - SendPacket.BuildLevel = BuildLevel; - SendPacket.UnitCount = MPlayerUnitCount; - SendPacket.Seed = Seed; - SendPacket.Special = Special; - SendPacket.GameSpeed = Options.GameSpeed; - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - transmittime = TickCount.Time(); - transmit = 0; - } - - // - // send a timing packet if enough time has gone by. - // - if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { - SendPacket.Command = SERIAL_TIMING; - SendPacket.ResponseTime = NullModem.Response_Time(); - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); - timingtime = TickCount.Time(); - } - - /*--------------------------------------------------------------------- - Check for an incoming message - ---------------------------------------------------------------------*/ - if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { - - lastmsgtime = TickCount.Time(); - msg_timeout = 600; // reset timeout value to 10 seconds - // (only the 1st time through is 20 seconds) - - - if (ReceivePacket.Command >= SERIAL_CONNECT && - ReceivePacket.Command < SERIAL_LAST_COMMAND && - ReceivePacket.Command != SERIAL_MESSAGE && - ReceivePacket.ID == ModemGameToPlay) { - - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - break; - } - - event = (EventClass *)&ReceivePacket; - if (event->Type <= EventClass::FRAMEINFO) { - if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { - lastredrawtime = TickCount.Time(); - oppscorescreen = true; - parms_received = 1; - } - } else { - switch ( ReceivePacket.Command ) { - /*.................................................................. - Sign-off: Give the other machine time to receive my ACK, display a - message, and exit. - ..................................................................*/ - case (SERIAL_SIGN_OFF): - starttime = TickCount.Time(); - while (TickCount.Time() - starttime < 60) - NullModem.Service(); - CCMessageBox().Process(TXT_USER_SIGNED_OFF); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - recsignedoff = true; - break; - - /*.................................................................. - Game Options: Store the other machine's name, color & house; - If they've picked the same color as myself, re-transmit my settings - to force him to choose a different color. (Com_Show_Scenario_Dialog - is responsible for ensuring the colors are different.) - ..................................................................*/ - case (SERIAL_GAME_OPTIONS): - oppscorescreen = false; - gameoptions = true; - strcpy (TheirName, ReceivePacket.Name); - TheirColor = ReceivePacket.Color; - TheirHouse = ReceivePacket.House; - transmit = 1; - - parms_received = 1; - - /*............................................................... - Check the version number of the other system. - ...............................................................*/ -#ifdef PATCH - if (IsV107) { - version = 1; - } else { - version = 2; - } -#else - version = Version_Number(); -#endif - if (ReceivePacket.Version > version) { - CCMessageBox().Process (TXT_YOURGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } else { - if (ReceivePacket.Version < version) { - CCMessageBox().Process (TXT_DESTGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } - } - break; - - /*.................................................................. - Incoming message: add to our list - ..................................................................*/ - - // - // get their response time - // - case (SERIAL_TIMING): - oppscorescreen = false; - theirresponsetime = ReceivePacket.ResponseTime; - - if ( !gameoptions ) { - transmit = 1; - }else{ - process = false; - rc = true; - } - break; - - // - // print msg waiting for opponent - // - case (SERIAL_SCORE_SCREEN): - oppscorescreen = true; - parms_received = 1; - break; - - default: - break; - } - } - } - - // if we haven't received a msg for 10 seconds exit - - if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - } - - /*--------------------------------------------------------------------- - Service the connection - ---------------------------------------------------------------------*/ - NullModem.Service(); - - } /* end of while */ - - /*------------------------------------------------------------------------ - Sort player ID's, so we can execute commands in the same order on both - machines. - ------------------------------------------------------------------------*/ - if (rc) { - /*..................................................................... - Set the number of players in this game, and my ID - .....................................................................*/ - MPlayerCount = 2; - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - TheirID = Build_MPlayerID (TheirColor,TheirHouse); - - /*..................................................................... - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - .....................................................................*/ - if (TheirID < MPlayerLocalID) { - MPlayerID[0] = TheirID; - MPlayerID[1] = MPlayerLocalID; - strcpy (MPlayerNames[0], TheirName); - strcpy (MPlayerNames[1], MPlayerName); - } else { - MPlayerID[0] = MPlayerLocalID; - MPlayerID[1] = TheirID; - strcpy (MPlayerNames[0], MPlayerName); - strcpy (MPlayerNames[1], TheirName); - } - - /*..................................................................... - Get the scenario filename - .....................................................................*/ - Scenario = MPlayerFilenum[ScenarioIdx]; - - /*..................................................................... - Send all players the GO packet. - .....................................................................*/ - SendPacket.Command = SERIAL_GO; - SendPacket.ResponseTime = NullModem.Response_Time(); - if ( theirresponsetime == 10000 ) { -// Mono_Clear_Screen(); -// Smart_Printf( "Did not receive their response time!!!!!!!\n" ); -// Get_Key(); - } else { - if (SendPacket.ResponseTime < theirresponsetime) { - SendPacket.ResponseTime = theirresponsetime; - } - } - - // - // calculated one way delay for a packet and overall delay to execute - // a packet - // - ////////MPlayerMaxAhead = MAX( (SendPacket.ResponseTime / 8), 2); - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while ( ( NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) ) - || ((TickCount.Time() - starttime) < 60) ) { - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - NullModem.Service(); - Keyboard::Check(); //Make sure the message loop gets called - } - - // clear queue to keep from doing any resends - NullModem.Init_Send_Queue(); - - } else { - if ( !recsignedoff ) { - /*..................................................................... - Broadcast my sign-off over my network - .....................................................................*/ - SendPacket.Command = SERIAL_SIGN_OFF; - SendPacket.Color = MPlayerLocalID; // use Color for ID - SendPacket.ID = ModemGameToPlay; - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while ( (NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) ) - || ((TickCount.Time() - starttime) < 60) ) { - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { - - // are we getting our own packets back?? - - if (ReceivePacket.Command == SERIAL_SIGN_OFF - && ReceivePacket.ID == ModemGameToPlay) { - - // exit while - break; - } - } - - NullModem.Service(); - } - } - - Shutdown_Modem(); - } - - /*------------------------------------------------------------------------ - Restore screen - ------------------------------------------------------------------------*/ - Hide_Mouse(); - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Show_Mouse(); - - /*------------------------------------------------------------------------ - Save any changes made to our options - ------------------------------------------------------------------------*/ - if (changed) { - Write_MultiPlayer_Settings (); - } - - return(rc); - -} /* end of Com_Scenario_Dialog */ - - - - - - - - - - - - - - - - - - - - - - - - - - -int Com_Show_Fake_Scenario_Dialog(void) -{ - /*........................................................................ - Dialog variables - ........................................................................*/ - bool display = true; // redraw level - BOOL process = true; // process while true - - char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name - int transmit; // 1 = re-transmit new game options - int first; // 1 = no packets received yet - int parms_received = 0; // 1 = game options received - int changed = 0; // 1 = user has changed an option - - int rc; - int recsignedoff = 0; - int i; - int version; - unsigned long starttime; - unsigned long timingtime; - unsigned long lastmsgtime; - unsigned long lastredrawtime; - unsigned long transmittime = 0; - int packetlen; - bool oppscorescreen = false; - bool gameoptions = false; - EventClass *event; // event ptr - unsigned long msg_timeout = 60*60; // init to 60 seconds - - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /*........................................................................ - Dialog variables - ........................................................................*/ - TextButtonClass * buttons = 0; - - KeyNumType input; - - int x,y; - int width=0; - int height=0; - char text_buffer[80*3]; - - const char *current_status_string = Text_String(TXT_WINSOCK_CONNECTING); - strcpy(text_buffer, current_status_string); - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - - Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height); - - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (SeenBuff.Get_Width() - width) / 2; - y = (SeenBuff.Get_Height() - height) / 2; - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1), - y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); - - Set_Logic_Page(SeenBuff); - buttons = &cancelbtn; - - buttons->Flag_List_To_Redraw(); - - - transmit = 1; - first = 1; - - - /* - ---------------------------- Processing loop ----------------------------- - */ - NullModem.Reset_Response_Time(); // clear response time - timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); - - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=true; - } - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - /* - .................. Redraw backgound & dialog box ................... - */ - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - Set_Palette(Palette); - /* - ..................... Draw the background ....................... - */ - Dialog_Box(x, y, width, height); - /* - ....................... Draw the labels ......................... - */ - Draw_Caption(TXT_NONE, x, y, width); - - Fancy_Text_Print(text_buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - buttons->Draw_All(); - Show_Mouse(); - display = false; - } - - - /* - ............................ Process input ............................ - */ - input = buttons->Input(); - switch (input) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - process = false; - rc = false; - break; - - default: - break; - } - - - - /*--------------------------------------------------------------------- - If our Transmit flag is set, we need to send out a game option packet - ---------------------------------------------------------------------*/ - if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { - SendPacket.Command = SERIAL_GAME_OPTIONS; - strcpy (SendPacket.Name, MPlayerName); -#ifdef PATCH - if (IsV107) { - SendPacket.Version = 1; - } else { - SendPacket.Version = 2; - } -#else - SendPacket.Version = Version_Number(); -#endif - SendPacket.House = MPlayerHouse; - SendPacket.Color = MPlayerColorIdx; - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - transmittime = TickCount.Time(); - transmit = 0; - } - - // - // send a timing packet if enough time has gone by. - // - if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { - SendPacket.Command = SERIAL_TIMING; - SendPacket.ResponseTime = NullModem.Response_Time(); - SendPacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); - timingtime = TickCount.Time(); - } - - /*--------------------------------------------------------------------- - Check for an incoming message - ---------------------------------------------------------------------*/ - if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { - - lastmsgtime = TickCount.Time(); - - msg_timeout = 600; - - // are we getting our own packets back?? - - if (ReceivePacket.Command >= SERIAL_CONNECT && - ReceivePacket.Command < SERIAL_LAST_COMMAND && - ReceivePacket.Command != SERIAL_MESSAGE && - ReceivePacket.ID == ModemGameToPlay) { - - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - break; - } - - event = (EventClass *)&ReceivePacket; - if (event->Type <= EventClass::FRAMEINFO) { - if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { - lastredrawtime = TickCount.Time(); - oppscorescreen = true; - display = false; - parms_received = 1; - } - } else { - switch ( ReceivePacket.Command ) { - /*.................................................................. - Other system signs off: Give it time to receive my ACK, then show - a message. - ..................................................................*/ - case (SERIAL_SIGN_OFF): - starttime = TickCount.Time(); - while ( (TickCount.Time() - starttime) < 60) - NullModem.Service(); - CCMessageBox().Process(TXT_USER_SIGNED_OFF); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - recsignedoff = true; - break; - - /*.................................................................. - Game Options: Store all options; check my color & game version. - ..................................................................*/ - case (SERIAL_GAME_OPTIONS): - oppscorescreen = false; - gameoptions = true; - display = false; - parms_received = 1; - - strcpy (TheirName, ReceivePacket.Name); - TheirColor = ReceivePacket.Color; - TheirHouse = ReceivePacket.House; - - /*............................................................... - Save scenario settings. - ...............................................................*/ - MPlayerCredits = ReceivePacket.Credits; - MPlayerBases = ReceivePacket.IsBases; - MPlayerTiberium = ReceivePacket.IsTiberium; - MPlayerGoodies = ReceivePacket.IsGoodies; - MPlayerGhosts = ReceivePacket.IsGhosties; - BuildLevel = ReceivePacket.BuildLevel; - MPlayerUnitCount = ReceivePacket.UnitCount; - Seed = ReceivePacket.Seed; - Special = ReceivePacket.Special; - Options.GameSpeed = ReceivePacket.GameSpeed; - - if (MPlayerTiberium) { - Special.IsTGrowth = 1; - Special.IsTSpread = 1; - } else { - Special.IsTGrowth = 0; - Special.IsTSpread = 0; - } - - /*............................................................... - Find the index of the scenario number; if it's not found, leave - it at -1. - ...............................................................*/ - ScenarioIdx = -1; - for (i = 0; i < MPlayerFilenum.Count(); i++) { - if (ReceivePacket.Scenario == MPlayerFilenum[i]) - ScenarioIdx = i; - } - - /*............................................................... - Check our version numbers; if they're incompatible, sign off. - ...............................................................*/ -#ifdef PATCH - if (IsV107) { - version = 1; - } else { - version = 2; - } -#else - version = Version_Number(); -#endif - if (ReceivePacket.Version > version) { - CCMessageBox().Process (TXT_YOURGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } else { - if (ReceivePacket.Version < version) { - CCMessageBox().Process (TXT_DESTGAME_OUTDATED); - - // to skip the other system not responding msg - lastmsgtime = TickCount.Time(); - - process = false; - rc = false; - } - } - - /*............................................................... - If this is the first game-options packet we've received, transmit - our options to him. - ...............................................................*/ - if (first) { - first = 0; - - // force transmitting of game options packet - - transmit = 1; - transmittime = 0; - } - break; - - /*.................................................................. - GO: Exit this routine with a success code. - ..................................................................*/ - case (SERIAL_GO): - - // - // calculated one way delay for a packet and overall delay - // to execute a packet - // - ////////MPlayerMaxAhead = MAX( (ReceivePacket.ResponseTime / 8), 2); - - process = false; - rc = true; - break; - - // - // throw away timing packet - // - case (SERIAL_TIMING): - oppscorescreen = false; - break; - - // - // print msg waiting for opponent - // - case (SERIAL_SCORE_SCREEN): -// Smart_Printf( "received score screen\n" ); - oppscorescreen = true; - display = false; - parms_received = 1; - break; - - default: - break; - } - } - } - - // if we haven't received a msg for 10 seconds exit - - if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - process = false; - rc = false; - - // say we did receive sign off to keep from sending one - recsignedoff = true; - } - - - /*--------------------------------------------------------------------- - Service the connection - ---------------------------------------------------------------------*/ - NullModem.Service(); - - } /* end of while */ - - /*------------------------------------------------------------------------ - Sort player ID's, so we can execute commands in the same order on both - machines. - ------------------------------------------------------------------------*/ - if (rc) { - /*..................................................................... - Set the number of players in this game, and my ID - .....................................................................*/ - MPlayerCount = 2; - MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); - - TheirID = Build_MPlayerID (TheirColor,TheirHouse); - - /*..................................................................... - Store every player's ID in the MPlayerID[] array. This array will - determine the order of event execution, so the ID's must be stored - in the same order on all systems. - .....................................................................*/ - if (TheirID < MPlayerLocalID) { - MPlayerID[0] = TheirID; - MPlayerID[1] = MPlayerLocalID; - strcpy (MPlayerNames[0], TheirName); - strcpy (MPlayerNames[1], MPlayerName); - } else { - MPlayerID[0] = MPlayerLocalID; - MPlayerID[1] = TheirID; - strcpy (MPlayerNames[0], MPlayerName); - strcpy (MPlayerNames[1], TheirName); - } - - /*..................................................................... - Get the scenario filename - .....................................................................*/ - Scenario = MPlayerFilenum[ScenarioIdx]; - - starttime = TickCount.Time(); - while ( ( NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) ) - || ((TickCount.Time() - starttime) < 60) ) { - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - NullModem.Service(); - Keyboard::Check(); //Make sure the message loop gets called - } - - // clear queue to keep from doing any resends - NullModem.Init_Send_Queue(); - - } else { - if ( !recsignedoff ) { - /*..................................................................... - Broadcast my sign-off over my network - .....................................................................*/ - SendPacket.Command = SERIAL_SIGN_OFF; - SendPacket.Color = MPlayerLocalID; // use Color for ID - SendPacket.ID = ModemGameToPlay; - NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); - - starttime = TickCount.Time(); - while ( (NullModem.Num_Send() - && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) ) - || ((TickCount.Time() - starttime) < 60) ) { - #if(SHOW_MONO) - NullModem.Mono_Debug_Print(0); - #endif - - if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { - - // are we getting our own packets back?? - - if (ReceivePacket.Command == SERIAL_SIGN_OFF - && ReceivePacket.ID == ModemGameToPlay) { - - // exit while - break; - } - } - - NullModem.Service(); - } - } - - Shutdown_Modem(); - } - - /*------------------------------------------------------------------------ - Save any changes made to our options - ------------------------------------------------------------------------*/ - if (changed) { - Write_MultiPlayer_Settings (); - } - - return(rc); - -} /* end of Com_Show_Scenario_Dialog */ - - -#endif //(0) - - -#endif //(0) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Smart_Printf( char *format, ... ) -{ - va_list arglist; - char buf[501]; - - - va_start(arglist,format); - vsprintf(buf,format,arglist); - va_end(arglist); - - if (Debug_Smart_Print) { - if (Special.IsMonoEnabled) { -// Mono_Set_Cursor(0,0); - Mono_Printf("%s",buf); - } else { -// Mono_Printf("%s",buf); - printf("%s",buf); - } - } else { - if (Debug_Heap_Dump) { - printf("%s",buf); - } - } -} - - -void Hex_Dump_Data( char *buffer, int length ) -{ - int i; - int offset = 0; - char buff[10]; - char ptr[16]; - char c; - - - while (length >= 16) { - memcpy( ptr, (buffer + offset), 16); - - Smart_Printf("%05lX ", offset); - - for (i = 0; i < 16; i++) { - - c = ptr[i]; - itoh(c, buff); - - if (!(i & 0x3) && i) { - Smart_Printf("³ "); - } - - Smart_Printf("%s ", buff); - } - - Smart_Printf(" "); - - for (i = 0; i < 16; i++) { - c = ptr[i]; - - if (c && ((c < 7) || (c > 11)) && (c != 13)) { - Smart_Printf("%c", c); - } else { - Smart_Printf("."); - } - } - - Smart_Printf("\n"); - - offset += 16; - length -= 16; - } - - if (length) { - memcpy( ptr, (buffer + offset), 16); - - Smart_Printf("%05lX ", offset); - - for (i = 0; i < 16; i++) { - if (i < length) { - c = ptr[i]; - itoh(c, buff); - if (!(i & 0x3) && i) { - Smart_Printf("³ "); - } - Smart_Printf("%s ", buff); - } else { - if (!(i & 0x3) && i) { - Smart_Printf(" "); - } - Smart_Printf(" "); - } - } - - Smart_Printf(" "); - - for (i = 0; i < length; i++) { - - c = ptr[i]; - - if (c && ((c < 7) || (c > 11)) && (c != 13)) { - Smart_Printf("%c", c); - } else { - Smart_Printf("."); - } - } - - Smart_Printf("\n"); - } - -} /* end of Hex_Dump_Data */ - - -void itoh( int i, char *s) -{ - - int nibble, loop; - -// *s++ = '0'; -// *s++ = 'x'; - - if (i == 0) { - *s++ = '0'; - *s++ = '0'; - } else { - for (loop = 1; loop >= 0; loop--) { - nibble = (i >> (loop << 2)) & 0x000F; - - /* decimal range */ - if (nibble < 10) { - *s++ = '0' + nibble; - } else { - *s++ = 'A' + (nibble - 10); - } - } - } - *s = 0; /* null terminate it */ -} - diff --git a/code/TIBERIANDAWN/NULLMGR.CPP b/code/TIBERIANDAWN/NULLMGR.CPP deleted file mode 100644 index d6aef4f..0000000 --- a/code/TIBERIANDAWN/NULLMGR.CPP +++ /dev/null @@ -1,2350 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\nullmgr.cpv 1.10 16 Oct 1995 16:51:52 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : NULLMGR.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : April 5, 1995 * - * * - * Last Update : May 1, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * NullModemClass::NullModemClass -- class constructor * - * NullModemClass::~NullModemClass -- class destructor * - * NullModemClass::Init -- initialization * - * NullModemClass::Send_Message -- sends a message * - * NullModemClass::Get_Message -- polls the Queue for a message * - * NullModemClass::Service -- main polling routine * - * NullModemClass::Num_Send -- Returns # of unACK'd send entries * - * NullModemClass::Num_Receive -- Returns # entries in the receive queue * - * NullModemClass::Response_Time -- Returns Queue's avg response time * - * NullModemClass::Reset_Response_Time -- Resets response time computatio* - * NullModemClass::Oldest_Send -- Returns ptr to oldest unACK'd send buf * - * NullModemClass::Detect_Modem -- Detects and initializes the modem * - * NullModemClass::Dial_Modem -- dials a number passed * - * NullModemClass::Answer_Modem -- waits for call and answers * - * NullModemClass::Hangup_Modem -- hangs up the modem * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "wincomm.h" -#include "modemreg.h" -//#include "i86.h" -#include "tcpip.h" - -//PG_TO_FIX -#if (0) - -extern ModemRegistryEntryClass *ModemRegistry; - -// the following line was taken from Greenleaf's -// because of other define conflicts - -#define ESC 27 -#define NOKEY 0xffff -#define INIT_COMMAND_RETRIES 2 - -// this time is in milliseconds - -#define DEFAULT_TIMEOUT 2000 - -// -// the following is for a fix around a greenleaf bug -// where they do not check for the value of abortkey -// to determine whether or not they call the abort modem function. -// -extern "C" { - extern void (*_AbortModemFunctionPtr)(int); -} - -static void (*NullModemClass::OrigAbortModemFunc)(int); - -static KeyNumType NullModemClass::Input; -static GadgetClass *NullModemClass::Commands; // button list - -/* -** Ugly hack: this string stores the string received from the modem -*/ -char ModemRXString[80]; - -/*************************************************************************** - * NullModemClass::NullModemClass -- class constructor * - * * - * INPUT: * - * numsend # desired entries for the send queue * - * numreceive # desired entries for the receive queue * - * maxlen application's max packet length * - * magicnum application-specific magic # (so we don't * - * accidentally end up talking to another one of our own * - * products using the same protocol) * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -NullModemClass::NullModemClass (int numsend, int numreceive, int maxlen, - unsigned short magicnum) : ConnManClass() -{ - /*------------------------------------------------------------------------ - Init Port to NULL; we haven't opened Greenleaf yet. - ------------------------------------------------------------------------*/ - PortHandle = NULL; - Connection = NULL; - - NumSend = numsend; - NumReceive = numreceive; - MaxLen = maxlen; - MagicNum = magicnum; - - RXBuf = 0; - BuildBuf = 0; - - EchoSize = 500; - EchoBuf = 0; - - OldIRQPri = -1; - - ModemVerboseOn = false; // default true - ModemEchoOn = false; // default true - ModemWaitCarrier = 50000; // default 50 * 1000ms = 50 secs - ModemCarrierDetect = 600; // default 6 * 100ms = .6 secs - ModemCarrierLoss = 1400; // default 14 * 100ms = 1.4 secs - ModemHangupDelay = 20000; // default 20 * 1000ms = 20 secs - ModemGuardTime = 1000; // default 50 * 20ms = 1 sec - ModemEscapeCode = '+'; // default ASCII 43 - - SendOverflows = 0; - ReceiveOverflows = 0; - CRCErrors = 0; - - NumConnections = 0; - - /*........................................................................ - Init timing parameters - ........................................................................*/ - RetryDelta = 60; // 60 ticks between retries - MaxRetries = -1; // disregard # retries - Timeout = 1200; // report bad connection after 20 seconds - -} /* end of NullModemClass */ - - -/*************************************************************************** - * NullModemClass::~NullModemClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -NullModemClass::~NullModemClass () -{ - Delete_Connection(); -} /* end of ~NullModemClass */ - - -/*************************************************************************** - * NullModemClass::Init -- initialization * - * * - * INPUT: * - * port address * - * irq 2-15 * - * baud 300, 1200, 9600, etc * - * parity 'O' (odd), 'E' (even), 'N' (none), 'S' (space), * - * 'M' (mark) * - * wordlength 5, 6, 7, or 8 * - * stopbits 1 or 2 * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -//int NullModemClass::Init (int port, int irq, int baud, char parity, int wordlen, int stopbits) -#pragma off (unreferenced) -int NullModemClass::Init (int port, int ,char *dev_name, int baud, char parity, int wordlen, int stopbits, int flowcontrol) -{ - int com; - //int irqnum; - //int address; - //int status; - - - if (PortHandle) { - CloseHandle(PortHandle); - PortHandle = NULL; - } - - if (!Connection){ - /*------------------------------------------------------------------------ - Init our Connection - ------------------------------------------------------------------------*/ - Connection = new NullModemConnClass (NumSend, NumReceive, MaxLen, - MagicNum); - - Connection->Set_Retry_Delta (RetryDelta); - Connection->Set_Max_Retries (MaxRetries); - Connection->Set_TimeOut (Timeout); - - /*------------------------------------------------------------------------ - Allocate our packet parsing buffer; make it the same # of packets as the - # of receive queue entries the application has requested. Use the - "Actual" maximum packet size, given from the connection; this allows for - both headers that get added to the packet. - ------------------------------------------------------------------------*/ - RXSize = Connection->Actual_Max_Packet() * NumReceive; - RXBuf = new char [RXSize]; - - BuildBuf = new char [MaxLen]; - - EchoBuf = new char [ EchoSize ]; - } - - RXCount = 0; - EchoCount = 0; - - - /*------------------------------------------------------------------------ - This call allocates all necessary queue buffers - ------------------------------------------------------------------------*/ - switch (port) { - case 0x3f8: - com = COM1; - break; - - case 0x2f8: - com = COM2; - break; - - case 0x3e8: - com = COM3; - break; - - case 0x2e8: - com = COM4; - break; - - default: - com = COM5; - break; - } - - int i; - - /* - ** Create a new modem class for our com port - */ - if (!SerialPort) { - SerialPort = new WinModemClass; - } - - /* - ** Shift up the baud rate to sensible values - */ -// if (baud == 14400) baud = 19200; -// if (baud == 28800) baud = 38400; - - static char com_ids[9][5]={ - "COM1", - "COM2", - "COM3", - "COM4", - "COM5", - "COM6", - "COM7", - "COM8", - "COM9" - }; - - char *device; - - switch ( port ) { - - case 0x3f8: - device = com_ids[0]; - break; - - case 0x2f8: - device = com_ids[1]; - break; - - case 0x3e8: - device = com_ids[2]; - break; - - case 0x2e8: - device = com_ids[3]; - break; - - case 1: - /* - ** 1 is a special value. It means use the device name not the port address. - */ - device = dev_name; - - /* - ** If we can match a registry entry with the device name then use that, otherwise use - ** the device name directly to open the port with. - */ - if (ModemRegistry){ - delete ModemRegistry; - ModemRegistry = NULL; - } - for ( i=0 ; i<10 ; i++ ){ - ModemRegistry = new ModemRegistryEntryClass (i); - if (ModemRegistry->Get_Modem_Name()){ - if (!strcmp (dev_name, ModemRegistry->Get_Modem_Name() )){ - device = ModemRegistry->Get_Modem_Device_Name(); - break; - } - } - delete ModemRegistry; - ModemRegistry = NULL; - } - break; - - default: - device = NULL; - } - - /* - ** Open the com port - */ - PortHandle = SerialPort->Serial_Port_Open (device, baud, parity, wordlen, stopbits, flowcontrol); - if (PortHandle == INVALID_HANDLE_VALUE) { - Shutdown(); - return(false); - } - - /*------------------------------------------------------------------------ - Init the Connection - ------------------------------------------------------------------------*/ - Connection->Init(PortHandle); - - NumConnections = 1; - - return(true); -} - - -/*********************************************************************************************** - * NMC::Num_Connections -- returns NumConnections member * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: NumConnections * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 11:44AM ST : Documented / Win32 support * - *=============================================================================================*/ -int NullModemClass::Num_Connections( void ) -{ - return(NumConnections); -} - - - -/*********************************************************************************************** - * NMC::Delete_Connection -- removes the connection * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: true * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 11:44AM ST : Documented / Win32 support * - *=============================================================================================*/ -int NullModemClass::Delete_Connection( void ) -{ - if (Connection) { - delete Connection; - Connection = NULL; - } - - if (RXBuf) { - delete [] RXBuf; - RXBuf = NULL; - } - - if (BuildBuf) { - delete [] BuildBuf; - BuildBuf = NULL; - } - - if (EchoBuf) { - delete [] EchoBuf; - EchoBuf = NULL; - } - - NumConnections = 0; - - return( true ); -} /* end of Delete_Connection */ - - -/*********************************************************************************************** - * NMC::Init_Send_Queue -- Initialises the connections send queue * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: true * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 11:46AM ST : Documented / Win32 support * - *=============================================================================================*/ -int NullModemClass::Init_Send_Queue( void ) -{ - - /*--------------------------------------------------------------- - Init the send queue - -----------------------------------------------------------------*/ - if ( Connection ) { - Connection->Queue->Init_Send_Queue(); - } - - return(true); -} - - -//DetectPortType NullModemClass::Detect_Port( SerialSettingsType *settings ) -/*********************************************************************************************** - * NMC::Detect_Port -- Checks that the specified com port exists * - * * - * * - * * - * INPUT: ptr to SerialSettingsType * - * * - * OUTPUT: true if port is valid * - * * - * HISTORY: * - * 8/2/96 11:47AM ST : Documented / Win32 support * - *=============================================================================================*/ -DetectPortType NullModemClass::Detect_Port( SerialSettingsType *settings) -{ - - static char com_ids[9][5]={ - "COM1", - "COM2", - "COM3", - "COM4", - "COM5", - "COM6", - "COM7", - "COM8", - "COM9" - }; - - int i; - - /* - ** Create a new modem class for our com port - */ - if (!SerialPort) { - SerialPort = new WinModemClass; - }else{ - SerialPort->Serial_Port_Close(); - } - - /* - ** Shift up the baud rate to sensible values - */ - int baud = settings->Baud; -// if (baud == 14400) baud = 19200; -// if (baud == 28800) baud = 38400; - - - /* - ** Translate the port address into a usable device name - */ - char *device; - - switch ( settings->Port ) { - - case 0x3f8: - device = com_ids[0]; - break; - - case 0x2f8: - device = com_ids[1]; - break; - - case 0x3e8: - device = com_ids[2]; - break; - - case 0x2e8: - device = com_ids[3]; - break; - - case 1: - /* - ** 1 is a special value. It means use the device name not the port address. - */ - device = settings->ModemName; - - /* - ** If we can match a registry entry with the device name then use that, otherwise use - ** the device name directly to open the port with. - */ - if (ModemRegistry){ - delete ModemRegistry; - ModemRegistry = NULL; - } - for ( i=0 ; i<10 ; i++){ - ModemRegistry = new ModemRegistryEntryClass (i); - if (ModemRegistry->Get_Modem_Name()){ - if (!strcmp (device, ModemRegistry->Get_Modem_Name() )){ - /* - ** Got a match. Break out leaving the registry info intact. - */ - device = ModemRegistry->Get_Modem_Device_Name(); - break; - } - } - delete ModemRegistry; - ModemRegistry = NULL; - } - break; - - default: - return (PORT_INVALID); - } - - /* - ** Open the com port - */ - HANDLE porthandle = SerialPort->Serial_Port_Open (device, baud, 0, 8, 1, settings->HardwareFlowControl); - - if (porthandle == INVALID_HANDLE_VALUE){ - return (PORT_INVALID); - } - - SerialPort->Serial_Port_Close(); - return (PORT_VALID); - -} - - - - -/*********************************************************************************************** - * NullModemClass::ShutDown -- Closes serial port and removes the connection * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 11:43AM ST : Documented / Win32 support * - *=============================================================================================*/ -void NullModemClass::Shutdown ( void ) -{ - if (PortHandle && SerialPort) { - SerialPort->Serial_Port_Close(); - delete SerialPort; - SerialPort = NULL; - PortHandle = NULL; - Delete_Connection(); - } - -#ifdef FORCE_WINSOCK - if (Winsock.Get_Connected()){ - Delete_Connection(); - } -#endif - -} /* end of Shutdown */ - - -/*************************************************************************** - * NullModemClass::Set_Timing -- sets timing for all connections * - * * - * This will set the timing parameters. This allows an application to * - * measure the Response_Time while running, and adjust timing accordingly. * - * * - * INPUT: * - * retrydelta value to set for retry delta * - * maxretries value to set for max # retries * - * timeout value to set for connection timeout * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/07/1995 DRD : Created. * - *=========================================================================*/ -void NullModemClass::Set_Timing (unsigned long retrydelta, - unsigned long maxretries, unsigned long timeout) -{ - RetryDelta = retrydelta; - MaxRetries = maxretries; - Timeout = timeout; - - Connection->Set_Retry_Delta (RetryDelta); - Connection->Set_Max_Retries (MaxRetries); - Connection->Set_TimeOut (Timeout); - -} /* end of Set_Timing */ - - -/*************************************************************************** - * NullModemClass::Send_Message -- sends a message * - * * - * For clarity's sake, here's what happens to the buffer passed in: * - * - It gets passed to the Connection's Send_Packet() routine * - * - The CommHeaderType header gets tacked onto it * - * - The resulting buffer gets added to the Connection's Send Queue * - * - When Service() determines that it needs to send the data, it * - * copies the entire packet (CommHeaderType and all) into its local * - * SendBuf, adds the packet start ID, length, and CRC, then sends it out.* - * * - * The ack_req argument will almost always be '1' (the default). The only * - * reason to use 0 is if you don't know whether the other system is * - * ready or not, so you have to periodically send out a query packet, * - * and wait for a response. (Using the connection's built-in retry * - * system would just blast out useless data if the other system isn't * - * even there.) * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buffer * - * ack_req 1 = ACK is required; 0 = not * - * * - * OUTPUT: * - * 1 = OK; 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NullModemClass::Send_Message (void *buf, int buflen, int ack_req) -{ - int rc; - - if (NumConnections == 0) { - return( false ); - } - - rc = Connection->Send_Packet(buf,buflen,ack_req); - if (!rc) - SendOverflows++; - - return(rc); - -} /* end of Send_Message */ - - -/*************************************************************************** - * NullModemClass::Get_Message -- polls the Queue for a message * - * * - * INPUT: * - * buf buffer to store message in * - * buflen ptr filled in with length of message * - * * - * OUTPUT: * - * 1 = message was received; 0 = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NullModemClass::Get_Message (void *buf, int *buflen) -{ - if (NumConnections == 0) { - return( false ); - } - return( Connection->Get_Packet( buf, buflen ) ); -} - - -/*************************************************************************** - * NullModemClass::Service -- main polling routine * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = connection has gone bad * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int NullModemClass::Service (void) -{ - int pos; // current position in RXBuf - int i; // loop counter - //int status; - unsigned short length; - SerialHeaderType *header; // decoded packet start, length - SerialCRCType *crc; // decoded packet CRC - char moredata = 0; - - if (NumConnections == 0) { - return( false ); - } - - /*------------------------------------------------------------------------ - First, copy all the bytes we can from the Greenleaf RX buffer to our - own buffer. - ------------------------------------------------------------------------*/ - RXCount += SerialPort->Read_From_Serial_Port((unsigned char*)(RXBuf + RXCount), int(RXSize - RXCount) ); - -// if (RXCount){ -//char port[128]; -//sprintf (port, "C&C95 - RXCount = %d bytes.\n", RXCount); -//CCDebugString (port); -// } - -BOOL enabled = FALSE; - -#if (0) -if (SerialPort->FramingErrors || - SerialPort->IOErrors || - SerialPort->InBufferOverflows || - SerialPort->BufferOverruns || - SerialPort->InBufferOverflows || - SerialPort->OutBufferOverflows){ - - -if (!MonoClass::Is_Enabled()) { -MonoClass::Enable(); -enabled = TRUE; -} -Special.IsMonoEnabled = TRUE; -Debug_Smart_Print = TRUE; -Mono_Set_Cursor(0,0); -Smart_Printf( " In Queue: %5d \n", SerialPort->InQueue); -Smart_Printf( " Out Queue: %5d \n", SerialPort->OutQueue); -Smart_Printf( " Framing errors: %5d \n", SerialPort->FramingErrors); -Smart_Printf( " IO errors: %5d \n", SerialPort->IOErrors); -Smart_Printf( " Parity Errors: %5d \n", SerialPort->InBufferOverflows); -Smart_Printf( " Buffer overruns: %5d \n", SerialPort->BufferOverruns); -Smart_Printf( " In buffer overflows: %5d \n", SerialPort->InBufferOverflows); -Smart_Printf( "Out buffer overflows: %5d \n", SerialPort->OutBufferOverflows); - -MonoClass::Disable(); -Debug_Smart_Print = FALSE; -} -#endif //(0) - - // minimum packet size - - if ( RXCount < (PACKET_SERIAL_OVERHEAD_SIZE + 1) ) { - return( Connection->Service() ); - } - - /*------------------------------------------------------------------------ - Now scan the buffer for the start of a packet. - ------------------------------------------------------------------------*/ - pos = -1; - for (i = 0; i <= RXCount - sizeof( short ); i++) { - if ( *((unsigned short *)(RXBuf + i)) == PACKET_SERIAL_START ) { - pos = i; - break; - } - } - - /*------------------------------------------------------------------------ - No start code was found; throw away all bytes except the last few, and - return. - ------------------------------------------------------------------------*/ - if (pos==-1) { -// Smart_Printf( "No magic number found \n" ); - /*..................................................................... - move the remaining, un-checked bytes to the start of the buffer - .....................................................................*/ - memmove (RXBuf, RXBuf + i, sizeof( short ) - 1); - RXCount = sizeof( short ) - 1; - return( Connection->Service() ); - } - - /*........................................................................ - Check to see if there are enough bytes for the header to be decoded - ........................................................................*/ - if ( (RXCount - pos) < sizeof( SerialHeaderType ) ) { - memmove (RXBuf, RXBuf + pos, RXCount - pos); - RXCount -= pos; - return(Connection->Service()); - } - - /*------------------------------------------------------------------------ - A start code was found; check the packet's length & CRC - ------------------------------------------------------------------------*/ - header = (SerialHeaderType *)(RXBuf + pos); - - /*........................................................................ - If we lost a byte in the length, we may end up waiting a very long time - for the buffer to get to the right length; check the verify value to - make sure this didn't happen. - ........................................................................*/ - if ( header->MagicNumber2 != PACKET_SERIAL_VERIFY ) { -// Smart_Printf( "Verify failed\n"); -// Hex_Dump_Data( (RXBuf + pos), PACKET_SERIAL_OVERHEAD_SIZE ); - - pos += sizeof ( short ); // throw away the bogus start code - memmove (RXBuf, RXBuf + pos, RXCount - pos); - RXCount -= pos; - return(Connection->Service()); - } - - length = header->Length; - - /*........................................................................ - Special case: if the length comes out too long for us to process: - - Assume the packet is bad - - Throw away the bogus packet-start code - - Return; we'll search for another packet-start code next time. - ........................................................................*/ - if (length > MaxLen) { -#if (CONN_DEBUG) - printf( "length too lonnng\n" ); -#endif -// Smart_Printf( "length too lonnng %d, max %d \n", length, MaxLen ); - - pos += sizeof ( short ); // throw away the bogus start code - memmove (RXBuf, RXBuf + pos, RXCount - pos); - RXCount -= pos; - return(Connection->Service()); - } - - /*........................................................................ - If the entire packet isn't stored in our buffer, copy the remaining bytes - to the front of the buffer & return. - ........................................................................*/ - if ( (pos + length + PACKET_SERIAL_OVERHEAD_SIZE) > RXCount) { - - if ( moredata ) { -// Smart_Printf( "waiting for more data %d, pos = %d \n", ((length + PACKET_SERIAL_OVERHEAD_SIZE) - (RXCount - pos)), pos ); - } - - if (pos) { - memmove (RXBuf, RXBuf + pos, RXCount - pos); - RXCount -= pos; - } - return(Connection->Service()); - } - - /*........................................................................ - Now grab the CRC value in the packet, & compare it to the CRC value - computed from the actual data. If they don't match, throw away the bogus - start-code, move the rest to the front of the buffer, & return. - We'll continue parsing this data when we're called next time. - ........................................................................*/ - crc = (SerialCRCType *)(RXBuf + pos + sizeof( SerialHeaderType ) + length); - if (NullModemConnClass::Compute_CRC(RXBuf + pos + - sizeof( SerialHeaderType ), length) != crc->SerialCRC) { - - CRCErrors++; - -#if (CONN_DEBUG) - printf( "CRC check failed\n" ); -#endif -// Smart_Printf( "CRC check failed for packet of length %d \n", length ); - -// if (length < 100) { -// Hex_Dump_Data( (RXBuf + pos), (PACKET_SERIAL_OVERHEAD_SIZE + length) ); -// } - - pos += sizeof ( short ); // throw away the bogus start code - memmove (RXBuf, RXBuf + pos, RXCount - pos); - RXCount -= pos; - return(Connection->Service()); - } - - /*------------------------------------------------------------------------ - Give the new packet to the Connection to process. - ------------------------------------------------------------------------*/ - if (!Connection->Receive_Packet(RXBuf + pos + sizeof( SerialHeaderType ), length)) { - ReceiveOverflows++; -// Smart_Printf( "Received overflows %d \n", ReceiveOverflows ); - } - -#if (0) - Hex_Dump_Data( (RXBuf + pos), (PACKET_SERIAL_OVERHEAD_SIZE + length) ); -#endif - - /*------------------------------------------------------------------------ - Move all data past this packet to the front of the buffer. - ------------------------------------------------------------------------*/ - pos += (PACKET_SERIAL_OVERHEAD_SIZE + length); - memmove (RXBuf, RXBuf + pos, RXCount - pos); - RXCount -= pos; - - /*------------------------------------------------------------------------ - Now, service the connection's Queue's; this will handle ACK & Retries. - ------------------------------------------------------------------------*/ - return(Connection->Service()); - -} /* end of Service */ - - -/*************************************************************************** - * NullModemClass::Num_Send -- Returns # of unACK'd send entries * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/01/1995 BRR : Created. * - *=========================================================================*/ -int NullModemClass::Num_Send(void) -{ - if (Connection) - return( Connection->Queue->Num_Send() ); - else - return (0); - -} /* end of Num_Send */ - - -/*************************************************************************** - * NullModemClass::Num_Receive -- Returns # entries in the receive queue * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/01/1995 BRR : Created. * - *=========================================================================*/ -int NullModemClass::Num_Receive(void) -{ - if (Connection) - return( Connection->Queue->Num_Receive() ); - else - return (0); - -} /* end of Num_Receive */ - - -/*************************************************************************** - * NullModemClass::Response_Time -- Returns Queue's avg response time * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/01/1995 BRR : Created. * - *=========================================================================*/ -unsigned long NullModemClass::Response_Time(void) -{ - if (Connection) - return( Connection->Queue->Avg_Response_Time() ); - else - return (0); - -} /* end of Response_Time */ - - -/*************************************************************************** - * NullModemClass::Reset_Response_Time -- Resets response time computation * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/01/1995 BRR : Created. * - *=========================================================================*/ -void NullModemClass::Reset_Response_Time(void) -{ - if (Connection) - Connection->Queue->Reset_Response_Time(); - -} /* end of Reset_Response_Time */ - - -/*************************************************************************** - * Oldest_Send -- Returns ptr to oldest unACK'd send buffer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/01/1995 BRR : Created. * - *=========================================================================*/ -void * NullModemClass::Oldest_Send(void) -{ - int i; - SendQueueType *send_entry; // ptr to send entry header - CommHeaderType *packet; - void *buf = NULL; - - for (i = 0; i < Connection->Queue->Num_Send(); i++) { - send_entry = Connection->Queue->Get_Send(i); - if (send_entry) { - packet = (CommHeaderType *)send_entry->Buffer; - if (packet->Code == ConnectionClass::PACKET_DATA_ACK && send_entry->IsACK == 0) { - buf = send_entry->Buffer; - break; - } - } - } - - return(buf); - -} /* end of Oldest_Send */ - - -/*************************************************************************** - * NullModemClass::Configure_Debug -- sets up special debug values * - * * - * Mono_Debug_Print2() can look into a packet to pull out a particular * - * ID, and can print both that ID and a string corresponding to * - * that ID. This routine configures these values so it can find * - * and decode the ID. This ID is used in addition to the normal * - * CommHeaderType values. * - * * - * INPUT: * - * index connection index to configure (-1 = Global Channel) * - * offset ID's byte offset into packet * - * size size of ID, in bytes; 0 if none * - * names ptr to array of names; use ID as an index into this * - * maxnames max # in the names array; 0 if none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * Names shouldn't be longer than 12 characters. * - * * - * HISTORY: * - * 05/31/1995 BRR : Created. * - *=========================================================================*/ -void NullModemClass::Configure_Debug(int , int offset, int size, - char **names, int maxnames) -{ - if (Connection) - Connection->Queue->Configure_Debug (offset, size, names, maxnames); -} - - -/*************************************************************************** - * Mono_Debug_Print -- Debug output routine * - * * - * INPUT: * - * refresh 1 = clear screen & completely refresh * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/02/1995 BRR : Created. * - *=========================================================================*/ -void NullModemClass::Mono_Debug_Print(int, int refresh) -{ - if (!Connection) - return; - - Connection->Queue->Mono_Debug_Print (refresh); - - if (refresh) { - Mono_Set_Cursor (31,1); - Mono_Printf ("Serial Port Queues"); - - Mono_Set_Cursor (9,2); - Mono_Printf ("Average Response Time:"); - - Mono_Set_Cursor (20,3); - Mono_Printf ("CRC Errors:"); - - Mono_Set_Cursor (43,2); - Mono_Printf ("Send Overflows:"); - - Mono_Set_Cursor (40,3); - Mono_Printf ("Receive Overflows:"); - } - - Mono_Set_Cursor (32,2); - Mono_Printf ("%d ", Connection->Queue->Avg_Response_Time()); - - Mono_Set_Cursor (32,3); - Mono_Printf ("%d ", CRCErrors); - - Mono_Set_Cursor (59,2); - Mono_Printf ("%d ", SendOverflows); - - Mono_Set_Cursor (59,3); - Mono_Printf ("%d ", ReceiveOverflows); - - Mono_Set_Cursor (2,5); - Mono_Printf ("%d ", Num_Send()); - - Mono_Set_Cursor (41,5); - Mono_Printf ("%d ", Num_Receive()); - -} /* end of Mono_Debug_Print */ - - -void Timer_Test (int line, char *file) -{ - - char abuffer [128]; - - sprintf (abuffer, "Testing timer at line %d in file %s", line, file); - CCDebugString (abuffer); - - CountDownTimerClass timer; - - timer.Set (1); - - while (timer.Time()){ - CCDebugString ("."); - } - - CCDebugString ("OK\n"); -} - - - - -/*************************************************************************** - * NullModemClass::Detect_Modem -- Detects and initializes the modem * - * * - * INPUT: * - * settings ptr to SerialSettings structure * - * * - * OUTPUT: * - * -1 init string invalid * - * 0 no modem found * - * 1 modem found * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/02/1995 DRD : Created. * - *=========================================================================*/ -int NullModemClass::Detect_Modem( SerialSettingsType *settings, bool reconnect ) -{ - /*........................................................................ - Button Enumerations - ........................................................................*/ -// enum { -// BUTTON_CANCEL = 100, -// }; - - int status; -// int modemstatus; - int value; - int error_count = 0; - - int x,y,width,height; // dialog dimensions - char buffer[80*3]; - - int factor = SeenBuff.Get_Width()/320; - - - -//Timer_Test(__LINE__, __FILE__); - - - /* - ** Determine the dimensions of the text to be used for the dialog box. - ** These dimensions will control how the dialog box looks. - */ - strcpy( buffer, Text_String( TXT_INITIALIZING_MODEM ) ); - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(buffer, SeenBuff.Get_Height(), width, height); - - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (SeenBuff.Get_Width() - width) / 2; - y = (SeenBuff.Get_Height() - height) / 2; - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ............................ Draw the dialog ............................. - */ - Hide_Mouse(); - if ( !reconnect ) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - } - - Dialog_Box(x, y, width, height); - Draw_Caption(TXT_NONE, x, y, width); - - Fancy_Text_Print(buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Show_Mouse(); - - HMWaitForOK( 0, NULL ); - - - - - /* - ** OK, lets not mess about any more. Just turn on echo, verbose, and result codes - ** before we even begin. At least this way when we get an error later on we have already - ** removed all the steps we use to try and recover. - ** The timeouts need to be quite small in case the modem is turned off. - */ - - /* - ** Turn on result codes. - */ - Send_Modem_Command ( "ATQ0", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2); - - /* - ** Make result codes verbose. - */ - Send_Modem_Command ( "ATV1", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2); - - /* - ** Turn on echo. - */ - Send_Modem_Command ( "ATE1", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2); - - ModemVerboseOn = true; - ModemEchoOn = true; - - - - /* - ** Try sending a plain old AT command to the modem. Now that we have theoretically - ** turned on verbose result codes we should get an 'OK' back. - ** - */ - status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 2 ); - - if (status < ASSUCCESS) { - /* - ** No 'OK' came back so return failure. We cant print an error message here because - ** the calling function may want to upshift the baud rate (eg from 14400 to 19200) and - ** try again. - */ - return (false); - } - - /* - ** Send the user supplied modem init string - */ - if (settings->InitStringIndex == -1) { - status = Send_Modem_Command( "", '\r', buffer, 81, 300, 1 ); - } else { - /* - ** Split up the init string into seperate strings if it contains one or more '|' characters. - ** This character acts as a carriage return/pause. - */ - char *istr = new char [2 + strlen( InitStrings [settings->InitStringIndex] )]; - char *tokenptr; - strcpy (istr, InitStrings [settings->InitStringIndex] ); - - /* - ** Tokenise the string and send it in chunks - */ - tokenptr = strtok ( istr, "|" ); - while ( tokenptr ) { - - status = Send_Modem_Command( tokenptr, '\r', buffer, 81, DEFAULT_TIMEOUT, 1 ); - /* - ** Handle error case. - */ - if (status < ASSUCCESS) { - if (CCMessageBox().Process(TXT_ERROR_NO_INIT, TXT_IGNORE, TXT_CANCEL)) { - delete istr; - return( false ); - } - error_count++; - break; - } - - tokenptr = strtok ( NULL, "|"); - - } - } - /* - ** Use the settings from the registry to further initialise the modem - */ - if (settings->Port == 1 && ModemRegistry) { - /* - ** Send the init strings from the registry if available - */ - char send_string[256] = {"AT"}; - - if (settings->HardwareFlowControl){ - /* - ** Send the init string for hardware flow control - */ - if (ModemRegistry->Get_Modem_Hardware_Flow_Control()) { - strcpy (&send_string[2], ModemRegistry->Get_Modem_Hardware_Flow_Control()); - status = Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1); - if (status != MODEM_CMD_OK && status != MODEM_CMD_0) { - if (CCMessageBox().Process(TXT_NO_FLOW_CONTROL_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false); - } - } - }else{ - /* - ** Send the init string for no flow control - */ - if (ModemRegistry->Get_Modem_No_Flow_Control()) { - strcpy (&send_string[2], ModemRegistry->Get_Modem_No_Flow_Control()); - status = Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1); - if (status != MODEM_CMD_OK && status != MODEM_CMD_0) { - if (CCMessageBox().Process(TXT_NO_FLOW_CONTROL_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false); - } - } - } - - - /* - ** Send the string for data compresseion - */ - if (settings->Compression){ - - if (ModemRegistry->Get_Modem_Compression_Enable()) { - strcpy (&send_string[2], ModemRegistry->Get_Modem_Compression_Enable()); - Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1); - if (status != MODEM_CMD_OK && status != MODEM_CMD_0) { - if (CCMessageBox().Process(TXT_NO_COMPRESSION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false); - } - } - }else{ - - if (ModemRegistry->Get_Modem_Compression_Disable()) { - strcpy (&send_string[2], ModemRegistry->Get_Modem_Compression_Disable()); - Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1); - if (status != MODEM_CMD_OK && status != MODEM_CMD_0) { - if (CCMessageBox().Process(TXT_NO_COMPRESSION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false); - } - } - } - - - /* - ** Send the string for error correction - */ - if (settings->ErrorCorrection){ - - if (ModemRegistry->Get_Modem_Error_Correction_Enable()) { - strcpy (&send_string[2], ModemRegistry->Get_Modem_Error_Correction_Enable()); - Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1); - if (status != MODEM_CMD_OK && status != MODEM_CMD_0) { - if (CCMessageBox().Process(TXT_NO_ERROR_CORRECTION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false); - } - } - }else{ - if (ModemRegistry->Get_Modem_Error_Correction_Disable()) { - strcpy (&send_string[2], ModemRegistry->Get_Modem_Error_Correction_Disable()); - Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1); - if (status != MODEM_CMD_OK && status != MODEM_CMD_0) { - if (CCMessageBox().Process(TXT_NO_ERROR_CORRECTION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false); - } - } - } - - - } - /* - ** We require that auto-answer be disabled so turn it off now. - */ - status = Send_Modem_Command( "ATS0=0", '\r', buffer, 81, DEFAULT_TIMEOUT, INIT_COMMAND_RETRIES ); - if (status != MODEM_CMD_OK) { - if (CCMessageBox().Process(TXT_ERROR_NO_DISABLE, TXT_IGNORE, TXT_CANCEL)) return( false ); - error_count++; - } - - /* - ** If we had an unreasonable number of ignored errors then return failure - */ - if (error_count >= 3) { - CCMessageBox().Process(TXT_ERROR_TOO_MANY, TXT_OK); - return (false); - } - - return( true ); -} - - -/*************************************************************************** - * NullModemClass::Dial_Modem -- dials a number passed * - * * - * INPUT: * - * settings ptr to SerialSettings structure * - * * - * OUTPUT: * - * status DialStatus * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/02/1995 DRD : Created. * - *=========================================================================*/ -DialStatusType NullModemClass::Dial_Modem( char *string, DialMethodType method, bool reconnect ) -{ - -//Timer_Test(__LINE__, __FILE__); - - - int factor = SeenBuff.Get_Width()/320; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /*........................................................................ - Dialog variables - ........................................................................*/ - bool process = true; // process while true - - //int status; - int delay; - DialStatusType dialstatus; - - int x,y,width,height; // dialog dimensions - char buffer[80*3]; - - Input = 0; - - -//Timer_Test(__LINE__, __FILE__); - - - /* - ** Determine the dimensions of the text to be used for the dialog box. - ** These dimensions will control how the dialog box looks. - */ - if (reconnect) { - strcpy( buffer, Text_String( TXT_MODEM_CONNERR_REDIALING ) ); - } else { - strcpy( buffer, Text_String( TXT_DIALING ) ); - } - - -//Timer_Test(__LINE__, __FILE__); - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(buffer, SeenBuff.Get_Height(), width, height); - - int text_width = width; - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (SeenBuff.Get_Width() - width) / 2; - y = (SeenBuff.Get_Height() - height) / 2; - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1), - y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); - - -//Timer_Test(__LINE__, __FILE__); - - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - /* - ............................ Create the list ............................. - */ - Commands = &cancelbtn; - - -//Timer_Test(__LINE__, __FILE__); - - Commands->Flag_List_To_Redraw(); - - -//Timer_Test(__LINE__, __FILE__); - - - /* - ............................ Draw the dialog ............................. - */ - Hide_Mouse(); - if ( !reconnect ) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - } - - -//Timer_Test(__LINE__, __FILE__); - - - - Dialog_Box(x, y, width, height); - Draw_Caption(TXT_NONE, x, y, width); - - -//Timer_Test(__LINE__, __FILE__); - - - Fancy_Text_Print(buffer, SeenBuff.Get_Width()/2 - text_width/2, y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - -//Timer_Test(__LINE__, __FILE__); - - - CCDebugString ("C&C95 - About to draw buttons.\n"); - Commands->Draw_All(); - CCDebugString ("C&C95 - About to show mouse.\n"); - Show_Mouse(); - - -//Timer_Test(__LINE__, __FILE__); - - // start waiting - - //CCDebugString ("C&C95 - About to delay for 2 seconds.\n"); - //Delay(120); - //HMSetDialingMethod( Port, (int)method ); - CCDebugString ("C&C95 - About to set modem dial type.\n"); - SerialPort->Set_Modem_Dial_Type((WinCommDialMethodType) method); - - -//Timer_Test(__LINE__, __FILE__); - - //Clear out any old modem result codes - CCDebugString ("C&C95 - About to call 'Get_Modem_Result'.\n"); - SerialPort->Get_Modem_Result(60, buffer, 81); - //status = HMDial( Port, string ); - CCDebugString ("C&C95 - About to call 'SerialPort->Dial_Modem'.\n"); - SerialPort->Dial_Modem(string); - - -//Timer_Test(__LINE__, __FILE__); - - - // - // Sets up the ability to abort modem commands when any input is in the - // Keyboard buffer. This also calls the game CallBack(). - // - CCDebugString ("C&C95 - About to call 'Setup_Abort_Modem'.\n"); - Setup_Abort_Modem(); - - -//Timer_Test(__LINE__, __FILE__); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - process = true; - delay = ModemWaitCarrier; - CCDebugString ("C&C95 - About to enter main process loop.\n"); - while (process) { - - -//Timer_Test(__LINE__, __FILE__); - - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - CCDebugString ("C&C95 - About to restore video surfaces.\n"); - AllSurfaces.SurfacesRestored=FALSE; - Commands->Draw_All(); - } - -//Timer_Test(__LINE__, __FILE__); - - - //delay = HMInputLine( Port, delay, buffer, 81 ); - CCDebugString ("C&C95 - About to call 'Get_Modem_Result 2'.\n"); - - -//Timer_Test(__LINE__, __FILE__); - - - char abuffer [128]; - sprintf (abuffer, "C&C95 - ModemWaitCarrier delay = %d\n", delay); - CCDebugString (abuffer); - delay = SerialPort->Get_Modem_Result(delay, buffer, 81); - - - /* - ............................ Process input ............................ - */ - CCDebugString ("C&C95 - About to check for keyboard input.\n"); - if (!Input) Input = Commands->Input(); - - - switch (Input) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - dialstatus = DIAL_CANCELED; - process = false; - break; - - default: - break; - } - - if (process) { - if ( strncmp( buffer, "CON", 3 ) == 0 ) { - memset (ModemRXString, 0, 80); - strncpy (ModemRXString, buffer, 79); - dialstatus = DIAL_CONNECTED; - process = false; - } - else if ( strncmp( buffer, "BUSY", 4 ) == 0 ) { - dialstatus = DIAL_BUSY; - process = false; - } - else if ( strncmp( buffer, "NO C", 4 ) == 0 ) { - dialstatus = DIAL_NO_CARRIER; - process = false; - } - else if ( strncmp( buffer, "NO D", 4 ) == 0 ) { - dialstatus = DIAL_NO_DIAL_TONE; - process = false; - } - else if ( strncmp( buffer, "ERRO", 4 ) == 0 ) { - dialstatus = DIAL_ERROR; - process = false; - } - } - - if (delay <= 0) { - if (delay < 0) { - } - process = false; - } - } - - Remove_Abort_Modem(); - - return( dialstatus ); - -} /* end of Dial_Modem */ - - -/*************************************************************************** - * NullModemClass::Answer_Modem -- waits for call and answers * - * * - * INPUT: * - * reconnect whether this is to reconnect * - * * - * OUTPUT: * - * status DialStatus * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/02/1995 DRD : Created. * - *=========================================================================*/ -DialStatusType NullModemClass::Answer_Modem( bool reconnect ) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /*........................................................................ - Redraw values: in order from "top" to "bottom" layer of the dialog - ........................................................................*/ - typedef enum { - REDRAW_NONE = 0, - REDRAW_BUTTONS, - REDRAW_BACKGROUND, - REDRAW_ALL = REDRAW_BACKGROUND - } RedrawType; - - /*........................................................................ - Dialog variables - ........................................................................*/ - RedrawType display = REDRAW_ALL; // redraw level - bool process = true; // process while true - - //int status; - int delay; - DialStatusType dialstatus; - bool ring = false; - - int x,y,width,height; // dialog dimensions - char text_buffer[80*3]; - char comm_buffer[80*3]; - - int text_width; - - /* - ** Determine the dimensions of the text to be used for the dialog box. - ** These dimensions will control how the dialog box looks. - */ - if (reconnect) { - strcpy( text_buffer, Text_String( TXT_MODEM_CONNERR_WAITING ) ); - } else { - strcpy( text_buffer, Text_String( TXT_WAITING_FOR_CALL ) ); - } - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height); - - text_width = width; - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (SeenBuff.Get_Width() - width) / 2; - y = (SeenBuff.Get_Height() - height) / 2; - - TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, - TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, - x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1), - y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); - - /* - ------------------------------- Initialize ------------------------------- - */ - Set_Logic_Page(SeenBuff); - - //Load_Picture("TITLE.CPS", HidPage, HidPage, Palette, BM_DEFAULT); - - Input = 0; - - /* - ............................ Create the list ............................. - */ - Commands = &cancelbtn; - - Commands->Flag_List_To_Redraw(); - - // start waiting - - -// HMWaitForOK( 1000, NULL ); -// status = HMSendString( Port, "ATS0=1" ); - - - // - // Sets up the ability to abort modem commands when any input is in the - // Keyboard buffer. This also calls the game CallBack() and Input(). - // - Setup_Abort_Modem(); - - /* - -------------------------- Main Processing Loop -------------------------- - */ - process = true; - delay = 60000; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=REDRAW_ALL; - } - - /* - ...................... Refresh display if needed ...................... - */ - if (display) { - Hide_Mouse(); - if (display >= REDRAW_BACKGROUND) { - /* - ..................... Refresh the backdrop ...................... - */ - if ( !reconnect ) { - Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); - Blit_Hid_Page_To_Seen_Buff(); - } - /* - ..................... Draw the background ....................... - */ - Dialog_Box(x, y, width, height); - /* - ....................... Draw the labels ......................... - */ - Draw_Caption(TXT_NONE, x, y, width); - - Fancy_Text_Print(text_buffer, SeenBuff.Get_Width()/2 - text_width/2, y + 25*factor, CC_GREEN, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - Commands->Draw_All(); - } - Show_Mouse(); - display = REDRAW_NONE; - } - - //delay = HMInputLine( Port, delay, buffer, 81 ); - delay = SerialPort->Get_Modem_Result(delay, comm_buffer, 81); - - /* - ............................ Process input ............................ - */ - if (!Input) Input = Commands->Input(); - switch (Input) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): -// Sound_Effect(VOC_BUTTON,255); - dialstatus = DIAL_CANCELED; - process = false; - break; - - default: - break; - } - - if (process) { - if ( strncmp( comm_buffer, "RING", 4 ) == 0 ) { - - strcpy( text_buffer, Text_String( TXT_ANSWERING ) ); - - Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); - Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height); - - text_width = width; - width = MAX(width, 50*factor); - width += 40*factor; - height += 60*factor; - - x = (SeenBuff.Get_Width() - width) / 2; - y = (SeenBuff.Get_Height() - height) / 2; - - //PortKillTime( Port, 100 ); - - //HMWaitForOK( 0, NULL ); - //status = HMAnswer( Port ); - SerialPort->Write_To_Serial_Port ((unsigned char*)"ATA\r", strlen("ATA\r")); - - ring = true; - delay = ModemWaitCarrier; - display = REDRAW_ALL; - } - else if ( strncmp( comm_buffer, "CON", 3 ) == 0 ) { - memset (ModemRXString, 0, 80); - strncpy (ModemRXString, comm_buffer, 79); - dialstatus = DIAL_CONNECTED; - process = false; - } - else if ( strncmp( comm_buffer, "BUSY", 4 ) == 0 ) { - dialstatus = DIAL_BUSY; - process = false; - } - else if ( strncmp( comm_buffer, "NO C", 4 ) == 0 ) { - dialstatus = DIAL_NO_CARRIER; - process = false; - } - else if ( strncmp( comm_buffer, "NO D", 4 ) == 0 ) { - dialstatus = DIAL_NO_DIAL_TONE; - process = false; - } - else if ( strncmp( comm_buffer, "ERRO", 4 ) == 0 ) { - dialstatus = DIAL_ERROR; - CCMessageBox().Process ("Error - Modem returned error status.", TXT_OK); - process = false; - } - } - - if (delay <= 0) { - if (ring) { - if (SerialPort->Get_Modem_Status() & CD_SET){ - sprintf(ModemRXString, "%s", "Connected"); - dialstatus = DIAL_CONNECTED; - }else{ - dialstatus = DIAL_ERROR; - CCMessageBox().Process ("Error - TIme out waiting for connect.", TXT_OK); - } - process = false; - } else { - delay = 60000; - } - } - } - - Remove_Abort_Modem(); - - return( dialstatus ); - -} /* end of Answer_Modem */ - - -/*************************************************************************** - * NullModemClass::Hangup_Modem -- hangs up the modem * - * * - * INPUT: * - * none * - * * - * OUTPUT: * - * status successful or not * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/02/1995 DRD : Created. * - *=========================================================================*/ -bool NullModemClass::Hangup_Modem( void ) -{ - int status; - int delay; - char buffer[81]; - char escape[4]; - - /* - ** Turn modem servicing off in the callback routine. - */ - ModemService = false; - - - status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 ); - - if (status == MODEM_CMD_OK) { - ModemService = true; - return( true ); - } - - SerialPort->Set_Serial_DTR(FALSE); - Delay(3200/60); - SerialPort->Set_Serial_DTR(TRUE); - - //SetDtr( Port, 0 ); - //PortKillTime( Port, 3200 ); - //SetDtr( Port, 1 ); - - status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 ); - - if (status == MODEM_CMD_OK) { - ModemService = true; - return( true ); - } - - delay = ModemGuardTime; - while ( delay > 0 ) { - //delay = HMInputLine( Port, delay, buffer, 81 ); - delay = SerialPort->Get_Modem_Result(delay, buffer, 81); - - } - - escape[0] = ModemEscapeCode; - escape[1] = ModemEscapeCode; - escape[2] = ModemEscapeCode; - escape[3] = 0; - - //status = HMSendStringNoWait( Port, escape, -1 ); - SerialPort->Write_To_Serial_Port((unsigned char*)escape, 3); - - delay = ModemGuardTime; - while ( delay > 0 ) { - delay = SerialPort->Get_Modem_Result(delay, buffer, 81); - //delay = HMInputLine( Port, delay, buffer, 81 ); - - if ( strncmp( buffer, "OK", 2 ) == 0 ) { - break; - } - } - - status = Send_Modem_Command( "ATH", '\r', buffer, 81, ModemHangupDelay, 1 ); - - if (status == MODEM_CMD_OK) { - } else { - ModemService = true; - return( false ); - } - - status = Send_Modem_Command( "ATZ", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 ); - - if (status == MODEM_CMD_OK) { - } else { - ModemService = true; - return( false ); - } - - ModemService = true; - return( true ); - -} /* end of Hangup_Modem */ - - -/*********************************************************************************************** - * NMC::Setup_Modem_Echo -- Sets the echo callback function pointer * - * * - * * - * * - * INPUT: Ptr to callback function * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 12:48PM ST : Documented and added WIn32 support * - *=============================================================================================*/ -void NullModemClass::Setup_Modem_Echo( void ( *func )( char c) ) -{ - SerialPort->Set_Echo_Function(func); - //HMSetUpEchoRoutine( func ); - -} /* end of Setup_Modem_Echo */ - - -/*********************************************************************************************** - * NMC::Remove_Modem_Echo -- Set the echo function callback pointer to null * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 12:50PM ST : Documented / Win32 support added * - *=============================================================================================*/ -void NullModemClass::Remove_Modem_Echo( void ) -{ - SerialPort->Set_Echo_Function(NULL); - //HMSetUpEchoRoutine( NULL ); - -} /* end of Remove_Modem_Echo */ - - -/*********************************************************************************************** - * NMC::Print_EchoBuf -- Print out the contents of the echo buffer * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 12:51PM ST : Documented * - *=============================================================================================*/ -void NullModemClass::Print_EchoBuf( void ) -{ - for (int i = 0; i < strlen(NullModem.EchoBuf); i++) { - if (NullModem.EchoBuf[i] == '\r') { - NullModem.EchoBuf[i] = 1; - } else { - if (NullModem.EchoBuf[i] == '\n') { - NullModem.EchoBuf[i] = 2; - } - } - } -} - - -/*********************************************************************************************** - * NMC::Reset_EchoBuf -- Empties the echo buffer * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 12:51PM ST : Documented * - *=============================================================================================*/ -void NullModemClass::Reset_EchoBuf( void ) -{ - *EchoBuf = 0; - EchoCount = 0; -} - - -/*********************************************************************************************** - * NMC::Abort_Modem -- Checks for user input so that modem operations can be aborted * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: ASUSERABORT if abort key pressed. ASSUCESS otherwise. * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 12:52PM ST : Documented * - *=============================================================================================*/ -int NullModemClass::Abort_Modem(void) -//int NullModemClass::Abort_Modem( PORT * ) -{ - /*........................................................................ - Button Enumerations - ........................................................................*/ - enum { - BUTTON_CANCEL = 100, - }; - - /* - ........................ Invoke game callback ......................... - */ - Call_Back(); - - /* - ........................... Get user input ............................ - */ - Input = Commands->Input(); - - switch ( Input ) { - case (KN_ESC): - case (BUTTON_CANCEL | KN_BUTTON): - return( ASUSERABORT ); - } - - return( ASSUCCESS ); - -} /* end of Abort_Modem */ - - -/*********************************************************************************************** - * NMC::Setup_Abort_Modem -- sets the modem abort function pointer * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 2:59PM ST : Documented / Win32 support added * - *=============================================================================================*/ -void NullModemClass::Setup_Abort_Modem( void ) -{ - SerialPort->Set_Abort_Function((int(*)(void))Abort_Modem); -} /* end of Setup_Abort_Modem */ - - -/*********************************************************************************************** - * NMC::Remove_Abort_Modem -- Removes the modem abort function pointer * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 3:01PM ST : Documented / Win32 support added * - *=============================================================================================*/ -void NullModemClass::Remove_Abort_Modem( void ) -{ - SerialPort->Set_Abort_Function(NULL); -} /* end of Remove_Abort_Modem */ - - - -/*********************************************************************************************** - * NMC::Change_IRQ_Priority -- Increases the priority of the serial interrupt * - * * - * * - * * - * INPUT: Interrupt request number * - * * - * OUTPUT: ASSUCCESS if changed * - * * - * WARNINGS: The Win32 version of this function does nothing. * - * Priorities are controlled by windoze * - * * - * HISTORY: * - * 8/2/96 3:03PM ST : Documented / Win32 support added * - *=============================================================================================*/ -int NullModemClass::Change_IRQ_Priority( int ) -{ - return (ASSUCCESS); -} /* end of Change_IRQ_Priority */ - - -/*********************************************************************************************** - * NMC::Get_Modem_Status -- returns status of modem control bits * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Modem status * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 3:06PM ST : Documented / Win32 support added * - *=============================================================================================*/ -int NullModemClass::Get_Modem_Status( void ) -{ - int modemstatus; - int status; - char buffer[81]; - - //modemstatus = GetModemStatus( Port ); - modemstatus = SerialPort->Get_Modem_Status(); - - status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 ); - - if (status == MODEM_CMD_OK) { - modemstatus &= (~CD_SET); - } - - return( modemstatus ); - -} /* end of Get_Modem_Status */ - - -/*********************************************************************************************** - * NMC::Send_Modem_Command -- Sends an 'AT' command to the modem and gets the response * - * * - * * - * * - * INPUT: command to send to modem. e.g. 'ATZ' * - * terminator byte for command string * - * buffer to put modem response into * - * length of above buffer * - * delay to wait for response * - * number of times to retry when modem doesnt respond * - * * - * OUTPUT: input delay less the time it took the modem to respond * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 3:09PM ST : Documented / Win32 support added * - *=============================================================================================*/ -int NullModemClass::Send_Modem_Command( char *command, char terminator, char *buffer, int buflen, int delay, int retries ) -{ - return (SerialPort->Send_Command_To_Modem(command, terminator, buffer, buflen, delay, retries)); -} - - -/*********************************************************************************************** - * NMC::Verify_And_Convert_To_Int -- converts a text string of numbers to an int * - * * - * * - * * - * INPUT: ptr to buffer * - * * - * OUTPUT: value of text number in buffer * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 8/2/96 3:13PM ST : Documented * - *=============================================================================================*/ -int NullModemClass::Verify_And_Convert_To_Int( char *buffer ) -{ - int value = 0; - int len = strlen(buffer); - - - for (int i = 0; i < len; i++) { - if ( !isdigit( *(buffer + i) ) ) { - value = -1; - break; - } - } - - if (value == 0) { - value = atoi( buffer ); - } - - return( value ); - -} /* end of Verify_And_Convert_To_Int */ - -/*************************** end of nullmgr.cpp ****************************/ -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/NULLMGR.H b/code/TIBERIANDAWN/NULLMGR.H deleted file mode 100644 index 14ae347..0000000 --- a/code/TIBERIANDAWN/NULLMGR.H +++ /dev/null @@ -1,214 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\nullmgr.h_v 1.14 16 Oct 1995 16:45:26 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : CONNECT.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 3, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This is the Connection Manager for a NULL-Modem connection. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef NULLMODEM_H -#define NULLMODEM_H - - -/* -********************************* Includes ********************************** -*/ -#include "nullconn.h" -#include "connmgr.h" -#include "commlib.h" - -/* -***************************** Class Declaration ***************************** -*/ -class NullModemClass : public ConnManClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - enum SendModemEnum { - MODEM_CMD_TIMEOUT = 0, - MODEM_CMD_OK, - MODEM_CMD_0, - MODEM_CMD_ERROR - }; - - char *BuildBuf; - int MaxLen; - - char *EchoBuf; - int EchoSize; - int EchoCount; - - int OldIRQPri; - - bool ModemVerboseOn; - bool ModemEchoOn; - int ModemWaitCarrier; - int ModemCarrierDetect; - int ModemCarrierLoss; - int ModemHangupDelay; - int ModemGuardTime; - char ModemEscapeCode; - - static void (*OrigAbortModemFunc)(int); - static KeyNumType Input; - static GadgetClass *Commands; // button list - - /* - ** Constructor/destructor. - */ - NullModemClass (int numsend, int numreceive, int maxlen, unsigned short magicnum); - virtual ~NullModemClass (); - - /* - ** This is the main initialization routine. - */ - int Init( int port, int irq, char *dev_name, int baud, char parity, int wordlength, int stopbits, int flowcontrol ); - int Delete_Connection( void ); - virtual int Num_Connections(void); - virtual int Connection_ID(int ) {return (0);} - virtual int Connection_Index(int ) {return (0);} - int Init_Send_Queue( void ); - void Shutdown( void ); - - virtual void Set_Timing (unsigned long retrydelta, - unsigned long maxretries, unsigned long timeout); - - /* - ** This is how the application sends & receives messages. - */ - int Send_Message (void *buf, int buflen, int ack_req = 1); - int Get_Message (void *buf, int *buflen); - - /* - ** These are for compatibility - */ - virtual int Send_Private_Message (void *buf, int buflen, - int ack_req = 1, int = CONNECTION_NONE) - {return (Send_Message(buf,buflen,ack_req));} - virtual int Get_Private_Message (void *buf, int *buflen, int *) - {return (Get_Message(buf,buflen));} - - /* - ** The main polling routine; should be called as often as possible. - */ - virtual int Service (void); - - /* - ** Queue utility routines. The application can determine how many - ** messages are in the send/receive queues, and the queue's average - ** response time (in clock ticks). - */ - int Num_Send(void); - int Num_Receive(void); - virtual unsigned long Response_Time(void); - virtual void Reset_Response_Time(void); - void * Oldest_Send(void); - virtual void Configure_Debug(int index, int offset, int size, - char **names, int maxnames); - virtual void Mono_Debug_Print(int index, int refresh = 0); - - /* - ** These are for compatibility - */ - virtual int Global_Num_Send(void) {return (Num_Send());} - virtual int Global_Num_Receive(void) {return (Num_Receive());} - virtual int Private_Num_Send(int = CONNECTION_NONE) - {return (Num_Send());} - virtual int Private_Num_Receive(int = CONNECTION_NONE) - {return (Num_Receive());} - - DetectPortType Detect_Port( SerialSettingsType *settings ); - int Detect_Modem( SerialSettingsType *settings, bool reconnect = false ); - DialStatusType Dial_Modem(char *string, DialMethodType method, bool reconnect = false); - DialStatusType Answer_Modem(bool reconnect = false); - bool Hangup_Modem(void); - void Setup_Modem_Echo(void (*func)(char c)); - void Remove_Modem_Echo(void); - void Print_EchoBuf(void); - void Reset_EchoBuf(void); - //static int Abort_Modem(PORT *); - static int Abort_Modem(void); - void Setup_Abort_Modem(void); - void Remove_Abort_Modem(void); - - int Change_IRQ_Priority(int irq); - int Get_Modem_Status(void); - int Send_Modem_Command( char *command, char terminator, char *buffer, int buflen, int delay, int retries ); - int Verify_And_Convert_To_Int( char *buffer ); - - /* - ** Private Interface. - */ - private: - - /* - ** This is a pointer to the NULL-Modem Connection object. - */ - NullModemConnClass *Connection; - int NumConnections; // # connection objects in use - - /* - ** This is the Greenleaf port handle. - */ - PORT *Port; - HANDLE PortHandle; - - int NumSend; - int NumReceive; - unsigned short MagicNum; - - /* - ** This is the staging buffer for parsing incoming packets. - ** RXSize is the allocated size of the RX buffer. - ** RXCount is the # of characters we currently have in our buffer. - */ - char *RXBuf; - int RXSize; - int RXCount; - - /*..................................................................... - Timing parameters for all connections - .....................................................................*/ - unsigned long RetryDelta; - unsigned long MaxRetries; - unsigned long Timeout; - - /* - ** Various Statistics - */ - int SendOverflows; - int ReceiveOverflows; - int CRCErrors; -}; - -#endif diff --git a/code/TIBERIANDAWN/OBJECT.CPP b/code/TIBERIANDAWN/OBJECT.CPP deleted file mode 100644 index ce137f0..0000000 --- a/code/TIBERIANDAWN/OBJECT.CPP +++ /dev/null @@ -1,1712 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\object.cpv 2.17 16 Oct 1995 16:49:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OBJECT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : August 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ObjectClass::Debug_Dump -- Displays status of the object class to the mono monitor. * - * ObjectClass::Detach_All -- Removes the object from all tracking systems. * - * ObjectClass::Detach_This_From_All -- Detatches this object from all others. * - * ObjectClass::Fire_Out -- Informs object that attached animation has finished. * - * ObjectClass::Get_Mission -- Fetches the current mission of this object. * - * ObjectClass::Init -- Initializes the basic object system. * - * ObjectClass::Limbo -- Brings the object into a state of limbo. * - * ObjectClass::Mark -- Handles basic marking logic. * - * ObjectClass::Mark_For_Redraw -- Marks object and system for redraw. * - * ObjectClass::Move -- Moves (by force) the object in the desired direction. * - * ObjectClass::ObjectClass -- Default constructor for objects. * - * ObjectClass::Passive_Click_With -- Right mouse button click process. * - * ObjectClass::Receive_Message -- Processes an incoming radio message. * - * ObjectClass::Render -- Displays the object onto the map. * - * ObjectClass::Repair -- Handles object repair control. * - * ObjectClass::Revealed -- Reveals this object to the house specified. * - * ObjectClass::Select -- Try to make this object the "selected" object. * - * ObjectClass::Sell_Back -- Sells the object -- if possible. * - * ObjectClass::Take_Damage -- Applies damage to the object. * - * ObjectClass::Unlimbo -- Brings the object into the game system. * - * ObjectClass::Unselect -- This will un-select the object if it was selected. * - * ObjectClass::Value -- Fetches the target value of this object. * - * ObjectClass::What_Action -- Deteremines what action to perform on specified object. * - * ObjectClass::What_Am_I -- RTTI query of this object type. * - * ObjectTypeClass::Cost_Of -- Returns the cost to buy this unit. * - * ObjectTypeClass::Dimensions -- Gets the dimensions of the object in pixels. * - * ObjectTypeClass::Get_Cameo_Data -- Fetches pointer to cameo data for this object type. * - * ObjectTypeClass::Max_Pips -- Fetches the maximum pips allowed for this object. * - * ObjectTypeClass::ObjectTypeClass -- Normal constructor for object type class objects. * - * ObjectTypeClass::Occupy_List -- Returns with simple occupation list for object. * - * ObjectTypeClass::One_Time -- Handles one time processing for object types. * - * ObjectTypeClass::Overlap_List -- Returns a pointer to a simple overlap list. * - * ObjectTypeClass::Time_To_Build -- Fetches the time to construct this object. * - * ObjectTypeClass::Who_Can_Build_Me -- Finds the factory building that can build this object* - * ObjectClass::What_Action -- Returns with the action to perform for this object. * - * ObjectClass::In_Which_Layer -- Fetches what layer this object is located in. * - * ObjectClass::Is_Techno -- Checks to see if this object is a techno type. * - * ObjectClass::Get_Ownable -- Fetches the house owner legality options for this object. * - * ObjectClass::Can_Repair -- Queries whether this object can be repaired. * - * ObjectClass::Can_Demolish -- Queries whether this object can be sold back. * - * ObjectClass::Can_Player_Fire -- Can the player give this object an attack mission? * - * ObjectClass::Can_Player_Move -- Can the player give this object a movement mission? * - * ObjectClass::Target_Coord -- Fetches the coordinate if this object is a target. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -** Selected objects have a special marking box around them. This is the shapes that are -** used for this purpose. -*/ -void const * ObjectTypeClass::SelectShapes = 0; - -void const * ObjectTypeClass::PipShapes = 0; - - -bool ObjectClass::Is_Infantry(void) const -{ - return(false); -} - - - -/*********************************************************************************************** - * ObjectTypeClass::ObjectTypeClass -- Normal constructor for object type class objects. * - * * - * This is the base constructor that is used when constructing the object type classes. * - * Every tangible game piece type calls this constructor for the ObjectTypeClass. This * - * class holds static information that is common to objects in general. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/23/1995 JLB : Created. * - *=============================================================================================*/ -ObjectTypeClass::ObjectTypeClass( - bool is_sentient, - bool is_flammable, - bool is_crushable, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - int name, - char const *ini, - ArmorType armor, - unsigned short strength) : - AbstractTypeClass(name, ini) -{ - IsSentient = is_sentient; - IsFlammable = is_flammable; - IsCrushable = is_crushable; - IsStealthy = is_stealthy; - IsSelectable = is_selectable; - IsLegalTarget = is_legal_target; - IsInsignificant = is_insignificant; - IsImmune = is_immune; - Armor = armor; - MaxStrength = strength; - ImageData = NULL; - //RadarIcon = NULL; -} - - -/*********************************************************************************************** - * ObjectTypeClass::Max_Pips -- Fetches the maximum pips allowed for this object. * - * * - * This routine will return the maximum number of pips that can be displayed for this * - * object. When dealing with generic objects, this value is always zero. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of pip boxes (empty or otherwise) to display. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -int ObjectTypeClass::Max_Pips(void) const -{ - return(0); -} - - -/*********************************************************************************************** - * ObjectTypeClass::Dimensions -- Gets the dimensions of the object in pixels. * - * * - * This routine will fetch the dimensions of this object expressed as pixels width and * - * pixels height. This information can be used to intelligently update the clipping * - * rectangles. * - * * - * INPUT: width -- Reference to the width variable that will be filled in. * - * * - * height -- Reference to the height variable that will be filled in. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -void ObjectTypeClass::Dimensions(int &width, int &height) const -{ - width = 10; - height = 10; -} - - -/*********************************************************************************************** - * ObjectTypeClass::Cost_Of -- Returns the cost to buy this unit. * - * * - * This routine will return the cost to purchase this unit. This routine is expected to be * - * overridden by the objects that can actually be purchased. All other object types can * - * simply return zero since this value won't be used. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the cost of the object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -int ObjectTypeClass::Cost_Of(void) const -{ - return(0); -} - - -/*********************************************************************************************** - * ObjectTypeClass::Time_To_Build -- Fetches the time to construct this object. * - * * - * This routine will fetch the time in takes to construct this object. Objects that can * - * be constructed will override this routine in order to return a useful value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the time units (arbitrary) that it takes to construct this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -int ObjectTypeClass::Time_To_Build(HousesType ) const -{ - return(0); -} - - -/*********************************************************************************************** - * ObjectTypeClass::Who_Can_Build_Me -- Finds the factory building that can build this object. * - * * - * This routine will search for a factory building that can build this object type. * - * * - * INPUT: this routine is just here to be overridden by other classes. * - * * - * OUTPUT: Returns with a pointer to the building that can construct the object specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -BuildingClass * ObjectTypeClass::Who_Can_Build_Me(bool, bool, HousesType) const -{ - return(NULL); -} - - -/*********************************************************************************************** - * ObjectTypeClass::Get_Cameo_Data -- Fetches pointer to cameo data for this object type. * - * * - * This routine will return with the cameo data pointer for this object type. It is * - * expected that objects that can appear on the sidebar will override this routine in order * - * to provide proper cameo data pointer. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the cameo shape data. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -void const * ObjectTypeClass::Get_Cameo_Data(void) const -{ - return(NULL); -} - - - -/*********************************************************************************************** - * ObjectClass::ObjectClass -- Default constructor for objects. * - * * - * This is the default constructor for objects. It is called as an inherent part of the * - * construction process for all the normal game objects instantiated. It serves merely to * - * initialize the object values to a common (default) state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Objects always start in a state of limbo. They must be Unlimbo()ed before they * - * can be used. * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass::ObjectClass(void) -{ - Coord = 0xFFFFFFFFL; // Some bogus illegal value. - Next = 0; // Not part of any object list. - Trigger = 0; // No associated trigger. - IsToDamage = false; - IsToDisplay = false; // Redraw is presumed unnecessary. - IsInLimbo = true; // Always presumed to start in limbo state. - IsSelected = false; // Limboed units cannot be selected. - IsDown = false; // Limboed units cannot be on the map. - IsAnimAttached = false; // Anim is not attached. - Strength = 255; // nominal strength value - IsSelectedMask = 0; // Mask showing who has selected this object -} - - -/*********************************************************************************************** - * ObjectClass::What_Am_I -- RTTI query of this object type. * - * * - * This routine will never be called, but is here for completeness. Every object that * - * is derived from object class must overload this function and return their own proper * - * object RTTI value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the RTTI value that coresponds to the object's type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -RTTIType ObjectClass::What_Am_I(void) const -{ - return(RTTI_OBJECT); -} - - -/*********************************************************************************************** - * ObjectClass::What_Action -- Deteremines what action to perform on specified object. * - * * - * This routine will return that action that this object could perform if the mouse were * - * clicked over the object specified. * - * * - * INPUT: object -- Pointer to the object to check this object against when determining * - * the action to perform. * - * * - * OUTPUT: It returns that action that will be performed if the mouse were clicked over the * - * object. Since non-derived objects cannot do anything, and cannot even be * - * instantiated, this routine will always return ACTION_NONE. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -ActionType ObjectClass::What_Action(ObjectClass *) const -{ - return(ACTION_NONE); -} - - -/*********************************************************************************************** - * ObjectClass::What_Action -- Returns with the action to perform for this object. * - * * - * This routine is called when information on a potential action if the mouse were clicked * - * on the cell specified. This routine merely serves as a virtual placeholder so that * - * object types that can actually perform some action will override this routine to provide * - * true functionality. * - * * - * INPUT: cell -- The cell that the mouse is over and might be clicked on. * - * * - * OUTPUT: Returns with the action that this object would try to perform if the mouse were * - * clicked. Since objects at this level have no ability to do anything, this routine * - * will always returns ACTION_NONE unless it is overridden. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -ActionType ObjectClass::What_Action(CELL) const -{ - return(ACTION_NONE); -} - - -/*********************************************************************************************** - * ObjectClass::In_Which_Layer -- Fetches what layer this object is located in. * - * * - * The default layer for object location is the LAYER_GROUND. Aircraft will override this * - * routine and make adjustments as necessary according to the aircraft's altitude. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the layer that this object is located in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -LayerType ObjectClass::In_Which_Layer(void) const -{ - return(LAYER_GROUND); -} - - -/*********************************************************************************************** - * ObjectClass::Is_Techno -- Checks to see if this object is a techno type. * - * * - * Most active objects in the game are of the techno type. This routine will return true * - * if called on an object that is derived from TechnoClass. The RTTI interface is * - * insufficient for this purpose -- hence the existence of this routine. * - * * - * INPUT: none * - * * - * OUTPUT: Is this object derived from the TechnoClass object? This is true for units, * - * infantry, aircraft, and buildings. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Is_Techno(void) const -{ - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Get_Ownable -- Fetches the house owner legality options for this object. * - * * - * This routine will return the ownable bits for this object. Objects at this level can't * - * really be owned by anyone, but return the full spectrum of legality just to be safe. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the ownable flags (as a combined bitfield) for this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -unsigned char ObjectClass::Get_Ownable(void) const -{ - return(0xff); -} - - -/*********************************************************************************************** - * ObjectClass::Can_Repair -- Queries whether this object can be repaired. * - * * - * Most objects cannot be repaired. This routine defaults to returning "false", but is * - * overridden by derived functions defined by object types that can support repair. * - * * - * INPUT: none * - * * - * OUTPUT: Can this object be repaired? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Can_Repair(void) const -{ - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Can_Demolish -- Queries whether this object can be sold back. * - * * - * This routine is used to determine if this object can be sold. Most objects cannot be * - * but for those objects that can, this routine will be overridden as necessary. * - * * - * INPUT: none * - * * - * OUTPUT: Can this object be sold back? Typically, the answer is no. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Can_Demolish(void) const -{ - return(false); -} - - -bool ObjectClass::Can_Demolish_Unit(void) const -{ - return(false); -} - - -bool ObjectClass::Can_Capture(void) const -{ - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Can_Player_Fire -- Can the player give this object an attack mission? * - * * - * This routine is used to determine if attacking is an option under player control with * - * respect to this unit. This routine will be overridden as necessary for those objects * - * that have the ability to attack. * - * * - * INPUT: none * - * * - * OUTPUT: Can this object be given an attack order by the player? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Can_Player_Fire(void) const -{ - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Can_Player_Move -- Can the player give this object a movement mission? * - * * - * This routine is used to determine if the player has the ability to command this object * - * with a movement mission. This routine will be overridden as necessary to support this * - * ability. * - * * - * INPUT: none * - * * - * OUTPUT: Can this object be given a movement mission by the player? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Can_Player_Move(void) const -{ - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Target_Coord -- Fetches the coordinate if this object is a target. * - * * - * When the coordinate to use when firing at this object is needed, this routine will * - * provide it. Normal objects just use the center of the object for this, but there are * - * some more sophisticated objects that are not fired upon the center. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate to fire at if this object is a target. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE ObjectClass::Target_Coord(void) const -{ - return(Center_Coord()); -} - -COORDINATE ObjectClass::Center_Coord(void) const {return Coord;}; -COORDINATE ObjectClass::Render_Coord(void) const {return(Center_Coord());} -COORDINATE ObjectClass::Docking_Coord(void) const {return(Center_Coord());} -COORDINATE ObjectClass::Sort_Y(void) const {return Coord;}; -COORDINATE ObjectClass::Fire_Coord(int ) const {return Coord;}; -void ObjectClass::Record_The_Kill(TechnoClass * ) {}; -void ObjectClass::Do_Shimmer(void) {}; -int ObjectClass::Exit_Object(TechnoClass *) {return 0;}; -void ObjectClass::Hidden(void) {}; -void ObjectClass::Look(bool ) {}; -void ObjectClass::Active_Click_With(ActionType , ObjectClass *) {}; -void ObjectClass::Active_Click_With(ActionType , CELL ) {}; -void ObjectClass::Clicked_As_Target(HousesType house, int) {}; // 2019/09/20 JAS - Added record of who clicked on the object -bool ObjectClass::In_Range(COORDINATE , int) const {return false;}; -int ObjectClass::Weapon_Range(int) const {return 0x0000;}; -TARGET ObjectClass::As_Target(void) const {return TARGET_NONE;}; -void ObjectClass::Scatter(COORDINATE , bool, bool) {}; -bool ObjectClass::Catch_Fire(void) {return false;}; - - -/*********************************************************************************************** - * ObjectClass::Fire_Out -- Informs object that attached animation has finished. * - * * - * This routine is called if there is an attached animation on this object and that * - * animation has finished. Typically, this is necessary for when trees are on fire. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Fire_Out(void) -{ -} - - -/*********************************************************************************************** - * ObjectClass::Value -- Fetches the target value of this object. * - * * - * This routine will return the target value of this object. The higher the number, the * - * better the object will be as a target. This routine is called when searching for * - * targets. Generic objects have no target potential, and this routine returns zero to * - * reflect that. Other object types will override this routine to return the appropriate * - * target value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the value of this object as a target. Higher values mean better * - * target. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -int ObjectClass::Value(void) const -{ - return(0); -} - - -/*********************************************************************************************** - * ObjectClass::Get_Mission -- Fetches the current mission of this object. * - * * - * Generic objects don't have a mission, so this routine will just return MISSION_NONE. * - * However, techno objects do have a mission and this routine is overloaded to handle * - * those objects in order to return the correct mission value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current mission being followed by this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -MissionType ObjectClass::Get_Mission(void) const -{ - return(MISSION_NONE); -} - - -/*********************************************************************************************** - * ObjectClass::Repair -- Handles object repair control. * - * * - * This routine will control object repair mode. At the object level, no repair is * - * possible, so it is expected that any object that can repair will override this function * - * as necessary. * - * * - * INPUT: control -- The repair control parameter. * - * 0 = turn repair off * - * 1 = turn repair on * - * -1 = toggle repair state * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Repair(int ) -{ -} - - -/*********************************************************************************************** - * ObjectClass::Sell_Back -- Sells the object -- if possible. * - * * - * This routine is called to sell back the object. Override this routine for the more * - * sophisticated objects that can actually be sold back. Normal objects can't be sold and * - * this routine does nothing as a consequence. * - * * - * INPUT: control -- How to control the sell state of this object. * - * 0 = stop selling. * - * 1 = start selling. * - * -1 = toggle selling state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Sell_Back(int ) -{ -} - - -/*********************************************************************************************** - * ObjectClass::Move -- Moves (by force) the object in the desired direction. * - * * - * This routine will instantly move the object one cell in the specified direction. It * - * moves the object by force. This is typically ONLY used by the scenario editor * - * process. * - * * - * INPUT: facing -- The direction to move the object. * - * * - * OUTPUT: none * - * * - * WARNINGS: Naturally, this can cause illegal placement situations -- use with caution. * - * * - * HISTORY: * - * 06/19/1994 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Move(FacingType facing) -{ - COORDINATE coord; - - Mark(MARK_UP); - coord = Adjacent_Cell(Coord, facing); - if (Can_Enter_Cell(Coord_Cell(coord)) == MOVE_OK) { - Coord = coord; - } - Mark(MARK_DOWN); -} - -// Object selection list is switched with player context for GlyphX. ST - 4/17/2019 9:42AM -extern void Logic_Switch_Player_Context(ObjectClass *object); - -/*********************************************************************************************** - * ObjectClass::Unselect -- This will un-select the object if it was selected. * - * * - * This routine brings a currently selected object into an unselected state. This is * - * needed when another object becomes selected as well as if the object is destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1994 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Unselect(void) -{ - //if (IsSelected) { - // Updated to function for multiplayer - 6/26/2019 JAS - if (Is_Selected_By_Player()) { - - if (In_Which_Layer()==LAYER_GROUND){ - Mark(MARK_OVERLAP_UP); - } - - //IsSelected = false; - // Updated to function for multiplayer - 6/26/2019 JAS - Set_Unselected_By_Player(); - - if (In_Which_Layer()==LAYER_GROUND){ - Mark(MARK_OVERLAP_DOWN); - } - } -} - -/*********************************************************************************************** - * ObjectClass::Unselect_All_Players -- This will un-select the object if it was selected * -* from all players * - * * - * This routine brings a currently selected object into an unselected state for all players.* -* This is needed when the object is destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/2019 JAS : Created. * - *=============================================================================================*/ -void ObjectClass::Unselect_All_Players(void) -{ - CurrentObject.Delete_All(this); - - if (In_Which_Layer() == LAYER_GROUND) { - Mark(MARK_OVERLAP_UP); - } - - IsSelected = false; - IsSelectedMask = 0; - - if (In_Which_Layer() == LAYER_GROUND) { - Mark(MARK_OVERLAP_DOWN); - } -} - -/*********************************************************************************************** - * ObjectClass::Unselect_All_Players_Except_Owner -- This will un-select the object if it was * -* selected for all players except for the object's owner * - * * - * This routine brings a currently selected object into an unselected state for all players.* -* This is needed when the object cloaks. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/28/2019 JAS : Created. * - *=============================================================================================*/ -void ObjectClass::Unselect_All_Players_Except_Owner(void) -{ - CurrentObject.Delete_All_Except(this, Owner()); - - if (In_Which_Layer() == LAYER_GROUND) { - Mark(MARK_OVERLAP_UP); - } - - int owner_mask = 1 << Owner(); - if (IsSelectedMask & owner_mask) - { - IsSelected = true; - IsSelectedMask = owner_mask; - } - else - { - IsSelected = false; - IsSelectedMask = 0; - } - - if (In_Which_Layer() == LAYER_GROUND) { - Mark(MARK_OVERLAP_DOWN); - } -} - - -/*********************************************************************************************** - * ObjectClass::Select -- Try to make this object the "selected" object. * - * * - * This routine is used to make this object into the one that is "selected". A selected * - * object usually displays a floating bar graph and is available to be given orders from * - * the player's I/O. * - * * - * INPUT: allow_mixed -- Allow a mix of player and non-player controlled units? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1994 JLB : Created. * - * 06/12/1995 JLB : Cannot select a loaner object. * - * 07/23/1995 JLB : Adds to head or tail depending on leader type flag. * - *=============================================================================================*/ -bool ObjectClass::Select(bool allow_mixed) -{ - // if (!Debug_Map && (IsSelected || !Class_Of().IsSelectable)) return(false); - // Updated to function for multiplayer - 6/26/2019 JAS - if (!Debug_Map && (Is_Selected_By_Player() || !Class_Of().IsSelectable)) return(false); - - if (Can_Player_Move() && Is_Techno() && ((TechnoClass *)this)->IsALoaner) return(false); - - /* - ** Don't allow selection of object when in building placement mode. - */ - if (Map.PendingObject) return(false); - - if (!allow_mixed) { - /* - ** If selecting an object of a different house than the player's, make sure that - ** the entire selection list is cleared. - */ - for (int i = 0; i < CurrentObject.Count(); i++) { - if (Owner() != CurrentObject[i]->Owner()) { - Unselect_All(); - break; - } - } - } - - if (In_Which_Layer()==LAYER_GROUND){ - Mark(MARK_OVERLAP_UP); - } - - //IsSelected = true; - // Updated to function for multiplayer - 6/26/2019 JAS - Set_Selected_By_Player(); - - if (In_Which_Layer()==LAYER_GROUND){ - Mark(MARK_OVERLAP_DOWN); - } - return(true); -} - - -/*********************************************************************************************** - * ObjectClass::Render -- Displays the object onto the map. * - * * - * This routine will determine the location of the object and if it is roughly on the * - * visible screen, it will display it. Not displaying objects that are not on the screen * - * will save valuable time. * - * * - * INPUT: bool; Should the render be forced regardless of whether the object is flagged to * - * be redrawn? * - * * - * OUTPUT: bool; Was the draw code called for this object? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1994 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Render(bool forced) -{ - int x,y; - COORDINATE coord = Render_Coord(); - CELL cell = Coord_Cell(coord); - - if (Debug_Map || Debug_Unshroud || ((forced || IsToDisplay) && IsDown && !IsInLimbo)) { - IsToDisplay = false; - - /* - ** Draw the path as lines on the map if so directed and the object is one that - ** contains a path. - */ - - //if (Special.IsShowPath && IsSelected) { - // Updated to function for multiplayer - 6/26/2019 JAS - if (Special.IsShowPath && Is_Selected_By_Player()) { - switch (What_Am_I()) { - case RTTI_INFANTRY: - case RTTI_UNIT: - FootClass * foot = (FootClass *)this; - CELL cell; - int oldx, oldy; - - if (foot->Head_To_Coord() && foot->Path[0] != FACING_NONE) { - cell = Adjacent_Cell(Coord_Cell(foot->Head_To_Coord()), (FacingType)((foot->Path[0] + FACING_S) & FACING_NW)); - Map.Coord_To_Pixel(Cell_Coord(cell), oldx, oldy); - for (int index = 0; index < MAX_PATH; index++) { - if (foot->Path[index] == FACING_NONE) break; - cell = Adjacent_Cell(cell, foot->Path[index]); - if (Map.Coord_To_Pixel(Cell_Coord(cell), x, y)) { - LogicPage->Draw_Line(oldx, 8+oldy, x, 8+y, BLACK); - } - oldx = x; - oldy = y; - } - } - break; - } - } - - if (Map.Coord_To_Pixel(coord, x, y)) { - - /* - ** Draw the object itself - */ - Draw_It(x, y, WINDOW_TACTICAL); - -#ifdef SCENARIO_EDITOR - /* - ** Draw the trigger attached to the object. Draw_It is window- - ** relative, so add the window's x-coord to 'x'. - */ - if (Debug_Map && Trigger) { - Fancy_Text_Print(Trigger->Get_Name(), x + (WinX<<3), y, PINK, TBLACK, TPF_CENTER | TPF_NOSHADOW | TPF_6POINT); - } -#endif - - return(true); - } - } - return(false); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * ObjectClass::Debug_Dump -- Displays status of the object class to the mono monitor. * - * * - * This routine is used to display the current status of the object class to the mono * - * monitor. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Debug_Dump(MonoClass *mono) const -{ - mono->Text_Print("X", 16 + (IsToDisplay?2:0), 18); - mono->Text_Print("X", 16 + (IsActive?2:0), 3); - mono->Text_Print("X", 16 + (IsInLimbo?2:0), 4); - //mono->Text_Print("X", 16 + (IsSelected?2:0), 7); - // Updated to function for multiplayer - 6/26/2019 JAS - mono->Text_Print("X", 16 + (Is_Selected_By_Player() ?2:0), 7); - mono->Set_Cursor(56, 1); - mono->Printf("%08lX", Coord); - mono->Set_Cursor(14, 1);mono->Printf("[%04X]", As_Target()); - mono->Set_Cursor(20, 3);mono->Printf("%2d[%d]", Strength, Class_Of().MaxStrength); -} -#endif - - -/*********************************************************************************************** - * ObjectTypeClass::Occupy_List -- Returns with simple occupation list for object. * - * * - * This routine returns a pointer to a simple occupation list for this object. Since at * - * this tier of the object class chain, the exact shape of the object is indeterminate, * - * this function merely returns a single cell occupation list. This actually works for * - * most vehicles. * - * * - * INPUT: none * - * * - * OUTPUT: Returns a pointer to a simple occupation list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -short const * ObjectTypeClass::Occupy_List(bool) const -{ - static short const _list[] = {0, REFRESH_EOL}; - return(_list); -} - - -/*********************************************************************************************** - * ObjectTypeClass::Overlap_List -- Returns a pointer to a simple overlap list. * - * * - * This function returns a pointer to an overlap list for the object. An overlap list is * - * the offsets from the object's cell to get the cells the imagery overlaps, but is object * - * is not considered to occupy. Since at this stage, the overlap information is not * - * available, this function merely returns a pointer to an empty list. * - * * - * INPUT: none * - * * - * OUTPUT: Returns a pointer to the generic overlap list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -short const * ObjectTypeClass::Overlap_List(void) const -{ - static short const _list[] = {REFRESH_EOL}; - return(_list); -} - - -/*********************************************************************************************** - * ObjectTypeClass::One_Time -- Handles one time processing for object types. * - * * - * This routine is used to handle the once per game processing required for object types. * - * This consists of loading any data and initializing any data tables the game requires. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine goes to disk. * - * * - * HISTORY: * - * 11/01/1994 JLB : Created. * - *=============================================================================================*/ -void ObjectTypeClass::One_Time(void) -{ - SelectShapes = MixFileClass::Retrieve("SELECT.SHP"); -#if (FRENCH) - PipShapes = Hires_Retrieve("PIPS_F.SHP"); -#else -#if (GERMAN) - PipShapes = Hires_Retrieve("PIPS_G.SHP"); -#else - PipShapes = Hires_Retrieve("PIPS.SHP"); -#endif -#endif -} - - -/*********************************************************************************************** - * ObjectClass::Mark_For_Redraw -- Marks object and system for redraw. * - * * - * This routine will mark the object and inform the display system * - * that appropriate rendering is needed. Whenever it is determined * - * that an object needs to be redrawn, call this routine. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This is a subordinate function to the function Mark(). If an object needs to * - * be redrawn it is probably better to call the function Mark(MARK_CHANGE) rather * - * than this function. This function does not inform the map system that * - * overlapping objects are to be redrawn and thus unless you are really sure that * - * this routine should be called, don't. * - * * - * HISTORY: * - * 05/08/1994 JLB : Created. * - * 12/23/1994 JLB : Flags map and flags unit only. * - *=============================================================================================*/ -void ObjectClass::Mark_For_Redraw(void) -{ - if (!IsToDisplay) { - IsToDisplay = true; - - /* - ** This tells the map rendering logic to "go through the motions" and call the - ** rendering function. In the rendering function, it will sort out what gets - ** rendered and what doesn't. - */ - Map.Flag_To_Redraw(false); - } -} - - -/*********************************************************************************************** - * ObjectClass::Limbo -- Brings the object into a state of limbo. * - * * - * An object brought into a state of limbo by this routine can be safely deleted. This * - * routine will remove the object from all game lists and tracking systems. It is called * - * prior to deleting the object or placing the object "on ice". * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the object successfully placed in limbo? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Limbo(void) -{ - if (GameActive && !IsInLimbo) { - - //Unselect(); - // Updated to function for multiplayer - 6/26/2019 JAS - Unselect_All_Players(); - - Detach_All(); - Mark(MARK_UP); - - /* - ** Remove the object from the appropriate display list. - */ - Map.Remove(this, In_Which_Layer()); - - /* - ** Remove the object from the logic processing list. - */ - if (Class_Of().IsSentient) { - Logic.Delete(this); - } - - Hidden(); - IsInLimbo = true; - IsToDisplay = false; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Unlimbo -- Brings the object into the game system. * - * * - * This routine will place the object into the game tracking and display systems. It is * - * called as a consequence of creating the object. Every game object must be unlimboed at * - * some point. * - * * - * INPUT: coord -- The coordinate to place the object into the game system. * - * * - * dir (optional) -- initial facing direction for this object * - * * - * OUTPUT: bool; Was the game object successfully unlimboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - * 12/23/1994 JLB : Sets object strength. * - *=============================================================================================*/ -bool ObjectClass::Unlimbo(COORDINATE coord, DirType ) -{ - if (GameActive && IsInLimbo && !IsDown) { - if (ScenarioInit || Can_Enter_Cell(Coord_Cell(coord), FACING_NONE) == MOVE_OK) { - IsInLimbo = false; - IsToDisplay = false; - Coord = Class_Of().Coord_Fixup(coord); - - if (Mark(MARK_DOWN)) { - if (IsActive) { - - /* - ** Add the object to the appropriate map layer. This layer is used - ** for rendering purposes. - */ - if (In_Which_Layer() != LAYER_NONE) { - Map.Submit(this, In_Which_Layer()); - } - - if (Class_Of().IsSentient) { - Logic.Submit(this); - } - } - return(true); - } - } - } - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Detach_All -- Removes the object from all tracking systems. * - * * - * This routine will take the object and see that it is removed from all miscellaneous * - * tracking systems in the game. This operation is vital when deleting an object. It is * - * necessary so that when the object is removed from the game, existing game objects won't * - * be referencing a now invalid game object. This typically affects the targeting * - * and navigation computers of other game objects. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Detach_All(bool all) -{ - /* - ** Unselect this object if it was selected. - */ - //if (all || Owner() != PlayerPtr->Class->House) { - // Unselect(); - //} - - //Added some error handling incase there was an issue removing the object - JAS 6/28/2019 - if (all) { - //Unselect(); - // Updated to function for multiplayer - 6/28/2019 JAS - Unselect_All_Players(); - } - else - { - Unselect_All_Players_Except_Owner(); - } - //End of change - JAS 6/28/2019 - - Map.Detach(this); - - /* - ** Remove from targeting computers. - */ - Detach_This_From_All(As_Target(), all); -} - - -/*********************************************************************************************** - * ObjectClass::Detach_This_From_All -- Detatches this object from all others. * - * * - * This routine sweeps through all game objects and makes sure that it is no longer * - * referenced by them. Typically, this is called in preparation for the object's death * - * or limbo state. * - * * - * INPUT: target -- This object expressed as a target number. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Detach_This_From_All(TARGET target, bool all) -{ - int index; - if (Target_Legal(target)) { - - for (index = 0; index < Houses.Count(); index++) { - Houses.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Teams.Count(); index++) { - Teams.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Units.Count(); index++) { - Units.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Infantry.Count(); index++) { - Infantry.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Aircraft.Count(); index++) { - Aircraft.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Buildings.Count(); index++) { - Buildings.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Bullets.Count(); index++) { - Bullets.Ptr(index)->Detach(target, all); - } - for (index = 0; index < Anims.Count(); index++) { - Anims.Ptr(index)->Detach(target, all); - } - } -} - - -/*********************************************************************************************** - * ObjectClass::Receive_Message -- Processes an incoming radio message. * - * * - * Any radio message received that applies to objects in general are handled by this * - * routine. Typically, this is the "redraw" message, which occurs when another object is * - * loading or unloading and thus overlapping. * - * * - * INPUT: message -- The message received. * - * * - * OUTPUT: Returns with the appropriate radio response. If the message was recognized, then * - * RADIO_ROGER is returned, otherwise, just RADIO_STATIC is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -RadioMessageType ObjectClass::Receive_Message(RadioClass *, RadioMessageType message, long & ) -{ - switch (message) { - - /* - ** This message serves as a rendering convenience. It lets the system - ** know that there might be a visual conflict and the unit in radio - ** contact should be redrawn. This typically occurs when a vehicle - ** is being unloaded from a hover lander. - */ - case RADIO_REDRAW: - Mark(MARK_CHANGE); - return(RADIO_ROGER); - - default: - break; - } - return(RADIO_STATIC); -} - - -/*********************************************************************************************** - * ObjectClass::Take_Damage -- Applies damage to the object. * - * * - * This routine applies damage to the object according to the damage parameters. It handles * - * reducing the strength of the object and also returns the result of that damage. The * - * result value can be examined to determine if the object was destroyed, greatly damaged, * - * or other results. * - * * - * INPUT: damage -- Reference to the damage number to apply. This number will be adjusted * - * according to defensive armor and distance. Examine this value after * - * the call to determine the actual amount of damage applied. * - * * - * distance -- The distance (in leptons) from the center of the damage causing * - * explosion to the object itself. * - * * - * warhead -- The warhead type that is causing the damage. * - * * - * OUTPUT: Returns the ResultType that indicates what the affect of the damage was. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/29/1994 JLB : Created. * - * 12/27/1994 JLB : Trigger event processing for attacked or destroyed. * - * 01/01/1995 JLB : Reduces damage greatly depending on range. * - *=============================================================================================*/ -ResultType ObjectClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - ResultType result = RESULT_NONE; - int oldstrength = Strength; - - if (oldstrength && damage && !Class_Of().IsImmune) { - int maxstrength = Class_Of().MaxStrength; - - /* - ** Modify damage based on the warhead type and the armor of the object. This results - ** in a reduced damage value, but never below 1 damage point. - */ - damage = Modify_Damage(damage, warhead, Class_Of().Armor, distance); - if (!damage) return(RESULT_NONE); - - /* - ** At this point, we KNOW that at least light damage has occurred. - */ - result = RESULT_LIGHT; - - /* - ** A non-fatal blow has occurred. Check to see if the object transitioned to below - ** half strength or if it is now down to one hit point. - */ - if (oldstrength > damage) { - - if (oldstrength >= (maxstrength >> 1) && (oldstrength-damage) < (maxstrength >> 1)) { - result = RESULT_HALF; - } - } else { - - /* - ** When an object is damaged to destruction, it will instead stop at one - ** damage point. This will prolong the damage state as well as - ** give greater satisfaction when it is finally destroyed. - */ - damage = oldstrength; - } - - /* - ** Apply the damage to the object. - */ - Strength = oldstrength - damage; - - /* - ** Check to see if the object is majorly damaged or destroyed. - */ - switch (Strength) { - case 0: - Record_The_Kill(source); - result = RESULT_DESTROYED; - Detach_All(); - break; - - case 1: - result = RESULT_MAJOR; - break; - - default: - break; - } - - /* - ** Handle any trigger event associated with this object. - */ - if (source && Trigger && result != RESULT_DESTROYED) { - Trigger->Spring(EVENT_ATTACKED, this); - } - - /* - ** If any damage was assessed and this object is selected, then flag - ** the object to be redrawn so that the health bar will be updated. - */ - //if (result != RESULT_NONE && IsSelected) { - // Updated to function for multiplayer - 6/26/2019 JAS - if (result != RESULT_NONE && Is_Selected_By_Player()) { - Mark(MARK_CHANGE); - } - } - - /* - ** Return with the result of the damage taken. - */ - return(result); -} - - -/*********************************************************************************************** - * ObjectClass::Mark -- Handles basic marking logic. * - * * - * This routine handles the base logic for marking an object up or down on the map. It * - * manages the IsDown flag as well as flagging the object to be redrawn if necessary. * - * Whenever an object is to be marked, it should call this base class function first. If * - * this function returns true, then the higher level function should proceed with its own * - * logic. * - * * - * INPUT: mark -- The marking method to use for this object. It can be either MARK_DOWN, * - * MARK_UP, or MARK_CHANGE. * - * * - * OUTPUT: bool; Was the object marked successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Mark(MarkType mark) -{ - TechnoClass *tech; - CELL cell; - int threat; - HousesType house; - - if (!IsInLimbo && IsActive) { - - /* - ** A mark for change is always successful UNLESS the object - ** is not placed down or has already been flagged as changed - ** this game frame. - */ - if (mark == MARK_CHANGE) { - if (IsToDisplay) return(false); - if (IsDown == true) { - Mark_For_Redraw(); - return(true); - } - return(false); - } - - /* - ** Handle adding or removing the object in the cells' overlap lists - */ - if (mark == MARK_OVERLAP_UP) { - if (IsDown == true) { - Map.Overlap_Up(Coord_Cell(Coord),this); - Mark_For_Redraw(); - return(true); - } - } - if (mark == MARK_OVERLAP_DOWN) { - if (IsDown == true) { - Map.Overlap_Down(Coord_Cell(Coord),this); - Mark_For_Redraw(); - return(true); - } - } - - /* - ** It is important to know whether the object is a techno class - ** or not to see if we have to adjust the regional threat ratings - */ - if (Is_Techno()) { - tech = (TechnoClass *)this; - threat = tech->Risk(); - house = tech->Owner(); - cell = Coord_Cell(Coord); - } else - tech = NULL; - - /* - ** Marking down is only successful if the object isn't already - ** placed down. - */ - if (mark == MARK_DOWN && !IsDown) { - if (tech && GameToPlay == GAME_NORMAL) { - Map[cell].Adjust_Threat(house, threat); - } - IsDown = true; - Mark_For_Redraw(); - return(true); - } - - /* - ** Lifting up is only successful if the object isn't already - ** lifted up from the map. - */ - if (mark == MARK_UP && IsDown) { - if (tech && GameToPlay == GAME_NORMAL) { - Map[cell].Adjust_Threat(house, -threat); - } - Map.Overlap_Up(Coord_Cell(Coord), this); - IsDown = false; - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * ObjectClass::Init -- Initializes the basic object system. * - * * - * This routine should be called when the basic object system needs to be initialized. This * - * occurs when the scenario is about to be loaded. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -void ObjectClass::Init(void) -{ - CurrentObject.Clear_All(); -} - - -/*********************************************************************************************** - * ObjectClass::Revealed -- Reveals this object to the house specified. * - * * - * This routine is called when this object gets revealed to the house specified. * - * * - * INPUT: house -- Pointer to the house that this object is being revealed to. * - * * - * OUTPUT: Was this object revealed for the first time to this house? Generic objects always * - * return true unless an invalid house pointer was specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -bool ObjectClass::Revealed(HouseClass * house) -{ - return(house != NULL); -} - -/*********************************************************************************************** - * ObjectClass::Set_Selected_By_Player -- Set this object as selected by the given player or * - * the default player. * - * * - * INPUT: Player pointer * - * * - * OUTPUT: * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 6/25/2019 - JAS * - *=============================================================================================*/ -void ObjectClass::Set_Selected_By_Player(HouseClass *player) -{ - if (!player || !player->Class) { - player = PlayerPtr; - } - - HousesType house = player->Class->House; - if (((TechnoTypeClass const &)Class_Of()).IsLeader) { - CurrentObject.Add_Head(house, this); - } - else { - CurrentObject.Add(house, this); - } - - int shift = (int)house; - IsSelectedMask |= (1 << shift); - - if (GameToPlay == GAME_NORMAL && player == PlayerPtr) { - IsSelected = true; - } -} - -/*********************************************************************************************** - * ObjectClass::Set_Unselected_By_Player -- Set this object as unselected by the given player * - * orthe default player. * - * * - * INPUT: Player pointer * - * * - * OUTPUT: * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 6/25/2019 - JAS * - *=============================================================================================*/ -void ObjectClass::Set_Unselected_By_Player(HouseClass *player) -{ - if (!player || !player->Class) { - player = PlayerPtr; - } - - HousesType house = player->Class->House; - CurrentObject.Delete(house, this); - - int shift = (int)house; - IsSelectedMask &= ~(1 << shift); - - if (GameToPlay == GAME_NORMAL && player == PlayerPtr) { - IsSelected = false; - } -} - -/*********************************************************************************************** - * ObjectClass::Is_Selected_By_Player -- Has this object been selected by the given player * - * * - * INPUT: Player pointer * - * * - * OUTPUT: True if selected by that player * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 6/25/2019 - JAS * - *=============================================================================================*/ -bool ObjectClass::Is_Selected_By_Player(HouseClass *player) const -{ - if (player && player->Class) { - int shift = (int)player->Class->House; - return (IsSelectedMask & (1 << shift)) ? true : false; - } - else { - int shift = (int)PlayerPtr->Class->House; - return (IsSelectedMask & (1 << shift)) ? true : false; - } - return false; -} - - - -// These can't be made inline (for various reasons). -short const * ObjectClass::Occupy_List(bool placement) const {return(Class_Of().Occupy_List(placement));}; -short const * ObjectClass::Overlap_List(void) const {return(Class_Of().Overlap_List());}; -BuildingClass * ObjectClass::Who_Can_Build_Me(bool intheory, bool legal) const {return(Class_Of().Who_Can_Build_Me(intheory, legal, Owner()));}; -unsigned ObjectClass::Health_Ratio(void) const {return(Cardinal_To_Fixed(Class_Of().MaxStrength, Strength));}; -int ObjectClass::Full_Name(void) const {return Class_Of().Full_Name();}; - diff --git a/code/TIBERIANDAWN/OBJECT.H b/code/TIBERIANDAWN/OBJECT.H deleted file mode 100644 index 2bf51cb..0000000 --- a/code/TIBERIANDAWN/OBJECT.H +++ /dev/null @@ -1,262 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\object.h_v 2.15 16 Oct 1995 16:46:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OBJECT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : April 29, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef OBJECT_H -#define OBJECT_H - -#include "abstract.h" - -class ObjectClass; -class TechnoClass; -class ObjectTypeClass; -class HouseClass; -class TriggerClass; -class BuildingClass; -class RadioClass; - -//extern "C" { -//unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal); -//} - -/********************************************************************** -** Every game object (that can exist on the map) is ultimately derived from this object -** class. It holds the common information between all objects. This is primarily the -** object unique ID number and its location in the world. All common operations between -** game objects are represented by virtual functions in this class. -*/ -class ObjectClass : public AbstractClass -{ - public: - /* - ** The object can be in one of two states -- placed down on the map, or not. If the - ** object is placed down on the map, then this flag will be true. - */ - unsigned IsDown:1; - - /* - ** This is a support flag that is only used while building a list of objects to - ** be damaged by a proximity affect (explosion). When this flag is set, this object - ** will not be added to the list of units to damage. When damage is applied to the - ** object, this flag is cleared again. This process ensures that an object is never - ** subject to "double jeapordy". - */ - unsigned IsToDamage:1; - -// private: - /* - ** Is this object flagged to be displayed during the next rendering process? This - ** flag could be set by many different circumstances. It is automatically cleared - ** when the object is rerendered. - */ - unsigned IsToDisplay:1; - - - public: - /* - ** An object in the game may be valid yet held in a state of "limbo". Units are in such - ** a state if they are being transported or are otherwise "inside" another unit. They can - ** also be in limbo if they have been created but are being held until the proper time - ** for delivery. - */ - unsigned IsInLimbo:1; - - /* - ** When an object is "selected" it is given a floating bar graph or other graphic imagery - ** to display this fact. When the player performs I/O, the actions may have a direct - ** bearing on the actions of the currently selected object. For quick checking purposes, - ** if this object is the one that is "selected", this flag will be true. - */ - unsigned IsSelected:1; - - //Added a mask instead of bool for selecting players. This is because we must now support multiplayer. - // - 6/26/2019 - unsigned short IsSelectedMask; - - /* - ** If an animation is attached to this object, then this flag will be true. - */ - unsigned IsAnimAttached:1; - - /* - ** Several objects could exist in the same cell list. This is a pointer to the - ** next object in the cell list. The objects in this list are not in any - ** significant order. - */ - ObjectClass * Next; - - /* - ** Every object can be assigned a trigger; the same trigger can be assigned - ** to multiple objects. - */ - TriggerClass * Trigger; - - /* - ** This is the current strength of this object. - */ - short Strength; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[16]; - - /*----------------------------------------------------------------------------------- - ** Constructor & destructors. - */ - ObjectClass(void); - virtual ~ObjectClass(void) {}; - virtual RTTIType What_Am_I(void) const; - int operator < (ObjectClass const & object) const {return Sort_Y() < object.Sort_Y();}; - int operator > (ObjectClass const & object) const {return Sort_Y() > object.Sort_Y();}; - - /* - ** Object selection control. - */ - static void Init(void); - - /* - ** Query functions. - */ - virtual ActionType What_Action(ObjectClass *) const; - virtual ActionType What_Action(CELL) const; - virtual LayerType In_Which_Layer(void) const; - virtual bool Is_Infantry(void) const; - virtual bool Is_Techno(void) const; - virtual unsigned char Get_Ownable(void) const; - virtual ObjectTypeClass const & Class_Of(void) const = 0; - virtual int Full_Name(void) const; - virtual bool Can_Repair(void) const; - virtual bool Can_Demolish(void) const; - virtual bool Can_Demolish_Unit(void) const; - virtual bool Can_Capture(void) const; - virtual bool Can_Player_Fire(void) const; - virtual bool Can_Player_Move(void) const; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Docking_Coord(void) const; - virtual COORDINATE Target_Coord(void) const; - virtual COORDINATE Center_Coord(void) const; - virtual COORDINATE Render_Coord(void) const; - virtual COORDINATE Sort_Y(void) const; - virtual COORDINATE Fire_Coord(int ) const; - - /* - ** Object entry and exit from the game system. - */ - virtual bool Limbo(void); - virtual bool Unlimbo(COORDINATE , DirType facing = DIR_N); - virtual void Detach(TARGET, bool) {}; - virtual void Detach_All(bool all=true); - static void Detach_This_From_All(TARGET target, bool all=true); - virtual void Record_The_Kill(TechnoClass * ); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual void Do_Shimmer(void); - virtual int Exit_Object(TechnoClass *); - virtual bool Render(bool forced); - virtual short const * Occupy_List(bool placement=false) const; - virtual short const * Overlap_List(void) const; - virtual unsigned Health_Ratio(void) const; - virtual void Draw_It(int x, int y, WindowNumberType ) = 0; - virtual void Hidden(void); - virtual void Look(bool =false); - virtual bool Mark(MarkType); - - private: - virtual void Mark_For_Redraw(void); - - public: - - /* - ** User I/O. - */ - virtual void Active_Click_With(ActionType , ObjectClass *); - virtual void Active_Click_With(ActionType , CELL ); - virtual void Clicked_As_Target(HousesType house,int = 7); - virtual bool Select(bool allow_mixed = false); - virtual void Unselect(void); - - //These selection functions were added to handle the fact that we now need to support - //client-server multiplayer. - JAS 6/26/2019 - virtual void Unselect_All_Players(void); - virtual void Unselect_All_Players_Except_Owner(void); - virtual bool Is_Selected_By_Player(HouseClass *player = NULL) const; - virtual void Set_Selected_By_Player(HouseClass *player = NULL); - virtual void Set_Unselected_By_Player(HouseClass *player = NULL); - - /* - ** Combat related. - */ - virtual bool In_Range(COORDINATE , int=0) const; - virtual int Weapon_Range(int =0) const; - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source=0); - virtual TARGET As_Target(void) const; - virtual void Scatter(COORDINATE , bool=false, bool=false); - virtual bool Catch_Fire(void); - virtual void Fire_Out(void); - virtual int Value(void) const; - virtual MissionType Get_Mission(void) const; - - /* - ** AI. - */ - virtual BuildingClass * Who_Can_Build_Me(bool intheory, bool legal) const; - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual bool Revealed(HouseClass * house); - virtual void Repair(int ); - virtual void Sell_Back(int ); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - virtual void Move(FacingType); - -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/ODATA.CPP b/code/TIBERIANDAWN/ODATA.CPP deleted file mode 100644 index 67ac74f..0000000 --- a/code/TIBERIANDAWN/ODATA.CPP +++ /dev/null @@ -1,922 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\odata.cpv 2.16 16 Oct 1995 16:50:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : ODATA.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 16, 1994 * - * * - * Last Update : April 19, 1995 [PWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * OverlayTypeClass::Display -- Displays a generic representation of overlay. * - * OverlayTypeClass::From_Name -- Determine overlay from ASCII name. * - * OverlayTypeClass::Init -- Loads graphic data for overlays. * - * OverlayTypeClass::Occupy_List -- Determines occupation list. * - * OverlayTypeClass::Prep_For_Add -- Prepares to add overlay to scenario. * - * OverlayTypeClass::Create_And_Place -- Creates and places a overlay object on the map. * - * OverlayTypeClass::Create_One_Of -- Creates an object of this overlay type. * - * OverlayTypeClass::OverlayTypeClass -- Constructor for overlay type objects. * - * OverlayTypeClass::Draw_It -- Draws the overlay image at location specified. * - * OverlayTypeClass::One_Time -- Loads all the necessary general overlay shape data. * - * OverlayTypeClass::Init -- Initialize the overlay graphic data per theater. * - * OverlayTypeClass::Radar_Icon -- Gets a pointer to the radar icons * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "type.h" - - -static OverlayTypeClass const Road( - OVERLAY_ROAD, // Overlay type number. - "ROAD", // INI name of overlay. - TXT_CONCRETE, // Full name of overlay. - LAND_ROAD, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Concrete( - OVERLAY_CONCRETE, // Overlay type number. - "CONC", // INI name of overlay. - TXT_CONCRETE, // Full name of overlay. - LAND_ROAD, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Sandbag( - OVERLAY_SANDBAG_WALL, // Overlay type number. - "SBAG", // INI name of overlay. - TXT_SANDBAG_WALL, // Full name of overlay. - LAND_WALL, // What kind of ground is it? - 1, // If this is a wall, how many damage levels? - 20, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - true, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - true, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Cyclone( - OVERLAY_CYCLONE_WALL, // Overlay type number. - "CYCL", // INI name of overlay. - TXT_CYCLONE_WALL, // Full name of overlay. - LAND_WALL, // What kind of ground is it? - 2, // If this is a wall, how many damage levels? - 10, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - true, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - true, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Brick( - OVERLAY_BRICK_WALL, // Overlay type number. - "BRIK", // INI name of overlay. - TXT_BRICK_WALL, // Full name of overlay. - LAND_WALL, // What kind of ground is it? - 3, // If this is a wall, how many damage levels? - 70, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - true, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - true, // Stops low level bullets in flight? - false, // Theater specific art? - true, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Barbwire( - OVERLAY_BARBWIRE_WALL, // Overlay type number. - "BARB", // INI name of overlay. - TXT_BARBWIRE_WALL, // Full name of overlay. - LAND_WALL, // What kind of ground is it? - 1, // If this is a wall, how many damage levels? - 2, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - true, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - true, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Wood( - OVERLAY_WOOD_WALL, // Overlay type number. - "WOOD", // INI name of overlay. - TXT_WOOD_WALL, // Full name of overlay. - LAND_WALL, // What kind of ground is it? - 1, // If this is a wall, how many damage levels? - 2, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - true, // Is it a wooden overlay (affected by fire)? - true, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - true, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium1( - OVERLAY_TIBERIUM1, // Overlay type number. - "TI1", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium2( - OVERLAY_TIBERIUM2, // Overlay type number. - "TI2", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium3( - OVERLAY_TIBERIUM3, // Overlay type number. - "TI3", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium4( - OVERLAY_TIBERIUM4, // Overlay type number. - "TI4", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium5( - OVERLAY_TIBERIUM5, // Overlay type number. - "TI5", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium6( - OVERLAY_TIBERIUM6, // Overlay type number. - "TI6", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium7( - OVERLAY_TIBERIUM7, // Overlay type number. - "TI7", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium8( - OVERLAY_TIBERIUM8, // Overlay type number. - "TI8", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium9( - OVERLAY_TIBERIUM9, // Overlay type number. - "TI9", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium10( - OVERLAY_TIBERIUM10, // Overlay type number. - "TI10", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium11( - OVERLAY_TIBERIUM11, // Overlay type number. - "TI11", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Tiberium12( - OVERLAY_TIBERIUM12, // Overlay type number. - "TI12", // INI name of overlay. - TXT_TIBERIUM, // Full name of overlay. - LAND_TIBERIUM, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - true, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const Squish( - OVERLAY_SQUISH, // Overlay type number. - "SQUISH", // INI name of overlay. - TXT_SQUISH, // Full name of overlay. - LAND_CLEAR, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); - -static OverlayTypeClass const V12( - OVERLAY_V12, // Overlay type number. - "V12", // INI name of overlay. - TXT_CIV12, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const V13( - OVERLAY_V13, // Overlay type number. - "V13", // INI name of overlay. - TXT_CIV13, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const V14( - OVERLAY_V14, // Overlay type number. - "V14", // INI name of overlay. - TXT_CIV14, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const V15( - OVERLAY_V15, // Overlay type number. - "V15", // INI name of overlay. - TXT_CIV15, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const V16( - OVERLAY_V16, // Overlay type number. - "V16", // INI name of overlay. - TXT_CIV16, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const V17( - OVERLAY_V17, // Overlay type number. - "V17", // INI name of overlay. - TXT_CIV17, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const V18( - OVERLAY_V18, // Overlay type number. - "V18", // INI name of overlay. - TXT_CIV18, // Full name of overlay. - LAND_ROCK, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - true, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - true, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const FlagSpot( - OVERLAY_FLAG_SPOT, // Overlay type number. - "FPLS", // INI name of overlay. - TXT_FLAG_SPOT, // Full name of overlay. - LAND_CLEAR, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - true, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - false, // Is this a wall type? - false // Is this a crate? -); -static OverlayTypeClass const WoodCrate( - OVERLAY_WOOD_CRATE, // Overlay type number. - "WCRATE", // INI name of overlay. - TXT_WOOD_CRATE, // Full name of overlay. - LAND_CLEAR, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - false, // Is this a wall type? - true // Is this a crate? -); -static OverlayTypeClass const SteelCrate( - OVERLAY_STEEL_CRATE, // Overlay type number. - "SCRATE", // INI name of overlay. - TXT_STEEL_CRATE, // Full name of overlay. - LAND_CLEAR, // What kind of ground is it? - 0, // If this is a wall, how many damage levels? - 0, // If this is a wall, how many damage points can it take per level? - false, // Visible on the radar map? - false, // Is it a wooden overlay (affected by fire)? - false, // Targetable as a destroyable overlay? - false, // Crushable by tracked vehicle? - false, // Is this harvestable Tiberium? - false, // Stops low level bullets in flight? - false, // Theater specific art? - false, // Is this a wall type? - true // Is this a crate? -); - - -OverlayTypeClass const * const OverlayTypeClass::Pointers[OVERLAY_COUNT] = { - &Concrete, // OVERLAY_CONCRETE - &Sandbag, // OVERLAY_SANDBAG_WALL - &Cyclone, // OVERLAY_CYCLONE_WALL - &Brick, // OVERLAY_BRICK_WALL - &Barbwire, // OVERLAY_BARBWIRE_WALL - &Wood, // OVERLAY_WOOD_WALL - &Tiberium1, // OVERLAY_TIBERIUM1 - &Tiberium2, // OVERLAY_TIBERIUM2 - &Tiberium3, // OVERLAY_TIBERIUM3 - &Tiberium4, // OVERLAY_TIBERIUM4 - &Tiberium5, // OVERLAY_TIBERIUM5 - &Tiberium6, // OVERLAY_TIBERIUM6 - &Tiberium7, // OVERLAY_TIBERIUM7 - &Tiberium8, // OVERLAY_TIBERIUM8 - &Tiberium9, // OVERLAY_TIBERIUM9 - &Tiberium10, // OVERLAY_TIBERIUM10 - &Tiberium11, // OVERLAY_TIBERIUM11 - &Tiberium12, // OVERLAY_TIBERIUM12 - &Road, // OVERLAY_ROAD - &Squish, // OVERLAY_SQUISH - &V12, // OVERLAY_V12 - &V13, // OVERLAY_V13 - &V14, // OVERLAY_V14 - &V15, // OVERLAY_V15 - &V16, // OVERLAY_V16 - &V17, // OVERLAY_V17 - &V18, // OVERLAY_V18 - &FlagSpot, // OVERLAY_FLAG_SPOT - &WoodCrate, // OVERLAY_WOOD_CRATE - &SteelCrate, // OVERLAY_STEEL_CRATE -}; - - -/*********************************************************************************************** - * OverlayTypeClass::OverlayTypeClass -- Constructor for overlay type objects. * - * * - * This is the constructor for the overlay types. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1994 JLB : Created. * - *=============================================================================================*/ -OverlayTypeClass::OverlayTypeClass( - OverlayType iconset, - char const *ininame, - int fullname, - LandType ground, - int damagelevels, - int damagepoints, - bool isradarvisible, - bool iswooden, - bool istarget, - bool iscrushable, - bool istiberium, - bool high, - bool theater, - bool walltype, - bool iscrate) : - ObjectTypeClass(false, - false, - iscrushable, - true, - false, - istarget, - true, - false, - fullname, - ininame, - ARMOR_NONE, - 0) -{ - IsRadarVisible = isradarvisible; - IsCrate = iscrate; - IsWooden = iswooden; - IsHigh = high; - IsTheater = theater; - IsTiberium = istiberium; - Type = iconset; - Land = ground; - IsWall = walltype; - DamageLevels = damagelevels; - DamagePoints = damagepoints; -} - - -/*********************************************************************************************** - * OverlayTypeClass::One_Time -- Loads all the necessary general overlay shape data. * - * * - * This routine should be called once when the game first starts. It will establish * - * pointers to the graphic data of the overlay objects. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -void OverlayTypeClass::One_Time(void) -{ -} - - -/*********************************************************************************************** - * OverlayTypeClass::From_Name -- Determine overlay from ASCII name. * - * * - * This routine is used to determine the overlay number given only * - * an ASCII representation. The scenario loader uses this routine * - * to construct the map from the INI control file. * - * * - * INPUT: name -- Pointer to the ASCII name of the overlay. * - * * - * OUTPUT: Returns with the overlay number. If the name had no match, * - * then returns with OVERLAY_NONE. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -OverlayType OverlayTypeClass::From_Name(char const *name) -{ - if (name) { - for (OverlayType index = OVERLAY_FIRST; index < OVERLAY_COUNT; index++) { - if (stricmp(As_Reference(index).IniName, name) == 0) { - return(index); - } - } - } - return(OVERLAY_NONE); -} - - -/*********************************************************************************************** - * OverlayTypeClass::Occupy_List -- Determines occupation list. * - * * - * This routine is used to examine the overlay map and build an * - * occupation list. This list is used to render a overlay cursor as * - * well as placement of icon numbers. * - * * - * INPUT: placement -- Is this for placement legality checking only? The normal condition * - * is for marking occupation flags. * - * * - * OUTPUT: Returns with a pointer to the overlay occupation list. * - * * - * WARNINGS: The return pointer is valid only until the next time that * - * this routine is called. * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -short const * OverlayTypeClass::Occupy_List(bool) const -{ - static short _simple[] = {0, REFRESH_EOL}; - - return(_simple); -} - - -/*************************************************************************** - * OverlayTypeClass::Radar_Icon -- Gets a pointer to the radar icons * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/19/1995 PWG : Created. * - *=========================================================================*/ -unsigned char * OverlayTypeClass::Radar_Icon(int data) const -{ - unsigned char *icon = (unsigned char *)Get_Radar_Data(); // Get pointer to radar icons - icon += (data * 9) + 2; // move icon ptr to correct icon - return(icon); // Return the correct icon -} - - -#ifdef SCENARIO_EDITOR -/*********************************************************************************************** - * OverlayTypeClass::Display -- Displays a generic representation of overlay. * - * * - * This routine is used to display a generic view of the overlay * - * object. This is necessary for selection in the scenario editor. * - * * - * INPUT: x,y -- The coordinates to center the display about. * - * * - * window-- The window to base the coordinates upon. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -void OverlayTypeClass::Display(int x, int y, WindowNumberType window, HousesType ) const -{ - /* - ---------------------------- Draw the shape ------------------------------ - */ - if (Get_Image_Data()) { - int frame = 0; - - if (IsTiberium) { - frame = 7; - } - - CC_Draw_Shape(Get_Image_Data(), frame, x, y, window, SHAPE_NORMAL|SHAPE_CENTER|SHAPE_WIN_REL); - } -} - - -/*********************************************************************************************** - * OverlayTypeClass::Prep_For_Add -- Prepares to add overlay to scenario. * - * * - * This routine prepares a list of overlay objects so that the * - * scenario editor can use this list to display a dialog box. The * - * selection of a overlay object will allow its placement upon the * - * map. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/06/1994 JLB : Created * - *=============================================================================================*/ -void OverlayTypeClass::Prep_For_Add(void) -{ - for (OverlayType index = OVERLAY_FIRST; index < OVERLAY_COUNT; index++) { - OverlayTypeClass const & overlay = As_Reference(index); - if (overlay.Get_Image_Data() && !overlay.IsWall && (!overlay.IsTiberium || index == OVERLAY_TIBERIUM1)) { - Map.Add_To_List(&overlay); - } - } -} -#endif - - -/*********************************************************************************************** - * OverlayTypeClass::Create_And_Place -- Creates and places a overlay object on the map. * - * * - * This support routine is used by the scenario editor to add a overlay object to the map * - * and to the game. * - * * - * INPUT: cell -- The cell to place the overlay object. * - * * - * OUTPUT: bool; Was the overlay object placed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -bool OverlayTypeClass::Create_And_Place(CELL cell, HousesType ) const -{ - if (new OverlayClass(Type, cell)) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * OverlayTypeClass::Create_One_Of -- Creates an object of this overlay type. * - * * - * This routine will create an object of this type. For certain overlay objects, such * - * as walls, it is actually created as a building. The "building" wall is converted into * - * a overlay at the moment of placing down on the map. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the appropriate object for this overlay type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/18/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * OverlayTypeClass::Create_One_Of(HouseClass *) const -{ - return(new OverlayClass(Type, -1)); -} - - -/*********************************************************************************************** - * OverlayTypeClass::Draw_It -- Draws the overlay image at location specified. * - * * - * This routine will draw the overlay shape at the coordinates specified. It is presumed * - * that all the underlying layers have already been rendered by the time this routine is * - * called. * - * * - * INPUT: x, y -- Coordinate (upper left) of cell where overlay image is to be drawn. * - * * - * data -- Cell specific data that controls the imagery of the overlay. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -void OverlayTypeClass::Draw_It(int x, int y, int data) const -{ - CC_Draw_Shape(Get_Image_Data(), data, Map.TacPixelX+x+(CELL_PIXEL_W>>1), Map.TacPixelY+y+(CELL_PIXEL_H>>1), WINDOW_MAIN, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST, NULL, Map.UnitShadow); -} - - -/*********************************************************************************************** - * OverlayTypeClass::Init -- Initialize the overlay graphic data per theater. * - * * - * This routine will update the overlay graphic data according to the theater specified. * - * It is typically called when the scenario is first loaded (theater change). * - * * - * INPUT: theater -- The theater to load specific data for. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - * 4/25/1996 ST : Modified to load theater specific sidebar icons if available * - *=============================================================================================*/ -void OverlayTypeClass::Init(TheaterType theater) -{ - if (theater != LastTheater){ - for (OverlayType index = OVERLAY_FIRST; index < OVERLAY_COUNT; index++) { - OverlayTypeClass const & overlay = As_Reference(index); - char fullname[_MAX_FNAME+_MAX_EXT]; // Fully constructed iconset name. - - if (overlay.IsTheater) { - _makepath(fullname, NULL, NULL, overlay.IniName, Theaters[theater].Suffix); - } else { - _makepath(fullname, NULL, NULL, overlay.IniName, ".SHP"); - } - ((void const *&)overlay.ImageData) = MixFileClass::Retrieve(fullname); - - IsTheaterShape = overlay.IsTheater; - if (overlay.RadarIcon) delete[] (char *)overlay.RadarIcon; - ((void const *&)overlay.RadarIcon) = Get_Radar_Icon(overlay.Get_Image_Data(), 0, -1, 3); - IsTheaterShape = false; - } - } -} diff --git a/code/TIBERIANDAWN/OPTIONS.CPP b/code/TIBERIANDAWN/OPTIONS.CPP deleted file mode 100644 index f84e1b2..0000000 --- a/code/TIBERIANDAWN/OPTIONS.CPP +++ /dev/null @@ -1,797 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\options.cpv 2.17 16 Oct 1995 16:51:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : June 30, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * OptionsClass::Adjust_Palette -- Adjusts the palette according to the settings specified. * - * OptionsClass::Get_Brightness -- Fetches the current brightness setting. * - * OptionsClass::Get_Color -- Fetches the current color setting. * - * OptionsClass::Get_Contrast -- Gets the current contrast setting. * - * OptionsClass::Get_Game_Speed -- Fetches the current game speed setting. * - * OptionsClass::Get_Scroll_Rate -- Fetches the current scroll rate setting. * - * OptionsClass::Get_Tint -- Fetches the current tint setting. * - * OptionsClass::Load_Settings -- reads options settings from the INI file * - * OptionsClass::Normalize_Delay -- Normalizes delay factor to keep rate constant. * - * OptionsClass::One_Time -- This performs any one time initialization for the options class.* - * OptionsClass::OptionsClass -- The default constructor for the options class. * - * OptionsClass::Process -- Handles all the options graphic interface. * - * OptionsClass::Save_Settings -- writes options settings to the INI file * - * OptionsClass::Set -- Sets options based on current settings * - * OptionsClass::Set_Brightness -- Sets the brightness level to that specified. * - * OptionsClass::Set_Color -- Sets the color to the value specified. * - * OptionsClass::Set_Contrast -- Sets the contrast to the value specified. * - * OptionsClass::Set_Game_Speed -- Sets the game speed as specified. * - * OptionsClass::Set_Repeat -- Controls the score repeat option. * - * OptionsClass::Set_Score_Volume -- Sets the global score volume to that specified. * - * OptionsClass::Set_Scroll_Rate -- Sets the scroll rate as specified. * - * OptionsClass::Set_Shuffle -- Controls the play shuffle setting. * - * OptionsClass::Set_Sound_Volume -- Sets the sound effects volume level. * - * OptionsClass::Set_Tint -- Sets the tint setting. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "options.h" - - -/*********************************************************************************************** - * OptionsClass::OptionsClass -- The default constructor for the options class. * - * * - * This is the constructor for the options class. It handles setting up all the globals * - * necessary for the options. This includes setting them to their default state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/21/1994 JLB : Created. * - *=============================================================================================*/ -OptionsClass::OptionsClass(void) -{ - GameSpeed = TIMER_SECOND / TICKS_PER_SECOND; - ScrollRate = TIMER_SECOND / TICKS_PER_SECOND; - Volume = 0xE0; - ScoreVolume = 0x90; - Contrast = 0x80; - Color = 0x80; - Contrast = 0x80; - Tint = 0x80; - Brightness = 0x80; - AutoScroll = true; -#if (GERMAN | FRENCH) - IsDeathAnnounce = true; -#else - IsDeathAnnounce = false; -#endif - IsScoreRepeat = false; - IsScoreShuffle = false; - IsFreeScroll = false; -} - - -/*********************************************************************************************** - * OptionsClass::One_Time -- This performs any one time initialization for the options class. * - * * - * This routine should be called only once and it will perform any inializations for the * - * options class that is needed. This may include things like file loading and memory * - * allocation. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Only call this routine once. * - * * - * HISTORY: * - * 07/21/1994 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::One_Time(void) -{ - Set_Score_Vol(ScoreVolume); -} - - -/*********************************************************************************************** - * OptionsClass::Process -- Handles all the options graphic interface. * - * * - * This routine is the main control for the visual representation of the options * - * screen. It handles the visual overlay and the player input. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/21/1994 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Process(void) -{ -} - - -/*********************************************************************************************** - * OptionsClass::Set_Shuffle -- Controls the play shuffle setting. * - * * - * This routine will control the score shuffle flag. The setting to use is provided as * - * a parameter. When shuffling is on, the score play order is scrambled. * - * * - * INPUT: on -- Should the shuffle option be activated? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Shuffle(int on) -{ - IsScoreShuffle = on; -} - - -/*********************************************************************************************** - * OptionsClass::Set_Repeat -- Controls the score repeat option. * - * * - * This routine is used to control whether scores repeat or not. The setting to use for * - * the repeat flag is provided as a parameter. * - * * - * INPUT: on -- Should the scores repeat? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Repeat(int on) -{ - IsScoreRepeat = on; -} - - -/*********************************************************************************************** - * OptionsClass::Set_Score_Volume -- Sets the global score volume to that specified. * - * * - * This routine will set the global score volume to the value specified. The value ranges * - * from zero to 255. * - * * - * INPUT: volume -- The new volume setting to use for scores. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Score_Volume(int volume) -{ - volume = Bound(volume, 0, 255); - ScoreVolume = volume; - Set_Score_Vol(ScoreVolume); -} - - -/*********************************************************************************************** - * OptionsClass::Set_Sound_Volume -- Sets the sound effects volume level. * - * * - * This routine will set the sound effect volume level as indicated. It can generate a * - * sound effect for feedback purposes if desired. The volume setting can range from zero * - * to 255. The value of 255 is the loudest. * - * * - * INPUT: volume -- The volume setting to use for the new value. 0 to 255. * - * * - * feedback -- Should a feedback sound effect be generated? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Sound_Volume(int volume, int feedback) -{ - volume = Bound(volume, 0, 255); - Volume = volume; - if (feedback) { - Sound_Effect(VOC_BLEEPY3, NULL); - } -} - - -/*********************************************************************************************** - * OptionsClass::Set_Brightness -- Sets the brightness level to that specified. * - * * - * This routine will set the current brightness level to the value specified. This value * - * can range from zero to 255, with 128 being the normal (default) brightness level. * - * * - * INPUT: brightness -- The brightness level to set as current. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Brightness(int brightness) -{ - Brightness = 0x40 + Fixed_To_Cardinal(0x80, brightness); - Adjust_Palette(OriginalPalette, GamePalette, Brightness, Color, Tint, Contrast); - if (InMainLoop){ - Set_Palette(GamePalette); - } -} - - -/*********************************************************************************************** - * OptionsClass::Get_Brightness -- Fetches the current brightness setting. * - * * - * This routine will fetch the current setting for the brightness level. The value ranges * - * from zero to 255, with 128 being the normal (default) value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current brightness setting. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -int OptionsClass::Get_Brightness(void) const -{ - return(Cardinal_To_Fixed(0x80, Brightness-0x40)); -} - - -/*********************************************************************************************** - * OptionsClass::Set_Color -- Sets the color to the value specified. * - * * - * This routine will set the color value to that specified. The value specified can range * - * from zero to 255. The value of 128 is the normal default color setting. * - * * - * INPUT: color -- The new color value to set as current. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Color(int color) -{ - Color = color; - Adjust_Palette(OriginalPalette, GamePalette, Brightness, Color, Tint, Contrast); - if (InMainLoop){ - Set_Palette(GamePalette); - } -} - - -/*********************************************************************************************** - * OptionsClass::Get_Color -- Fetches the current color setting. * - * * - * This routine will fetch the current color setting. This value ranges from zero to * - * 255. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current color setting. The value of 128 is the normal (default) * - * color setting. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -int OptionsClass::Get_Color(void) const -{ - return(Color); -} - - -/*********************************************************************************************** - * OptionsClass::Set_Contrast -- Sets the contrast to the value specified. * - * * - * This routine will set the constrast to the setting specified. This setting ranges from * - * zero to 255. The value o 128 is the normal default value. * - * * - * INPUT: contrast -- The constrast setting to make as the current setting. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Contrast(int contrast) -{ - Contrast = 0x40 + Fixed_To_Cardinal(0x80, contrast); - Adjust_Palette(OriginalPalette, GamePalette, Brightness, Color, Tint, Contrast); - if (InMainLoop){ - Set_Palette(GamePalette); - } -} - - -/*********************************************************************************************** - * OptionsClass::Get_Contrast -- Gets the current contrast setting. * - * * - * This routine will get the current contrast setting. The value returned is in the range * - * of zero to 255. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the current contrast setting. A setting of 128 is the normal default value.* - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -int OptionsClass::Get_Contrast(void) const -{ - return(Cardinal_To_Fixed(0x80, Contrast-0x40)); -} - - -/*********************************************************************************************** - * OptionsClass::Set_Tint -- Sets the tint setting. * - * * - * This routine will change the current tint setting according to the value specified. * - * * - * INPUT: tint -- The desired tint setting. This value ranges from zero to 255. * - * * - * OUTPUT: none * - * * - * WARNINGS: The value of 128 is the default (normal) tint setting. * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Set_Tint(int tint) -{ - Tint = tint; - Adjust_Palette(OriginalPalette, GamePalette, Brightness, Color, Tint, Contrast); - if (InMainLoop){ - Set_Palette(GamePalette); - } -} - - -/*********************************************************************************************** - * OptionsClass::Get_Tint -- Fetches the current tint setting. * - * * - * This fetches the current tint setting. The value is returned as a number between * - * zero and 255. This has been adjusted for the valid range allowed. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current tint setting. Normal tint setting is 128. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -int OptionsClass::Get_Tint(void) const -{ - return(Tint); -} - - -/*********************************************************************************************** - * OptionsClass::Adjust_Palette -- Adjusts the palette according to the settings specified. * - * * - * This routine is used to adjust the palette according to the settings provided. It is * - * used by the options class to monkey with the palette. * - * * - * INPUT: oldpal -- Pointer to the original (unmodified) palette. * - * * - * newpal -- The new palette to create according to the settings provided. * - * * - * brightness -- The brightness level (0..255). * - * * - * color -- The color level (0..255). * - * * - * tint -- The tint (hue) level (0..255). * - * * - * contrast -- The contrast level (0..255). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/21/1994 JLB : Created. * - *=============================================================================================*/ -void OptionsClass::Adjust_Palette(void *oldpal, void *newpal, unsigned char brightness, unsigned char color, unsigned char tint, unsigned char contrast) const -{ -// ST - 1/3/2019 10:49AM -#if (0) - int index; - unsigned h,s,v; - unsigned r,g,b; - - if (!oldpal || !newpal) return; - - /* - ** Adjust for palette. - */ - for (index = 0; index < 256; index++) { - if (/*index == LTGREEN ||*/ index == 255) { - memcpy(&((char*)newpal)[index*3], &((char*)oldpal)[index*3], 3); - } else { - r = ((char*)oldpal)[(index*3)+0]; - g = ((char*)oldpal)[(index*3)+1]; - b = ((char*)oldpal)[(index*3)+2]; - Convert_RGB_To_HSV(r, g, b, &h, &s, &v); - - /* - ** Adjust contrast by moving the value toward the center according to the - ** percentage indicated. - */ - int temp; - - temp = (v * brightness) / 0x80; // Brightness - temp = Bound(temp, 0, 0xFF); - v = temp; - temp = (((((int)v) - 0x80) * contrast) / 0x80) + 0x80; // Contrast - temp = Bound(temp, 0, 0xFF); - v = temp; - temp = (s * color) / 0x80; // Color - temp = Bound(temp, 0, 0xFF); - s = temp; - temp = (h * tint) / 0x80; // Tint - temp = Bound(temp, 0, 0xFF); - h = temp; - Convert_HSV_To_RGB(h, s, v, &r, &g, &b); - ((char*)newpal)[(index*3)+0] = r; - ((char*)newpal)[(index*3)+1] = g; - ((char*)newpal)[(index*3)+2] = b; - } - } -#endif -} - - -/*********************************************************************************************** - * OptionsClass::Load_Settings -- reads options settings from the INI file * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void OptionsClass::Load_Settings (void) -{ - char *buffer; // INI staging buffer pointer. - - /* - ** Fetch working pointer to the INI staging buffer. Make sure that the buffer - ** is cleared out before proceeding. (Don't use the HidPage for this, since - ** the HidPage may be needed for various uncompressions during the INI - ** parsing.) - */ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - /* - ** Create filename and read the file. - */ - CCFileClass file ("CONQUER.INI"); - if (!file.Is_Available()) { - return; - } else { - file.Read(buffer, _ShapeBufferSize-1); - } - file.Close(); - - /* - ** Read in the Options values - */ - GameSpeed = WWGetPrivateProfileInt("Options", "GameSpeed", 4, buffer); - ScrollRate = WWGetPrivateProfileInt("Options", "ScrollRate", 4, buffer); - Set_Brightness(WWGetPrivateProfileInt("Options", "Brightness", 0x80, buffer)); - Set_Sound_Volume(WWGetPrivateProfileInt("Options", "Volume", 0xA0, buffer),false); - Set_Score_Volume(WWGetPrivateProfileInt("Options", "ScoreVolume", 0xFF, buffer)); - Set_Contrast(WWGetPrivateProfileInt("Options", "Contrast", 0x80, buffer)); - Set_Color(WWGetPrivateProfileInt("Options", "Color", 0x80, buffer)); - Set_Tint(WWGetPrivateProfileInt("Options", "Tint", 0x80, buffer)); - AutoScroll = WWGetPrivateProfileInt("Options", "AutoScroll", 1, buffer); - Set_Repeat(WWGetPrivateProfileInt("Options", "IsScoreRepeat", 0, buffer)); - Set_Shuffle(WWGetPrivateProfileInt("Options", "IsScoreShuffle", 0, buffer)); - IsDeathAnnounce = WWGetPrivateProfileInt("Options", "DeathAnnounce", 0, buffer); - IsFreeScroll = WWGetPrivateProfileInt("Options", "FreeScrolling", 0, buffer); - SlowPalette = WWGetPrivateProfileInt("Options", "SlowPalette", 1, buffer); - - char workbuf[128]; - - /* - ** Check for and possible enable true object names. - */ - WWGetPrivateProfileString("Options", "TrueNames", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_TRUENAME) { - Special.IsNamed = true; - } - - /* - ** Enable 6 player games if special flag is detected. - */ - WWGetPrivateProfileString("Options", "Players", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_6PLAYER) { - MPlayerMax = 6; - } - - /* - ** Enable three point turning logic as indicated. - */ - WWGetPrivateProfileString("Options", "Rotation", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_3POINT) { - Special.IsThreePoint = true; - } - - /* - ** Allow purchase of the helipad separately from the helicopter. - */ - WWGetPrivateProfileString("Options", "Helipad", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_HELIPAD) { - Special.IsSeparate = true; - } - - /* - ** Allow the MCV to undeploy rather than sell. - */ - WWGetPrivateProfileString("Options", "MCV", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_MCV) { - Special.IsMCVDeploy = true; - } - - /* - ** Allow disabling of building bibs so that tigher building packing can occur. - */ - WWGetPrivateProfileString("Options", "Bibs", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_BIB) { - Special.IsRoad = true; - } - - /* - ** Allow targeting of trees without having to hold down the shift key. - */ - WWGetPrivateProfileString("Options", "TreeTarget", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_TREETARGET) { - Special.IsTreeTarget = true; - } - - /* - ** Allow infantry to fire while moving. Attacker gets advantage with this flag. - */ - WWGetPrivateProfileString("Options", "Combat", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_COMBAT) { - Special.IsDefenderAdvantage = false; - } - - /* - ** Allow custom scores. - */ - WWGetPrivateProfileString("Options", "Scores", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_SCORE) { - Special.IsVariation = true; - } - - /* - ** Smarter self defense logic. Tanks will try to run over adjacent infantry. Buildings - ** will automatically return fire if they are fired upon. Infantry will run from an - ** incoming explosive (grenade or napalm) or damage that can't be directly addressed. - */ - WWGetPrivateProfileString("Options", "CombatIQ", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_IQ) { - Special.IsSmartDefense = true; - Special.IsScatter = true; - } - - /* - ** Enable the infantry squish marks when run over by a vehicle. - */ - WWGetPrivateProfileString("Options", "Overrun", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_SQUISH) { - Special.IsGross = true; - } - - /* - ** Enable the human generated sound effects. - */ - WWGetPrivateProfileString("Options", "Sounds", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_HUMAN) { - Special.IsJuvenile = true; - } - - /* - ** Scrolling is disabled over the tabs with this option. - */ - WWGetPrivateProfileString("Options", "Scrolling", "", workbuf, sizeof(workbuf), buffer); - if (Obfuscate(workbuf) == PARM_SCROLLING) { - Special.IsScrollMod = true; - } -} - - -/*********************************************************************************************** - * OptionsClass::Save_Settings -- writes options settings to the INI file * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 02/14/1995 BR : Created. * - *=============================================================================================*/ -void OptionsClass::Save_Settings (void) -{ - char * buffer; // INI staging buffer pointer. - CCFileClass file; - - /* - ** Get a working pointer to the INI staging buffer. Make sure that the buffer - ** starts cleared out of any data. - */ - buffer = (char *)_ShapeBuffer; - memset(buffer, '\0', _ShapeBufferSize); - - file.Set_Name("CONQUER.INI"); - if (file.Is_Available()) { - file.Read(buffer, _ShapeBufferSize-1); - } - - /* - ** Save Options settings - */ - WWWritePrivateProfileInt("Options", "GameSpeed", GameSpeed, buffer); - WWWritePrivateProfileInt("Options", "ScrollRate", ScrollRate, buffer); - WWWritePrivateProfileInt("Options", "Brightness", Brightness, buffer); - WWWritePrivateProfileInt("Options", "Volume", Volume, buffer); - WWWritePrivateProfileInt("Options", "ScoreVolume", ScoreVolume, buffer); - WWWritePrivateProfileInt("Options", "Contrast", Contrast, buffer); - WWWritePrivateProfileInt("Options", "Color", Color, buffer); - WWWritePrivateProfileInt("Options", "Tint", Tint, buffer); - WWWritePrivateProfileInt("Options", "AutoScroll", AutoScroll, buffer); - WWWritePrivateProfileInt("Options", "IsScoreRepeat", IsScoreRepeat, buffer); - WWWritePrivateProfileInt("Options", "IsScoreShuffle", IsScoreShuffle, buffer); - WWWritePrivateProfileInt("Options", "DeathAnnounce", IsDeathAnnounce, buffer); - WWWritePrivateProfileInt("Options", "FreeScrolling", IsFreeScroll, buffer); - - /* - ** Write the INI data out to a file. - */ - file.Write(buffer,strlen(buffer)); -} - - -/*********************************************************************************************** - * OptionsClass::Set -- Sets options based on current settings * - * * - * Use this routine to adjust the palette or sound settings after a fresh scenario load. * - * It assumes the values needed are already loaded into OptionsClass. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/24/1995 BRR : Created. * - *=============================================================================================*/ -void OptionsClass::Set(void) -{ - Set_Brightness(Brightness); - Set_Contrast(Contrast); - Set_Color(Color); - Set_Tint(Tint); - Set_Sound_Volume(Volume,false); - Set_Score_Volume(ScoreVolume); - Set_Repeat(IsScoreRepeat); - Set_Shuffle(IsScoreShuffle); -} - - -/*********************************************************************************************** - * OptionsClass::Normalize_Delay -- Normalizes delay factor to keep rate constant. * - * * - * This routine is used to adjust delay factors that MUST be synchronized on all machines * - * but should maintain a speed as close to constant as possible. Building animations are * - * a good example of this. * - * * - * INPUT: delay -- The normal delay factor. * - * * - * OUTPUT: Returns with the delay to use that has been modified so that a reasonably constant * - * rate will result. * - * * - * WARNINGS: This calculation is crude due to the coarse resolution that a 1/15 second timer * - * allows. * - * * - * Use of this routine ASSUMES that the GameSpeed is synchronized on all machines. * - * * - * HISTORY: * - * 06/18/1995 JLB : Created. * - * 06/30/1995 JLB : Handles low values in a more consistent manner. * - *=============================================================================================*/ -int OptionsClass::Normalize_Delay(int delay) const -{ - static int _adjust[][8] = { - {2,2,1,1,1,1,1,1}, - {3,3,3,2,2,2,1,1}, - {5,4,4,3,3,2,2,1}, - {7,6,5,4,4,4,3,2} - }; - if (delay) { - if (delay < 5) { - delay = _adjust[delay-1][GameSpeed]; - } else { - delay = ((delay * 8) / (GameSpeed+1)); - } - } - return(delay); -} - - - -void OptionsClass::Fixup_Palette(void) const -{ - Adjust_Palette(OriginalPalette, GamePalette, Brightness, Color, Tint, Contrast); -} - - -int OptionsClass::Normalize_Sound(int volume) const -{ - return(Fixed_To_Cardinal(volume, Volume)); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/OPTIONS.H b/code/TIBERIANDAWN/OPTIONS.H deleted file mode 100644 index e2c6097..0000000 --- a/code/TIBERIANDAWN/OPTIONS.H +++ /dev/null @@ -1,101 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\options.h_v 2.18 16 Oct 1995 16:46:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : June 8, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef OPTIONS_H -#define OPTIONS_H - -class OptionsClass { - public: - enum { - MAX_SCROLL_SETTING=7, - MAX_SPEED_SETTING=7 - }; - - OptionsClass(void); - - void One_Time(void); - void Process(void); - - void Fixup_Palette(void) const; - void Set_Shuffle(int on); - void Set_Repeat(int on); - void Set_Score_Volume(int volume); - void Set_Sound_Volume(int volume, int feedback); - void Set_Brightness(int brightness); - int Get_Brightness(void) const; - void Set_Color(int color); - int Get_Color(void) const; - void Set_Contrast(int contrast); - int Get_Contrast(void) const; - void Set_Tint(int tint); - int Get_Tint(void) const; - int Normalize_Delay(int delay) const; - int Normalize_Sound(int volume) const; - - /* - ** File I/O routines - */ - void Load_Settings(void); - void Save_Settings(void); - - void Set(void); - - /* - ** This is actually the delay between game frames expressed as 1/60 of - ** a second. The default value is 4 (1/15 second). - */ - unsigned int GameSpeed; - - int ScrollRate; // Distance to scroll. - unsigned char Brightness; - unsigned char Volume; // Volume for sound effects. - unsigned char ScoreVolume; // Volume for scores. - unsigned char Contrast; // Value - unsigned char Color; // Saturation - unsigned char Tint; // Hue - unsigned AutoScroll:1; // Does map autoscroll? - unsigned IsScoreRepeat:1; // Score should repeat? - unsigned IsScoreShuffle:1; // Score list should shuffle? - unsigned IsDeathAnnounce:1;// Announce enemy deaths? - unsigned IsFreeScroll:1; // Allow free direction scrolling? - - protected: - - void Adjust_Palette(void *oldpal, void *newpal, unsigned char brightness, unsigned char color, unsigned char tint, unsigned char contrast) const; - - private: -}; - - -#endif diff --git a/code/TIBERIANDAWN/OVERLAY.CPP b/code/TIBERIANDAWN/OVERLAY.CPP deleted file mode 100644 index 7ea4940..0000000 --- a/code/TIBERIANDAWN/OVERLAY.CPP +++ /dev/null @@ -1,429 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\overlay.cpv 2.17 16 Oct 1995 16:50:44 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OVERLAY.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 17, 1994 * - * * - * Last Update : July 24, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * OverlayClass::Read_INI -- Reads the overlay data from an INI file. * - * OverlayClass::Write_INI -- Writes the overlay data to an INI file. * - * OverlayClass::delete -- Returns a overlay object to the pool. * - * OverlayClass::Init -- Resets the overlay object system. * - * OverlayClass::new -- Allocates a overlay object from pool * - * OverlayClass::OverlayClass -- Overlay object constructor. * - * OverlayClass::Mark -- Marks the overlay down on the map. * - * OverlayClass::Validate -- validates overlay * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "overlay.h" - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * OverlayClass::VTable; - -HousesType OverlayClass::ToOwn = HOUSE_NONE; - -OverlayClass::OverlayClass(void) : Class(0) {ToOwn = HOUSE_NONE;}; - - -/*********************************************************************************************** - * OverlayClass::Validate -- validates overlay * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int OverlayClass::Validate(void) const -{ - int num; - - num = Overlays.ID(this); - if (num < 0 || num >= OVERLAY_MAX) { - Validate_Error("OVERLAY"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * OverlayClass::Init -- Resets the overlay object system. * - * * - * This routine resets the overlay object system. It is called * - * prior to loading a new scenario. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void OverlayClass::Init(void) -{ - OverlayClass *ptr; - - Overlays.Free_All(); - - ptr = new OverlayClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * OverlayClass::new -- Allocates a overlay object from pool * - * * - * This routine is used to allocate a overlay object from the * - * overlay object pool. * - * * - * INPUT: size -- The size of a overlay object (not used). * - * * - * OUTPUT: Returns with a pointer to an available overlay object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -void * OverlayClass::operator new(size_t ) -{ - void * ptr = Overlays.Allocate(); - if (ptr) { - ((OverlayClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * OverlayClass::delete -- Returns a overlay object to the pool. * - * * - * This routine will return a overlay object to the overlay object * - * pool. A overlay so returned is available for allocation again. * - * * - * INPUT: ptr -- Pointer to the object to be returned. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -void OverlayClass::operator delete(void *ptr) -{ - if (ptr) { - ((OverlayClass *)ptr)->IsActive = false; - } - Overlays.Free((OverlayClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * OverlayClass::OverlayClass -- Overlay object constructor. * - * * - * This is the constructor for a overlay object. * - * * - * INPUT: type -- The overlay object this is to become. * - * * - * pos -- The position on the map to place the object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -OverlayClass::OverlayClass(OverlayType type, CELL pos, HousesType house) : - Class(&OverlayTypeClass::As_Reference(type)) -{ - if (pos != -1) { - ToOwn = house; - Unlimbo(Cell_Coord(pos)); - ToOwn = HOUSE_NONE; - } -} - - -/*********************************************************************************************** - * OverlayClass::Mark -- Marks the overlay down on the map. * - * * - * This routine will place the overlay onto the map. The overlay object is deleted by this * - * operation. The map is updated to reflect the presence of the overlay. * - * * - * INPUT: mark -- The type of marking to perform. Only MARK_DOWN is supported. * - * * - * OUTPUT: bool; Was the overlay successfully marked? Failure occurs if it is not being * - * marked down. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - * 12/23/1994 JLB : Checks low level legality before proceeding. * - *=============================================================================================*/ -bool OverlayClass::Mark(MarkType mark) -{ - Validate(); - if (ObjectClass::Mark(mark)) { - if (mark == MARK_DOWN) { - CELL cell = Coord_Cell(Coord); - CellClass * cellptr = &Map[cell]; - - /* - ** Road placement occurs in two steps. First the foundation is placed, but only - ** on buildable terrain. Second, the road is completed, but only if the foundation - ** was previously placed. - */ - if (*this == OVERLAY_ROAD) { - if ((cellptr->Overlay == OVERLAY_ROAD && cellptr->OverlayData == 0) || - (cellptr->Overlay == OVERLAY_NONE && cellptr->Is_Generally_Clear())) { - - if (cellptr->Overlay == OVERLAY_ROAD) { - cellptr->OverlayData = 1; - } else { - cellptr->OverlayData = 0; - } - cellptr->Overlay = Class->Type; - cellptr->Redraw_Objects(); - } - } else { - - /* - ** Walls have special logic when they are marked down. - */ - if (Class->IsWall) { - if (cellptr->Is_Generally_Clear() && cellptr->Overlay != OVERLAY_FLAG_SPOT) { - cellptr->Overlay = Class->Type; - cellptr->OverlayData = 0; - cellptr->Redraw_Objects(); - cellptr->Wall_Update(); - - /* - ** Flag ownership of the cell if the 'global' ownership flag indicates that this - ** is necessary for the overlay. - */ - if (ToOwn != HOUSE_NONE) { - cellptr->Owner = ToOwn; - } - - } else { - Delete_This(); - return(false); - } - } else { - if ((cellptr->Overlay == OVERLAY_NONE || cellptr->Overlay == OVERLAY_SQUISH) && !cellptr->Cell_Terrain() && Ground[cellptr->Land_Type()].Build) { - - /* - ** Increment the global crate counter. This is used to regulate - ** the crate generation. - */ - if (Class->IsCrate) CrateCount++; - - /* - ** Don't show the squish unless the gross flag is active. - */ - if (!Special.IsGross && Class->Type != OVERLAY_SQUISH) { - cellptr->Overlay = Class->Type; - cellptr->OverlayData = 0; - } - cellptr->Redraw_Objects(); - if (Class->Land == LAND_TIBERIUM) { - cellptr->OverlayData = 1; - cellptr->Tiberium_Adjust(); - } else { - if (*this == OVERLAY_CONCRETE) { - CELL newcell; - - /* - ** Smudges go away when concrete is laid down. - */ - cellptr->Smudge = SMUDGE_NONE; - cellptr->SmudgeData = 0; - cellptr->Concrete_Calc(); - - /* - ** Possibly add concrete to adjacent cells depending on whether this - ** concrete is in an odd or even row. - */ - if (Cell_X(cell) & 0x01) { - newcell = Adjacent_Cell((CELL)(cellptr->Cell_Number()), FACING_W); - } else { - newcell = Adjacent_Cell((CELL)(cellptr->Cell_Number()), FACING_E); - } - if (Map[newcell].Overlay != OVERLAY_CONCRETE) { - Class->Create_And_Place(newcell); - } - - /* - ** The display attributes must be recalculated for all adjacent - ** cells since their shape can be altered by the presence of - ** concrete at this location. - */ - static FacingType _face[4] = {FACING_N, FACING_E, FACING_S, FACING_W}; - - for (int index = 0; index < (sizeof(_face)/sizeof(_face[0])); index++) { - CellClass * adjcell = cellptr->Adjacent_Cell(_face[index]); - if (adjcell) adjcell->Concrete_Calc(); - } - } - } - } - } - - /* - ** ***** Is this really needed? - */ - cellptr->Recalc_Attributes(); - } - Delete_This(); - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * OverlayClass::Read_INI -- Reads the overlay data from an INI file. * - * * - * This routine is used to load a scenario's overlay data. The overlay objects are read * - * from the INI file and then created on the map. * - * * - * INPUT: buffer -- Pointer to the INI file staging buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - * 07/24/1995 JLB : Specifically forbid manual crates in multiplayer scenarios. * - *=============================================================================================*/ -void OverlayClass::Read_INI(char *buffer) -{ - char *tbuffer; - int len; // Length of data in buffer. - char buf[128]; - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - while (*tbuffer != '\0') { - CELL cell; - OverlayType classid; - - cell = atoi(tbuffer); - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - classid = OverlayTypeClass::From_Name(strtok(buf, ",\n\r")); - - /* - ** Don't allow placement of crates in the multiplayer scenarios. - */ - if (classid != OVERLAY_NONE && (GameToPlay == GAME_NORMAL || !OverlayTypeClass::As_Reference(classid).IsCrate)) { - - /* - ** Don't allow placement of overlays on the top or bottom rows of - ** the map. - */ - if (cell >= MAP_CELL_W && cell <= MAP_CELL_TOTAL - MAP_CELL_W) { - new OverlayClass(classid, cell); - } - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * OverlayClass::Write_INI -- Writes the overlay data to an INI file. * - * * - * This is used to output the overlay data to a scenario INI file. Typically, this is * - * only used by the scenario editor. * - * * - * INPUT: buffer -- Pointer to the INI file staging buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void OverlayClass::Write_INI(char *buffer) -{ - int index; - char uname[10]; - char buf[128]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing unit data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Write the unit data out. - */ - for (index = 0; index < MAP_CELL_TOTAL; index++) { - CellClass * cellptr = &Map[index]; - - if (cellptr->Overlay != OVERLAY_NONE) { - sprintf(uname, "%03d", index); - sprintf(buf, "%s", OverlayTypeClass::As_Reference(cellptr->Overlay).IniName); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/OVERLAY.H b/code/TIBERIANDAWN/OVERLAY.H deleted file mode 100644 index 007f384..0000000 --- a/code/TIBERIANDAWN/OVERLAY.H +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\overlay.h_v 2.16 16 Oct 1995 16:44:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OVERLAY.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 17, 1994 * - * * - * Last Update : May 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef OVERLAY_H -#define OVERLAY_H - -#include "object.h" -#include "type.h" - -/****************************************************************************** -** This class controls the overlay object. Overlay objects function congruously -** to carpet on a floor. They have no depth, but merely control the icon to be rendered -** as the cell's bottom most layer. -*/ -class OverlayClass : public ObjectClass -{ - public: - /*------------------------------------------------------------------- - ** Constructors and destructors. - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - OverlayClass(void); - OverlayClass(OverlayType type, CELL pos=-1, HousesType = HOUSE_NONE); - virtual ~OverlayClass(void) {if (GameActive) OverlayClass::Limbo();}; - operator OverlayType(void) const {return Class->Type;}; - virtual RTTIType What_Am_I(void) const {return RTTI_OVERLAY;}; - - static void Init(void); - - /* - ** File I/O. - */ - static void Read_INI(char *); - static void Write_INI(char *); - static char *INI_Name(void) {return "OVERLAY";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Virtual support functionality. - */ - virtual bool Mark(MarkType); - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - virtual void Draw_It(int , int , WindowNumberType ) {}; - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - private: - /* - ** This is used to control the marking process of the overlay. If this is - ** set to a valid house number, then the cell that the overlay is marked down - ** upon will be flagged as being owned by the specified house. - */ - static HousesType ToOwn; - - /* - ** This is a pointer to the overlay object's class. - */ - OverlayTypeClass const * const Class; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[8]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/PACKET.CPP b/code/TIBERIANDAWN/PACKET.CPP deleted file mode 100644 index 2d0b33a..0000000 --- a/code/TIBERIANDAWN/PACKET.CPP +++ /dev/null @@ -1,461 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - * * - * Project Name : Westwood Auto Registration App * - * * - * File Name : PACKET.CPP * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 04/22/96 * - * * - * Last Update : April 24, 1996 [PWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * *PacketClass::Find_Field -- Finds a field if it exists in the packets * - * Get_Field -- Find specified name and returns data * - * PacketClass::~PacketClass -- destroys a packet class be freeing list * - * PacketClass::Add_Field -- Adds a FieldClass entry to head of packet li* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include -//#include -#include - -//enum {false=0,true=1}; -//typedef int bool; - -#include "packet.h" - - -/************************************************************************** - * PACKETCLASS::~PACKETCLASS -- destroys a packet class be freeing list * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 04/24/1996 PWG : Created. * - *========================================================================*/ -PacketClass::~PacketClass(void) -{ - FieldClass *current; - FieldClass *next; - // - // Loop through the entire field list and delete each entry. - // - for (current = Head; current; current = next) { - next = current->Next; - delete current; - } -} - - -/************************************************************************** - * PACKETCLASS::ADD_FIELD -- Adds a FieldClass entry to head of packet li * - * * - * INPUT: FieldClass * - a properly constructed field class entry. * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 04/24/1996 PWG : Created. * - *========================================================================*/ -void PacketClass::Add_Field(FieldClass *field) -{ - field->Next = Head; - Head = field; -} - -/************************************************************************** - * PACKETCLASS::PACKETCLASS -- Creates a Packet object from a COMMS packe * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/22/1996 PWG : Created. * - *========================================================================*/ -PacketClass::PacketClass(char *curbuf) -{ - int remaining_size; - // - // Pull the size and packet ID out of the linear packet stream. - // - Size = *(unsigned short *)curbuf; - curbuf += sizeof (unsigned short); - Size = ntohs(Size); - ID = *(short *)curbuf; - curbuf += sizeof (short); - ID = ntohs(ID); - Head = NULL; - - // - // Calculate the remaining size so that we can loop through the - // packets and extract them. - // - remaining_size = Size - 4; - - // - // Loop through the linear packet until we run out of room and - // create a field for each. - // - while (remaining_size > 0) { - FieldClass *field = new FieldClass; - - // - // Copy the adjusted header into the buffer and then advance the buffer - // - memcpy(field, curbuf, FIELD_HEADER_SIZE); - curbuf += FIELD_HEADER_SIZE; - remaining_size -= FIELD_HEADER_SIZE; - - // - // Copy the data into the buffer - // - int size = ntohs(field->Size); - field->Data = new char[size]; - memcpy(field->Data, curbuf, size); - curbuf += size; - remaining_size -= size; - // - // Make sure we allow for the pad bytes. - // - int pad = (4 - (ntohs(field->Size) & 3)) & 3; - curbuf += pad; - remaining_size -= pad; - - // - // Convert the field back to the host format - // - field->Net_To_Host(); - - // - // Finally add the field to the field list in the packet - // structure. - // - Add_Field(field); - } -} - -/************************************************************************** - * CREATE_COMMS_PACKET -- Walks field list creating a packet * - * * - * INPUT: short - the id of the packet so the server can identify it * - * unsigned short & - the size of the packet returned here * - * * - * OUTPUT: void * pointer to the linear packet data * - * * - * WARNINGS: This routine allocates memory that the user is responsible * - * for freeing. * - * * - * HISTORY: * - * 04/22/1996 PWG : Created. * - *========================================================================*/ -char *PacketClass::Create_Comms_Packet(int &size) -{ - FieldClass *current; - - // - // Size starts at four because that is the size of the packet header. - // - size = 4; - - // - // Take a quick spin through and calculate the size of the packet we - // are building. - // - for (current = Head; current; current=current->Next) { - size += (unsigned short)FIELD_HEADER_SIZE; // add in packet header size - size += current->Size; // add in data size - size += (4 - (size & 3)) & 3; // add in pad value to dword align next packet - } - - // - // Now that we know the size allocate a buffer big enough to hold the - // packet. - // - char *retval = new char[size]; - char *curbuf = retval; - - // - // write the size into the packet header - // - *(unsigned short *)curbuf = (unsigned short)htons((unsigned short)size); - curbuf += sizeof (unsigned short); - *(short *)curbuf = htons(ID); - curbuf += sizeof (short); - - // - // Ok now that the actual header information has been written we need to write out - // field information. - // - for (current = Head; current; current = current->Next) { - // - // Temporarily convert the packet to net format (this saves alot of - // effort, and seems safe...) - // - current->Host_To_Net(); - - // - // Copy the adjusted header into the buffer and then advance the buffer - // - memcpy(curbuf, current, FIELD_HEADER_SIZE); - curbuf += FIELD_HEADER_SIZE; - - // - // Copy the data into the buffer and then advance the buffer - // - memcpy(curbuf, current->Data, ntohs(current->Size)); - curbuf += ntohs(current->Size); - - // - // Finally take care of any pad bytes by setting them to 0 - // - int pad = (4 - (ntohs(current->Size) & 3)) & 3; - - // - // If there is any pad left over, make sure you memset it - // to zeros, so it looks like a pad. - // - if (pad) { - memset(curbuf, 0, pad); - curbuf += pad; - } - - current->Net_To_Host(); - } - return(retval); -} - - -/************************************************************************** - * PACKETCLASS::FIND_FIELD -- Finds a field if it exists in the packets * - * * - * INPUT: char * - the id of the field we are looking for. * - * * - * OUTPUT: FieldClass * pointer to the field class * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -FieldClass *PacketClass::Find_Field(char *id) -{ - for (FieldClass *current = Head; current; current = current->Next) { - if ( strncmp(id, current->ID, 4) == 0) - return current; - } - return NULL; -} - - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * char & - the reference to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, char &data) -{ - FieldClass *field = Find_Field(id); - if (field) { - data = *((char *)field->Data); - } - return((field) ? true : false); -} - - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * unsigned char & - the reference to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, unsigned char &data) -{ - FieldClass *field = Find_Field(id); - if (field) { - data = *((unsigned char *)field->Data); - } - return((field) ? true : false); -} - - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * short & - the reference to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, short &data) -{ - FieldClass *field = Find_Field(id); - if (field) { - data = *((short *)field->Data); - } - return((field) ? true : false); -} - - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * unsigned short & - the reference to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, unsigned short &data) -{ - FieldClass *field = Find_Field(id); - if (field) { - data = *((unsigned short *)field->Data); - } - return((field) ? true : false); -} - - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * long & - the reference to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, long &data) -{ - FieldClass *field = Find_Field(id); - if (field) { - data = *((long *)field->Data); - } - return((field) ? true : false); -} - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data as a string * - * * - * INPUT: char * - the id of the field that holds the data. * - * char * - the string to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The string is not changed if the field is not found. It * - * is assumed that the string variabled specified by the * - * pointer is large enough to hold the data. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -#pragma warning(disable:4996) -bool PacketClass::Get_Field(char *id, char *data) -{ - FieldClass *field = Find_Field(id); - if (field) { - strcpy(data, (char *)field->Data); - } - return((field) ? true : false); -} - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * unsigned long & - the reference to store the data into * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 04/23/1996 PWG : Created. * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, unsigned long &data) -{ - FieldClass *field = Find_Field(id); - if (field) { - data = *((unsigned long *)field->Data); - } - return((field) ? true : false); -} - - -/************************************************************************** - * GET_FIELD -- Find specified name and returns data * - * * - * INPUT: char * - the id of the field that holds the data. * - * void * - the reference to store the data into * - * int - the length of the buffer passed in * - * * - * OUTPUT: true if the field was found, false if it was not. * - * * - * WARNINGS: The data reference is not changed if the field is not * - * found. * - * * - * HISTORY: * - * 6/4/96 4:46PM ST : Created * - *========================================================================*/ -bool PacketClass::Get_Field(char *id, void *data, int &length) -{ - FieldClass *field = Find_Field(id); - if (field) { - memcpy (data, field->Data, min(field->Size, length)); - length = (int) field->Size; - } - return((field) ? true : false); -} diff --git a/code/TIBERIANDAWN/PACKET.H b/code/TIBERIANDAWN/PACKET.H deleted file mode 100644 index 367d802..0000000 --- a/code/TIBERIANDAWN/PACKET.H +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - * * - * Project Name : Westwood Auto Registration App * - * * - * File Name : PACKET.H * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 04/19/96 * - * * - * Last Update : April 19, 1996 [PWG] * - * * - * This header defines the functions for the PacketClass. The packet * - * class is used to create a linked list of field entries which can be * - * converted to a linear packet in a COMMS API compatible format. * - * * - * Packets can be created empty and then have fields added to them or can * - * be created from an existing linear packet. * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef __PACKET_H -#define __PACKET_H - - -#include "field.h" - -class PacketClass { - public: - PacketClass(short id = 0) - { - Size = 0; - ID = id; - Head = 0; - } - PacketClass(char *cur_buf); - ~PacketClass(void); - - // - // This function allows us to add a field to the start of the list. As the field is just - // a big linked list it makes no difference which end we add a member to. - // - void Add_Field(FieldClass *field); - - // - // These conveniance functions allow us to add a field directly to the list without - // having to worry about newing one first. - // - void Add_Field(char *field, char data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, unsigned char data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, short data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, unsigned short data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, long data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, unsigned long data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, char *data) {Add_Field(new FieldClass(field, data));}; - void Add_Field(char *field, void *data, int length) {Add_Field(new FieldClass(field, data, length));}; - - // - // These functions search for a field of a given name in the list and - // return the data via a reference value. - // - FieldClass *Find_Field(char *id); - bool Get_Field(char *id, char &data); - bool Get_Field(char *id, unsigned char &data); - bool Get_Field(char *id, short &data); - bool Get_Field(char *id, unsigned short &data); - bool Get_Field(char *id, long &data); - bool Get_Field(char *id, unsigned long &data); - bool Get_Field(char *id, char *data); - bool Get_Field(char *id, void *data, int &length); - - char *Create_Comms_Packet(int &size); - - private: - unsigned short Size; - short ID; - FieldClass *Head; - FieldClass *Current; -}; - - -#endif diff --git a/code/TIBERIANDAWN/PAGFAULT.ASM b/code/TIBERIANDAWN/PAGFAULT.ASM deleted file mode 100644 index 48112be..0000000 --- a/code/TIBERIANDAWN/PAGFAULT.ASM +++ /dev/null @@ -1,222 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Library * -;* * -;* File Name : PAGFAULT.ASM * -;* * -;* Programmer : Julio R Jerez * -;* * -;* Date : April 25,1995 * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -; -; Here are prototypes for the routines defined within this module: -; VOID Install_Page_Fault_Handle (void) ; -; -; ---------------------------------------------------------------- - -IDEAL ; the product runs in ideal mode -P386 ; use 386 real mode instructions -MODEL USE32 FLAT -LOCALS ?? ; ?? is the symbol for a local -WARN ; generate all warnings we can -JUMPS ; optimize jumps if possible - -;--------------------------------------------------------------------------- -; Make some general equates for easy compatability -;--------------------------------------------------------------------------- -DPMI_INTR EQU 31h -PAGE_FAULT equ 0eh -DIVIDE_ERROR equ 00h -RESET_VIDEO_MODE equ -1 - -global C Install_Page_Fault_Handle : NEAR -global C Set_Video_Mode : NEAR -global C Remove_Mouse : NEAR -global C Remove_Keyboard_Interrupt : NEAR -global C Remove_Timer_Interrupt : NEAR - -DATASEG - Old_Page_Fault_handle DF ? - Page_Fault_SS DD ? - Page_Fault_ESP DD ? - - Old_Div_Error_handle DF ? - Div_Error_SS DD ? - Div_Error_ESP DD ? - - -CODESEG -;*************************************************************************** -;* INSTALL_PAGE_FAULT_HANDLE -- Installs new page fault and div Error * -;* handles. * -;* This function will install a new page fault handle and Div Error * -;* so in the event that we have a program crash these handles will * -;* remove all interrupts and then will chain to the default Exception * -;* Handle * -;* * -;* INPUT: none * -;* * -;* * -;* OUTPUT: none * -;* * -;* PROTO: VOID Install_Page_Fault_Handle( void); * -;* * -;* HISTORY: 04/25/96 Created * -;*=========================================================================* - PROC Install_Page_Fault_Handle C NEAR - USES eax,ebx,ecx,edx,esi,edi - - ; Install_Page_Fault_Handle - mov eax,0202h ; get address of exception handle - mov bl,PAGE_FAULT - int DPMI_INTR - jc ??exit ; not action is taken - - ; save addrees of default handle - mov [dword ptr Old_Page_Fault_handle],edx - mov [word ptr Old_Page_Fault_handle+4],cx - - ; redirect default handle to a new Page Fault Handle - mov eax,0203h - mov bl,PAGE_FAULT - mov cx,cs - lea edx,[Page_Fault_Handle] - int DPMI_INTR - - - ; Install_Divide_Error_Handle - mov eax,0202h ; get address of exception handle - mov bl,DIVIDE_ERROR - int DPMI_INTR - jc ??exit ; not action is taken - - ; save addrees of default fault handle - mov [dword ptr Old_Div_Error_handle],edx - mov [word ptr Old_Div_Error_handle+4],cx - - ; redirect default handle to a new Divede Handle - mov eax,0203h - mov bl,DIVIDE_ERROR - mov cx,cs - lea edx,[Divide_Error_Handle] - int DPMI_INTR - - ??exit: - - - ret - ENDP Install_Page_Fault_Handle - - -;*************************************************************************** -;* PAGE_FAULT_HANDLE -- This * -;* * -;* * -;* * -;* HISTORY: 04/25/96 Created * -;*=========================================================================* -PROC Page_Fault_Handle far - - ; preserve used registers - push eax - push ebx - ; save Page Fault satck frame - mov ax,ss - mov [Page_Fault_SS],eax - mov [Page_Fault_ESP],esp - - ; retrieve application original stack frame - mov eax , [ esp + ( 6 + 2 ) * 4 ] - mov ebx , [ esp + ( 7 + 2 ) * 4 ] - mov ss , bx - mov esp , eax - - ; set video mode to standard text mode - push RESET_VIDEO_MODE - call Set_Video_Mode - pop eax - call Remove_Mouse - call Remove_Keyboard_Interrupt - call Remove_Timer_Interrupt - - ; restore Page Fault stack frame - mov eax,[Page_Fault_SS] - mov ss , ax - mov esp, [Page_Fault_ESP] - - ; restore used registers and chain to default Page Fault Handle - pop ebx - pop eax - jmp [fword Old_Page_Fault_handle] - - ENDP Page_Fault_Handle - - - -;*************************************************************************** -;* Divide_Error -- * -;* * -;* * -;* * -;* HISTORY: 04/25/96 Created * -;*=========================================================================* -PROC Divide_Error_Handle far - - ; preserve used registers - push eax - push ebx - ; save Page Fault satck frame - mov ax,ss - mov [Div_Error_SS],eax - mov [Div_Error_ESP],esp - - ; retrieve application original stack frame - mov eax , [ esp + ( 6 + 2 ) * 4 ] - mov ebx , [ esp + ( 7 + 2 ) * 4 ] - mov ss , bx - mov esp , eax - - ; set video mode to standard text mode - push RESET_VIDEO_MODE - call Set_Video_Mode - pop eax - call Remove_Mouse - call Remove_Keyboard_Interrupt - call Remove_Timer_Interrupt - - ; restore Fault stack frame - mov eax,[Div_Error_SS] - mov ss , ax - mov esp, [Div_Error_ESP] - - ; restore used registers and chain to default Page Fault Handle - pop ebx - pop eax - jmp [fword Old_Div_Error_handle] - - ENDP Divide_Error_Handle - - -;*************************************************************************** -;* End of File. * -;*************************************************************************** -END diff --git a/code/TIBERIANDAWN/PHONE.H b/code/TIBERIANDAWN/PHONE.H deleted file mode 100644 index bcb6f65..0000000 --- a/code/TIBERIANDAWN/PHONE.H +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\phone.h_v 1.9 16 Oct 1995 16:47:58 JOE_BOSTIC $ */ -/*************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : PHONE.H * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 04/28/95 * - * * - * Last Update : April 28, 1995 [BRR] * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef PHONE_H -#define PHONE_H - -/* -***************************** Class Declaration ***************************** -*/ -class PhoneEntryClass -{ - public: - enum PhoneEntryEnum { - PHONE_MAX_NAME = 21, - PHONE_MAX_NUM = 21 - }; - - PhoneEntryClass(void) {}; - ~PhoneEntryClass() {}; - - operator == (PhoneEntryClass &obj) - { return (memcmp (Name,obj.Name,strlen(Name))==0);} - operator != (PhoneEntryClass &obj) - { return (memcmp (Name,obj.Name,strlen(Name))!=0);} - operator > (PhoneEntryClass &obj) - { return (memcmp(Name, obj.Name, strlen(Name)) > 0);} - operator < (PhoneEntryClass &obj) - { return (memcmp(Name, obj.Name, strlen(Name)) < 0);} - operator >= (PhoneEntryClass &obj) - { return (memcmp(Name, obj.Name, strlen(Name)) >= 0);} - operator <= (PhoneEntryClass &obj) - { return (memcmp(Name, obj.Name, strlen(Name)) <= 0);} - - SerialSettingsType Settings; - char Name[ PHONE_MAX_NAME ]; // destination person's name - char Number[ PHONE_MAX_NUM ]; // phone # -}; - -#endif diff --git a/code/TIBERIANDAWN/POWER.CPP b/code/TIBERIANDAWN/POWER.CPP deleted file mode 100644 index 021a0ad..0000000 --- a/code/TIBERIANDAWN/POWER.CPP +++ /dev/null @@ -1,459 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\power.cpv 2.18 16 Oct 1995 16:52:10 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : POWER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : August 7, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * PowerClass::AI -- Process the power bar logic. * - * PowerClass::Draw_It -- Renders the power bar graphic. * - * PowerClass::Init_Clear -- Clears all the power bar variables. * - * PowerClass::One_Time -- One time processing for the power bar. * - * PowerClass::PowerButtonClass::Action -- Handles the mouse over the power bar area. * - * PowerClass::PowerClass -- Default constructor for the power bar class. * - * PowerClass::Refresh_Cells -- Intercepts the redraw logic to see if sidebar to redraw too. * - * Power_Height -- Given a value figure where it falls on bar * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -** Points to the shape to use for the "desired" power level indicator. -*/ -void const * PowerClass::PowerShape; -void const * PowerClass::PowerBarShape; - -PowerClass::PowerButtonClass PowerClass::PowerButton; - - -/*********************************************************************************************** - * PowerClass::PowerClass -- Default constructor for the power bar class. * - * * - * This is the default constructor for the power bar class. It doesn't really do anything. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/20/1994 JLB : Created. * - *=============================================================================================*/ -PowerClass::PowerClass(void) -{ - IsToRedraw = false; - RecordedDrain = -1; - RecordedPower = -1; - DesiredDrainHeight = 0; - DesiredPowerHeight = 0; - DrainHeight = 0; - PowerHeight = 0; - PowerBounce = 0; - DrainBounce = 0; - DrainDir = 0; - PowerDir = 0; -} - - -/*********************************************************************************************** - * PowerClass::Init_Clear -- Clears all the power bar variables. * - * * - * This routine is called in preparation for the start of a scenario. The power bar is * - * initialized into the null state by this routine. As soon as the scenario starts, the * - * power bar will rise to reflect the actual power output and drain. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/07/1995 JLB : Created. * - *=============================================================================================*/ -void PowerClass::Init_Clear(void) -{ - RadarClass::Init_Clear(); - RecordedDrain = -1; - RecordedPower = -1; - DesiredDrainHeight = 0; - DesiredPowerHeight = 0; - DrainHeight = 0; - PowerHeight = 0; - PowerBounce = 0; - DrainBounce = 0; - DrainDir = 0; - PowerDir = 0; -} - - -/*********************************************************************************************** - * PowerClass::One_Time -- One time processing for the power bar. * - * * - * This routine is for code that truly only needs to be done once per game run. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -void PowerClass::One_Time(void) -{ - RadarClass::One_Time(); - - int factor = Get_Resolution_Factor(); - PowX = SeenBuff.Get_Width() - Map.RadWidth; - PowY = Map.RadY+Map.RadHeight + (13 << factor); - PowWidth = 8 << factor; - PowHeight = SeenBuff.Get_Height() - PowY; - PowLineSpace = 5 << factor; - PowLineWidth = PowWidth - 4; - - PowerButton.X = PowX; - PowerButton.Y = PowY; - PowerButton.Width = PowWidth-1; - PowerButton.Height = PowHeight; - - PowerShape = MixFileClass::Retrieve((factor)? "HPOWER.SHP" :"POWER.SHP"); - PowerBarShape = Hires_Retrieve("PWRBAR.SHP"); -} - - -/*********************************************************************************************** - * PowerClass::Draw_It -- Renders the power bar graphic. * - * * - * This routine will draw the power bar graphic to the LogicPage. * - * * - * INPUT: complete -- Should the power bar be redrawn even if it isn't specifically flagged * - * to do so? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/20/1994 JLB : Created. * - * 12/27/1994 JLB : Changes power bar color depending on amount of power. * - *=============================================================================================*/ -void PowerClass::Draw_It(bool complete) -{ - static int _modtable[]={ - 0, -1, 0, 1, 0, -1, -2, -1, 0, 1, 2, 1 ,0 - }; - int power_color; - - if (complete || IsToRedraw) { -// PowX = TacPixelX + TacWidth*ICON_PIXEL_W; // X position of upper left corner of power bar. - - if (LogicPage->Lock()){ - - if (Map.IsSidebarActive) { - IsToRedraw = false; - - /* - ** 1st get the height of the filled section of the power bar - */ - int bottom = PowY + PowHeight - 1; - int power_height = (PowerHeight == DesiredPowerHeight) ? PowerHeight + (_modtable[PowerBounce] * PowerDir) : PowerHeight; - int drain_height = (DrainHeight == DesiredDrainHeight) ? DrainHeight + (_modtable[DrainBounce] * DrainDir) : DrainHeight; - power_height = Bound(power_height, 0, PowHeight - 2); - drain_height = Bound(drain_height, 0, PowHeight - 2); - - /* - ** Create a clip region to draw the unfilled section of the bar - */ - WindowList[WINDOW_CUSTOM][WINDOWX] = 0; - WindowList[WINDOW_CUSTOM][WINDOWY] = 0; - WindowList[WINDOW_CUSTOM][WINDOWWIDTH] = SeenBuff.Get_Width(); - WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = bottom-power_height; - - /* - ** Draw the unfilled section - */ - CC_Draw_Shape(PowerBarShape, 0, PowX, PowY, WINDOW_CUSTOM, SHAPE_WIN_REL); - CC_Draw_Shape(PowerBarShape, 1 ,PowX, PowY+100, WINDOW_CUSTOM, SHAPE_WIN_REL); - - - /* - ** Set up the clip region for the filled section - */ - WindowList[WINDOW_CUSTOM][WINDOWY] = bottom-power_height; - WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = SeenBuff.Get_Height() - WindowList[WINDOW_CUSTOM][WINDOWY]; - - /* - ** What color is the filled section? - */ - if (power_height) { - power_color = 0; //green - - if (PlayerPtr->Drain > PlayerPtr->Power) { - power_color = 2; - } - if (PlayerPtr->Drain > (PlayerPtr->Power * 2)) { - power_color = 4; - } - - /* - ** Draw the filled section - */ - CC_Draw_Shape(PowerBarShape, 2+power_color, - PowX, - PowY - WindowList[WINDOW_CUSTOM][WINDOWY], - WINDOW_CUSTOM, - SHAPE_WIN_REL); - - CC_Draw_Shape(PowerBarShape, 3+power_color, - PowX, - PowY - WindowList[WINDOW_CUSTOM][WINDOWY] + 100, - WINDOW_CUSTOM, - SHAPE_WIN_REL); - } - - /* - ** Draw the power drain threshold marker. - */ - CC_Draw_Shape(PowerShape, 0, PowX, bottom - drain_height + 1, WINDOW_MAIN, SHAPE_NORMAL); - - } - LogicPage->Unlock(); - } - } - RadarClass::Draw_It(complete); -} - - -/*********************************************************************************************** - * PowerClass::AI -- Process the power bar logic. * - * * - * Use this routine to process the power bar logic. This consists of animation effects. * - * * - * INPUT: input -- The player input value to be consumed or ignored as appropriate. * - * * - * x,y -- Mouse coordinate parameters to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/20/1994 JLB : Created. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - *=============================================================================================*/ -void PowerClass::AI(KeyNumType &input, int x, int y) -{ -// if (!IsActive) { -// IsActive = true; -// IsToRedraw = true; -// Flag_To_Redraw(false); -// } - - if (Map.IsSidebarActive /*IsActive*/) { - int olddrain = DrainHeight; - int oldpower = PowerHeight; - - - /* - ** If the recorded power value has changed we need to adjust for - ** it. - */ - if (PlayerPtr->Power != RecordedPower) { - DesiredPowerHeight = Power_Height(PlayerPtr->Power); - RecordedPower = PlayerPtr->Power; - PowerBounce = 12; - if (PowerHeight > DesiredPowerHeight) { - PowerDir = -1; - } else if (PowerHeight < DesiredPowerHeight) { - PowerDir = 1; - } else { - PowerBounce = 0; - } - } - - /* - ** If the recorded drain value has changed we need to adjust for - ** it. - */ - if (PlayerPtr->Drain != RecordedDrain) { - DesiredDrainHeight = Power_Height(PlayerPtr->Drain); - RecordedDrain = PlayerPtr->Drain; - DrainBounce = 12; - if (DrainHeight > DesiredDrainHeight) { - DrainDir = -1; - } else if (DrainHeight < DesiredDrainHeight) { - DrainDir = 1; - } else { - DrainBounce = 0; - } - } - - if (DrainBounce && DrainHeight == DesiredDrainHeight) { - IsToRedraw = true; - Flag_To_Redraw(false); - DrainBounce--; - } else { - /* - ** If we need to move the drain height then do so. - */ - if (DrainHeight != DesiredDrainHeight) { - DrainHeight += DrainDir; - } - } - - if (PowerBounce && PowerHeight == DesiredPowerHeight) { - IsToRedraw = true; - Flag_To_Redraw(false); - PowerBounce--; - } else { - /* - ** If we need to move the power height then do so. - */ - if (PowerHeight != DesiredPowerHeight) { - PowerHeight += PowerDir; - } - } - - if (olddrain != DrainHeight || oldpower != PowerHeight) { - IsToRedraw = true; - Flag_To_Redraw(false); - } - } - RadarClass::AI(input, x, y); -} - - -/*********************************************************************************************** - * PowerClass::Refresh_Cells -- Intercepts the redraw logic to see if sidebar to redraw too. * - * * - * This routine will examine a refresh list request and determine if the sidebar would be * - * affect. If so, it will flag the sidebar to be redrawn. * - * * - * INPUT: cell -- The cell that the offset list is base on. * - * * - * list -- The list of cell offset used to flag for redraw. If the special sidebar * - * affecting cell magic offset number is detected, the sidebar is flagged * - * for redraw and the magic offset is removed. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/01/1995 JLB : Created. * - *=============================================================================================*/ -void PowerClass::Refresh_Cells(CELL cell, short const *list) -{ - if (*list == REFRESH_SIDEBAR) { - IsToRedraw = true; - Flag_To_Redraw(false); - } - RadarClass::Refresh_Cells(cell, list); -} - - -/*************************************************************************** - * PowHeight -- Given a value figure where it falls on bar * - * * - * INPUT: int value - the value we are testing * - * * - * OUTPUT: int the height of the point that this value is on graph * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/14/1995 PWG : Created. * - *=========================================================================*/ -int PowerClass::Power_Height(int value) -{ - int num = value/ POWER_STEP_LEVEL; // figure out the initial num of DRAIN_VALUE's - int retval = 0; // currently there is no power - - /* - ** Loop through the diffrent hundreds figuring out the fractional piece - ** of each. - */ - for (int lp = 0; lp < num; lp ++) { - retval = retval + (((PowHeight - 2) - retval) / POWER_STEP_FACTOR); - value -= POWER_STEP_LEVEL; - } - - /* - ** Adjust the retval to factor in the remainder - */ - if (value) { - retval = retval + (((((PowHeight - 2) - retval) / POWER_STEP_FACTOR) * value) / POWER_STEP_LEVEL); - } - - retval = Bound(retval, 0, PowHeight -2); - return(retval); -} - - -/*********************************************************************************************** - * PowerClass::PowerButtonClass::Action -- Handles the mouse over the power bar area. * - * * - * This routine handles input on the power bar area. Since no input is used for the power * - * bar, this routine just pops up appropriate help text for the power bar. * - * * - * INPUT: flags -- The event flags that triggered this action call. * - * * - * key -- The key code (if any) associated with the trigger event. * - * * - * OUTPUT: Should further button processing be stopped? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/07/1995 JLB : Created. * - *=============================================================================================*/ -int PowerClass::PowerButtonClass::Action(unsigned flags, KeyNumType & key) -{ - if (!Map.IsSidebarActive) { - return(false); - } - - /* - ** Force any help label to disappear when the mouse is held over the - ** radar map. - */ - Map.Override_Mouse_Shape(MOUSE_NORMAL); - if (PlayerPtr->Power_Fraction() < 0x0100 && PlayerPtr->Power > 0) { - Map.Help_Text(TXT_POWER_OUTPUT_LOW, -1, -1, CC_GREEN); - } else { - Map.Help_Text(TXT_POWER_OUTPUT, -1, -1, CC_GREEN); - } - GadgetClass::Action(flags, key); - return(true); -} - - diff --git a/code/TIBERIANDAWN/POWER.H b/code/TIBERIANDAWN/POWER.H deleted file mode 100644 index 5223e63..0000000 --- a/code/TIBERIANDAWN/POWER.H +++ /dev/null @@ -1,123 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\power.h_v 2.16 16 Oct 1995 16:48:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : POWER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : December 15, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef POWER_H -#define POWER_H - -#include "radar.h" - -class PowerClass : public RadarClass -{ - public: - int PowX; - int PowY; - int PowWidth; - int PowHeight; - int PowLineSpace; - int PowLineWidth; - - - PowerClass(); - - /* - ** Initialization - */ - virtual void One_Time(void); // One-time inits - - virtual void Init_Clear(void); // Clears all to known state - virtual void Draw_It(bool complete=false); - virtual void AI(KeyNumType &input, int x, int y); - virtual void Refresh_Cells(CELL cell, short const *list); -// virtual void Must_Redraw_Sidebar(void); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - unsigned IsToRedraw:1; - - protected: - /* - ** This gadget is used to capture mouse input on the power bar. - */ - class PowerButtonClass : public GadgetClass { - public: - PowerButtonClass(void) : GadgetClass(0,0,0,0,LEFTPRESS|LEFTRELEASE|LEFTHELD|LEFTUP|RIGHTPRESS,true) {}; - - protected: - virtual int Action(unsigned flags, KeyNumType & key); - friend class PowerClass; - }; - - /* - ** This is the "button" that tracks all input to the tactical map. - ** It must be available to derived classes, for Save/Load purposes. - */ - static PowerButtonClass PowerButton; - - enum PowerEnums { - POWER_STEP_LEVEL=100, - POWER_STEP_FACTOR=6, - }; - - private: - int Power_Height(int value); - - unsigned IsActive:1; - - int RecordedDrain; - int RecordedPower; - int DesiredDrainHeight; - int DesiredPowerHeight; - int DrainHeight; - int PowerHeight; - int DrainBounce; - int PowerBounce; - short PowerDir; - short DrainDir; - - /* - ** Points to the shape to use for the "desired" power level indicator. - */ - static void const * PowerShape; - - /* - ** Points to the shapes to be used for drawing the power bar - */ - static void const * PowerBarShape; -}; - -#endif diff --git a/code/TIBERIANDAWN/PROFILE.CPP b/code/TIBERIANDAWN/PROFILE.CPP deleted file mode 100644 index 335592b..0000000 --- a/code/TIBERIANDAWN/PROFILE.CPP +++ /dev/null @@ -1,654 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\profile.cpv 2.18 16 Oct 1995 16:51:14 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : PROFILE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : September 10, 1993 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * WWGetPrivateProfileInt -- Fetches integer value from INI. * - * WWWritePrivateProfileInt -- Write a profile int to the profile data block. * - * WWGetPrivateProfileString -- Fetch string from INI. * - * WWWritePrivateProfileString -- Write a string to the profile data block. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** - * Read_Private_Config_Struct -- Fetches override integer value. * - * * - * INPUT: * - * OUTPUT: * - * WARNINGS: * - * HISTORY: * - * 08/05/1992 JLB : Created. * - *=========================================================================*/ -bool Read_Private_Config_Struct (char *profile, NewConfigType *config) -{ - config->DigitCard = WWGetPrivateProfileHex ("Sound", "Card", profile); - config->IRQ = WWGetPrivateProfileInt ("Sound", "IRQ", 0,profile); - config->DMA = WWGetPrivateProfileInt ("Sound", "DMA", 0,profile); - config->Port = WWGetPrivateProfileHex ("Sound", "Port", profile); - config->BitsPerSample= WWGetPrivateProfileInt ("Sound", "BitsPerSample",0,profile); - config->Channels = WWGetPrivateProfileInt ("Sound", "Channels", 0,profile); - config->Reverse = WWGetPrivateProfileInt ("Sound", "Reverse", 0,profile); - config->Speed = WWGetPrivateProfileInt ("Sound", "Speed", 0,profile); - WWGetPrivateProfileString ("Language", "Language", NULL, config->Language, 3, profile); - - return((config->DigitCard == 0) && (config->IRQ == 0) && (config->DMA == 0)); -} - - -/*************************************************************************** - * Get_Private_Profile_Hex -- Fetches override integer value. * - * * - * INPUT: * - * OUTPUT: * - * WARNINGS: * - * HISTORY: * - * 08/05/1992 JLB : Created. * - *=========================================================================*/ -unsigned WWGetPrivateProfileHex (char const *section, char const *entry, char *profile) -{ - // This buffer was overrun at the end due to the forced termination at MAX_ENTRY_SIZE below - char buffer[MAX_ENTRY_SIZE + 1]; // Integer staging buffer. - unsigned card; - - memset (buffer, '0', MAX_ENTRY_SIZE); // MAX_ENTRY_SIZE = 15 - buffer[MAX_ENTRY_SIZE] = '\0'; - - WWGetPrivateProfileString(section, entry, "0", buffer, MAX_ENTRY_SIZE, profile); - - if (strlen (buffer) > 0) { - sscanf (buffer, "%x", &card); - } else { - card = 0; - } - - return(card); -} - - -/*********************************************************************************************** - * WWGetPrivateProfileInt -- Fetches integer value. * - * * - * INPUT: * - * section section to read from * - * * - * entry name of entry to read * - * * - * def default value, if entry isn't found * - * * - * profile buffer containing INI data * - * * - * OUTPUT: * - * integer requested * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - *=============================================================================================*/ -int WWGetPrivateProfileInt(char const *section, char const *entry, int def, char *profile) -{ - char buffer[16]; // Integer staging buffer. - - /* - ** Store the default in the buffer. - */ - sprintf(buffer, "%d", def); - - /* - ** Get the buffer; use itself as the default. - */ - WWGetPrivateProfileString(section, entry, buffer, buffer, 15, profile); - - /* - ** Convert to int & return. - */ - return(atoi(buffer)); -} - - -/*********************************************************************************************** - * WWWritePrivateProfileInt -- Write a profile int to the profile data block. * - * * - * INPUT: * - * section section name to write to * - * * - * entry name of entry to write; if NULL, the entire section is deleted * - * * - * value value to write * - * * - * profile INI buffer * - * * - * OUTPUT: * - * true = success, false = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -bool WWWritePrivateProfileInt(char const *section, char const *entry, int value, char *profile) -{ - char buffer[250]; // Working section buffer. - - /* - ** Just return if nothing to do. - */ - if (!profile || !section) { - return(true); - } - - /* - ** Generate string to save. - */ - sprintf(buffer, "%d", value); - - /* - ** Save the string. - */ - return(WWWritePrivateProfileString(section, entry, buffer, profile)); -} - - -/*********************************************************************************************** - * WWGetPrivateProfileString -- Fetch game override string. * - * * - * INPUT: * - * section section name to read from * - * * - * entry name of entry to read; if NULL, all entry names are returned * - * * - * def default string to use if not found; can be NULL * - * * - * retbuffer buffer to store result in * - * * - * retlen max length of return buffer * - * * - * profile INI buffer * - * * - * OUTPUT: * - * ptr to entry found in INI buf; NULL if not found * - * * - * WARNINGS: * - * On the PC, the "\n" (10) is translated to "\r\n" (13,10) when it's written * - * to disk. This routine must take this into consideration, by searching * - * for \n when scanning backward, and for \r when scanning forward. * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - *=============================================================================================*/ -char * WWGetPrivateProfileString(char const *section, char const *entry, char const *def, char *retbuffer, int retlen, char *profile) -{ - char * workptr, // Working pointer into profile block. - * altworkptr; // Alternate work pointer. - char sec[50]; // Working section buffer. - char *retval; // Start of section or entry pointer. - char * next; // Pointer to start of next section (or EOF). - char c,c2; // Working character values. - int len; // Working substring length value. - int entrylen; // Byte length of specified entry. - char *orig_retbuf; // original retbuffer ptr - - /* - ** Fill in the default value just in case the entry could not be found. - */ - if (retbuffer) { - if (def) { - strncpy(retbuffer, def, retlen); - } - retbuffer[retlen-1] = '\0'; - orig_retbuf = retbuffer; - } - - /* - ** Make sure a profile string was passed in - */ - if (!profile || !section) { - return(retbuffer); - } - - /* - ** Build section string to match file image. - */ - sprintf(sec, "[%s]", section); // sec = section name including []'s - strupr(sec); - len = strlen(sec); // len = section name length, incl []'s - - /* - ** Scan for a matching section - */ - retval = profile; - workptr = profile; - for (;;) { - - /* - ** 'workptr' = start of next section - */ - workptr = strchr(workptr, '['); - - /* - ** If the end has been reached without finding the desired section - ** then abort with a failure flag. - */ - if (!workptr) { - return(NULL); - } - - /* - ** 'c' = character just before the '[' - */ - if (workptr==profile) { - c = '\n'; - } else { - c = *(workptr-1); - } - - /* - ** If this is the section name & the character before is a newline, - ** process this section - */ - if (memicmp(workptr, sec, len) == 0 && (c == '\n')) { - - /* - ** Skip work pointer to start of first valid entry. - */ - workptr += len; - while (isspace(*workptr)) { - workptr++; - } - - /* - ** If the section name is empty, we will have stepped onto the start - ** of the next section name; inserting new entries here will leave - ** a blank line between this section's name & 1st entry. So, check - ** for 2 newlines in a row & step backward. - */ - if (workptr - profile > 4) { - if ( *(workptr-1)=='\n' && *(workptr-3)=='\n') - workptr -= 2; - } - - /* - ** 'next = end of section or end of file. - */ - next = strchr(workptr, '['); - for (;;) { - if (next) { - - c = *(next-1); - - /* - ** If character before '[' is newline, this is the start of the - ** next section - */ - if (c == '\n') { - if (*(next-1)=='\n' && *(next-3)=='\n') { - next -= 2; - } - break; - } - - /* - ** This bracket was in the section; keep looking - */ - next = strchr(next+1, '['); - } else { - - /* - ** No bracket found; set 'next' to the end of the file - */ - next = workptr + strlen(workptr)-1; - break; - } - } - - /* - ** If a specific entry was specified then return with the associated - ** string. - */ - if (entry) { - retval = workptr; - entrylen = strlen(entry); - - for (;;) { - /* - ** Search for the 1st character of the entry - */ - workptr = strchr(workptr, *entry); - - /* - ** If the end of the file has been reached or we have spilled - ** into the next section, then abort - */ - if (!workptr || workptr >= next) { - return(NULL); - } - - /* - ** 'c' = character before possible entry; must be a newline - ** 'c2' = character after possible entry; must be '=' or space - */ - c = *(workptr-1); - c2 = *(workptr+entrylen); - - /* - ** Entry found; extract it - */ - if (memicmp(workptr, entry, entrylen) == 0 && (c == '\n') && - (c2 == '=' || isspace(c2))) { - retval = workptr; - workptr += entrylen; // skip entry name - workptr = strchr(workptr, '='); // find '=' - - /* - ** 'altworkptr' = next newline; \r is used here since we're - ** scanning forward! - */ - if (workptr) { - altworkptr = strchr(workptr, '\r'); // find next newline - } - - /* - ** Return if there was no '=', or if the newline is before - ** the next '=' - */ - if (workptr == NULL || altworkptr < workptr) { - return(retval); - } - - /* - ** Skip any white space after the '=' and before the first - ** valid character of the parameter. - */ - workptr++; // Skip the '='. - while (isspace(*workptr)) { - - /* - ** Just return if there's no entry past the '='. - */ - if (workptr >= altworkptr) - return(retval); - - workptr++; // Skip the whitespace - } - - /* - ** Copy the entry into the return buffer. - */ - len = (int)(altworkptr - workptr); - if (len > retlen-1) { - len = retlen-1; - } - - if (retbuffer) { - memcpy(retbuffer, workptr, len); - *(retbuffer + len) = '\0'; // Insert trailing null. - strtrim(retbuffer); - } - return(retval); - } - - /* - ** Entry was not found; go to the next one - */ - workptr++; - } - } else { - - /* - ** No entry was specified, so build a list of all entries. - ** 'workptr' is at 1st entry after section name - ** 'next' is next bracket, or end of file - */ - retval = workptr; - - if (retbuffer) { - - /* - ** Keep accumulating the identifier strings in the retbuffer. - */ - while (workptr && workptr < next) { - altworkptr = strchr(workptr, '='); // find '=' - - if (altworkptr && altworkptr < next) { - int length; // Length of ID string. - - length = (int)(altworkptr - workptr); - - /* - ** Make sure we don't write past the end of the retbuffer; - ** add '3' for the 3 NULL's at the end - */ - if (retbuffer - orig_retbuf + length + 3 < retlen) { - memcpy(retbuffer, workptr, length); // copy entry name - *(retbuffer+length) = '\0'; // NULL-terminate it - strtrim(retbuffer); // trim spaces - retbuffer += strlen(retbuffer)+1; // next pos in dest buf - } else { - break; - } - - /* - ** Advance the work pointer to the start of the next line - ** by skipping the end of line character. - */ - workptr = strchr(altworkptr, '\n'); - if (!workptr) { - break; - } - workptr++; - } else { - - /* - ** If no '=', break out of loop - */ - break; - } - } - - /* - ** Final trailing terminator. Make double sure the double - ** trailing null is added. - */ - *retbuffer++ = '\0'; - *retbuffer++ = '\0'; - } - break; - } - } else { - - /* - ** Section name not found; go to the next bracket & try again - ** Advance past '[' and keep scanning. - */ - workptr++; - } - } - - return(retval); -} - - -/*********************************************************************************************** - * WWWritePrivateProfileString -- Write a string to the profile data block. * - * * - * INPUT: * - * section section name to write to * - * entry name of entry to write; if NULL, the section is deleted * - * string string to write; if NULL, the entry is deleted * - * profile INI buffer * - * * - * OUTPUT: * - * true = success, false = failure * - * * - * WARNINGS: * - * This function has to translate newlines into \r\n sequences. * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -bool WWWritePrivateProfileString(char const *section, char const *entry, char const *string, char *profile) -{ - char buffer[250]; // Working section buffer - char *offset; - char *next; // ptr to next section - char c; // Working character value - - /* - ** Just return if nothing to do. - */ - if (!profile || !section) { - return(true); - } - - /* - ** Try to find the section. WWGetPrivateProfileString with NULL entry name - ** will return all entry names in the given buffer, truncated to the given - ** buffer length. 'offset' will point to 1st entry in the section, NULL if - ** section not found. - */ - offset = WWGetPrivateProfileString(section, NULL, NULL, NULL, 0, profile); - - /* - ** If the section could not be found, then add it to the end. Don't add - ** anything if a removal of an entry is requested (it is obviously already - ** non-existent). Make sure two newlines precede the section name. - */ - if (!offset && entry) { - sprintf(buffer, "\r\n[%s]\r\n", section); - strcat(profile, buffer); - } - - /* - ** If the section is there and 'entry' is NULL, remove the entire section - */ - if (offset && !entry) { - - /* - ** 'next = end of section or end of file. - */ - next = strchr(offset, '['); - for (;;) { - if (next) { - c = *(next-1); - - /* - ** If character before '[' is newline, this is the start of the - ** next section - */ - if (c == '\n') { - if ( *(next-1)=='\n' && *(next-3)=='\n') { - next -= 2; - } - break; - } - - /* - ** This bracket was in the section; keep looking - */ - next = strchr(next+1, '['); - } else { - - /* - ** No bracket found; set 'next' to the end of the file - */ - next = offset + strlen(offset); - break; - } - } - - /* - ** Remove the section - */ - strcpy(offset,next); - - return(true); - } - - /* - ** Find the matching entry within the desired section. A NULL return buffer - ** with 0 length will just return the offset of the found entry, NULL if - ** entry not found. - */ - offset = WWGetPrivateProfileString(section, entry, NULL, NULL, 0, profile); - - /* - ** Remove any existing entry - */ - if (offset) { - int eol; // Working EOL offset. - - /* - ** Get # characters up to newline; \n is used since we're after the end - ** of this line - */ - eol = strcspn(offset, "\n"); - - /* - ** Erase the entry by strcpy'ing the entire INI file over this entry - */ - if (eol) { - strcpy(offset, offset + eol + 1); - } - } else { - - /* - ** Entry doesn't exist, so point 'offset' to the 1st entry position in - ** the section. - */ - offset = WWGetPrivateProfileString(section, NULL, NULL, NULL, 0, profile); - } - - /* - ** Add the desired entry. - */ - if (entry && string) { - - /* - ** Generate entry string. - */ - sprintf(buffer, "%s=%s\r\n", entry, string); - - /* - ** Make room for new entry. - */ - memmove(offset+strlen(buffer), offset, strlen(offset)+1); - - /* - ** Copy the entry into the INI buffer. - */ - memcpy(offset, buffer, strlen(buffer)); - } - - return(true); -} diff --git a/code/TIBERIANDAWN/QUEUE.CPP b/code/TIBERIANDAWN/QUEUE.CPP deleted file mode 100644 index e0c9aaf..0000000 --- a/code/TIBERIANDAWN/QUEUE.CPP +++ /dev/null @@ -1,4214 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c0\vcs\code\queue.cpv 2.24 11 Oct 1995 13:47:40 JOE_BOSTIC $ */ -/*************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : QUEUE.CPP * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 11/28/95 * - * * - * Last Update : November 28, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions for Queueing Events: * - * Queue_Mission -- Queue a mega mission event. * - * Queue_Options -- Queue the options event. * - * Queue_Exit -- Add the exit game event to the queue. * - * * - * Functions for processing Queued Events: * - * Queue_AI -- Process all queued events. * - * Queue_AI_Normal -- Process all queued events. * - * Queue_AI_Multiplayer -- Process all queued events. * - * * - * Main Multiplayer Queue Logic: * - * Wait_For_Players -- Waits for other systems to come on-line * - * Generate_Timing_Event -- computes & queues a RESPONSE_TIME event * - * Process_Send_Period -- timing for sending packets every 'n' frames * - * Send_Packets -- sends out events from the OutList * - * Send_FrameSync -- Sends a FRAMESYNC packet * - * Process_Receive_Packet -- processes an incoming packet * - * Process_Serial_Packet -- Handles an incoming serial packet * - * Can_Advance -- determines if it's OK to advance to the next frame * - * Process_Reconnect_Dialog -- processes the reconnection dialog * - * Handle_Timeout -- attempts to reconnect; if fails, bails. * - * Stop_Game -- stops the game * - * * - * Packet Compression / Decompression: * - * Build_Send_Packet -- Builds a big packet from a bunch of little ones. * - * Add_Uncompressed_Events -- adds uncompressed events to a packet * - * Add_Compressed_Events -- adds compressed events to a packet * - * Breakup_Receive_Packet -- Splits a big packet into little ones. * - * Extract_Uncompressed_Events -- extracts events from a packet * - * Extract_Compressed_Events -- extracts events from a packet * - * * - * DoList Management: * - * Execute_DoList -- Executes commands from the DoList * - * Clean_DoList -- Cleans out old events from the DoList * - * Queue_Record -- Records the DoList to disk * - * Queue_Playback -- plays back queue entries from a record file * - * * - * Debugging: * - * Compute_Game_CRC -- Computes a CRC value of the entire game. * - * Add_CRC -- Adds a value to a CRC * - * Print_CRCs -- Prints a data file for finding Sync Bugs * - * Init_Queue_Mono -- inits mono display * - * Update_Queue_Mono -- updates mono display * - * Print_Framesync_Values -- displays frame-sync variables * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include "function.h" -#include "tcpip.h" - -/********************************** Defines *********************************/ -#define SHOW_MONO 1 - -int tmp_flag = 0; - -/********************************** Globals *********************************/ -//--------------------------------------------------------------------------- -// GameCRC is the current computed CRC value for this frame. -// CRC[] is a record of our last 32 game CRC's. -// ColorNames is for debug output in Print_CRCs -//--------------------------------------------------------------------------- -#ifndef DEMO -static unsigned long GameCRC; -static unsigned long CRC[32] = - {0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0}; - -static char *ColorNames[6] = { - "Yellow", - "Red", - "BlueGreen", - "Orange", - "Green", - "Blue", -}; -#endif //DEMO - -//........................................................................... -// Mono debugging variables: -// NetMonoMode: 0 = show connection output, 1 = flowcount output -// NewMonoMode: set by anything that toggles NetMonoMode; re-inits screen -// IsMono: used for taking control of Mono screen away from the engine -//........................................................................... -#ifndef DEMO -int NetMonoMode = 1; -int NewMonoMode = 1; -static int IsMono = 0; -#endif //DEMO - -//--------------------------------------------------------------------------- -// Several routines return various codes; here's an enum for all of them. -//--------------------------------------------------------------------------- -typedef enum RetcodeEnum { - RC_NORMAL, // no news is good news - RC_PLAYER_READY, // a new player has been heard from - RC_SCENARIO_MISMATCH, // scenario mismatch - RC_DOLIST_FULL, // DoList is full - RC_SERIAL_PROCESSED, // modem: SERIAL packet was processed - RC_PLAYER_LEFT, // modem: other player left the game - RC_HUNG_UP, // modem has hung up - RC_NOT_RESPONDING, // other player not responding (timeout/hung up) - RC_CANCEL, // user cancelled -} RetcodeType; - - -/********************************* Prototypes *******************************/ -//........................................................................... -// Main multiplayer queue logic -//........................................................................... -static void Queue_AI_Normal(void); -#ifndef DEMO -static void Queue_AI_Multiplayer(void); -static RetcodeType Wait_For_Players(int first_time, ConnManClass *net, - int resend_delta, int dialog_time, int timeout, char *multi_packet_buf, - int my_sent, long *their_frame, unsigned short *their_sent, - unsigned short *their_recv); -static void Generate_Timing_Event(ConnManClass *net, int my_sent); -static void Generate_Real_Timing_Event(ConnManClass *net, int my_sent); -static void Generate_Process_Time_Event(ConnManClass *net); -static int Process_Send_Period(ConnManClass *net); -static int Send_Packets(ConnManClass *net, char *multi_packet_buf, - int multi_packet_max, int max_ahead, int my_sent); -static void Send_FrameSync(ConnManClass *net, int cmd_count); -static RetcodeType Process_Receive_Packet(ConnManClass *net, - char *multi_packet_buf, int id, int packetlen, long *their_frame, - unsigned short *their_sent, unsigned short *their_recv); -static RetcodeType Process_Serial_Packet(char *multi_packet_buf, - int first_time); -static int Can_Advance(ConnManClass *net, int max_ahead, long *their_frame, - unsigned short *their_sent, unsigned short *their_recv); -static int Process_Reconnect_Dialog(CountDownTimerClass *timeout_timer, - long *their_frame, int num_conn, int reconn, int fresh); -static int Handle_Timeout(ConnManClass *net, long *their_frame, - unsigned short *their_sent, unsigned short *their_recv); -static void Stop_Game(void); -#endif //DEMO - -//........................................................................... -// Packet compression/decompression: -//........................................................................... -#ifndef DEMO -static int Build_Send_Packet(void *buf, int bufsize, int frame_delay, - int num_cmds, int cap); -static int Breakup_Receive_Packet(void *buf, int bufsize ); -#endif //DEMO -int Add_Uncompressed_Events(void *buf, int bufsize, int frame_delay, int size, - int cap); -int Add_Compressed_Events(void *buf, int bufsize, int frame_delay, int size, - int cap); -int Extract_Uncompressed_Events(void *buf, int bufsize); -int Extract_Compressed_Events(void *buf, int bufsize); - -//........................................................................... -// DoList management: -//........................................................................... -static int Execute_DoList(int max_houses, HousesType base_house, - ConnManClass *net, TCountDownTimerClass *skip_crc, - long *their_frame, unsigned short *their_sent, unsigned short *their_recv); -static void Clean_DoList(ConnManClass *net); -#ifndef DEMO -static void Queue_Record(void); -static void Queue_Playback(void); -#endif //DEMO - -//........................................................................... -// Debugging: -//........................................................................... -#ifndef DEMO -static void Compute_Game_CRC(void); -static void Init_Queue_Mono(ConnManClass *net); -static void Update_Queue_Mono(ConnManClass *net, int flow_index); -static void Print_Framesync_Values(long curframe, unsigned long max_ahead, - int num_connections, unsigned short *their_recv, - unsigned short *their_sent, unsigned short my_sent); -#endif //DEMO -void Add_CRC(unsigned long *crc, unsigned long val); -void Print_CRCs(EventClass *); - -extern void Keyboard_Process(KeyNumType &input); -void Dump_Packet_Too_Late_Stuff(EventClass *event); - -extern void Register_Game_End_Time(void); -extern void Send_Statistics_Packet(void); - -/*************************************************************************** - * Queue_Mission -- Queue a mega mission event. * - * * - * This routine is called when the player causes a change to a game unit. * - * The event that initiates the change is queued to as a result of a call * - * to this routine. * - * * - * INPUT: * - * whom Whom this mission request applies to (a friendly unit). * - * mission The mission to assign to this object. * - * target The target of this mission (if any). * - * dest The movement destination for this mission (if any). * - * * - * OUTPUT: * - * Was the mission request queued successfully? * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 09/21/1995 JLB : Created. * - *=========================================================================*/ -bool Queue_Mission(TARGET whom, MissionType mission, TARGET target, - TARGET destination) -{ - if (! OutList.Add(EventClass(whom, mission, target, destination))) { - return(false); - } - else { - return(true); - } - -} /* end of Queue_Mission */ - - -/*************************************************************************** - * Queue_Options -- Queue the options event. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * Was the options screen event queued successfully? * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 09/21/1995 JLB : Created. * - *=========================================================================*/ -bool Queue_Options(void) -{ - if (! OutList.Add(EventClass(EventClass::OPTIONS))) { - return(false); - } - else { - return(true); - } - -} /* end of Queue_Options */ - - -/*************************************************************************** - * Queue_Exit -- Add the exit game event to the queue. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * Was the exit event queued successfully? * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 09/21/1995 JLB : Created. * - *=========================================================================*/ -bool Queue_Exit(void) -{ - if (! OutList.Add(EventClass(EventClass::EXIT))) { - return(false); - } - else { - return(true); - } - -} /* end of Queue_Exit */ - - -/*************************************************************************** - * Queue_AI -- Process all queued events. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 09/21/1995 JLB : Created. * - *=========================================================================*/ -void Queue_AI(void) -{ -#ifdef DEMO - Queue_AI_Normal(); -#else //DEMO - - if (PlaybackGame) { - Queue_Playback(); - } - - else { - - switch (GameToPlay) { - - case GAME_NORMAL: - Queue_AI_Normal(); - break; - - case GAME_MODEM: - case GAME_NULL_MODEM: - case GAME_IPX: - case GAME_INTERNET: - Queue_AI_Multiplayer(); - break; - } - } -#endif //DEMO - -} /* end of Queue_AI */ - - -/*************************************************************************** - * Queue_AI_Normal -- Process all queued events. * - * * - * This is the "normal" version of the queue management routine. It does * - * the following: * - * - Transfers items in the OutList to the DoList * - * - Executes any commands in the DoList that are supposed to be done on * - * this frame # * - * - Cleans out the DoList * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 09/21/1995 JLB : Created. * - *=========================================================================*/ -static void Queue_AI_Normal(void) -{ - //------------------------------------------------------------------------ - // Move events from the OutList (events generated by this player) into the - // DoList (the list of events to execute). - //------------------------------------------------------------------------ - while (OutList.Count) { - OutList.First().IsExecuted = false; - if (!DoList.Add(OutList.First())) { - ; - } - OutList.Next(); - } - - //------------------------------------------------------------------------ - // Save the DoList to disk, if we're in "Record" mode - //------------------------------------------------------------------------ -#ifndef DEMO - if (RecordGame) { - Queue_Record(); - } -#endif //DEMO - - //------------------------------------------------------------------------ - // Execute the DoList - //------------------------------------------------------------------------ - if (!Execute_DoList(1,PlayerPtr->Class->House, NULL, NULL, NULL, - NULL, NULL)) { - GameActive = 0; - return; - } - //------------------------------------------------------------------------ - // Clean out the DoList - //------------------------------------------------------------------------ - Clean_DoList(NULL); - -} /* end of Queue_AI_Normal */ - -#ifndef DEMO - -/*************************************************************************** - * Queue_AI_Multiplayer -- Process all queued events. * - * * - * This is the network version of the queue management routine. It does * - * the following: * - * - If this is the 1st frame, waits for other systems to signal ready * - * - Generates a timing event, to allow the connection time to be dynamic * - * - Handles timing related to sending packets every 'n' frames * - * - Sends outgoing events * - * - Frame-syncs to the other systems (see below) * - * - Executes & cleans out the DoList * - * * - * The Frame-Sync'ing logic is the heart & soul of network play. It works * - * by ensuring that any system won't out-run the other system by more than * - * 'MaxAhead' frames; this in turn ensures that a packet's * - * execution frame # won't have been passed by the time that packet is * - * received by all systems. * - * * - * To achieve this, the system must keep track of all other system's * - * current frame #'s; these are stored in an array called 'their_frame[]'. * - * However, because current frame #'s are sent in FRAMEINFO packets, which * - * don't require an ACK, and command packets are sent in packets requiring * - * an ACK, it's possible for a command packet to get lost, and the next * - * frame's FRAMEINFO packet to not get lost; the other system may then * - * advance past the frame # the command is to execute on! So, to prevent * - * this, all FRAMEINFO packets include a CommandCount field. This value * - * tells the other system how many events it should have received by this * - * time. This system can therefore keep track of how many commands it's * - * actually received, and compare it to the CommandCount field, to see if * - * it's missed an event packet. The # of events we've received from each * - * system is stored in 'their_recv[]', and the # events they say they've * - * sent is stored in 'their_sent[]'. * - * * - * Thus, two conditions must be met in order to advance to the next frame: * - * - Our current frame # must be <= their_frame + MaxAhead * - * - their_recv[i] must be >= their_sent[i] * - * * - * 'their_frame[] is updated by Process_Receive_Packet() * - * 'their_recv[] is updated by Process_Receive_Packet() * - * 'their_sent[] is updated by Process_Receive_Packet() * - * 'my_sent' is updated by this routine. * - * * - * The only routines allowed to pop up dialogs are: * - * Wait_For_Players() (only pops up the reconnect dialog) * - * Execute_DoList() (tells if out of sync, or packet recv'd too late) * - * * - * Sign-off's are detected by: * - * - Timing out while waiting for a packet * - * - Detecting that the other player is now at the score screen or * - * connection dialog (serial) * - * - If we see an EventClass::EXIT event on the private channel * - * * - * The current communications protocol, COMM_PROTOCOL_MULTI_E_COMP, has * - * the following properites: * - * - It compresses packets, so that the minimum number of bytes are * - * transmitted. Packets are compressed by extracting all info common to * - * the events into the packet header, and then sending only the bytes * - * relevant to each type of event. For instance, if 100 infantry guys * - * are told to move to the same location, the command itself & the * - * location will be included in the 1st movement command only; after * - * that, there will be a rep count then 99 infantry TARGET numbers, * - * identifying all the infantry told to move. * - * - The protocol also only sends packets out every 'n' frames. This cuts * - * the data rate dramatically. It means that 'MaxAhead' must be * - * divisible by 'n'; also, the minimum value for 'MaxAhead' is * - * 'n * 2', to give both sides some "breathing" room in case a FRAMEINFO * - * packet gets missed. * - * * - * Note: For synchronization-waiting loops (like waiting to hear from all * - * other players, waiting to advance to the next frame, etc), use * - * Net.Num_Connections() rather than NumPlayers; this reflects the * - * actual # of connections, and can be "faked" into playing even when * - * there aren't any other players actually there. A typical example of * - * this is playing back a recorded game. For command-execution loops, use * - * NumPlayers. This ensures all commands get executed, even if * - * there isn't a human generating those commands. * - * * - * The modem works a little differently from the network in this respect: * - * - The connection has to stay "alive" even if the other player exits to * - * the join dialog. This prevents each system from timing out & hanging * - * the modem up. Thus, packets are sent back & forth & just thrown away,* - * but each system knows the other is still there. Messages may be sent * - * between systems, though. * - * - Destroy_Null_Connection doesn't hang up the modem, so * - * Num_Connections() still reports a value of 1 even though the other * - * player has left. * - * - Any waits on Num_Connections() must also check for * - * NumPlayers > 1, to keep from waiting forever if the other * - * guy has left * - * - Packets sent to a player who's left require no ACK * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Queue_AI_Multiplayer(void) -{ - //........................................................................ - // Enums: - //........................................................................ - enum { - MIXFILE_RESEND_DELTA = 120, // ticks b/w resends - MIXFILE_TIMEOUT = 3600, // timeout waiting for mixfiles - FRAMESYNC_DLG_TIME = (3*60), // time until displaying reconnect dialog - FRAMESYNC_TIMEOUT = (25*60), // timeout waiting for frame sync packet - }; - - int timeout_factor = (GameToPlay == GAME_INTERNET) ? 6 : 1; - - //........................................................................ - // Variables for sending, receiving & parsing packets: - //........................................................................ - ConnManClass *net; // ptr to access all multiplayer functions - EventClass packet; // for sending single frame-sync's - char *multi_packet_buf; // buffer for sending/receiving - int multi_packet_max; // max length of multi_packet_buf - - //........................................................................ - // Frame-sync'ing variables. Values in these arrays are stored in the - // order in which the connections are created. - // (ie net->Connection_Index(id)) - //........................................................................ - static long - their_frame[MAX_PLAYERS - 1]; // other players' frame #'s - static unsigned short - their_sent[MAX_PLAYERS - 1]; // # cmds other player claims to have sent - static unsigned short - their_recv[MAX_PLAYERS - 1]; // # cmds actually received from others - static unsigned short - my_sent; // # cmds I've sent out - - //........................................................................ - // Other misc variables - //........................................................................ - int i; - RetcodeType rc; - int reconnect_dlg = 0; // 1 = the reconnect dialog is displayed - - //------------------------------------------------------------------------ - // Initialize the packet buffer pointer & its max size - //------------------------------------------------------------------------ - if (GameToPlay == GAME_MODEM - || GameToPlay == GAME_NULL_MODEM){ -//PG_TO_FIX -#if (0) - multi_packet_buf = NullModem.BuildBuf; - multi_packet_max = NullModem.MaxLen - sizeof (CommHeaderType); - net = &NullModem; -#endif - } - else if (GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) { - multi_packet_buf = MetaPacket; - multi_packet_max = MetaSize; - net = &Ipx; - } - - //------------------------------------------------------------------------ - // Debug stuff - //------------------------------------------------------------------------ - Init_Queue_Mono(net); - Update_Queue_Mono (net, 0); - - //------------------------------------------------------------------------ - // If we've just started a game, or loaded a multiplayer game, we must - // wait for all other systems to signal ready. - //------------------------------------------------------------------------ - if (Frame==0) { - //..................................................................... - // Initialize static locals - //..................................................................... - for (i = 0; i < MAX_PLAYERS - 1; i++) { - their_frame[i] = -1; - their_sent[i] = 0; - their_recv[i] = 0; - TheirProcessTime[i] = -1; - } - my_sent = 0; - for (i = 0; i < 32; i++) { - CRC[i] = 0; - } - - //..................................................................... - // Send our initial FRAMESYNC packet - //..................................................................... - Send_FrameSync(net, my_sent); - - //..................................................................... - // Wait for the other guys - //..................................................................... - rc = Wait_For_Players (1, net, MIXFILE_RESEND_DELTA, FRAMESYNC_DLG_TIME*timeout_factor, - MIXFILE_TIMEOUT, multi_packet_buf, my_sent, their_frame, - their_sent, their_recv); - - if (rc != RC_NORMAL) { - if (rc == RC_NOT_RESPONDING) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - } - else if (rc == RC_SCENARIO_MISMATCH) { - CCMessageBox().Process (TXT_SCENARIOS_DO_NOT_MATCH); - } - else if (rc == RC_DOLIST_FULL) { - CCMessageBox().Process(TXT_QUEUE_FULL); - } - Stop_Game(); - return; - } - - //..................................................................... - // Re-initialize frame numbers (in case somebody signed off while I was - // waiting for MIX files to load; we would have fallen through, but - // their frame # would still be -1). - //..................................................................... - for (i = 0; i < MAX_PLAYERS - 1; i++) - their_frame[i] = 0; - - //..................................................................... - // Reset the network response time computation, now that we're both - // sending data again (loading MIX files will have introduced - // deceptively large values). - //..................................................................... - net->Reset_Response_Time(); - - //..................................................................... - // Initialize the frame timers - //..................................................................... - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - Process_Send_Period(net); - } - - } // end of Frame 0 wait - - //------------------------------------------------------------------------ - // Adjust connection timing parameters every 128 frames. - //------------------------------------------------------------------------ - else if ( (Frame & 0x007f) == 0) { - // - // If we're using the new spiffy protocol, do proper timing handling. - // If we're the net "master", compute our desired frame rate & new - // 'MaxAhead' value. - // - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - - // - // All systems will transmit their required process time. - // - Generate_Process_Time_Event(net); - - // - // The game "host" will transmit timing adjustment events. - // - if (MPlayerLocalID == MPlayerID[0]) { - Generate_Real_Timing_Event(net, my_sent); - } - } else { - // - // For the older protocols, do the old broken timing handling. - // - Generate_Timing_Event(net, my_sent); - } - } - - //------------------------------------------------------------------------ - // Compute the Game's CRC - //------------------------------------------------------------------------ - Compute_Game_CRC(); - CRC[Frame & 0x001f] = GameCRC; - //unsigned long save_crc = GameCRC; - //Print_CRCs((EventClass *)NULL); - //GameCRC = save_crc; - - //------------------------------------------------------------------------ - // Only process every 'FrameSendRate' frames - //------------------------------------------------------------------------ - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - if (!Process_Send_Period(net)) { - if (IsMono) { - MonoClass::Disable(); - } - return; - } - } - - //------------------------------------------------------------------------ - // Send our data packet(s); update my command-sent counter - //------------------------------------------------------------------------ - my_sent += Send_Packets(net, multi_packet_buf, multi_packet_max, - MPlayerMaxAhead, my_sent); - - //------------------------------------------------------------------------ - // If this is our first time through, we're done. - //------------------------------------------------------------------------ - if (Frame==0) { - if (IsMono) { - MonoClass::Disable(); - } - return; - } - - //------------------------------------------------------------------------ - // Frame-sync'ing: wait until it's OK to advance to the next frame. - //------------------------------------------------------------------------ - rc = Wait_For_Players (0, net, - (MPlayerMaxAhead << 3), - MAX ( net->Response_Time() * 3, (unsigned long)FRAMESYNC_DLG_TIME*timeout_factor ), - FRAMESYNC_TIMEOUT * (timeout_factor*2), - multi_packet_buf, my_sent, their_frame, - their_sent, their_recv); - - if (rc != RC_NORMAL) { - if (rc == RC_NOT_RESPONDING) { - CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); - } - else if (rc == RC_SCENARIO_MISMATCH) { - CCMessageBox().Process (TXT_SCENARIOS_DO_NOT_MATCH); - } - else if (rc == RC_DOLIST_FULL) { - CCMessageBox().Process(TXT_QUEUE_FULL); - } - Stop_Game(); - return; - } - - //------------------------------------------------------------------------ - // Save the DoList to disk, if we're in "Record" mode - //------------------------------------------------------------------------ - if (RecordGame) { - Queue_Record(); - } - - //------------------------------------------------------------------------ - // Execute the DoList; if an error occurs, bail out. - //------------------------------------------------------------------------ - if (!Execute_DoList(MPlayerMax, HOUSE_MULTI1, net, NULL, - their_frame, their_sent, their_recv)) { - Stop_Game(); - return; - } - - //------------------------------------------------------------------------ - // Clean out the DoList - //------------------------------------------------------------------------ - Clean_DoList(net); - - if (IsMono) { - MonoClass::Disable(); - } - -} // end of Queue_AI_Multiplayer - - -/*************************************************************************** - * Wait_For_Players -- Waits for other systems to come on-line * - * * - * This routine performs the most critical logic in multiplayer; that of * - * synchronizing my frame number with those of the other systems. * - * * - * INPUT: * - * first_time 1 = 1st time this routine is called * - * net ptr to connection manager * - * resend_delta time (ticks) between FRAMESYNC resends * - * dialog_time time (ticks) until pop up a reconnect dialog * - * timeout time (ticks) until we give up the ghost * - * multi_packet_buf buffer to store packets in * - * my_sent # commands I've sent so far * - * their_frame array of their frame #'s * - * their_sent array of their CommandCount values * - * their_recv array of # cmds I've received from them * - * * - * OUTPUT: * - * RC_NORMAL OK to advance to the next frame * - * RC_CANCEL user hit 'Cancel' at the timeout countdown dlg * - * RC_NOT_RESPONDING other player(s) not responding * - * RC_SCENARIO_MISMATCH scenario's don't match (first_time only) * - * RC_DOLIST_FULL DoList was full * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static RetcodeType Wait_For_Players(int first_time, ConnManClass *net, - int resend_delta, int dialog_time, int timeout, char *multi_packet_buf, - int my_sent, long *their_frame, unsigned short *their_sent, - unsigned short *their_recv) -{ - //........................................................................ - // Variables for sending, receiving & parsing packets: - //........................................................................ - EventClass *event; // event ptr for parsing incoming packets - int packetlen; // size of meta-packet sent, & received - int id; // id of other player - int messages_this_loop; // to limit # messages processed each loop - - //........................................................................ - // Variables used only if 'first_time': - //........................................................................ - int num_ready; // # players signalling ready - - //........................................................................ - // Timing variables - //........................................................................ - CountDownTimerClass retry_timer; // time between FRAMESYNC packet resends - CountDownTimerClass dialog_timer; // time to pop up a dialog - CountDownTimerClass timeout_timer; // general-purpose timeout - - //........................................................................ - // Dialog variables - //........................................................................ - int reconnect_dlg = 0; // 1 = the reconnect dialog is displayed - - //........................................................................ - // Other misc variables - //........................................................................ - KeyNumType input; // for user input - int x,y; // for map input - RetcodeType rc; - - //------------------------------------------------------------------------ - // Wait to hear from all other players - //------------------------------------------------------------------------ - num_ready = 0; - retry_timer.Set (resend_delta, true); // time to retry - dialog_timer.Set (dialog_time, true); // time to show dlg - timeout_timer.Set (timeout, true); // time to bail out - - while (1) { - - Update_Queue_Mono (net, 2); - - //--------------------------------------------------------------------- - // Resend a frame-sync packet if longer than one propogation delay goes - // by; this prevents a "deadlock". If he's waiting for me to advance, - // but has missed my last few FRAMEINFO packets, I may be waiting for - // him to advance. Resending a FRAMESYNC ensures he knows what frame - // number I'm on. - //--------------------------------------------------------------------- - if (!retry_timer.Time()) { - retry_timer.Set (resend_delta, true); // time to retry - Update_Queue_Mono (net, 3); - Send_FrameSync(net, my_sent); - } - - //--------------------------------------------------------------------- - // Service the connections - //--------------------------------------------------------------------- - net->Service(); - - //--------------------------------------------------------------------- - // Pop up a reconnect dialog if enough time goes by - //--------------------------------------------------------------------- - if (!dialog_timer.Time() && SpecialDialog==SDLG_NONE) { - if (Process_Reconnect_Dialog(&timeout_timer, their_frame, - net->Num_Connections(), (first_time==0), (reconnect_dlg==0))) { - return (RC_CANCEL); - } - reconnect_dlg = 1; - } - - //--------------------------------------------------------------------- - // Exit if too much time goes by (the other system has crashed or - // bailed) - //--------------------------------------------------------------------- - if (!timeout_timer.Time()) { - //.................................................................. - // For the first-time run, just give up; something's wrong. - //.................................................................. - if (first_time) { - return (RC_NOT_RESPONDING); - } - //.................................................................. - // Otherwise, we're in the middle of a game; so, the modem & - // network must deal with a timeout differently. - //.................................................................. - else { - Update_Queue_Mono (net, 4); - - if (Handle_Timeout(net, their_frame, their_sent, their_recv)) { - Map.Flag_To_Redraw(true); // erase modem reconnect dialog - Map.Render(); - retry_timer.Set (resend_delta, true); - dialog_timer.Set (dialog_time, true); - timeout_timer.Set (timeout, true); - } - else { - return (RC_NOT_RESPONDING); - } - } - } - - //--------------------------------------------------------------------- - // Check for an incoming message. We must still process commands - // even if 'first_time' is set, in case the other system got my 1st - // FRAMESYNC, but I didn't get his; he'll be at the next frame, and - // may be sending commands. - // We have to limit the number of incoming messages we handle; it's - // possible to go into an infinite loop processing modem messages. - //--------------------------------------------------------------------- - messages_this_loop = 0; - while ( (messages_this_loop++ < 5) && - net->Get_Private_Message (multi_packet_buf, &packetlen, &id) ) { - Update_Queue_Mono (net, 5); - - /*.................................................................. - Get an event ptr to the incoming message - ..................................................................*/ - event = (EventClass *)multi_packet_buf; - - //------------------------------------------------------------------ - // Special processing for a modem game: process SERIAL packets - //------------------------------------------------------------------ - if (GameToPlay == GAME_MODEM - || GameToPlay == GAME_NULL_MODEM){ - //|| GameToPlay == GAME_INTERNET) { - rc = Process_Serial_Packet(multi_packet_buf, first_time); - //............................................................... - // SERIAL packet received & processed - //............................................................... - if (rc == RC_SERIAL_PROCESSED) { - net->Service(); - retry_timer.Set (resend_delta, true); - dialog_timer.Set (dialog_time, true); - timeout_timer.Set (timeout, true); - continue; - } - //............................................................... - // other player has left the game - //............................................................... - else if (rc == RC_PLAYER_LEFT) { - if (first_time) { - num_ready++; - } - break; - } - //............................................................... - // Connection was lost - //............................................................... - else if (rc == RC_HUNG_UP) { - return (RC_NOT_RESPONDING); - } - //............................................................... - // If it was any other type of serial packet, break - //............................................................... - else if (rc != RC_NORMAL) { - break; - } - } - - //------------------------------------------------------------------ - // Process the incoming packet - //------------------------------------------------------------------ - rc = Process_Receive_Packet(net, multi_packet_buf, id, packetlen, - their_frame, their_sent, their_recv); - //.................................................................. - // New player heard from - //.................................................................. - if (rc == RC_PLAYER_READY) { - num_ready++; - } - //.................................................................. - // Scenario's don't match - //.................................................................. - else if (rc == RC_SCENARIO_MISMATCH) { - return (RC_SCENARIO_MISMATCH); - } - //.................................................................. - // DoList was full - //.................................................................. - else if (rc == RC_DOLIST_FULL) { - return (RC_DOLIST_FULL); - } - - //.................................................................. - // Service the connection, to clean out the receive queues - //.................................................................. - net->Service(); - } - - //--------------------------------------------------------------------- - // Debug output - //--------------------------------------------------------------------- - Print_Framesync_Values(Frame, MPlayerMaxAhead, net->Num_Connections(), - their_recv, their_sent, my_sent); - - //--------------------------------------------------------------------- - // Attempt to advance to the next frame. - //--------------------------------------------------------------------- - //..................................................................... - // For the first-time run, just check to see if we've heard from - // everyone. - //..................................................................... - if (first_time) { - if (num_ready >= net->Num_Connections()) break; - } - //..................................................................... - // For in-game processing, we have to check their_sent, their_recv, - // their_frame, etc. - //..................................................................... - else { - if (Can_Advance(net, MPlayerMaxAhead, their_frame, their_sent, - their_recv)) { - break; - } - } - - //--------------------------------------------------------------------- - // Service game stuff. Servicing the map's input, and rendering the - // map, allows the map to scroll even though we're hung up waiting for - // packets. Don't do this if 'first_time' is set, since users could be - // waiting a very long time for all systems to load the scenario, and - // it gets frustrating being able to scroll around without doing - // anything. - //--------------------------------------------------------------------- - Call_Back(); - if (!first_time && SpecialDialog == SDLG_NONE && reconnect_dlg==0) { - WWMouse->Erase_Mouse(&HidPage, TRUE); - Map.Input(input, x, y); - if (input) - Keyboard_Process(input); - Map.Render(); - } - - } /* end of while */ - - //------------------------------------------------------------------------ - // If the reconnect dialog was shown, force the map to redraw. - //------------------------------------------------------------------------ - if (reconnect_dlg) { - Map.Flag_To_Redraw(true); - Map.Render(); - } - - return (RC_NORMAL); - -} // end of Wait_For_Players - - -/*************************************************************************** - * Generate_Timing_Event -- computes & queues a RESPONSE_TIME event * - * * - * This routine adjusts the connection timing on the local system; it also * - * optionally generates a RESPONSE_TIME event, to tell all systems to * - * dynamically adjust the current MaxAhead value. This allows both the * - * MaxAhead & the connection retry logic to have dynamic timing, to adjust * - * to varying line conditions. * - * * - * INPUT: * - * net ptr to connection manager * - * my_sent # commands I've sent out so far * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Generate_Timing_Event(ConnManClass *net, int my_sent) -{ - unsigned long resp_time; // connection response time, in ticks - EventClass ev; - - //------------------------------------------------------------------------ - // Measure the current connection response time. This time will be in - // 60ths of a second, and represents full round-trip time of a packet. - // To convert to one-way packet time, divide by 2; to convert to game - // frames, divide again by 4, assuming a game rate of 15 fps. - //------------------------------------------------------------------------ - resp_time = net->Response_Time(); - - //------------------------------------------------------------------------ - // Adjust my connection retry timing; only do this if I've sent out more - // than 5 commands, so I know I have a measure of the response time. - //------------------------------------------------------------------------ - if (my_sent > 5) { - - net->Set_Timing (resp_time + 10, -1, (resp_time * 4)+15); - - //..................................................................... - // If I'm the network "master", I'm also responsible for updating the - // MaxAhead value on all systems, so do that here too. - //..................................................................... - if (MPlayerLocalID == MPlayerID[0]) { - ev.Type = EventClass::RESPONSE_TIME; - //.................................................................. - // For multi-frame compressed events, the MaxAhead must be an even - // multiple of the FrameSendRate. - //.................................................................. - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - ev.Data.FrameInfo.Delay = MAX( ((((resp_time / 8) + - (FrameSendRate - 1)) / FrameSendRate) * - FrameSendRate), (FrameSendRate * 2) ); -char flip[128]; -sprintf (flip, "C&C95 - Generating timing packet - MaxAhead = %d frames\n", ev.Data.FrameInfo.Delay); -CCDebugString (flip); - - } - //.................................................................. - // For sending packets every frame, just use the 1-way connection - // response time. - //.................................................................. - else { - if (GameToPlay == GAME_MODEM - || GameToPlay == GAME_NULL_MODEM){ - //|| GameToPlay == GAME_INTERNET) { - ev.Data.FrameInfo.Delay = MAX( (resp_time / 8), - (unsigned long)MODEM_MIN_MAX_AHEAD ); - } - else if (GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) { - ev.Data.FrameInfo.Delay = MAX( (resp_time / 8), - (unsigned long)NETWORK_MIN_MAX_AHEAD ); - } - } - OutList.Add(ev); - } - } - -} // end of Generate_Timing_Event - - -/*************************************************************************** - * Generate_Real_Timing_Event -- Generates a TIMING event * - * * - * INPUT: * - * net ptr to connection manager * - * my_sent # commands I've sent out so far * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/02/1996 BRR : Created. * - *=========================================================================*/ -static void Generate_Real_Timing_Event(ConnManClass *net, int my_sent) -{ - unsigned long resp_time; // connection response time, in ticks - EventClass ev; - int highest_ticks; - int i; - int specified_frame_rate; - int maxahead; - - // - // If we haven't sent out at least 5 guaranteed-delivery packets, don't - // bother trying to measure our connection response time; just return. - // - if (my_sent < 5) { - return; - } - - // - // Find the highest processing time we have stored - // - highest_ticks = 0; - for (i = 0; i < MPlayerCount; i++) { - // - // If we haven't heard from all systems yet, bail out. - // - if (TheirProcessTime[i] == -1) { - return; - } - if (TheirProcessTime[i] > highest_ticks) { - highest_ticks = TheirProcessTime[i]; - } - } - - // - // Compute our "desired" frame rate as the lower of: - // - What the user has dialed into the options screen - // - What we're really able to run at - // - if (highest_ticks == 0) { - DesiredFrameRate = 60; - } else { - DesiredFrameRate = 60 / highest_ticks; - } - - if (Options.GameSpeed == 0) { - specified_frame_rate = 60; - } else { - specified_frame_rate = 60 / Options.GameSpeed; - } - - DesiredFrameRate = MIN (DesiredFrameRate, specified_frame_rate); - - // - // Measure the current connection response time. This time will be in - // 60ths of a second, and represents full round-trip time of a packet. - // To convert to one-way packet time, divide by 2; to convert to game - // frames, ....uh.... - // - resp_time = net->Response_Time(); - - // - // Compute our new 'MaxAhead' value, based upon the response time of our - // connection and our desired frame rate. - // 'MaxAhead' in frames is: - // - // (resp_time / 2 ticks) * (1 sec/60 ticks) * (n Frames / sec) - // - // resp_time is divided by 2 because, as reported, it represents a round- - // trip, and we only want to use a one-way trip. - // - maxahead = (resp_time * DesiredFrameRate) / (2 * 60); - - // - // Now, we have to round 'maxahead' so it's an even multiple of our - // send rate. It also must be at least thrice the FrameSendRate. - // (Isn't "thrice" a cool word?) - // - maxahead = ((maxahead + FrameSendRate - 1) / FrameSendRate) * FrameSendRate; - maxahead = MAX (maxahead, (int)FrameSendRate * 3); - - ev.Type = EventClass::TIMING; - ev.Data.Timing.DesiredFrameRate = DesiredFrameRate; - ev.Data.Timing.MaxAhead = maxahead; - - OutList.Add(ev); - - // - // Adjust my connection retry timing. These values set the retry timeout - // to just over one round-trip time, the 'maxretries' to -1, and the - // connection timeout to allow for about 4 retries. - // - net->Set_Timing (resp_time + 10, -1, (resp_time * 4)+15); - -} - - -/*************************************************************************** - * Generate_Process_Time_Event -- Generates a PROCESS_TIME event * - * * - * INPUT: * - * net ptr to connection manager * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 07/02/1996 BRR : Created. * - *=========================================================================*/ -static void Generate_Process_Time_Event(ConnManClass *net) -{ - EventClass ev; - int avgticks; - unsigned long resp_time; // connection response time, in ticks - - // - // Measure the current connection response time. This time will be in - // 60ths of a second, and represents full round-trip time of a packet. - // To convert to one-way packet time, divide by 2; to convert to game - // frames, ....uh.... - // - resp_time = net->Response_Time(); - - // - // Adjust my connection retry timing. These values set the retry timeout - // to just over one round-trip time, the 'maxretries' to -1, and the - // connection timeout to allow for about 4 retries. - // - net->Set_Timing (resp_time + 10, -1, (resp_time * 4)+15); - - if (IsMono) { - MonoClass::Enable(); - Mono_Set_Cursor(0,23); - Mono_Printf("Processing Ticks:%03d Frames:%03d\n", ProcessTicks,ProcessFrames); - MonoClass::Disable(); - } - - avgticks = ProcessTicks / ProcessFrames; - - ev.Type = EventClass::PROCESS_TIME; - ev.Data.ProcessTime.AverageTicks = avgticks; -char flip[128]; -sprintf (flip, "C&C95 - Sending PROCESS_TIME packet of %04x ticks\n", ev.Data.ProcessTime.AverageTicks); -CCDebugString (flip); - - OutList.Add(ev); - - ProcessTicks = 0; - ProcessFrames = 0; -} - - -/*************************************************************************** - * Process_Send_Period -- timing for sending packets every 'n' frames * - * * - * This function is for a CommProtocol of COMM_PROTOCOL_MULTI_E_COMP only. * - * It determines if it's time to send a packet or not. * - * * - * INPUT: * - * net ptr to connection manager * - * * - * OUTPUT: * - * 1 = it's time to send a packet; 0 = don't send a packet this frame. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Process_Send_Period(ConnManClass *net) -{ - //------------------------------------------------------------------------ - // If the current frame # is not an even multiple of 'FrameSendRate', then - // it's not time to send a packet; just return. - //------------------------------------------------------------------------ - if (Frame != (((Frame + (FrameSendRate - 1)) / - FrameSendRate) * FrameSendRate) ) { - - net->Service(); - - if (IsMono) { - MonoClass::Disable(); - } - - return (0); - } - - return (1); - -} // end of Process_Send_Period - - -/*************************************************************************** - * Send_Packets -- sends out events from the OutList * - * * - * This routine computes how many events can be sent this frame, and then * - * builds the "meta-packet" & sends it. * - * * - * The 'cap' value is the max # of events we can send. Ideally, it should * - * be based upon the bandwidth of our connection. Currently, it's just * - * hardcoded to prevent the modem from having to resend "too much" data, * - * which is about 200 bytes per frame. * - * * - * INPUT: * - * net ptr to connection manager * - * multi_packet_buf buffer to store packets in * - * multi_packet_max max size of multi_packet_buf * - * max_ahead current game MaxAhead value * - * my_sent # commands I've sent this game * - * * - * OUTPUT: * - * # events sent, NOT including the FRAMEINFO event * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Send_Packets(ConnManClass *net, char *multi_packet_buf, - int multi_packet_max, int max_ahead, int my_sent) -{ - int cap; // max # events to send, NOT including FRAMEINFO event - int do_once; // true: only go through packet loop once - int ack_req; // 0 = no ack required on outgoing packet - int packetlen; // size of meta-packet sent - - //------------------------------------------------------------------------ - // Determine how many events it's OK to send this frame. - //------------------------------------------------------------------------ - //........................................................................ - // If we have 4 or more packets queue'd for sending, don't add any more - // this frame. - //........................................................................ - if (net->Private_Num_Send() >= 4) { - cap = 0; - do_once = 1; - } - //........................................................................ - // If there are 2 or more packets queued, the entire packet we send must - // fit within a single ComQueue buffer, so limit # events to 5. - // (The Modem connection manager has a max buffer size of 200 bytes, which - // is large enough for 6 uncompressed events, which leaves room for 5 - // events plus a FRAMEINFO.) - //........................................................................ - else if (net->Private_Num_Send() >= 2) { - cap = 5; - do_once = 1; - - } - //........................................................................ - // Otherwise, just send all events in the OutList - //........................................................................ - else { - cap = OutList.Count; - do_once = 0; - } - //........................................................................ - // Make sure we aren't sending more events than are in the OutList - //........................................................................ - if (cap > OutList.Count) { - cap = OutList.Count; - } - - //........................................................................ - // Make sure we don't send so many events that our DoList fills up - //........................................................................ - if (cap > (MAX_EVENTS * 8) - DoList.Count) { - cap = (MAX_EVENTS * 8) - DoList.Count; - } - - /* - ** No cap for internet game - ** - ** Or for serial games for that matter ST - 5/31/96 4:00PM - */ - if (GameToPlay == GAME_INTERNET || GameToPlay == GAME_MODEM || GameToPlay == GAME_NULL_MODEM){ - cap = OutList.Count; - do_once = 0; - } - - //------------------------------------------------------------------------ - // Build our meta-packet & transmit it. - //------------------------------------------------------------------------ - while (1) { - - Update_Queue_Mono (net, 1); - - //..................................................................... - // If there are no commands this frame, we'll just be sending a FRAMEINFO - // packet; no ack is required. For the modem's sake, check - // MPlayerCount; no ACK is needed if we're just sending to someone - // who's left the game. - //..................................................................... - if (cap == 0 || OutList.Count == 0 || MPlayerCount == 1) { - ack_req = 0; - } - else { - ack_req = 1; - } - - //..................................................................... - // Build & send out our message - //..................................................................... - packetlen = Build_Send_Packet (multi_packet_buf, multi_packet_max, - max_ahead, my_sent, cap); - net->Send_Private_Message (multi_packet_buf, packetlen, ack_req); - - //..................................................................... - // Call Service() to actually send the packet - //..................................................................... - net->Service(); - - //..................................................................... - // Stop if there's no more data to send, or if our send queue is - // filling up. - //..................................................................... - if (OutList.Count == 0 || do_once) { - break; - } - } - - return (cap); - -} // end of Send_Packets - - -/*************************************************************************** - * Send_FrameSync -- Sends a FRAMESYNC packet * - * * - * This routine is used to periodically remind the other systems that * - * we're still here, and to tell them what frame # we're on, in case * - * they've missed my FRAMEINFO packets. * - * * - * INPUT: * - * net ptr to connection manager * - * cmd_count # commands I've sent so far * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Send_FrameSync(ConnManClass *net, int cmd_count) -{ - EventClass packet; - - //------------------------------------------------------------------------ - // Build a frame-sync event to send. FRAMESYNC packets contain a - // scenario-based CRC rather than a game-state-based CRC, to let the - // games compare scenario CRC's on startup. - //------------------------------------------------------------------------ - memset (&packet, 0, sizeof(EventClass)); - packet.Type = EventClass::FRAMESYNC; - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - packet.Frame = ((Frame + MPlayerMaxAhead + (FrameSendRate - 1)) / - FrameSendRate) * FrameSendRate; - } - else { - packet.Frame = Frame + MPlayerMaxAhead; - } - packet.ID = Houses.ID(PlayerPtr); - packet.MPlayerID = MPlayerLocalID; - packet.Data.FrameInfo.CRC = ScenarioCRC; - packet.Data.FrameInfo.CommandCount = cmd_count; - packet.Data.FrameInfo.Delay = MPlayerMaxAhead; - - //------------------------------------------------------------------------ - // Send the event. For modem, this just sends to the other player; - // for network, it sends to everyone we're connected to. - //------------------------------------------------------------------------ - net->Send_Private_Message (&packet, (offsetof(EventClass, Data) + - size_of(EventClass, Data.FrameInfo)), 0 ); - - return; - -} // end of Send_FrameSync - - -/*************************************************************************** - * Process_Receive_Packet -- processes an incoming packet * - * * - * This routine receives a packet from another system, adds it to our * - * execution queue (the DoList), and updates my arrays of their frame #, * - * their commands-sent, and their commands-received. * - * * - * INPUT: * - * net ptr to connection manager * - * multi_packet_buf buffer containing packet(s) to parse * - * id id of sender * - * their_frame array containing frame #'s of other players * - * their_sent array containing command count of other players * - * their_recv array containing # recv'd cmds from other players * - * * - * OUTPUT: * - * RC_NORMAL: nothing unusual happened, although * - * their_sent or their_recv may have been * - * altered * - * RC_PLAYER_READY: player has been heard from for the 1st time; * - * this presumes that his original * - * 'their_frame[]' value was -1 when this * - * routine was called * - * RC_SCENARIO_MISMATCH: FRAMEINFO scenario CRC doesn't match; * - * normally only applies after loading a new * - * scenario or save-game * - * RC_DOLIST_FULL: fatal error; unable to add events to DoList * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static RetcodeType Process_Receive_Packet(ConnManClass *net, - char *multi_packet_buf, int id, int packetlen, long *their_frame, - unsigned short *their_sent, unsigned short *their_recv) -{ - EventClass *event; - int index; - RetcodeType retcode = RC_NORMAL; - int i; - - //------------------------------------------------------------------------ - // Get an event ptr to the incoming message - //------------------------------------------------------------------------ - event = (EventClass *)multi_packet_buf; - - //------------------------------------------------------------------------ - // Get the index of the sender - //------------------------------------------------------------------------ - index = net->Connection_Index(id); - - //------------------------------------------------------------------------ - // Compute the other player's frame # (at the time this packet was sent) - //------------------------------------------------------------------------ - if (their_frame[index] < - (int)(event->Frame - event->Data.FrameInfo.Delay)) { - - //..................................................................... - // If the original frame # for this player is -1, it means we've heard - // from this player for the 1st time; return the appropriate value. - //..................................................................... - if (their_frame[index]==-1) { - retcode = RC_PLAYER_READY; - } - - their_frame[index] = event->Frame - event->Data.FrameInfo.Delay; - } - - //------------------------------------------------------------------------ - // Extract the other player's CommandCount. This count will include - // the commands in this packet, if there are any. - //------------------------------------------------------------------------ - if (event->Data.FrameInfo.CommandCount > their_sent[index]) { - their_sent[index] = event->Data.FrameInfo.CommandCount; - } - - //------------------------------------------------------------------------ - // If this packet was not a FRAMESYNC packet: - // - Add the events in it to our DoList - // - Increment our commands-received counter by the number of non- - // FRAMEINFO packets received - //------------------------------------------------------------------------ - if (event->Type != EventClass::FRAMESYNC) { - //..................................................................... - // Break up the packet into its component events. A returned packet - // count of -1 indicates a fatal queue-full error. - //..................................................................... - i = Breakup_Receive_Packet( multi_packet_buf, packetlen); - if (i==-1) { - return (RC_DOLIST_FULL); - } - //..................................................................... - // Compute the actual # commands in the packet by subtracting off the - // FRAMEINFO event - //..................................................................... - if ( (event->Type==EventClass::FRAMEINFO) && (i > 0)) { - i--; - } - - their_recv[index] += i; - } - - //------------------------------------------------------------------------ - // If the event was a FRAMESYNC packet, there will be no commands to add, - // but we must check the ScenarioCRC value. - //------------------------------------------------------------------------ - else if (event->Data.FrameInfo.CRC != ScenarioCRC) { - return (RC_SCENARIO_MISMATCH); - } - - return (retcode); - -} // end of Process_Receive_Packet - - -/*************************************************************************** - * Process_Serial_Packet -- Handles an incoming serial packet * - * * - * This routine is needed because the modem classes don't support a * - * "global channel" like the network classes do, but that functionality is * - * still needed for modem communications. Specifically, the modem dialogs * - * transmit their own special packets back & forth, and messages are sent * - * using a special packet type. Thus, we have to call this routine when * - * we receive a modem packet, to allow it to process messages & dialog * - * packets. * - * * - * INPUT: * - * multi_packet_buf packet buffer to process * - * first_time 1 = this is the 1st game frame * - * * - * OUTPUT: * - * RC_NORMAL: this wasn't a SERIAL-type packet * - * RC_SERIAL_PROCESSED: this was a SERIAL-type packet, and was * - * processed; the other player is still connected, * - * even if he's not in the game. * - * RC_PLAYER_LEFT: other player has left the game * - * RC_HUNG_UP: we're getting our own packets back; thus, the * - * modem is mirroring our packets, which means the * - * modem hung up! * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static RetcodeType Process_Serial_Packet(char *multi_packet_buf, - int first_time) -{ - multi_packet_buf; - first_time; - return (RC_NORMAL); -#if (0) // ST - 1/2/2019 5:28PM - SerialPacketType *serial_packet; // for parsing serial packets - int player_gone; - EventClass *event; - char txt[MAX_MESSAGE_LENGTH+80]; - unsigned short magic_number; - unsigned short crc; - - //------------------------------------------------------------------------ - // Determine if this packet means that the other player has left the game - //------------------------------------------------------------------------ - serial_packet = (SerialPacketType *)multi_packet_buf; - player_gone = 0; - //........................................................................ - // On Frame 0, only a SIGN_OFF means the other player left; the other - // packet types may be left over from a previous session. - //........................................................................ - if (first_time) { - if (serial_packet->Command == SERIAL_SIGN_OFF) { - player_gone = 1; - } - } - //........................................................................ - // On subsequent frames, any of SIGN_OFF, TIMING, or SCORE_SCREEN means - // the other player is gone. - //........................................................................ - else { - if (serial_packet->Command == SERIAL_SIGN_OFF || - serial_packet->Command == SERIAL_TIMING || - serial_packet->Command == SERIAL_SCORE_SCREEN ) { - player_gone = 1; - } - } - if (player_gone) { - Destroy_Null_Connection(serial_packet->Color, 0); - return (RC_PLAYER_LEFT); - } - - //------------------------------------------------------------------------ - // Process an incoming message - //------------------------------------------------------------------------ - if (serial_packet->Command == SERIAL_MESSAGE) { - sprintf(txt, Text_String(TXT_FROM), serial_packet->Name, - serial_packet->Message); - - magic_number = *((unsigned short*)(serial_packet->Message + COMPAT_MESSAGE_LENGTH-4)); - crc = *((unsigned short*)(serial_packet->Message + COMPAT_MESSAGE_LENGTH-2)); - - Messages.Add_Message (txt, - MPlayerTColors[MPlayerID_To_ColorIndex(serial_packet->ID)], - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, magic_number, crc); - - //..................................................................... - // Save this message in our last-message buffer - //..................................................................... - if (strlen (serial_packet->Message)) { - strcpy (LastMessage, serial_packet->Message); - } - - //..................................................................... - // Tell the map to do a partial update (just to force the - // messages to redraw). - //..................................................................... - Map.Flag_To_Redraw(false); - return (RC_SERIAL_PROCESSED); - } - - //------------------------------------------------------------------------ - // Any other SERIAL-type packet means the other player is still there; - // throw them away, but let the caller know the connection is OK. - //------------------------------------------------------------------------ - if ( (serial_packet->Command >= SERIAL_CONNECT && - serial_packet->Command < SERIAL_LAST_COMMAND) || - MPlayerCount == 1) { - return (RC_SERIAL_PROCESSED); - } - - //........................................................................ - // are we getting our own packets back?? - //........................................................................ - event = (EventClass *)multi_packet_buf; - if (event->ID == Houses.ID(PlayerPtr)) { - return (RC_HUNG_UP); - } - - return (RC_NORMAL); -#endif -} // end of Process_Serial_Packet - - -/*************************************************************************** - * Can_Advance -- determines if it's OK to advance to the next frame * - * * - * This routine uses the current values stored in their_frame[], * - * their_send[], and their_recv[] to see if it's OK to advance to the next * - * game frame. We must not advance if: * - * - If our frame # would be too far ahead of the slowest player (the * - * lowest their_frame[] value). "Too far" means * - * (Frame > their_frame + MaxAhead). * - * - our current command count doesn't match the sent command count of one * - * other player (meaning that we've missed a command packet from that * - * player, and thus the frame # we're receiving from him may be due to a * - * FRAMEINFO packet sent later than the command, so we shouldn't use * - * this frame # to see if we should advance; we should wait until we * - * have all the commands before we advance. * - * * - * Of course, this routine assumes the values in their_frame[] etc are * - * kept current by the caller. * - * * - * INPUT: * - * net ptr to connection manager * - * max_ahead max frames ahead * - * their_frame array of their frame #'s * - * their_sent array of their sent command count * - * their_recv array of their # received commands * - * * - * OUTPUT: * - * 1 = OK to advance; 0 = not OK * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Can_Advance(ConnManClass *net, int max_ahead, long *their_frame, - unsigned short *their_sent, unsigned short *their_recv) -{ - long their_oldest_frame; // other players' oldest frame # - int count_ok; // true = my cmd count matches theirs - int i; - - //------------------------------------------------------------------------ - // Special case for modem: if the other player has left, go ahead and - // advance to the next frame; don't wait on him. - //------------------------------------------------------------------------ - if (MPlayerCount == 1) { - return (1); - } - //------------------------------------------------------------------------ - // Find the oldest frame # in 'their_frame' - //------------------------------------------------------------------------ - their_oldest_frame = Frame + 1000; - for (i = 0; i < net->Num_Connections(); i++) { - if (their_frame[i] < their_oldest_frame) - their_oldest_frame = their_frame[i]; - } - - //------------------------------------------------------------------------ - // I can advance to the next frame IF: - // 1) I'm less than a one-way propogation delay ahead of the other - // players' frame numbers, AND - // 2) their_recv[i] >= their_sent[i] (ie I've received all the commands - // the other players have sent so far). - //------------------------------------------------------------------------ - count_ok = 1; - for (i = 0; i < net->Num_Connections(); i++) { - if (their_recv[i] < their_sent[i]) { - count_ok = 0; - break; - } - } - if (count_ok && (Frame < (their_oldest_frame + max_ahead))) { - return (1); - } - - return (0); - -} // end of Can_Advance - - -/*************************************************************************** - * Process_Reconnect_Dialog -- processes the reconnection dialog * - * * - * This routine [re]draws the reconnection dialog; if 'reconn' is set, * - * it tells the user who we're trying to reconnect to; otherwise, is just * - * says something generic like "Waiting for connections". * - * * - * INPUT: * - * timeout_timer ptr to count down timer, showing time remaining * - * their_frame array of other players' frame #'s * - * num_conn # connections in 'their_frame' * - * reconn 1 = reconnect, 0 = waiting for first-time connection * - * fresh 1 = draw from scratch, 0 = only update time counter * - * * - * OUTPUT: * - * 1 = user wants to cancel, 0 = not * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Process_Reconnect_Dialog(CountDownTimerClass *timeout_timer, - long *their_frame, int num_conn, int reconn, int fresh) -{ - static int displayed_time = 0; // time value currently displayed - int new_time; - int oldest_index; // index of person requiring a reconnect - int i,j; - - //------------------------------------------------------------------------ - // Convert the timer to seconds - //------------------------------------------------------------------------ - new_time = timeout_timer->Time() / 60; - - //-------------------------------------------------------------------------------- - // If we have just received input focus again after running in the background then - // we need to redraw the whole dialog. - //-------------------------------------------------------------------------------- - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - fresh = true; - } - - //------------------------------------------------------------------------ - // If the timer has changed, or 'fresh' is set, redraw the dialog - //------------------------------------------------------------------------ - if (fresh || (new_time != displayed_time)) { - //..................................................................... - // Find the index of the person we're trying to reconnect to - //..................................................................... - if (reconn) { - j = 0x7fffffff; - oldest_index = 0; - for (i = 0; i < num_conn; i++) { - if (their_frame[i] < j) { - j = their_frame[i]; - oldest_index = i; - } - } - } - Net_Reconnect_Dialog(reconn, fresh, oldest_index, new_time); - } - displayed_time = new_time; - - //........................................................................ - // If user hits ESC, bail out - //........................................................................ - if (Check_Key()) { - if (Get_Key_Num()==KN_ESC) { - return (1); - } - } - - return (0); - -} // end of Process_Reconnect_Dialog - - -/*************************************************************************** - * Handle_Timeout -- handles a timeout in the wait-for-players loop * - * * - * This routine "gracefully" handles a timeout in the frame-sync loop. * - * The timeout must be handled differently by a modem game or network * - * game. * - * * - * The modem game must detect if the other player is still connected * - * physically, even if he's not playing the game any more; if so, this * - * routine returns an OK status. If the other player isn't even * - * physically connected, an error is returned. * - * * - * The network game must find the connection that's causing the timeout, * - * and destroy it. The game continues, even if there are no more human * - * players left. * - * * - * INPUT: * - * net ptr to connection manager * - * their_frame array containing frame #'s of other players * - * their_sent array containing command count of other players * - * their_recv array containing # recv'd cmds from other players * - * * - * OUTPUT: * - * 1 = it's OK; reset timeout timers & keep processing * - * 0 = game over, man * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Handle_Timeout(ConnManClass *net, long *their_frame, - unsigned short *their_sent, unsigned short *their_recv) -{ - int oldest_index; // index of person requiring a reconnect - int i,j; - int id; - - //------------------------------------------------------------------------ - // For modem, attempt to reconnect; if that fails, save the game & bail. - //------------------------------------------------------------------------ - if (GameToPlay == GAME_MODEM || GameToPlay == GAME_NULL_MODEM) { -#if (0) //ST - 1/2/2019 5:28PM - if ( net->Num_Connections() ) { - if (!Reconnect_Modem()) { - return (0); - } - else { - return (1); - } - } -#endif - } - - //------------------------------------------------------------------------ - // For network, destroy the oldest connection - //------------------------------------------------------------------------ - else if (GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) { - j = 0x7fffffff; - oldest_index = 0; - for (i = 0; i < net->Num_Connections(); i++) { - if (their_frame[i] < j) { - j = their_frame[i]; - oldest_index = i; - } - } - - id = net->Connection_ID(oldest_index); - - /* - ** Send the game statistics packet now if the game is effectivly over - */ - if (MPlayerCount == 2 && - GameToPlay == GAME_INTERNET && - !GameStatisticsPacketSent){ - Register_Game_End_Time(); - ConnectionLost = true; - Send_Statistics_Packet(); - } - - if (id != ConnManClass::CONNECTION_NONE) { - for (i = oldest_index; i < net->Num_Connections() - 1; i++) { - their_frame[i] = their_frame[i+1]; - their_sent[i] = their_sent[i+1]; - their_recv[i] = their_recv[i+1]; - } - CCDebugString ("C&C95 = Destroying connection due to time out\n"); - Destroy_Connection(id,1); - } - } - - return (1); - -} // end of Handle_Timeout - - -/*************************************************************************** - * Stop_Game -- stops the game * - * * - * This routine clears any global flags that need it, in preparation for * - * halting the game prematurely. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/22/1995 BRR : Created. * - *=========================================================================*/ -static void Stop_Game(void) -{ - CCDebugString ("C&C95 - In Stop_Game.\n"); - GameActive = 0; - if (IsMono) { - MonoClass::Disable(); - } - - if (GameToPlay == GAME_INTERNET){ - ConnectionLost = true; - CCDebugString ("C&C95 - About to send statistics packet.\n"); - Register_Game_End_Time(); - Send_Statistics_Packet(); - CCDebugString ("C&C95 - Returned from sending stats packet.\n"); - } - - return; - -} // end of Stop_Game - - -/*************************************************************************** - * Build_Send_Packet -- Builds a big packet from a bunch of little ones. * - * * - * This routine takes events from the OutList, and puts them into a * - * "meta-packet", which is transmitted to all systems we're connected to. * - * Also, these events are added to our own DoList. * - * * - * Every Meta-Packet we send uses a FRAMEINFO packet as a header; this * - * tells the other systems what frame we're on, as well as serving as a * - * standard packet header. * - * * - * INPUT: * - * buf buffer to store packet in * - * bufsize max size of buffer * - * frame_delay desired frame delay to attach to all outgoing packets * - * num_cmds value to use for the CommandCount field * - * cap max # events to send * - * * - * OUTPUT: * - * new size of packet * - * * - * WARNINGS: * - * 'num_cmds' should be the total of of commands, including all those sent * - * this frame! * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Build_Send_Packet(void *buf, int bufsize, int frame_delay, - int num_cmds, int cap) -{ - int size = 0; - EventClass *finfo; - - //------------------------------------------------------------------------ - // All events start with a FRAMEINFO event; fill this part in. - //------------------------------------------------------------------------ - //........................................................................ - // Set the event type - //........................................................................ - finfo = (EventClass *)buf; - finfo->Type = EventClass::FRAMEINFO; - //........................................................................ - // Set the frame to execute this event on; this is protocol-specific - //........................................................................ - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - finfo->Frame = ((Frame + frame_delay + (FrameSendRate - 1)) / - FrameSendRate) * FrameSendRate; - } - else { - finfo->Frame = Frame + frame_delay; - } - //........................................................................ - // Fill in the rest of the event - //........................................................................ - finfo->ID = Houses.ID(PlayerPtr); - finfo->MPlayerID = MPlayerLocalID; - finfo->Data.FrameInfo.CRC = GameCRC; - finfo->Data.FrameInfo.CommandCount = num_cmds; - finfo->Data.FrameInfo.Delay = frame_delay; - - //------------------------------------------------------------------------ - // Initialize the # of bytes processed; this is protocol-specific - //------------------------------------------------------------------------ - if (CommProtocol==COMM_PROTOCOL_SINGLE_NO_COMP) { - size += sizeof(EventClass); - } - else { - size += (offsetof(EventClass, Data) + - size_of(EventClass, Data.FrameInfo)); - } - - //------------------------------------------------------------------------ - // Transfer all events from the OutList into the DoList, building our - // packet while we go. - //------------------------------------------------------------------------ - switch (CommProtocol) { - //..................................................................... - // COMM_PROTOCOL_SINGLE_NO_COMP: - // We'll send at least a FRAMEINFO every single frame, no compression - //..................................................................... - case (COMM_PROTOCOL_SINGLE_NO_COMP): - size = Add_Uncompressed_Events(buf, bufsize, frame_delay, size, cap); - break; - - //..................................................................... - // COMM_PROTOCOL_SINGLE_E_COMP: - // Compress a group of packets into our send buffer; send out - // compressed packets every frame. - // COMM_PROTOCOL_MULTI_E_COMP: - // Compress a group of packets into our send buffer; send out - // compressed packets every 'n' frames. - //..................................................................... - case (COMM_PROTOCOL_SINGLE_E_COMP): - case (COMM_PROTOCOL_MULTI_E_COMP): - size = Add_Compressed_Events(buf, bufsize, frame_delay, size, cap); - break; - - //..................................................................... - // Default: We have no idea what to do, so do nothing. - //..................................................................... - default: - size = 0; - break; - } - - return( size ); - -} /* end of Build_Send_Packet */ - - -/*************************************************************************** - * Add_Uncompressed_Events -- adds uncompressed events to a packet * - * * - * INPUT: * - * buf buffer to store packet in * - * bufsize max size of buffer * - * frame_delay desired frame delay to attach to all outgoing packets * - * size current packet size * - * cap max # events to process * - * * - * OUTPUT: * - * new size value * - * * - * WARNINGS: * - * This routine MUST check to be sure it doesn't overflow the buffer. * - * * - * HISTORY: * - * 11/21/1995 DRD : Created. * - *=========================================================================*/ -static int Add_Uncompressed_Events(void *buf, int bufsize, int frame_delay, - int size, int cap) -{ - int num = 0; // # of events processed - int ev_size; // size of event we're adding - - //------------------------------------------------------------------------ - // Loop until there are no more events, or we've processed our max # of - // events, or the buffer is full. - //------------------------------------------------------------------------ - while (OutList.Count && (num < cap)) { - ev_size = sizeof(EventClass); - //..................................................................... - // Will the next event exceed the size of the buffer? If so, break. - //..................................................................... - if ( (size + ev_size) > bufsize ) { - return (size); - } - - //..................................................................... - // Set the event's frame delay - //..................................................................... - OutList.First().Frame = Frame + frame_delay; - - //..................................................................... - // Set the event's ID - //..................................................................... - OutList.First().ID = Houses.ID(PlayerPtr); - OutList.First().MPlayerID = MPlayerLocalID; - - //..................................................................... - // Transfer the event in OutList to DoList, un-queue the OutList - // event. If the DoList is full, stop transferring immediately. - //..................................................................... - OutList.First().IsExecuted = 0; - if (!DoList.Add(OutList.First())) { - return (size); - } - - //..................................................................... - // Add event to the send packet - //..................................................................... - memcpy ( ((char *)buf) + size, &OutList.First(), sizeof(EventClass) ); - size += sizeof(EventClass); - - //..................................................................... - // Increment our event counter; delete the last event from the queue - //..................................................................... - num++; - OutList.Next(); - } - - return (size); - -} // end of Add_Uncompressed_Events - - -/*************************************************************************** - * Add_Compressed_Events -- adds an compressed events to a packet * - * * - * INPUT: * - * buf buffer to store packet in * - * bufsize max size of buffer * - * frame_delay desired frame delay to attach to all outgoing packets * - * size reference to current packet size * - * cap max # events to process * - * * - * OUTPUT: * - * new size value * - * * - * WARNINGS: * - * This routine MUST check to be sure it doesn't overflow the buffer. * - * * - * HISTORY: * - * 11/21/1995 DRD : Created. * - *=========================================================================*/ -static int Add_Compressed_Events(void *buf, int bufsize, int frame_delay, - int size, int cap) -{ - int num = 0; // # of events processed - EventClass::EventType eventtype; // type of event being compressed - EventClass prevevent; // last event processed - int datasize; // size of element plucked from event union - int storedsize; // actual # bytes stored from event - unsigned char *unitsptr = NULL; // ptr to buffer pos to store mega. rep count - unsigned char numunits = 0; // megamission rep count value - bool missiondup = false; // flag: is this event a megamission repeat? - - //------------------------------------------------------------------------ - // clear previous event - //------------------------------------------------------------------------ - memset (&prevevent, 0, sizeof(EventClass)); - - //------------------------------------------------------------------------ - // Loop until there are no more events, we've processed our max # of - // events, or the buffer is full. - //------------------------------------------------------------------------ - while (OutList.Count && (num < cap)) { - eventtype = OutList.First().Type; - datasize = EventClass::EventLength[ eventtype ]; - //..................................................................... - // For a variable-sized event, pull the size from the event; otherwise, - // the size will be the data element size plus the event type value. - //..................................................................... - storedsize = datasize + sizeof (EventClass::EventType); - - //..................................................................... - // MegaMission compression: MegaMissions are stored as: - // EventType - // Rep Count - // MegaMission structure (event # 1 only) - // Whom #2 - // Whom #3 - // Whom #4 - // ... - // Whom #n - //..................................................................... - if (prevevent.Type == EventClass::MEGAMISSION) { - //.................................................................. - // If previous & current events are both MegaMissions: - //.................................................................. - if (eventtype == EventClass::MEGAMISSION) { - //............................................................... - // If the Mission, Target, & Destination are the same, compress - // the events into one: - // - Change datasize to the size of the 'Whom' field only - // - set total # bytes to store to the size of the 'Whom' only - // - increment the MegaMission rep count - // - set the MegaMission rep flag - //............................................................... - if (OutList.First().Data.MegaMission.Mission == - prevevent.Data.MegaMission.Mission && - OutList.First().Data.MegaMission.Target == - prevevent.Data.MegaMission.Target && - OutList.First().Data.MegaMission.Destination == - prevevent.Data.MegaMission.Destination) { - - datasize = sizeof(prevevent.Data.MegaMission.Whom); - storedsize = datasize; - numunits++; - missiondup = true; - } - //............................................................... - // Data doesn't match; start a new run of MegaMissions: - // - Store previous MegaMission rep count - // - Init 'unitsptr' to buffer pos after next EventType - // - set total # bytes to store to 'datasize' + sizeof(EventType) + - // sizeof (numunits) - // - init the MegaMission rep count to 1 - // - clear the MegaMission rep flag - //............................................................... - else { - *unitsptr = numunits; - unitsptr = ((unsigned char *)buf) + size + - sizeof(EventClass::EventType); - storedsize += sizeof(numunits); - numunits = 1; - missiondup = false; - } - } - //.................................................................. - // Previous event was a MegaMission, but this one isn't: end the - // run of MegaMissions: - // - Store previous MegaMission rep count - // - Clear variables - //.................................................................. - else { - *unitsptr = numunits; // save # events in our run - unitsptr = NULL; // init other values - numunits = 0; - missiondup = false; - } - } - - //..................................................................... - // The previous event is not a MEGAMISSION but the current event is: - // Set up a new run of MegaMissions: - // - Init 'unitsptr' to buffer pos after next EventType - // - set total # bytes to store to 'datasize' + sizeof(EventType) + - // sizeof (numunits) - // - init the MegaMission rep count to 1 - // - clear the MegaMission rep flag - //..................................................................... - else if (eventtype == EventClass::MEGAMISSION) { - unitsptr = ((unsigned char *)buf) + size + - sizeof(EventClass::EventType); - storedsize += sizeof(numunits); - numunits = 1; - missiondup = false; - } - - //..................................................................... - // Will the next event exceed the size of the buffer? If so, - // stop compressing. - //..................................................................... - if ( (size + storedsize) > bufsize ) - break; - - //..................................................................... - // Set the event's frame delay (this is protocol-dependent) - //..................................................................... - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - OutList.First().Frame = ((Frame + frame_delay + - (FrameSendRate - 1)) / FrameSendRate) * - FrameSendRate; - } - else { - OutList.First().Frame = Frame + frame_delay; - } - - //..................................................................... - // Set the event's ID - //..................................................................... - OutList.First().ID = Houses.ID(PlayerPtr); - OutList.First().MPlayerID = MPlayerLocalID; - - //..................................................................... - // Transfer the event in OutList to DoList, un-queue the OutList event. - // If the DoList is full, stop transferring immediately. - //..................................................................... - OutList.First().IsExecuted = 0; - if ( !DoList.Add( OutList.First() ) ) { - break; - } - - //--------------------------------------------------------------------- - // Compress the event into the send packet buffer - //--------------------------------------------------------------------- - switch ( eventtype ) { - //.................................................................. - // RESPONSE_TIME: just use the Delay field of the FrameInfo union - //.................................................................. - case (EventClass::RESPONSE_TIME): - - *(EventClass::EventType *)( ((char *)buf) + size) = eventtype; - - memcpy ( ((char *)buf) + size + sizeof(EventClass::EventType), - &OutList.First().Data.FrameInfo.Delay, datasize ); - - size += (datasize + sizeof(EventClass::EventType)); - break; - - //.................................................................. - // MEGAMISSION: - //.................................................................. - case (EventClass::MEGAMISSION): - //............................................................... - // Repeated mission in a run: - // - Update the rep count (in case we break out) - // - Copy the Whom field only - //............................................................... - if (missiondup) { - *unitsptr = numunits; - - memcpy ( ((char *)buf) + size, - &OutList.First().Data.MegaMission.Whom, datasize ); - - size += datasize; - } - //............................................................... - // 1st mission in a run: - // - Init the rep count (in case we break out) - // - Set the EventType - // - Copy the MegaMission structure, leaving room for 'numunits' - //............................................................... - else { - *unitsptr = numunits; - - *(EventClass::EventType *)( ((char *)buf) + size) = eventtype; - - memcpy ( ((char *)buf) + size + - sizeof(EventClass::EventType) + sizeof(numunits), - &OutList.First().Data.MegaMission, datasize ); - - size += (datasize + sizeof(EventClass::EventType) + sizeof(numunits)); - } - break; - - //.................................................................. - // Default case: Just copy over the data field from the union - //.................................................................. - default: - *(EventClass::EventType *)( ((char *)buf) + size) = eventtype; - - memcpy ( ((char *)buf) + size + sizeof(EventClass::EventType), - &OutList.First().Data, datasize ); - - size += (datasize + sizeof(EventClass::EventType)); - - break; - } - - //--------------------------------------------------------------------- - // update # events processed - //--------------------------------------------------------------------- - num++; - - //--------------------------------------------------------------------- - // Update 'prevevent' - //--------------------------------------------------------------------- - memcpy ( &prevevent, &OutList.First(), sizeof(EventClass) ); - - //--------------------------------------------------------------------- - // Go to the next event to process - //--------------------------------------------------------------------- - OutList.Next(); - } - - return (size); - -} // end of Add_Compressed_Events - - -/*************************************************************************** - * Breakup_Receive_Packet -- Splits a big packet into little ones. * - * * - * INPUT: * - * buf buffer to break up * - * bufsize length of buffer * - * * - * OUTPUT: * - * # events added to queue, -1 if fatal error (queue is full) * - * (return value includes any FRAMEINFO packets encountered; * - * FRAMESYNC's are ignored) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Breakup_Receive_Packet(void *buf, int bufsize ) -{ - int count = 0; - - /* - ** is there enough leftover for another record - */ - switch (CommProtocol) { - case (COMM_PROTOCOL_SINGLE_NO_COMP): - count = Extract_Uncompressed_Events(buf, bufsize); - break; - - default: - count = Extract_Compressed_Events(buf, bufsize); - break; - } - - return (count); - -} /* end of Breakup_Receive_Packet */ - - -/*************************************************************************** - * Extract_Uncompressed_Events -- extracts events from a packet * - * * - * INPUT: * - * buf buffer containing events to extract * - * bufsize length of 'buf' * - * * - * OUTPUT: * - * # events extracted * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 DRD : Created. * - *=========================================================================*/ -static int Extract_Uncompressed_Events(void *buf, int bufsize) -{ - int count = 0; - int pos = 0; - int leftover = bufsize; - EventClass *event; - - //------------------------------------------------------------------------ - // Loop until there are no more events in the packet - //------------------------------------------------------------------------ - while (leftover >= sizeof(EventClass) ) { - event = (EventClass *)(((char *)buf) + pos); - - //..................................................................... - // add event to the DoList, only if it's not a FRAMESYNC - // (but FRAMEINFO's do get added.) - //..................................................................... - if (event->Type != EventClass::FRAMESYNC) { - event->IsExecuted = 0; - - if (!DoList.Add( *event )) { - return (-1); - } - - //.................................................................. - // Keep count of how many events we add to the queue - //.................................................................. - count++; - } - - //..................................................................... - // Point to the next position in the buffer; decrement our 'leftover' - //..................................................................... - pos += sizeof(EventClass); - leftover -= sizeof(EventClass); - } - - return (count); - -} // end of Extract_Uncompressed_Events - - -/*************************************************************************** - * Extract_Compressed_Events -- extracts events from a packet * - * * - * INPUT: * - * buf buffer containing events to extract * - * bufsize length of 'buf' * - * * - * OUTPUT: * - * # events extracted * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 DRD : Created. * - *=========================================================================*/ -static int Extract_Compressed_Events(void *buf, int bufsize) -{ - int pos = 0; // current buffer parsing position - int leftover = bufsize; // # bytes left to process - EventClass *event; // event ptr for parsing buffer - int count = 0; // # events processed - int datasize = 0; // size of data to copy - EventClass eventdata; // stores Frame, ID, etc - unsigned char numunits = 0; // # units stored in compressed MegaMissions -//int lasteventtype=0; - //------------------------------------------------------------------------ - // Clear work event structure - //------------------------------------------------------------------------ - memset (&eventdata, 0, sizeof(EventClass)); - - //------------------------------------------------------------------------ - // Assume the first event is a FRAMEINFO event - // Init 'datasize' to the amount of data to copy, minus the EventType value - // For the 1st packet only, this will include all info before the Data - // union, plus the size of the FrameInfo structure, minus the EventType size. - //------------------------------------------------------------------------ - datasize = (offsetof(EventClass, Data) + - size_of(EventClass, Data.FrameInfo)) - sizeof(EventClass::EventType); - event = (EventClass *)(((char *)buf) + pos); - - while ((unsigned)leftover >= (datasize + sizeof(EventClass::EventType)) ) { - //..................................................................... - // add event to the DoList, only if it's not a FRAMESYNC - // (but FRAMEINFO's do get added.) - //..................................................................... - if (event->Type != EventClass::FRAMESYNC) { - //.................................................................. - // initialize the common data from the FRAMEINFO event - // keeping IsExecuted 0 - //.................................................................. - if (event->Type == EventClass::FRAMEINFO) { - eventdata.Frame = event->Frame; - eventdata.ID = event->ID; - eventdata.MPlayerID = event->MPlayerID; - - //............................................................... - // Adjust position past the common data - //............................................................... - pos += (offsetof(EventClass, Data) - - sizeof(EventClass::EventType)); - leftover -= (offsetof(EventClass, Data) - - sizeof(EventClass::EventType)); - } - //.................................................................. - // if MEGAMISSION event get the number of units (events to generate) - //.................................................................. - else if (event->Type == EventClass::MEGAMISSION) { - numunits = *(((unsigned char *)buf) + pos + sizeof(eventdata.Type)); - pos += sizeof(numunits); - leftover -= sizeof(numunits); - } - - //.................................................................. - // clear the union data portion of the event - //.................................................................. - memset (&eventdata.Data, 0, sizeof(eventdata.Data)); - eventdata.Type = event->Type; - datasize = EventClass::EventLength[ eventdata.Type ]; - - switch (eventdata.Type) { - case (EventClass::RESPONSE_TIME): - memcpy ( &eventdata.Data.FrameInfo.Delay, - ((char *)buf) + pos + sizeof(EventClass::EventType), - datasize ); - break; - - case (EventClass::MEGAMISSION): - memcpy ( &eventdata.Data.MegaMission, - ((char *)buf) + pos + sizeof(EventClass::EventType), - datasize ); - - if (numunits > 1) { - pos += (datasize + sizeof(EventClass::EventType)); - leftover -= (datasize + sizeof(EventClass::EventType)); - datasize = sizeof(eventdata.Data.MegaMission.Whom); - - while (numunits) { - if ( !DoList.Add( eventdata ) ) { - return (-1); - } - - //...................................................... - // Keep count of how many events we add to the queue - //...................................................... - count++; - numunits--; - memcpy ( &eventdata.Data.MegaMission.Whom, - ((char *)buf) + pos, datasize ); - - //...................................................... - // if one unit left fall thru to normal code - //...................................................... - if (numunits == 1) { - datasize -= sizeof(EventClass::EventType); - break; - } - else { - pos += datasize; - leftover -= datasize; - } - } - } - break; - - default: - memcpy ( &eventdata.Data, - ((char *)buf) + pos + sizeof(EventClass::EventType), - datasize ); - break; - } - -char flip[128]; -sprintf (flip, "C&C95 - Adding event type %d to queue\n", eventdata.Type); -CCDebugString (flip); - -//if (lasteventtype == 11){ -// break; -//} - -//lasteventtype = (int) eventdata.Type; - - - if ( !DoList.Add( eventdata ) ) { - return (-1); - } - - //.................................................................. - // Keep count of how many events we add to the queue - //.................................................................. - count++; - - pos += (datasize + sizeof(EventClass::EventType)); - leftover -= (datasize + sizeof(EventClass::EventType)); - - if (leftover) { - event = (EventClass *)(((char *)buf) + pos); - datasize = EventClass::EventLength[ event->Type ]; - if (event->Type == EventClass::MEGAMISSION) { - datasize += sizeof(numunits); - } - } - } - //..................................................................... - // FRAMESYNC event: This >should< be the only event in the buffer, - // and it will be uncompressed. - //..................................................................... - else { - pos += (datasize + sizeof(EventClass::EventType)); - leftover -= (datasize + sizeof(EventClass::EventType)); - event = (EventClass *)(((char *)buf) + pos); - - //.................................................................. - // size of FRAMESYNC event - EventType size - //.................................................................. - datasize = (offsetof(EventClass, Data) + - size_of(EventClass, Data.FrameInfo)) - - sizeof(EventClass::EventType); - } - } - - return (count); - -} // end of Extract_Compressed_Events - -#endif //DEMO - -/*************************************************************************** - * Execute_DoList -- Executes commands from the DoList * - * * - * This routine executes any events in the DoList that need to be executed * - * on the current game frame. The events must be executed in a special * - * order, so that all systems execute all events in exactly the same * - * order. * - * * - * This routine also handles checking the Game CRC sent by other systems * - * against my own, to be sure we're still in sync. * - * * - * INPUT: * - * max_houses # houses to execute commands for * - * base_house HousesType to start with * - * net ptr to connection manager; NULL if none * - * skip_crc a frame-based countdown timer; if it's non-zero, the * - * CRC check will be skipped. Ignored if NULL. * - * their_frame array of their frame #'s * - * their_sent array of # commands they've sent * - * their_recv array of # commands I've received from them * - * * - * (their_xxx are ignored if 'net' is NULL.) * - * * - * OUTPUT: * - * 1 = OK, 0 = some error occurred (CRC error, packet rcv'd too late.) * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static int Execute_DoList(int , HousesType , - ConnManClass *net, TCountDownTimerClass *, - long *their_frame, unsigned short *their_sent, unsigned short *their_recv) -{ - int i,j,k,wibble; - int index; - - //------------------------------------------------------------------------ - // For a single-player game, just execute all events in the queue. - //------------------------------------------------------------------------ - if (GameToPlay == GAME_NORMAL) { - for (i = 0; i < DoList.Count; i++) { - if ((unsigned)Frame >= DoList[i].Frame && !DoList[i].IsExecuted) { - DoList[i].Execute(); // execute it - DoList[i].IsExecuted = true; // mark as having been executed - } - } - return (1); - } - -//#if(TIMING_FIX) - // - // If MPlayerMaxAhead is recomputed such that it increases, the systems - // may try to free-run to the new MaxAhead value. If so, they may miss - // an event that was generated after the TIMING event was created, but - // before it executed; this event will be scheduled with the older, - // shorter MaxAhead value. If a system doesn't receive this event, it - // may execute past the frame it's scheduled to execute on, creating - // a Packet-Recieved-Too-Late error. To prevent this, find any events - // that are scheduled to execute during this "period of vulnerability", - // and re-schedule for the end of that period. - // - if (CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - for (j = 0; j < DoList.Count; j++) { - if (DoList[j].Type != EventClass::FRAMEINFO && - DoList[j].Frame > (unsigned)NewMaxAheadFrame1 && - DoList[j].Frame < (unsigned)NewMaxAheadFrame2) { - DoList[j].Frame = (unsigned)NewMaxAheadFrame2; - } - } - } -//#endif - - //------------------------------------------------------------------------ - // Execute the DoList. Events must be executed in the same order on all - // systems; so, execute them in the order of the MPlayerID array. This - // array is stored in the same order on all systems. - //------------------------------------------------------------------------ - for (i = 0; i < MPlayerCount; i++) { - - HousesType house; - HouseClass *housep; - - house = MPlayerHouses [i]; - housep= HouseClass::As_Pointer (house); - - //..................................................................... - // If for some reason this house doesn't exist, skip it. - // Also, if this house has exited the game, skip it. (The user can - // generate events after he exits, because the exit event is scheduled - // at least FrameSendRate*3 frames ahead. If one system gets these - // packets & another system doesn't, they'll go out of sync because - // they aren't checking the CommandCount for that house, since that - // house isn't connected any more.) - //..................................................................... - if (!housep){ - continue; - } - - if (!housep->IsHuman){ - continue; - } - - //..................................................................... - // Loop through all events - //..................................................................... - for (j = 0; j < DoList.Count; j++) { - -#ifndef DEMO - if (net) - Update_Queue_Mono (net, 6); -#endif //DEMO - - //.................................................................. - // If this event was from the currently-executing player ID, and it's - // time to execute it, execute it. - //.................................................................. - if (DoList[j].MPlayerID == MPlayerID[i] && (unsigned)Frame >= DoList[j].Frame && - !DoList[j].IsExecuted) { - - //............................................................... - // Error if it's too late to execute this packet! - //............................................................... - if ((unsigned)Frame > DoList[j].Frame && DoList[j].Type != - EventClass::FRAMEINFO) { -#ifndef DEMO - Dump_Packet_Too_Late_Stuff(&DoList[j]); -#endif //DEMO - CCMessageBox().Process (TXT_PACKET_TOO_LATE); - return (0); - } - - //............................................................... - // Only execute EXIT & OPTIONS commands if they're from myself. - //............................................................... - if (DoList[j].Type==EventClass::EXIT || - DoList[j].Type==EventClass::OPTIONS) { - - - if (DoList[j].Type==EventClass::EXIT){ -CCDebugString ("C&C95 - Received EXIT packet\n"); - - /* - ** Flag that this house lost because it quit. ST - 6/5/96 0:29AM - */ - for (wibble = 0; wibble < MPlayerCount; wibble++) { - if (MPlayerID[wibble] == DoList[j].MPlayerID) { - house = MPlayerHouses[wibble]; - housep = HouseClass::As_Pointer (house); - housep->IGaveUp = true; - break; - } - } - - /* - ** Send the game statistics packet now since the game is effectivly over - */ - if (MPlayerCount == 2 && - GameToPlay == GAME_INTERNET && - !GameStatisticsPacketSent){ - Register_Game_End_Time(); - Send_Statistics_Packet(); - } - } - - - - if (DoList[j].ID == Houses.ID(PlayerPtr)) { - DoList[j].Execute(); - } - - //............................................................ - // If this EXIT event isn't from myself, destroy the connection - // for that player. The HousesType for this event is the - // connection ID. - //............................................................ - else if (DoList[j].Type==EventClass::EXIT) { - if (GameToPlay == GAME_MODEM - || GameToPlay == GAME_NULL_MODEM){ - //|| GameToPlay == GAME_INTERNET) { - - //ST - 1/2/2019 5:29PM - //Destroy_Null_Connection( DoList[j].MPlayerID, 0 ); - } - - else if ((GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) && net) { - index = net->Connection_Index (DoList[j].MPlayerID); - if (index != -1) { - for (k = index; k < net->Num_Connections() - 1; k++) { - their_frame[k] = their_frame[k+1]; - their_sent[k] = their_sent[k+1]; - their_recv[k] = their_recv[k+1]; - } - CCDebugString ("C&C95 = Destroying connection due to exit event\n"); -#ifndef DEMO - Destroy_Connection(DoList[j].MPlayerID,0); -#endif //DEMO - } - } - } - } - - //............................................................... - // For a FRAMEINFO event, check the CRC value. - // This could be an old FRAMEINFO packet that was floating around - // for awhile and just arrived; if so, its Frame value will be - // old. Ignore these packets. (This created bogus sync bugs on - // the Internet, when packets that were 35 frames old arrived.) - //............................................................... -#ifndef DEMO - else if (DoList[j].Type == EventClass::FRAMEINFO) { - if (DoList[j].Frame == Frame && - DoList[j].Data.FrameInfo.Delay < 32) { - index = ((DoList[j].Frame - DoList[j].Data.FrameInfo.Delay) & - 0x001f); - if (CRC[index] != DoList[j].Data.FrameInfo.CRC) { - Print_CRCs(&DoList[j]); - if (CCMessageBox().Process (TXT_OUT_OF_SYNC, - TXT_CONTINUE, TXT_STOP) == 0) { - if (GameToPlay == GAME_MODEM || - GameToPlay == GAME_NULL_MODEM){ -#if (0)//ST - 1/2/2019 5:29PM - Destroy_Null_Connection( DoList[j].MPlayerID, -1 ); - Shutdown_Modem(); -#endif - GameToPlay = GAME_NORMAL; - } - else if ((GameToPlay == GAME_IPX || GameToPlay == GAME_INTERNET) && net) { - CCDebugString ("C&C95 = Destroying connections due to bad frame info packet\n"); - while (net->Num_Connections()) { - Destroy_Connection (net->Connection_ID(0), -1); - } - } - Map.Flag_To_Redraw(true); - } - else { - return (0); - } - return (1); - } - } - } -#endif //DEMO - //............................................................... - // Execute other commands - //............................................................... - else { - DoList[j].Execute(); - } - - //............................................................... - // Mark this event as executed. - //............................................................... - DoList[j].IsExecuted = 1; - } - } - } - - return (1); - -} // end of Execute_DoList - - -/*************************************************************************** - * Clean_DoList -- Cleans out old events from the DoList * - * * - * Currently, an event can only be removed from the DoList if it's at the * - * head of the list; and event can't be removed from the middle. So, * - * this routine loops as long as the next event in the DoList has been * - * executed, it's removed. * - * * - * INPUT: * - * net ptr to connection manager; ignored if NULL * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Clean_DoList(ConnManClass *net) -{ - while (DoList.Count) { - -#ifndef DEMO - if (net) - Update_Queue_Mono (net, 7); -#else - net = net; -#endif //DEMO - - //..................................................................... - // Discard events that have been executed, OR it's too late to execute. - // (This happens if another player exits the game; he'll leave FRAMEINFO - // events lying around in my queue. They won't have been "executed", - // because his IPX connection was destroyed.) - //..................................................................... - if ( (DoList.First().IsExecuted) || ((unsigned)Frame > DoList.First().Frame) ) { - DoList.Next(); - } - else { - break; - } - } - -} // end of Clean_DoList - -#ifndef DEMO - -/*************************************************************************** - * Queue_Record -- Records the DoList to disk * - * * - * This routine just saves any events in the DoList to disk; we can later * - * "play back" the recording just be pulling events from disk rather than * - * from the network! * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/14/1995 BRR : Created. * - *=========================================================================*/ -static void Queue_Record(void) -{ - int i,j; - - //------------------------------------------------------------------------ - // Compute # of events to save this frame - //------------------------------------------------------------------------ - j = 0; - for (i = 0; i < DoList.Count; i++) { - if (Frame == DoList[i].Frame && !DoList[i].IsExecuted) { - j++; - } - } - - //------------------------------------------------------------------------ - // Save the # of events, then all events. - //------------------------------------------------------------------------ - RecordFile.Write (&j,sizeof(j)); - for (i = 0; i < DoList.Count; i++) { - if (Frame == DoList[i].Frame && !DoList[i].IsExecuted) { - RecordFile.Write (&DoList[i],sizeof (EventClass)); - j--; - } - } - -} /* end of Queue_Record */ - - -/*************************************************************************** - * Queue_Playback -- plays back queue entries from a record file * - * * - * This routine reads events from disk, putting them into the DoList; * - * it then executes the DoList just like the network version does. The * - * result is that the game "plays back" like a recording. * - * * - * This routine detects mouse motion and stops playback, so it can work * - * like an "attract" mode, showing a demo of the game itself. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/15/1995 BRR : Created. * - *=========================================================================*/ -static void Queue_Playback(void) -{ - int numevents; - EventClass event; - int i; - int ok; - static int mx,my; - int max_houses; - HousesType base_house; - int key; - int testframe; - - //------------------------------------------------------------------------ - // If the user hits ESC, stop the playback - //------------------------------------------------------------------------ - if (Check_Key_Num()) { - key = Get_Key(); - // - // If the user hit ESC, end the recording. If this is an Attract-mode - // recording, end it no matter what the user does (any key or mouse). - // - if (key == KA_ESC || AllowAttract) { - GameActive = 0; - return; - } - } - - //------------------------------------------------------------------------ - // If we're in "Attact" mode, and the user moves the mouse, stop the - // playback. - //------------------------------------------------------------------------ - if (AllowAttract && Frame > 0 && - (mx != Get_Mouse_X() || my != Get_Mouse_Y())) { - GameActive = 0; - return; - } - mx = Get_Mouse_X(); - my = Get_Mouse_Y(); - - //------------------------------------------------------------------------ - // Compute the Game's CRC - //------------------------------------------------------------------------ - Compute_Game_CRC(); - CRC[Frame & 0x001f] = GameCRC; - - //------------------------------------------------------------------------ - // Don't read anything the first time through (since the Queue_AI_Network - // routine didn't write anything the first time through); do this after the - // CRC is computed, since we'll still need a CRC for Frame 0. - //------------------------------------------------------------------------ - if (Frame==0 && GameToPlay!=GAME_NORMAL) { - return; - } - - //------------------------------------------------------------------------ - // Only process every 'FrameSendRate' frames - //------------------------------------------------------------------------ - testframe = ((Frame + (FrameSendRate - 1)) / FrameSendRate) * FrameSendRate; - - if (GameToPlay != GAME_NORMAL && - CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) { - if (Frame != testframe) { - return; - } - } - - //------------------------------------------------------------------------ - // Read the DoList from disk - //------------------------------------------------------------------------ - ok = 1; - if (RecordFile.Read (&numevents, sizeof(numevents)) == - sizeof(numevents)) { - for (i = 0; i < numevents; i++) { - if (RecordFile.Read (&event, sizeof(EventClass)) == - sizeof(EventClass)) { - event.IsExecuted = 0; - DoList.Add (event); - } - else { - ok = 0; - break; - } - } - } - else { - ok = 0; - } - - if (!ok) { - GameActive = 0; - return; - } - - - //------------------------------------------------------------------------ - // Execute the DoList; if an error occurs, bail out. - //------------------------------------------------------------------------ - if (GameToPlay == GAME_NORMAL) { - max_houses = 1; - base_house = PlayerPtr->Class->House; - } - else { - max_houses = MPlayerMax; - base_house = HOUSE_MULTI1; - } - if (!Execute_DoList(max_houses, base_house, NULL, NULL, NULL, NULL, NULL)) { - GameActive = 0; - return; - } - - //------------------------------------------------------------------------ - // Clean out the DoList - //------------------------------------------------------------------------ - Clean_DoList(NULL); - -} /* end of Queue_Playback */ - - -/*************************************************************************** - * Compute_Game_CRC -- Computes a CRC value of the entire game. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 05/09/1995 BRR : Created. * - *=========================================================================*/ -static void Compute_Game_CRC(void) -{ - int i; - InfantryClass *infp; - UnitClass *unitp; - BuildingClass *bldgp; - //ObjectClass *objp; - - GameCRC = 0; - - //------------------------------------------------------------------------ - // Infantry - //------------------------------------------------------------------------ - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - } - - //------------------------------------------------------------------------ - // Units - //------------------------------------------------------------------------ - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing + - (int)unitp->SecondaryFacing); - } - - //------------------------------------------------------------------------ - // Buildings - //------------------------------------------------------------------------ - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - } - -#if(0) - //------------------------------------------------------------------------ - // Map Layers - //------------------------------------------------------------------------ - for (i = 0; i < LAYER_COUNT; i++) { - for (j = 0; j < Map.Layer[i].Count(); j++) { - objp = Map.Layer[i][j]; - Add_CRC (&GameCRC, (int)objp->Coord + (int)objp->What_Am_I()); - } - } - - //------------------------------------------------------------------------ - // Logic Layers - //------------------------------------------------------------------------ - for (i = 0; i < Logic.Count(); i++) { - objp = Logic[i]; - Add_CRC (&GameCRC, (int)objp->Coord + (int)objp->What_Am_I()); - } -#endif - - //------------------------------------------------------------------------ - // A random # - //------------------------------------------------------------------------ - Add_CRC(&GameCRC, rand()); - -} /* end of Compute_Game_CRC */ - - -/*************************************************************************** - * Add_CRC -- Adds a value to a CRC * - * * - * INPUT: * - * crc ptr to crc * - * val value to add * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 05/09/1995 BRR : Created. * - *=========================================================================*/ -void Add_CRC(unsigned long *crc, unsigned long val) -{ - int hibit; - - if ( (*crc) & 0x80000000) { - hibit = 1; - } - else { - hibit = 0; - } - - (*crc) <<= 1; - (*crc) += val; - (*crc) += hibit; - -} /* end of Add_CRC */ - - -/*************************************************************************** - * Print_CRCs -- Prints a data file for finding Sync Bugs * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 05/09/1995 BRR : Created. * - *=========================================================================*/ -void Print_CRCs(EventClass *ev) -{ - ev=ev; - - int i; //,j; - InfantryClass *infp; - UnitClass *unitp; - BuildingClass *bldgp; - //ObjectClass *objp; - FILE *fp; - int rnd; - HouseClass *housep; - //HousesType house; - int color; - - Mono_Clear_Screen(); - Mono_Set_Cursor (0,0); - - char filename[80]; - sprintf (filename, "CRC%02d.TXT", Frame & 0x1f); - - fp = fopen(filename, "wt"); //"OUT.TXT","wt"); - if (fp==NULL) { - return; - } - - for (i = 0; i < 32; i++) { - fprintf(fp,"CRC[%d]=%x\n",i,CRC[i]); - } - - - housep = HouseClass::As_Pointer (HOUSE_MULTI1); - if (housep) { - color = housep->RemapColor; - fprintf(fp,"Multi1: IsHuman:%d Color:%s\n",housep->IsHuman, - ColorNames[color]); - } - - housep = HouseClass::As_Pointer (HOUSE_MULTI2); - if (housep) { - color = housep->RemapColor; - fprintf(fp,"Multi2: IsHuman:%d Color:%s\n",housep->IsHuman, - ColorNames[color]); - } - - housep = HouseClass::As_Pointer (HOUSE_MULTI3); - if (housep) { - color = housep->RemapColor; - fprintf(fp,"Multi3: IsHuman:%d Color:%s\n",housep->IsHuman, - ColorNames[color]); - } - - housep = HouseClass::As_Pointer (HOUSE_MULTI4); - if (housep) { - color = housep->RemapColor; - fprintf(fp,"Multi4: IsHuman:%d Color:%s\n",housep->IsHuman, - ColorNames[color]); - } - - housep = HouseClass::As_Pointer (HOUSE_MULTI5); - if (housep) { - color = housep->RemapColor; - fprintf(fp,"Multi5: IsHuman:%d Color:%s\n",housep->IsHuman, - ColorNames[color]); - } - - housep = HouseClass::As_Pointer (HOUSE_MULTI6); - if (housep) { - color = housep->RemapColor; - fprintf(fp,"Multi6: IsHuman:%d Color:%s\n",housep->IsHuman, - ColorNames[color]); - } - - - //------------------------------------------------------------------------ - // Multi1 Infantry - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI1)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI1 INFANTRY -------------------\n"); - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - if (infp->Owner()==HOUSE_MULTI1) { - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - infp->Coord,(int)infp->PrimaryFacing,infp->Get_Mission(), - infp->Class->Type); - } - } - Mono_Printf("Multi1 Infantry:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi2 Infantry - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI2)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI2 INFANTRY -------------------\n"); - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - if (infp->Owner()==HOUSE_MULTI2) { - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - infp->Coord,(int)infp->PrimaryFacing,infp->Get_Mission(), - infp->Class->Type); - } - } - Mono_Printf("Multi2 Infantry:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi3 Infantry - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI3)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI3 INFANTRY -------------------\n"); - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - if (infp->Owner()==HOUSE_MULTI3) { - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - infp->Coord,(int)infp->PrimaryFacing,infp->Get_Mission(), - infp->Class->Type); - } - } - Mono_Printf("Multi3 Infantry:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi4 Infantry - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI4)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI4 INFANTRY -------------------\n"); - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - if (infp->Owner()==HOUSE_MULTI4) { - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - infp->Coord,(int)infp->PrimaryFacing,infp->Get_Mission(), - infp->Class->Type); - } - } - Mono_Printf("Multi4 Infantry:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi5 Infantry - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI5)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI5 INFANTRY -------------------\n"); - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - if (infp->Owner()==HOUSE_MULTI5) { - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - infp->Coord,(int)infp->PrimaryFacing,infp->Get_Mission(), - infp->Class->Type); - } - } - Mono_Printf("Multi5 Infantry:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi6 Infantry - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI6)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI6 INFANTRY -------------------\n"); - for (i = 0; i < Infantry.Count(); i++) { - infp = (InfantryClass *)Infantry.Active_Ptr(i); - if (infp->Owner()==HOUSE_MULTI6) { - Add_CRC (&GameCRC, (int)infp->Coord + (int)infp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - infp->Coord,(int)infp->PrimaryFacing,infp->Get_Mission(), - infp->Class->Type); - } - } - Mono_Printf("Multi6 Infantry:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi1 Units - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI1)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI1 UNITS -------------------\n"); - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - if (unitp->Owner()==HOUSE_MULTI1) { - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing); - fprintf(fp, - "COORD:%x Facing:%d Facing2:%d Mission:%d Type:%d\n", - unitp->Coord,(int)unitp->PrimaryFacing, - (int)unitp->SecondaryFacing,unitp->Get_Mission(), - unitp->Class->Type); - } - } - Mono_Printf("Multi1 Units:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi2 Units - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI2)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI2 UNITS -------------------\n"); - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - if (unitp->Owner()==HOUSE_MULTI2) { - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing); - fprintf(fp, - "COORD:%x Facing:%d Facing2:%d Mission:%d Type:%d\n", - unitp->Coord,(int)unitp->PrimaryFacing, - (int)unitp->SecondaryFacing,unitp->Get_Mission(), - unitp->Class->Type); - } - } - Mono_Printf("Multi2 Units:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi3 Units - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI3)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI3 UNITS -------------------\n"); - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - if (unitp->Owner()==HOUSE_MULTI3) { - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing); - fprintf(fp, - "COORD:%x Facing:%d Facing2:%d Mission:%d Type:%d\n", - unitp->Coord,(int)unitp->PrimaryFacing, - (int)unitp->SecondaryFacing,unitp->Get_Mission(), - unitp->Class->Type); - } - } - Mono_Printf("Multi3 Units:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi4 Units - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI4)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI4 UNITS -------------------\n"); - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - if (unitp->Owner()==HOUSE_MULTI4) { - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing); - fprintf(fp, - "COORD:%x Facing:%d Facing2:%d Mission:%d Type:%d\n", - unitp->Coord,(int)unitp->PrimaryFacing, - (int)unitp->SecondaryFacing,unitp->Get_Mission(), - unitp->Class->Type); - } - } - Mono_Printf("Multi4 Units:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi5 Units - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI5)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI5 UNITS -------------------\n"); - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - if (unitp->Owner()==HOUSE_MULTI5) { - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing); - fprintf(fp, - "COORD:%x Facing:%d Facing2:%d Mission:%d Type:%d\n", - unitp->Coord,(int)unitp->PrimaryFacing, - (int)unitp->SecondaryFacing,unitp->Get_Mission(), - unitp->Class->Type); - } - } - Mono_Printf("Multi5 Units:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi6 Units - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI6)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI6 UNITS -------------------\n"); - for (i = 0; i < Units.Count(); i++) { - unitp = (UnitClass *)Units.Active_Ptr(i); - if (unitp->Owner()==HOUSE_MULTI6) { - Add_CRC (&GameCRC, (int)unitp->Coord + (int)unitp->PrimaryFacing); - fprintf(fp, - "COORD:%x Facing:%d Facing2:%d Mission:%d Type:%d\n", - unitp->Coord,(int)unitp->PrimaryFacing, - (int)unitp->SecondaryFacing,unitp->Get_Mission(), - unitp->Class->Type); - } - } - Mono_Printf("Multi6 Units:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi1 Buildings - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI1)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI1 BUILDINGS -------------------\n"); - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - if (bldgp->Owner()==HOUSE_MULTI1) { - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - bldgp->Coord,(int)bldgp->PrimaryFacing,bldgp->Get_Mission(), - bldgp->Class->Type); - } - } - Mono_Printf("Multi1 Buildings:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi2 Buildings - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI2)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI2 BUILDINGS -------------------\n"); - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - if (bldgp->Owner()==HOUSE_MULTI2) { - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - bldgp->Coord,(int)bldgp->PrimaryFacing,bldgp->Get_Mission(), - bldgp->Class->Type); - } - } - Mono_Printf("Multi2 Buildings:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi3 Buildings - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI3)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI3 BUILDINGS -------------------\n"); - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - if (bldgp->Owner()==HOUSE_MULTI3) { - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - bldgp->Coord,(int)bldgp->PrimaryFacing,bldgp->Get_Mission(), - bldgp->Class->Type); - } - } - Mono_Printf("Multi3 Buildings:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi4 Buildings - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI4)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI4 BUILDINGS -------------------\n"); - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - if (bldgp->Owner()==HOUSE_MULTI4) { - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - bldgp->Coord,(int)bldgp->PrimaryFacing,bldgp->Get_Mission(), - bldgp->Class->Type); - } - } - Mono_Printf("Multi4 Buildings:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi5 Buildings - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI5)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI5 BUILDINGS -------------------\n"); - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - if (bldgp->Owner()==HOUSE_MULTI5) { - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - bldgp->Coord,(int)bldgp->PrimaryFacing,bldgp->Get_Mission(), - bldgp->Class->Type); - } - } - Mono_Printf("Multi5 Buildings:%d\n",GameCRC); - } - - //------------------------------------------------------------------------ - // Multi6 Buildings - //------------------------------------------------------------------------ - if (HouseClass::As_Pointer(HOUSE_MULTI6)) { - GameCRC = 0; - fprintf(fp,"-------------------- MULTI6 BUILDINGS -------------------\n"); - for (i = 0; i < Buildings.Count(); i++) { - bldgp = (BuildingClass *)Buildings.Active_Ptr(i); - if (bldgp->Owner()==HOUSE_MULTI6) { - Add_CRC (&GameCRC, (int)bldgp->Coord + (int)bldgp->PrimaryFacing); - fprintf(fp,"COORD:%x Facing:%d Mission:%d Type:%d\n", - bldgp->Coord,(int)bldgp->PrimaryFacing,bldgp->Get_Mission(), - bldgp->Class->Type); - } - } - Mono_Printf("Multi6 Buildings:%d\n",GameCRC); - } -#if (0) - //------------------------------------------------------------------------ - // Map Layers - //------------------------------------------------------------------------ - GameCRC = 0; - for (i = 0; i < LAYER_COUNT; i++) { - fprintf(fp,">>>> MAP LAYER %d <<<<\n",i); - for (j = 0; j < Map.Layer[i].Count(); j++) { - objp = Map.Layer[i][j]; - Add_CRC (&GameCRC, (int)objp->Coord + (int)objp->What_Am_I()); - fprintf(fp,"Object %d: %x ",j,objp->Coord); - - if (objp->What_Am_I() == RTTI_AIRCRAFT) - fprintf(fp,"Aircraft (Type:%d) ", - (AircraftType)(*((AircraftClass *)objp))); - else if (objp->What_Am_I() == RTTI_ANIM) - fprintf(fp,"Anim (Type:%d) ", - (AnimType)(*((AnimClass *)objp))); - else if (objp->What_Am_I() == RTTI_BUILDING) - fprintf(fp,"Building (Type:%d) ", - (StructType)(*((BuildingClass *)objp))); - else if (objp->What_Am_I() == RTTI_BULLET) - fprintf(fp,"Bullet (Type:%d) ", - (BulletType)(*((BulletClass *)objp))); - else if (objp->What_Am_I() == RTTI_INFANTRY) - fprintf(fp,"Infantry (Type:%d) ", - (InfantryType)(*((InfantryClass *)objp))); - else if (objp->What_Am_I() == RTTI_OVERLAY) - fprintf(fp,"Overlay (Type:%d) ", - (OverlayType)(*((OverlayClass *)objp))); - else if (objp->What_Am_I() == RTTI_SMUDGE) - fprintf(fp,"Smudge (Type:%d) ", - (SmudgeType)(*((SmudgeClass *)objp))); - else if (objp->What_Am_I() == RTTI_TEMPLATE) - fprintf(fp,"Template (Type:%d) ", - (TemplateType)(*((TemplateClass *)objp))); - else if (objp->What_Am_I() == RTTI_TERRAIN) - fprintf(fp,"Terrain (Type:%d) ", - (TerrainType)(*((TerrainClass *)objp))); - else if (objp->What_Am_I() == RTTI_UNIT) - fprintf(fp,"Unit (Type:%d) ", - (UnitType)(*((UnitClass *)objp))); - - house = objp->Owner(); - if (house!=HOUSE_NONE) { - housep = HouseClass::As_Pointer (house); - fprintf(fp,"Owner: %s\n",housep->Class->IniName); - } - else { - fprintf(fp,"Owner: NONE\n"); - } - } - } - Mono_Printf("Map Layers:%d\n",GameCRC); - - //------------------------------------------------------------------------ - // Logic Layers - //------------------------------------------------------------------------ - GameCRC = 0; - fprintf(fp,">>>> LOGIC LAYER <<<<\n"); - for (i = 0; i < Logic.Count(); i++) { - objp = Logic[i]; - Add_CRC (&GameCRC, (int)objp->Coord + (int)objp->What_Am_I()); - fprintf(fp,"Object %d: %x ",i,objp->Coord); - - if (objp->What_Am_I() == RTTI_AIRCRAFT) - fprintf(fp,"Aircraft (Type:%d) ", - (AircraftType)(*((AircraftClass *)objp))); - else if (objp->What_Am_I() == RTTI_ANIM) - fprintf(fp,"Anim (Type:%d) ", - (AnimType)(*((AnimClass *)objp))); - else if (objp->What_Am_I() == RTTI_BUILDING) - fprintf(fp,"Building (Type:%d) ", - (StructType)(*((BuildingClass *)objp))); - else if (objp->What_Am_I() == RTTI_BULLET) - fprintf(fp,"Bullet (Type:%d) ", - (BulletType)(*((BulletClass *)objp))); - else if (objp->What_Am_I() == RTTI_INFANTRY) - fprintf(fp,"Infantry (Type:%d) ", - (InfantryType)(*((InfantryClass *)objp))); - else if (objp->What_Am_I() == RTTI_OVERLAY) - fprintf(fp,"Overlay (Type:%d) ", - (OverlayType)(*((OverlayClass *)objp))); - else if (objp->What_Am_I() == RTTI_SMUDGE) - fprintf(fp,"Smudge (Type:%d) ", - (SmudgeType)(*((SmudgeClass *)objp))); - else if (objp->What_Am_I() == RTTI_TEMPLATE) - fprintf(fp,"Template (Type:%d) ", - (TemplateType)(*((TemplateClass *)objp))); - else if (objp->What_Am_I() == RTTI_TERRAIN) - fprintf(fp,"Terrain (Type:%d) ", - (TerrainType)(*((TerrainClass *)objp))); - else if (objp->What_Am_I() == RTTI_UNIT) - fprintf(fp,"Unit (Type:%d) ", - (UnitType)(*((UnitClass *)objp))); - - house = objp->Owner(); - if (house!=HOUSE_NONE) { - housep = HouseClass::As_Pointer (house); - fprintf(fp,"Owner: %s\n",housep->Class->IniName); - } - else { - fprintf(fp,"Owner: NONE\n"); - } - } - Mono_Printf("Logic:%d\n",GameCRC); -#endif - - //------------------------------------------------------------------------ - // Random # generator, frame # - //------------------------------------------------------------------------ - rnd = rand(); - - Mono_Printf("Random Number:%d\n",rnd); - fprintf(fp,"\nRandom Number:%d\n",rnd); - - Mono_Printf("My Frame:%d\n",Frame); - fprintf(fp,"My Frame:%d\n",Frame); -#if (0) - fprintf(fp,"-------------- Offending event: ----------------\n"); - fprintf(fp,"Type: %d\n",ev->Type); - fprintf(fp,"Frame: %d\n",ev->Frame); - fprintf(fp,"MPlayerID: %04x\n",ev->MPlayerID); - if (ev->Type == EventClass::FRAMEINFO) { - fprintf(fp,"CRC: %x\n",ev->Data.FrameInfo.CRC); - fprintf(fp,"CommandCount: %x\n",ev->Data.FrameInfo.CommandCount); - fprintf(fp,"Delay: %x\n",ev->Data.FrameInfo.Delay); - } -#endif - fclose(fp); - -} /* end of Print_CRCs */ - - -/*************************************************************************** - * Init_Queue_Mono -- inits mono display * - * * - * This routine steals control of the mono screen away from the rest of * - * the engine, by setting the global IsMono; if IsMono is set, the other * - * routines in this module turn off the Mono display when they're done * - * with it, so the rest of the engine won't over-write what we're writing. * - * * - * INPUT: * - * net ptr to connection manager * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Init_Queue_Mono(ConnManClass *net) -{ -#if(SHOW_MONO) - //------------------------------------------------------------------------ - // Set 'IsMono' so we can steal the mono screen from the engine - //------------------------------------------------------------------------ - if (Frame==0 && MonoClass::Is_Enabled()) { - IsMono = true; - } - - //------------------------------------------------------------------------ - // Enable mono output for our stuff; we must Disable it before we return - // control to the engine. - //------------------------------------------------------------------------ - if (IsMono) - MonoClass::Enable(); - - if (net->Num_Connections() > 0) { - //..................................................................... - // Network mono debugging screen - //..................................................................... - if (NetMonoMode==0) { - if (Frame==0 || NewMonoMode) { - net->Configure_Debug (0, sizeof (CommHeaderType), - sizeof(EventClass::EventType), EventClass::EventNames, 0); - net->Mono_Debug_Print (0,1); - NewMonoMode = 0; - } - else { - net->Mono_Debug_Print (0,0); - } - } - //..................................................................... - // Flow control debugging output - //..................................................................... - else { - if (NewMonoMode) { - Mono_Clear_Screen(); - Mono_Printf(" Queue AI:\n"); // flowcount[0] - Mono_Printf(" Build Packet Loop:\n"); // flowcount[1] - Mono_Printf(" Frame Sync:\n"); // flowcount[2] - Mono_Printf(" Frame Sync Resend:\n"); // flowcount[3] - Mono_Printf(" Frame Sync Timeout:\n"); // flowcount[4] - Mono_Printf(" Frame Sync New Message:\n"); // flowcount[5] - Mono_Printf(" DoList Execution:\n"); // flowcount[6] - Mono_Printf(" DoList Cleaning:\n"); // flowcount[7] - Mono_Printf("\n"); - Mono_Printf(" Frame:\n"); - Mono_Printf(" MPlayerMaxAhead:\n"); - Mono_Printf(" their_recv:\n"); - Mono_Printf(" their_sent:\n"); - Mono_Printf(" my_sent:\n"); - Mono_Printf(" DesiredFrameRate:\n"); - NewMonoMode = 0; - } - } - } -#else - net = net; -#endif -} // end of Init_Queue_Mono - - -/*************************************************************************** - * Update_Queue_Mono -- updates mono display * - * * - * INPUT: * - * net ptr to connection manager * - * flow_index index # for flow-count updates * - * -1: display * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Update_Queue_Mono(ConnManClass *net, int flow_index) -{ -#if(SHOW_MONO) - static int flowcount[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - //------------------------------------------------------------------------ - // If 'NetMonoMode' is 1, display flowcount info - //------------------------------------------------------------------------ - if (NetMonoMode==1) { - if (flow_index >= 0 && flow_index < 20) { - Mono_Set_Cursor(35,flow_index); - flowcount[flow_index]++; - Mono_Printf("%d",flowcount[flow_index]); - } - } - //------------------------------------------------------------------------ - // Otherwise, display the connection debug screen - //------------------------------------------------------------------------ - else { - net->Mono_Debug_Print (0,0); - } - -#else - flow_index = flow_index; - net = net; -#endif - -} // end of Update_Queue_Mono - - -/*************************************************************************** - * Print_Framesync_Values -- displays frame-sync variables * - * * - * INPUT: * - * curframe current game Frame # * - * max_ahead max-ahead value * - * num_connections # connections * - * their_recv # commands I've received from my connections * - * their_sent # commands each connection claims to have sent * - * my_sent # commands I've sent * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/21/1995 BRR : Created. * - *=========================================================================*/ -static void Print_Framesync_Values(long curframe, unsigned long max_ahead, - int num_connections, unsigned short *their_recv, - unsigned short *their_sent, unsigned short my_sent) -{ -#if(SHOW_MONO) - int i; - - if (NetMonoMode==1) { - Mono_Set_Cursor(35,9); - Mono_Printf("%d",curframe); - - Mono_Set_Cursor(35,10); - Mono_Printf("%d",max_ahead); - - for (i = 0; i < num_connections; i++) { - Mono_Set_Cursor(35 + i*5,11); - Mono_Printf("%4d",(int)their_recv[i]); - } - - for (i = 0; i < num_connections; i++) { - Mono_Set_Cursor(35 + i*5,12); - Mono_Printf("%4d",(int)their_sent[i]); - } - - Mono_Set_Cursor(35,13); - Mono_Printf("%4d",(int)my_sent); - - Mono_Set_Cursor(35,14); - Mono_Printf("%2d",(int)DesiredFrameRate); - } -#else - curframe = curframe; - max_ahead = max_ahead; - num_connections = num_connections; - their_recv = their_recv; - their_sent = their_sent; - my_sent = my_sent; -#endif -} // end of Print_Framesync_Values - - -/*************************************************************************** - * Dump_Packet_Too_Late_Stuff -- Dumps a debug file to disk * - * * - * INPUT: * - * event ptr to event to print * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/28/1996 BRR : Created. * - *=========================================================================*/ -void Dump_Packet_Too_Late_Stuff(EventClass *event) -{ - FILE *fp; - int i; - - fp = fopen("toolate.txt", "wt"); - if (!fp) { - return; - } - fprintf(fp,"--------- Event data: -------------------\n"); - fprintf(fp,"Type: %s\n",EventClass::EventNames[event->Type]); - fprintf(fp,"Frame: %d\n",event->Frame); - fprintf(fp,"ID: %d\n",event->ID); - fprintf(fp,"MPlayerID: %04x\n",event->MPlayerID); - - for (i = 0; i < MPlayerCount; i++) { - if (event->MPlayerID == MPlayerID[i]) { - fprintf(fp,"Player's Name: %s",MPlayerNames[i]); - } - } - - fprintf(fp,"----------- My data: ------------------\n"); - fprintf(fp,"Frame:%d\n",Frame); - fprintf(fp,"MaxAhead:%d\n",MPlayerMaxAhead); - - fclose(fp); -} - -#endif //DEMO - -/*************************** end of queue.cpp ******************************/ \ No newline at end of file diff --git a/code/TIBERIANDAWN/QUEUE.H b/code/TIBERIANDAWN/QUEUE.H deleted file mode 100644 index e184ed4..0000000 --- a/code/TIBERIANDAWN/QUEUE.H +++ /dev/null @@ -1,272 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\queue.h_v 2.16 16 Oct 1995 16:45:50 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : QUEUE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/08/94 * - * * - * Last Update : December 9, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * QueueClass::Add -- Add object to queue. * - * QueueClass::First -- Fetches reference to first object in list. * - * QueueClass::Init -- Initializes queue to empty state. * - * QueueClass::Next -- Throws out the head of the line. * - * QueueClass::operator[] -- Fetches reference to sub object in queue. * - * QueueClass::QueueClass -- Default constructor for QueueClass objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef QUEUE_H -#define QUEUE_H - -#include "mission.h" -#include "target.h" -#include "defines.h" - -//#pragma warn -inl - -/* -** This class implements a classic FIFO queue (also known as - standing in line). Objects -** are added to the end (tail) of the line. Objects are removed from the start (first) of -** the line. A keyboard buffer is a good example of a common computer use of a queue. There -** is no provision for "taking cuts" or leaving the line once an object has been added. -** -** The implementation uses a circular list of objects. This allows adding and deleting of -** elements without any maintenance moves of remaining objects that would otherwise be -** necessary in a simple array storage method. A side effect of this means that accessing the -** internal array directly is not allowed. Supporting functions are provided for this purpose. -** -** WARNING WARNING WARNING WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -** The size parameter MUST be an exact power of two (2, 4, 8, 16, etc.) otherwise the internal -** indexing algorithm will fail. -*/ -template -class QueueClass -{ - public: - /* - ** This is the count of the number of objects in the queue. If this count is zero, - ** then the operator[], First(), and Next() functions are undefined. Check this - ** value BEFORE calling these functions. - */ - const int Count; - - //-------------- Functions -------------------- - QueueClass(void); // Default constructor. - - /* - ** The bracket subscript operator functions similarly to the way a normal subscript - ** operator works except that entry [0] matches the first-in-line and entry - ** [Count-1] matches the last-in-line. This is ensured regardless of the actual position - ** of the object in the circular internal list. - */ - T & operator[](int); - - /* - ** This function will return a reference to the "head of the line" object. - */ - T & First(void); - - /* - ** This function clears the list of objects. - */ - void Init(void); - - /* - ** This function discards the head-of-the-line object and advances all the remaining - ** objects up by one. Mnemonic: Imagine a broadway audition and the director yells - ** "NEXT!" - */ - int Next(void); - - /* - ** This will add an object to the tail of the line. If there is no more room to add - ** the object, then false will be returned. - */ - int Add(T const &); - - private: - int Head; // Index of element in list the longest. - int Tail; // Index where next new addition will go. - - T Array[size]; // Raw array of objects. -}; - - -/*********************************************************************************************** - * QueueClass::QueueClass -- Default constructor for QueueClass objects. * - * * - * This default constructor for QueueClass objects initializes the queue to an empty * - * state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -template -inline QueueClass::QueueClass(void) : Count(0) -{ - Init(); -} - - -/*********************************************************************************************** - * QueueClass::Init -- Initializes queue to empty state. * - * * - * This function resets the queue to an empty state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -template -inline void QueueClass::Init(void) -{ - ((int &)Count) = 0; - Head = 0; - Tail = 0; -} - - -/*********************************************************************************************** - * QueueClass::Add -- Add object to queue. * - * * - * This function is used to add an object to the tail of the line. If the queue cannot * - * accept any more entries, then the object won't be added and false will be returned. * - * * - * INPUT: object -- The object that is to be added to the queue. * - * * - * OUTPUT: bool; Was the object added successfully? * - * * - * WARNINGS: If the queue is full, then the object won't be added. Be sure to check for this.* - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -template -inline int QueueClass::Add(T const &q) -{ - if (Count < size) { - Array[Tail] = q; - Tail = (Tail + 1) & (size-1); - ((int &)Count) = Count + 1; - return(true); - } - Mono_Printf( "Queue Add failed Count %d size %d tail %d head %d \n", - Count, size, Tail, Head ); - return (false); -} - - -/*********************************************************************************************** - * QueueClass::Next -- Throws out the head of the line. * - * * - * This routine is used to discard the object at the head of the line. All remaining * - * objects "move up" one. No actual movement occurs, merely the index is adjusted, but * - * the affect is that the next oldest object in the queue will now be returned with the * - * next call to the First() function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of object remaining in the queue. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -template -inline int QueueClass::Next(void) -{ - if (Count) { - Head = (Head + 1) & (size-1); - ((int &)Count) = Count - 1; - } - return (Count); -} - - -/*********************************************************************************************** - * QueueClass::operator[] -- Fetches reference to sub object in queue. * - * * - * Use this routine to examine individual objects within the queue. The oldest object in * - * the queue is referenced by an index value of zero. The newest object in the queue is * - * referenced by a value of Count-1. If there are no objects in the queue, then this * - * operator is undefined. Although this operator allows examination of the queue, there is * - * no corresponding ability to insert or delete objects from the middle of the queue. * - * * - * INPUT: index -- The index into the queue of objects. Valid values range from zero to * - * Count-1. All other values return an undefined reference! * - * * - * OUTPUT: Returns with a reference to the object indicated by the index. * - * * - * WARNINGS: Check to make sure that Count is not zero before using this operator. Failure * - * to do so will return a reference to an undefined object. * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -template -inline T & QueueClass::operator[](int index) -{ - return Array[(Head + index) & (size-1)]; -} - - -/*********************************************************************************************** - * QueueClass::First -- Fetches reference to first object in list. * - * * - * This routine is used to fetch the first object in the list (head of the line). This * - * object is the oldest in the list. Typical use of this function is to get and process * - * the first object so that it may be discarded with the Next() function in order to bring * - * subsequent objects to the first position. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a reference to the oldest object in the queue. * - * * - * WARNINGS: If there are no objects in the queue, then this function returns an undefined * - * reference. Be sure to check Count against zero before calling this function. * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -template -inline T & QueueClass::First(void) -{ - return Array[Head]; -} - -#endif diff --git a/code/TIBERIANDAWN/RADAR.CPP b/code/TIBERIANDAWN/RADAR.CPP deleted file mode 100644 index ff090ee..0000000 --- a/code/TIBERIANDAWN/RADAR.CPP +++ /dev/null @@ -1,1961 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\radar.cpv 2.17 16 Oct 1995 16:49:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RADAR.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : November 17, 1995 [PWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Get_Multi_Color -- Get the multi color offset number * - * RadarClass::AI -- Processes radar input (non-tactical). * - * RadarClass::Cell_On_Radar -- Determines if a cell is currently visible on radar. * - * RadarClass::Click_Cell_Calc -- Determines what cell the pixel coordinate is over. * - * RadarClass::Click_In_Radar -- Check to see if a click is in radar map * - * RadarClass::Click_In_Radar -- Converts a radar click into cell X and Y coordinate. * - * RadarClass::Draw_It -- Displays the radar map of the terrain. * - * RadarClass::Draw_Names -- draws players' names on the radar map * - * RadarClass::Init_Clear -- Sets the radar map to a known state * - * RadarClass::Map_Cell -- Updates radar map when a cell becomes mapped. * - * RadarClass::One_Time -- Handles one time processing for the radar map. * - * RadarClass::Player_Names -- toggles the Player-Names mode of the radar map * - * RadarClass::Plot_Radar_Pixel -- Updates the radar map with a terrain pixel. * - * RadarClass::RadarClass -- Default constructor for RadarClass object. * - * RadarClass::Radar_Activate -- Controls radar activation. * - * RadarClass::Radar_Anim -- Renders current frame of radar animation * - * RadarClass::Radar_Cursor -- Adjust the position of the radar map cursor. * - * RadarClass::Radar_Pixel -- Mark a cell to be rerendered on the radar map. * - * RadarClass::Radar_Position -- Returns with the current position of the radar map. * - * RadarClass::Refresh_Cells -- Intercepts refresh request and updates radar if needed * - * RadarClass::Render_Infantry -- Displays objects on the radar map. * - * RadarClass::Render_Overlay -- Renders an icon for given overlay * - * RadarClass::Render_Terrain -- Render the terrain over the given cell * - * RadarClass::Set_Map_Dimensions -- Sets the tactical map dimensions. * - * RadarClass::Set_Radar_Position -- Sets the radar map coordinates. * - * RadarClass::Set_Radar_Position -- Sets the radar position to center around specified cell.* - * RadarClass::Set_Tactical_Position -- Called when setting the tactical display position. * - * RadarClass::Set_Tactical_Position -- Called when setting the tactical display position. * - * RadarClass::TacticalClass::Action -- I/O function for the radar map. * - * RadarClass::Zoom_Mode(void) -- Handles toggling zoom on the map * - * RadarClass::Set_Tactical_Position -- Sets the map's tactical position and adjusts radar to* - * RadarClass::Coord_To_Radar_Pixel -- Converts a coordinate to a radar pixel position * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include - -//void const * RadarClass::CoverShape; -RadarClass::TacticalClass RadarClass::RadarButton; - -void const * RadarClass::RadarAnim = NULL; - -static bool FullRedraw = false; - -#define _MAX_NAME 13 - -static GraphicBufferClass _IconStage(3,3); -static GraphicBufferClass _TileStage(24,24); - -/*********************************************************************************************** - * RadarClass::RadarClass -- Default constructor for RadarClass object. * - * * - * This default constructor merely sets the radar specific values to default settings. The * - * radar must be deliberately activated in order for it to be displayed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/16/1994 JLB : Created. * - *=============================================================================================*/ -RadarClass::RadarClass(void) -{ - IsZoomed = true; - IsRadarActive = false; - IsToRedraw = false; - RadarCursorRedraw = false; - PixelPtr = 0; - SpecialRadarFrame = 0; - IsPlayerNames = false; -} - - -/*********************************************************************************************** - * RadarClass::One_Time -- Handles one time processing for the radar map. * - * * - * This routine handles any one time processing required in order for the radar map to * - * function. This actually only requires an allocation of the radar staging buffer. This * - * buffer is needed for those cases where the radar area of the page is being destroyed * - * and it needs to be destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Be sure to call this routine only ONCE. * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -void RadarClass::One_Time(void) -{ - int factor = Get_Resolution_Factor(); - RadWidth = 80 << factor; - RadHeight = 70 << factor; - RadX = SeenBuff.Get_Width() - RadWidth; - RadY = Map.Get_Tab_Height() - (1 << factor); - RadPWidth = 64 << factor; - RadPHeight = 64 << factor; - if ( factor ) { - RadOffX = 16; - RadOffY = 7; - RadIWidth = 128; - RadIHeight = 128; - } else { - RadOffX = 4 << factor; - RadOffY = 1 << factor; - RadIWidth = 72 << factor; - RadIHeight = 69 << factor; - } - - DisplayClass::One_Time(); - RadarButton.X = RadX+RadOffX; - RadarButton.Y = RadY+RadOffY; - RadarButton.Width = RadIWidth; - RadarButton.Height = RadIHeight; -} - - -/*********************************************************************************************** - * RadarClass::Init_Clear -- Sets the radar map to a known state. * - * * - * This routine is used to initialize the radar map at the start of the scenario. It * - * sets the radar map position and starts it in the disabled state. * - * * - * INPUT: theater -- The theater that the scenario is starting (unused by this routine). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -void RadarClass::Init_Clear(void) -{ - DisplayClass::Init_Clear(); - IsRadarActive = false; - IsToRedraw = true; - RadarCursorRedraw = true; - IsRadarActivating = false; - IsRadarDeactivating = false; - DoesRadarExist = false; - PixelPtr = 0; - IsPlayerNames = false; - - /* - ** If we have a valid map lets make sure that we set it correctly - */ - if (MapCellWidth || MapCellHeight) { - IsZoomed = false; - Zoom_Mode(Coord_Cell(Map.TacticalCoord)); - } -} - - -/*********************************************************************************************** - * RadarClass::Radar_Activate -- Controls radar activation. * - * * - * Use this routine to turn the radar map on or off. * - * * - * INPUT: control -- What to do with the radar map: * - * 0 = Turn radar off. * - * 1 = Turn radar on. * - * 2 = Remove Radar Gadgets * - * 3 = Add Radar Gadgets * - * 4 = Remove radar. * - * -1= Toggle radar on or off. * - * * - * OUTPUT: bool; Was the radar map already on? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/11/1994 JLB : Created. * - *=============================================================================================*/ -bool RadarClass::Radar_Activate(int control) -{ - bool old = IsRadarActive; - - switch (control) { - - /* - ** Toggle the state of the radar map on or off. - */ - case -1: - { - int temp = (IsRadarActive == false); - if (temp) { - Radar_Activate(1); - } else { - Radar_Activate(0); - } - } - break; - - /* - ** Turn the radar map off properly. - */ - case 0: - if (Map.IsSidebarActive) { - if (IsRadarActive && !IsRadarDeactivating) { - Sound_Effect(VOC_RADAR_OFF); - IsRadarDeactivating = true; - IsRadarActive = false; - if (IsRadarActivating == true) { - IsRadarActivating = false; - } else { - RadarAnimFrame = RADAR_ACTIVATED_FRAME; - } - } - } else { - Radar_Activate(2); - } - return(old); - - case 1: - if (Map.IsSidebarActive) { - if (!IsRadarActivating && !IsRadarActive) { - Sound_Effect(VOC_RADAR_ON); - IsRadarActivating = true; - if (IsRadarDeactivating == true) { - IsRadarDeactivating = false; - } else { - if (DoesRadarExist) { - RadarAnimFrame = MAX_RADAR_FRAMES; - } else { - RadarAnimFrame = 0; - } - } - } - } else { - Radar_Activate(3); - } - return(old); - - case 2: - if (GameToPlay==GAME_NORMAL) { - Map.Zoom.Disable(); - } - IsRadarActive = false; - IsRadarActivating = false; - IsRadarDeactivating = false; - break; - - case 3: - if (GameToPlay==GAME_NORMAL) { - Map.Zoom.Enable(); - } - IsRadarActive = true; - IsRadarActivating = false; - IsRadarDeactivating = false; - break; - - case 4: - IsRadarActive = false; - IsRadarActivating = false; - IsRadarDeactivating = false; - DoesRadarExist = false; - Flag_To_Redraw(false); - IsToRedraw = true; - break; - } - - if (IsRadarActive != old) { - IsToRedraw = true; - Flag_To_Redraw(false); - } - FullRedraw = IsRadarActive; - return(old); -} - - -/*********************************************************************************************** - * RadarClass::Draw_It -- Displays the radar map of the terrain. * - * * - * This is used to display the radar map that appears in the lower * - * right corner. The main changes to this map are the vehicles and * - * structure pixels. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/24/1991 JLB : Created. * - * 05/08/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void RadarClass::Draw_It(bool forced) -{ - DisplayClass::Draw_It(forced); -// if (!In_Debugger) while (!HidPage.Lock()) {} - -#if (0) // Legacy radar rendering not used. ST - 2/26/2020 3:53PM - - /* - ** Don't perform any rendering if none is requested. - */ - if (!forced && !IsToRedraw && !FullRedraw) return; - - static HousesType _house = HOUSE_NONE; - if (PlayerPtr->ActLike != _house) { - char name[_MAX_NAME + _MAX_EXT]; - - if (Special.IsJurassic && AreThingiesEnabled) { - strcpy(name, "RADAR.JP"); - } else { - _makepath(name, NULL, NULL, "RADAR", HouseTypeClass::As_Reference(PlayerPtr->ActLike).Suffix); - } - RadarAnim = Hires_Retrieve(name); - _house = PlayerPtr->ActLike; - } - - /* - ** If in player name mode, just draw player names - */ - if (IsPlayerNames) { - Draw_Names(); - IsToRedraw = false; - return; - } - - if (IsRadarActivating || IsRadarDeactivating) { - Radar_Anim(); - IsToRedraw = false; - return; - } - - if (Map.IsSidebarActive) { - if (IsRadarActive) { - - //HidPage.Lock(); -// ST 8/13/96 2:24PM -//forced = true; - /* - ** If only a few of the radar pixels need to be redrawn, then find and redraw - ** only these. - */ - if (!forced && IsToRedraw && !FullRedraw) { - IsToRedraw = false; - - if (PixelPtr) { - - /* - ** Render all pixels in the "to redraw" stack. - */ - for (unsigned int index = 0; index < PixelPtr; index++) { - CELL cell = PixelStack[index]; - if (Cell_On_Radar(cell)) { - (*this)[cell].IsPlot = false; - Plot_Radar_Pixel(cell); - RadarCursorRedraw |= (*this)[cell].IsRadarCursor; - } - } - - - /* - ** Refill the stack if there is pending pixels yet to be plotted. - ** This should only process in sections for speed reasons - */ - - if (PixelPtr == PIXELSTACK) { - PixelPtr = 0; - - for (int y = 0; y < MapCellHeight; y++) { - for (int x = 0; x < MapCellWidth; x++) { - CELL cell = XY_Cell(MapCellX + x, MapCellY + y); - if (Cell_On_Radar(cell)) { - - if ((*this)[cell].IsPlot) { - PixelStack[PixelPtr++] = cell; - IsToRedraw = true; - if (PixelPtr == PIXELSTACK) break; - } - } - } - if (PixelPtr == PIXELSTACK) break; - } - } else { - PixelPtr = 0; - } - } - - Radar_Cursor(RadarCursorRedraw); - - } else { - GraphicViewPortClass *oldpage = Set_Logic_Page(HidPage); -// if (LogicPage->Lock()) { - CC_Draw_Shape(RadarAnim, RADAR_ACTIVATED_FRAME, RadX, RadY+1, WINDOW_MAIN, SHAPE_NORMAL); - if (BaseX || BaseY) { - LogicPage->Fill_Rect( RadX + RadOffX, - RadY + RadOffY, - RadX + RadOffX + RadIWidth - 1, - RadY + RadOffY + RadIHeight - 1, - DKGREY); - } else { - LogicPage->Fill_Rect( RadX + RadOffX, - RadY + RadOffY, - RadX + RadOffX + RadIWidth - 1, - RadY + RadOffY + RadIHeight - 1, - BLACK); - } - - /* - ** Draw the entire radar map. - */ - for (int index = 0; index < MAP_CELL_TOTAL; index++) { - Plot_Radar_Pixel(index); - } - Radar_Cursor(true); - FullRedraw = false; - IsToRedraw = false; - LogicPage->Unlock(); - if (oldpage == &SeenBuff) { - Hide_Mouse(); - LogicPage->Blit(SeenBuff, RadX, RadY, RadX, RadY, RadWidth, RadHeight); - Show_Mouse(); - } - -// Set_Logic_Page(oldpage); - -// } - - } - - } else { - - /* - ** If the radar is not active, then only draw the cover plate if forced to do so. - */ -// if (forced) { - int val = (DoesRadarExist) ? MAX_RADAR_FRAMES : 0; - CC_Draw_Shape(RadarAnim, val, RadX, RadY + 1, WINDOW_MAIN, SHAPE_NORMAL); - FullRedraw = false; - IsToRedraw = false; -// } - } - - //HidPage.Unlock(); -// Map.Activator.Draw_Me(true); - } -#endif -} - -/*************************************************************************** - * RadarClass::Render_Terrain -- Render the terrain over the given cell * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/12/1995 PWG : Created. * - *=========================================================================*/ -void RadarClass::Render_Terrain(CELL cell, int x, int y, int size) -{ - TerrainClass *list[4]; - int listidx = 0; - int lp,lp2; - - - ObjectClass *obj = Map[cell].Cell_Occupier(); - - /* - ** If the cell is occupied by a terrain type, add it to the sortable - ** list. - */ - if (obj && obj->What_Am_I() == RTTI_TERRAIN) - list[listidx++] = (TerrainClass *)obj; - - /* - ** Now loop through all the occupiers and add them to the list if they - ** are terrain type. - */ - for (lp = 0; lp < 3; lp ++) { - obj = Map[cell].Overlapper[lp]; - if (obj && obj->What_Am_I() == RTTI_TERRAIN) - list[listidx++] = (TerrainClass *)obj; - } - - /* - ** If there are no entrys in our list then just get out. - */ - if (!listidx) return; - - /* - ** If there is terrain in this cell then draw a dark pixel to - ** represent it. - */ - if (size == 1) { - LogicPage->Put_Pixel(x, y, 60); - return; - } - - /* - ** Sort the list by its sort Y value so that we can render in the proper - ** order. - */ - for (lp = 0; lp < listidx - 1; lp ++) { - for (lp2 = lp + 1; lp2 < listidx; lp2++) { - if (list[lp]->Sort_Y() > list[lp2]->Sort_Y()) { - TerrainClass *terrain = list[lp]; - list[lp] = list[lp2]; - list[lp2] = terrain; - } - } - } - - /* - ** loop through the list and take care of rendering the correct icon. - */ - for (lp = 0; lp < listidx; lp ++) { - unsigned char *icon = list[lp]->Radar_Icon(cell); - if (!icon) continue; - - Buffer_To_Page(0, 0, 3, 3, icon, _IconStage); - _IconStage.Scale(*LogicPage, 0, 0, x, y, 3, 3, ZoomFactor, ZoomFactor, TRUE, (char *)&FadingBrighten[0]); - } -} - - -/*********************************************************************************************** - * RadarClass::Render_Infantry -- Displays objects on the radar map. * - * * - * This routine will display an object imagery at the location specified according to the * - * condition of the specified cell. * - * * - * INPUT: cell -- The cell to use as reference when drawing the radar pixel. * - * * - * x,y -- The pixel coordinate to render the radar "pixel" at. * - * * - * size -- The size of the "pixel". When zoomed in, this value will be "3". * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/17/1995 JLB : Created. * - *=============================================================================================*/ -void RadarClass::Render_Infantry(CELL cell, int x, int y, int size) -{ - ObjectClass *obj; - int xoff,yoff; - - obj = (ObjectClass *)Map[cell].Cell_Occupier(); - while (obj) { - if (obj->Is_Techno() && (((TechnoClass *)obj)->Cloak != CLOAKED || ((TechnoClass *)obj)->House->Is_Ally(PlayerPtr))) { - switch (obj->What_Am_I()) { - case RTTI_INFANTRY: - { - //int divisor = 255 / ZoomFactor; - int divisor = 86; - if ( ZoomFactor >= 3 ) { - xoff = Coord_XLepton(obj->Coord) / divisor; - yoff = Coord_YLepton(obj->Coord) / divisor; - if ( ZoomFactor >= 6 ) { - xoff<<=1; - yoff<<=1; - } - } else { - xoff = 0; - yoff = 0; - } - LogicPage->Put_Pixel(x+xoff, y+yoff, ((InfantryClass *)obj)->House->Class->BrightColor); - } - break; - - case RTTI_UNIT: - case RTTI_AIRCRAFT: - // PWG: Slowdown? - //if (LogicPage->Lock()){ - Fat_Put_Pixel(x, y, ((UnitClass *)obj)->House->Class->BrightColor, size, *LogicPage); - //LogicPage->Unlock(); - //} - break; - } - } - obj = obj->Next; - } -} - - -/*************************************************************************** - * RadarClass::Render_Overlay -- Renders an icon for given overlay * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/18/1995 PWG : Created. * - *=========================================================================*/ -void RadarClass::Render_Overlay(CELL cell, int x, int y, int size) -{ - OverlayType overlay = (*this)[cell].Overlay; - if (overlay != OVERLAY_NONE) { - OverlayTypeClass const * otype = &OverlayTypeClass::As_Reference(overlay); - - if (otype->IsRadarVisible) { - unsigned char *icon = otype->Radar_Icon((*this)[cell].OverlayData); - if (!icon) return; - Buffer_To_Page(0, 0, 3, 3, icon, _IconStage); - if (otype->IsTiberium) { - _IconStage.Scale(*LogicPage, 0, 0, x, y, 3, 3, size, size, TRUE, (char *)&FadingGreen[0]); - } else { - _IconStage.Scale(*LogicPage, 0, 0, x, y, 3, 3, size, size, TRUE, (char *)&FadingBrighten[0]); - } - } - } -} - - -/*************************************************************************** - * RadarClass::Zoom_Mode -- Handles toggling zoom on the map * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 05/29/1995 PWG : Created. * - *=========================================================================*/ -void RadarClass::Zoom_Mode(CELL cell) -{ - int map_c_width; - int map_c_height; - /* - ** Set all of the initial zoom mode variables to the correct - ** setting. - */ - IsZoomed = !IsZoomed; - BaseX = 0; - BaseY = 0; - - /* - ** Figure out exactly what size we need to zoom the map to. - */ - if ( !IsZoomed ) { - int xfactor = RadIWidth / MapCellWidth; - int yfactor = RadIHeight / MapCellHeight; - ZoomFactor = MIN(xfactor,yfactor); - map_c_width = MapCellWidth; - map_c_height = MapCellHeight; - } else { - ZoomFactor = 6; - map_c_width = RadIWidth / ZoomFactor; - map_c_height = RadIHeight / ZoomFactor; - } - - /* - ** Make sure we do not show more cell then are on the map. - */ - map_c_width = MIN(map_c_width, 62); - map_c_height = MIN(map_c_height, 62); - - /* - ** Find the amount of remainder because this will let us calculate - ** how to center the thing. - */ - int rem_x = RadIWidth - (map_c_width * ZoomFactor); - int rem_y = RadIHeight - (map_c_height * ZoomFactor); - - /* - ** Finally mark the map so it shows just as much as it is supposed - ** to. - */ - BaseX = rem_x / 2; - BaseY = rem_y / 2; - RadarCellWidth = map_c_width; - RadarCellHeight = map_c_height; - RadarWidth = RadIWidth - rem_x; - RadarHeight = RadIWidth - rem_y; - - /* - ** Set the radar position to the current cell. - */ - Set_Radar_Position(cell); - - /* - ** When zoom mode changes then we need to redraw the radar - ** area. - */ - IsToRedraw = true; - - /* - ** Notify the map that we need to redraw a portion - */ - Flag_To_Redraw(false); - - /* - ** Since we have made a vast change we must redraw everything - */ - FullRedraw = true; -} - - -/*********************************************************************************************** - * RadarClass::Plot_Radar_Pixel -- Updates the radar map with a terrain pixel. * - * * - * This will update the radar map with a pixel. It is used to display * - * vehicle positions on the radar map. * - * * - * INPUT: unit -- Pointer to unit to render at the given position. If * - * NULL is passed in, then the underlying terrain is * - * displayed instead. * - * * - * pos -- Position on the map to update. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine does NOT hide the mouse. It is up to you to * - * do so. * - * * - * HISTORY: * - * 06/04/1991 JLB : Created. * - * 06/21/1991 JLB : Large blips for units & buildings. * - * 02/14/1994 JLB : Revamped. * - * 04/17/1995 PWG : Created. * - * 04/18/1995 PWG : Created. * - *=============================================================================================*/ -void RadarClass::Plot_Radar_Pixel(CELL cell) -{ - if (cell == -1) cell = 1; - - int x,y; // Coordinate of cell location. - - /* - ** Perform any clipping on the cell coordinate. - */ - if (!IsRadarActive || (unsigned)cell > MAP_CELL_TOTAL) return; - - if (!In_Radar(cell) || !Cell_On_Radar(cell)) { - return; - } - - /* - ** If we are zoomed in then calculate the pixel based off of the portion - ** of the map the radar is viewing. - */ - x = Cell_X(cell) - RadarX; - y = Cell_Y(cell) - RadarY; - - if (LogicPage->Lock()) { - CellClass * cellptr = &(*this)[cell]; - x = RadX + RadOffX + BaseX + (x * ZoomFactor); - y = RadY + RadOffY + BaseY + (y * ZoomFactor); - - /* - ** Determine what (if any) vehicle or unit should be rendered in this blip. - */ - int color=TBLACK; // Color of the pixel to plot. - if ((*this)[cell].IsVisible || Debug_Unshroud) { - color = cellptr->Cell_Color(true); - } else { - color = BLACK; - } - -// ST 8/13/96 2:24PM -//if (cellptr->IsRadarCursor){ -// color = WHITE; -//} - - /* - ** If no color override occurs for this cell, then render the underlying - ** terrain. - */ - if (color == TBLACK) { - if (ZoomFactor > 1) { - void const *ptr; - long offset; - int icon; - - if (cellptr->TType != TEMPLATE_NONE) { - ptr = TemplateTypeClass::As_Reference(cellptr->TType).Get_Image_Data(); - icon = cellptr->TIcon; - } else { - ptr = TemplateTypeClass::As_Reference(TEMPLATE_CLEAR1).Get_Image_Data(); - icon = cellptr->Clear_Icon(); - } - - /* - ** Convert the logical icon number into the actual icon number. - */ - Mem_Copy(Add_Long_To_Pointer((void *)ptr, 28), &offset, sizeof(offset)); - Mem_Copy(Add_Long_To_Pointer((void *)ptr, offset+icon), &icon, sizeof(char)); - icon &= 0x00FF; - - Mem_Copy(Add_Long_To_Pointer((void *)ptr, 12), &offset, sizeof(offset)); - ptr = Add_Long_To_Pointer((void *)ptr, offset + icon*(24*24)); - - unsigned char * data = (unsigned char *)ptr; - Buffer_To_Page(0, 0, 24, 24, data, _TileStage); - _TileStage.Scale(*LogicPage, 0, 0, x, y, 24, 24, ZoomFactor, ZoomFactor, TRUE); - - } else { - if (LogicPage->Lock()){ - Fat_Put_Pixel(x, y, cellptr->Cell_Color(false), ZoomFactor, *LogicPage); - LogicPage->Unlock(); - } - } - } else { - if (LogicPage->Lock()){ - Fat_Put_Pixel(x, y, color, ZoomFactor, *LogicPage); - LogicPage->Unlock(); - } - } - if (color != BLACK) { - Render_Overlay(cell, x, y, ZoomFactor); - Render_Terrain(cell, x, y, ZoomFactor); - Render_Infantry(cell, x, y, ZoomFactor); - } - LogicPage->Unlock(); - } -} - - -/*********************************************************************************************** - * RadarClass::Radar_Pixel -- Mark a cell to be rerendered on the radar map. * - * * - * This routine is used to inform the system that a pixel needs to be * - * rerendered on the radar map. The pixel(s) will be rendered the * - * next time the map is refreshed. * - * * - * INPUT: cell -- The map cell to be rerendered. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/12/1992 JLB : Created. * - * 05/08/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void RadarClass::Radar_Pixel(CELL cell) -{ - if (IsRadarActive && Map.IsSidebarActive && Cell_On_Radar(cell)) { - IsToRedraw = true; - (*this)[cell].IsPlot = true; - if (PixelPtr < PIXELSTACK) { - PixelStack[PixelPtr++] = cell; - } - } -} - - -/*********************************************************************************************** - * RadarClass::Click_In_Radar -- Converts a radar click into cell X and Y coordinate. * - * * - * This routine will examine the X and Y coordinate and convert them into the X and Y * - * cell coordinate value that cooresponds to the location. * - * * - * INPUT: x,y -- The X and Y moouse coordinate already normalized to the radar upper left * - * corner. * - * * - * OUTPUT: Returns with success rating in addition, the X and Y values will now hold the * - * cell coordinates of the cell the pixel offsets indicated. * - * Result 1 = click was in radar region * - * Result 0 = click was outside radar region completly * - * Result-1 = click in radar area but not on clickable reagion of radar. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/30/1995 PWG : Created. * - * 07/16/1995 JLB : Recognizes when sidebar is closed now. * - *=============================================================================================*/ -int RadarClass::Click_In_Radar(int &ptr_x, int &ptr_y, bool change) -{ - int x = ptr_x; - int y = ptr_y; - - /* - ** If radar is not active the click could have been on a radar point - */ - if (!IsRadarActive || !Map.IsSidebarActive) return(0); - - x -= (RadX + RadOffX); - y -= (RadY + RadOffY); - if (x < RadIWidth && y < RadIHeight) { - x -= BaseX; - y -= BaseY; - - if ((unsigned)x < RadarWidth && (unsigned)y < RadarHeight) { - x = RadarX + (x / ZoomFactor); - y = RadarY + (y / ZoomFactor); - if (change) { - ptr_x = x; - ptr_y = y; - } - return(1); - } - return(-1); - } - return(0); -} - - -/*********************************************************************************************** - * RadarClass::Click_Cell_Calc -- Determines what cell the pixel coordinate is over. * - * * - * This routine will examine the pixel coordinate provided and determine what cell it * - * represents. If the radar map is not active or the coordinates are not positioned over * - * the radar map, then it will fall into the base class corresponding routine. * - * * - * INPUT: x,y -- The pixel coordinate to convert into a cell number. * - * * - * OUTPUT: Returns with the cell number that the coordinate is over or -1 if not over any * - * cell. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -CELL RadarClass::Click_Cell_Calc(int x, int y) -{ - int result = Click_In_Radar(x, y, true); - switch (result) { - case 1: - return(XY_Cell(x, y)); - - case -1: - return(-1); - } - return(DisplayClass::Click_Cell_Calc(x, y)); -} - - -/*********************************************************************************************** - * RadarClass::Map_Cell -- Updates radar map when a cell becomes mapped. * - * * - * This routine will update the radar map if a cell becomes mapped. * - * * - * INPUT: cell -- The cell that is being mapped. * - * * - * house -- The house that is doing the mapping. * - * * - * OUTPUT: bool; Was the cell mapped (for the first time) by this routine? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -bool RadarClass::Map_Cell(CELL cell, HouseClass * house, bool and_for_allies) -{ - if (DisplayClass::Map_Cell(cell, house, and_for_allies)) { - Radar_Pixel(cell); - return(true); - } - return(false); -} - -void RadarClass::Cursor_Cell(CELL cell, int value) -{ - int temp = (*this)[cell].IsRadarCursor; - - /* - ** If this cell is not on the radar don't botther doing anything. - */ - if (In_Radar(cell) && temp != value) { - /* - ** Record the new state of this cell. - */ - (*this)[cell].IsRadarCursor = value; - - /* - ** If we are erasing then erase the cell. - */ -////// ST 8/13/96 2:23PM - if (value == FALSE) { - Plot_Radar_Pixel(cell); -////// - } - } -} - -void RadarClass::Mark_Radar(int x1, int y1, int x2, int y2, int value, int barlen) -{ - int x, y; - /* - ** First step is to convert pixel coordinates back to a CellX and CellY. - */ - x1 = RadarX + (x1 / ZoomFactor); - y1 = RadarY + (y1 / ZoomFactor); - x2 = RadarX + (x2 / ZoomFactor); - y2 = RadarY + (y2 / ZoomFactor); - - /* - ** Now we need to convert the Pixel length to a cell length. - */ - barlen = (barlen / ZoomFactor)+1; - - /* - ** Now lets loop through and mark the map with the proper value. - */ - for (int lp = 0; lp <= barlen; lp++) { - /* - ** Do Horizontal action to upper and lower left corners. - */ - x = x1 + lp; - Cursor_Cell(XY_Cell(x,y1), value); - Cursor_Cell(XY_Cell(x,y2), value); - /* - ** Do Horizontal Action to upper and lower right corners - */ - x = x2 - lp; - Cursor_Cell(XY_Cell(x,y1), value); - Cursor_Cell(XY_Cell(x,y2), value); - /* - ** Do Vertical Action to left and right upper corners - */ - y = y1 + lp; - Cursor_Cell(XY_Cell(x1,y), value); - Cursor_Cell(XY_Cell(x2,y), value); - - /* - ** Do Vertical action to left and right lower corners. - */ - y = y2 - lp; - Cursor_Cell(XY_Cell(x1,y), value); - Cursor_Cell(XY_Cell(x2,y), value); - } -} - - - -/*********************************************************************************************** - * RadarClass::Cell_XY_To_Radar_Pixel-- Adjust the position of the radar map cursor. * - * * - * This routine will adjust the location (and visibility) of the radar * - * map cursor. It handles all restoration, drawing, and flashing. * - * * - * INPUT: pos - Cell position for the cursor. If the value is -1 then * - * the cursor will be hidden. If the value is equal to * - * the last value passed in then cursor flashing will * - * be maintained. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1991 JLB : Created. * - * 11/17/1995 PWG : Created. * - *=============================================================================================*/ -void RadarClass::Cell_XY_To_Radar_Pixel(int cellx, int celly, int &x, int &y) -{ - x = (cellx - RadarX) * ZoomFactor; - y = (celly - RadarY) * ZoomFactor; -} - -/*********************************************************************************************** - * RadarClass::Radar_Cursor -- Adjust the position of the radar map cursor. * - * * - * This routine will adjust the location (and visibility) of the radar * - * map cursor. It handles all restoration, drawing, and flashing. * - * * - * INPUT: pos - Cell position for the cursor. If the value is -1 then * - * the cursor will be hidden. If the value is equal to * - * the last value passed in then cursor flashing will * - * be maintained. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1991 JLB : Created. * - * 11/17/1995 PWG : Created. * - *=============================================================================================*/ -//#pragma argsused -void RadarClass::Radar_Cursor(int forced) -{ - static int _last_pos = -1; - static int _last_frame = -1; - GraphicViewPortClass *oldpage; - int x1, y1, x2, y2; - /* - ** figure out these function calls as we will need to call them multiple times. - */ - int tac_cell = Coord_Cell(TacticalCoord); - int tac_cell_x = Cell_X(tac_cell); - int tac_cell_y = Cell_Y(tac_cell); - int barlen = 6; - /* - ** If the current tactical cell is invalid or we haven't moved and we are not forced to redraw then - ** just skip the redraw process. - */ - if (tac_cell != -1 && _last_pos == tac_cell && _last_frame == SpecialRadarFrame && !forced) return; - - if ( _last_pos != -1 ) { - /* - ** The first thing we need to do is take care of erasing the last radar cell position. We do this - ** by converting to pixel coordinates, then adjusting for the pixel coords for the current frame and - ** finally taking care of calling the erase procedure which will convert the pixel coordinates back - ** to the cells that need to be redraw. - **/ - int last_cell_x = Cell_X(_last_pos); - int last_cell_y = Cell_Y(_last_pos); - - Cell_XY_To_Radar_Pixel(last_cell_x, last_cell_y, x1, y1); - Cell_XY_To_Radar_Pixel(last_cell_x + Lepton_To_Cell(TacLeptonWidth), last_cell_y + Lepton_To_Cell(TacLeptonHeight), x2, y2); - x2--; - y2--; - - /* - ** Adjust the current coordinates based on the last animation frame. - */ - x1-= _last_frame; - y1-= _last_frame; - x2+= _last_frame; - y2+= _last_frame; - /* - ** Finally mark the map (actually remove the marks that indicate the radar cursor was there - */ - Mark_Radar(x1, y1, x2, y2, FALSE, barlen); - } - - - /* - ** find the upper left and lower right corners of the radar cursor. Remember to adjust x2 and y2 back - ** by one pixel as they will not be pointing to the right value otherwise. They point one cell ahead - ** of where they should. - */ - Cell_XY_To_Radar_Pixel(tac_cell_x, tac_cell_y, x1, y1); - Cell_XY_To_Radar_Pixel(tac_cell_x + Lepton_To_Cell(TacLeptonWidth), tac_cell_y + Lepton_To_Cell(TacLeptonHeight), x2, y2); - x2--; - y2--; - - /* - ** Adjust the coordinates based on the current frame of radar animation. - */ - x1-= SpecialRadarFrame; - y1-= SpecialRadarFrame; - x2+= SpecialRadarFrame; - y2+= SpecialRadarFrame; - - Mark_Radar(x1, y1, x2, y2, TRUE, barlen); - - /* - ** setup a graphic view port class so we can write all the pixels relative - ** to 0,0 rather than relative to full screen coordinates. - */ - oldpage = Set_Logic_Page(HidPage); - GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(), - RadX + RadOffX + BaseX + LogicPage->Get_XPos(), - RadY + RadOffY + BaseY + LogicPage->Get_YPos(), - RadarWidth, - RadarHeight); - - draw_window.Draw_Line(x1, y1, x1 + barlen, y1, LTGREEN); - draw_window.Draw_Line(x1, y1, x1, y1 + barlen, LTGREEN); - - // Draw upper right hand corner - draw_window.Draw_Line(x2 - barlen, y1, x2, y1, LTGREEN); - draw_window.Draw_Line(x2, y1, x2, y1 + barlen, LTGREEN); - - // Draw lower left hand corner - draw_window.Draw_Line(x1, y2 - barlen, x1, y2, LTGREEN); - draw_window.Draw_Line(x1, y2, x1 + barlen, y2, LTGREEN); - - // Draw lower right hand corner - draw_window.Draw_Line(x2, y2 - barlen, x2, y2, LTGREEN); - draw_window.Draw_Line(x2 - barlen, y2, x2, y2, LTGREEN); -#if(0) - draw_window.Draw_Rect(x1, y1, x2, y2, WHITE); -#endif - -#if(FALSE) - if (oldpage == &SeenBuff) { - Hide_Mouse(); - HidPage.Blit( SeenBuff, - (int)(RadX + RadOffX + BaseX), - (int)(RadY + RadOffY + BaseY), - (int)(RadX + RadOffX + BaseX), - (int)(RadY + RadOffY + BaseY), - (int)draw_window.Get_Width(), - (int)draw_window.Get_Height(), - (BOOL)FALSE); - - Show_Mouse(); - } -#endif - Set_Logic_Page(oldpage); - _last_pos = tac_cell; - _last_frame = SpecialRadarFrame; - RadarCursorRedraw = FALSE; -} - - -/*************************************************************************** - * RadarClass::Radar_Anim -- Renders current frame of radar animation * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/19/1995 PWG : Created. * - *=========================================================================*/ -void RadarClass::Radar_Anim(void) -{ - /* - ** Do nothing if we're in player-name mode - */ - if (IsPlayerNames) - return; - - if (!Map.IsSidebarActive) return; - - GraphicViewPortClass *oldpage= Set_Logic_Page(HidPage); - GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(), - RadX + RadOffX + LogicPage->Get_XPos(), - RadY + RadOffY + LogicPage->Get_YPos(), - RadIWidth, - RadIHeight); - - Draw_Box(RadX+RadOffX-1, RadY+RadOffY-1, RadIWidth+2, RadIHeight+2, BOXSTYLE_RAISED, true); - draw_window.Clear(); - CC_Draw_Shape(RadarAnim, RadarAnimFrame, RadX, RadY+1, WINDOW_MAIN, SHAPE_NORMAL); - - Flag_To_Redraw(false); - Set_Logic_Page(oldpage); -} - - -/*********************************************************************************************** - * RadarClass::AI -- Processes radar input (non-tactical). * - * * - * This routine intercepts any player input that concerns the radar map, but not those * - * areas that represent the tactical map. These are handled by the tactical map AI * - * processor. Primarily, this routine handles the little buttons that border the radar * - * map. * - * * - * INPUT: input -- The player input code. * - * * - * x,y -- Mouse coordinate parameters to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - * 12/26/1994 JLB : Moves tactical map with click or drag. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - *=============================================================================================*/ -void RadarClass::AI(KeyNumType & input, int x, int y) -{ - /* - ** Check to see if we need to animate the radar cursor - */ - if (IsRadarActive && Map.IsSidebarActive && SpecialRadarFrame) { - SpecialRadarFrame--; - RadarCursorRedraw = TRUE; - IsToRedraw = TRUE; - Flag_To_Redraw(FALSE); - } - - /* - ** Check goes here to see if there is enough power to run the radar - */ - if (IsRadarActivating) { - if (!DoesRadarExist) { - RadarAnimFrame++; - if (RadarAnimFrame < RADAR_ACTIVATED_FRAME) { - IsToRedraw = true; - Flag_To_Redraw(false); - } else { - DoesRadarExist = true; - Radar_Activate(3); - } - } else { - RadarAnimFrame--; - if (RadarAnimFrame > RADAR_ACTIVATED_FRAME) { - IsToRedraw = true; - Flag_To_Redraw(false); - } else { - Radar_Activate(3); - } - } - } - if (IsRadarDeactivating) { - RadarAnimFrame++; - if (RadarAnimFrame == MAX_RADAR_FRAMES) { - IsRadarDeactivating = false; - } else { - IsToRedraw = true; - Flag_To_Redraw(false); - } - } - - DisplayClass::AI(input, x, y); -} - - -/*********************************************************************************************** - * RadarClass::TacticalClass::Action -- I/O function for the radar map. * - * * - * This is the main action function for handling player I/O on the radar map. It processes * - * mouse clicks as well as mouse moves. * - * * - * INPUT: flags -- The event flags that trigger this function call. * - * * - * key -- Reference the keyboard event that applies to the trigger event. * - * * - * OUTPUT: Should further processing of the input list be aborted? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -int RadarClass::TacticalClass::Action(unsigned flags, KeyNumType & key) -{ - CELL cell; // cell num click happened over - int x,y; // Sub cell pixel coordinates. - int cellx,celly; // Sub cell pixel coordinates. - bool shadow; // is the cell in shadow or not - ObjectClass *object = 0; // what object is in the cell - ActionType action = ACTION_NONE; // Action possible with currently selected object. - - /* - ** Force any help label to disappear when the mouse is held over the - ** radar map. - */ - if (Map.IsSidebarActive) { - Map.Help_Text(TXT_NONE); - } - - if (!Map.IsRadarActive) { - if (Map.IsSidebarActive) { - Map.Override_Mouse_Shape(MOUSE_NORMAL, true); - } - return(false); - } - - /* - ** Disable processing if the player names are up - */ - if (Map.Is_Player_Names()) { - GadgetClass::Action(0, key); - return(true); - } - - /* - ** Set some working variables that depend on the mouse position. For the press - ** or release event, special mouse queuing storage variables are used. Other - ** events must use the current mouse position globals. - */ - if (flags & (LEFTPRESS|LEFTRELEASE|RIGHTPRESS|RIGHTRELEASE)) { - x = _Kbd->MouseQX; - y = _Kbd->MouseQY; - } else { - x = Get_Mouse_X(); - y = Get_Mouse_Y(); - } - - int result = Map.RadarClass::Click_In_Radar(x, y, false); - - if (result == 1) { - cell = Map.RadarClass::Click_Cell_Calc(x, y); - if (cell != -1) { - //using function for IsVisible so we have different results for different players - JAS 2019/09/30 - shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud); - cellx = 12; - celly = 12; - - /* - ** Determine the object that the mouse is currently over. - */ - if (!shadow) { - object = Map.Cell_Object(cell, cellx, celly); - } - - /* - ** If there is a currently selected object, then the action to perform if - ** the left mouse button were clicked must be determined. - */ - if (CurrentObject.Count()) { - if (object) { - action = CurrentObject[0]->What_Action(object); - } else { - action = CurrentObject[0]->What_Action(cell); - } - - /* - ** If this is not a valid radar map action then we are not going to do - ** anything. - */ - switch (action) { - case ACTION_MOVE: - case ACTION_NOMOVE: - case ACTION_ATTACK: - case ACTION_ENTER: - case ACTION_CAPTURE: - case ACTION_SABOTAGE: - break; - - default: - action = ACTION_NONE; - object = NULL; - break; - } - - /* - ** On the radar map the only reason we would want the normal cursor to - ** appear is if we were over one of our own selected units. Otherwise - ** we can't move there. - **/ - if (action == ACTION_NONE) { - if (object && object->Is_Selected_By_Player()) { - object = NULL; - } else { - action = ACTION_NOMOVE; - } - } - - /* - ** A right mouse button press toggles the zoom mode. - */ - if (flags & RIGHTPRESS) { - Map.Mouse_Right_Press(); - } - - /* - ** When the mouse buttons aren't pressed, only the mouse cursor shape is processed. - ** The shape changes depending on what object the mouse is currently over and what - ** object is currently selected. - */ - if (flags & LEFTUP) { - Map.Mouse_Left_Up(shadow, object, action, true); - } - - /* - ** Normal actions occur when the mouse button is released. The press event is - ** intercepted and possible rubber-band mode is flagged. - */ - if (flags & LEFTPRESS) { - Map.Mouse_Left_Release(cell, cellx, celly, object, action, true); - } - - } else { - - Map.Set_Default_Mouse(MOUSE_RADAR_CURSOR, !Map.IsZoomed); - - if (flags & LEFTPRESS) { - - cell = Map.RadarClass::Click_Cell_Calc(x, y); - if (cell != -1) { - int cellx = Cell_X(cell); - int celly = Cell_Y(cell); - cellx -= Lepton_To_Cell(Map.TacLeptonWidth) / 2; - cellx = MAX(cellx, Map.MapCellX); - celly -= Lepton_To_Cell(Map.TacLeptonHeight) / 2; - celly = MAX(celly, Map.MapCellY); - cell = XY_Cell(cellx, celly); - shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud); - Map.Set_Tactical_Position(Cell_Coord(cell)); - cell = Coord_Cell(Map.DesiredTacticalCoord); - Map.DisplayClass::IsToRedraw = true; - //Map.Flag_To_Redraw(false); - Map.Flag_To_Redraw(true); - Map.SpecialRadarFrame = 4; - } - } - - /* - ** A right mouse button press toggles the zoom mode. - */ - if (flags & RIGHTPRESS) { - Map.Zoom_Mode(cell); - } - } - } - } - if (result == -1) { - Map.Override_Mouse_Shape(MOUSE_NORMAL, true); - } - GadgetClass::Action(0, key); - return(true); -} - - -/*********************************************************************************************** - * RadarClass::Refresh_Cells -- Intercepts refresh request and updates radar if needed * - * * - * This routine intercepts the refresh cells request and if it detects that the sidebar * - * should be rerendered, it flags the radar map to redraw during the next draw operation. * - * * - * INPUT: cell -- The origin cell that the refresh cell offset list is based upon. * - * * - * list -- Pointer to the list of offsets from the origin cell that specifies the * - * cells to be flagged for redraw. If the list starts with the special * - * code to refresh the sidebar, then this routine recognizes it and flags * - * the radar map to be redrawn accordingly. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - *=============================================================================================*/ -void RadarClass::Refresh_Cells(CELL cell, short const *list) -{ - if (*list == REFRESH_SIDEBAR) { - IsToRedraw = true; - Flag_To_Redraw(false); - } - DisplayClass::Refresh_Cells(cell, list); -} - - -/*********************************************************************************************** - * RadarClass::Set_Radar_Position -- Sets the radar position to center around specified cell. * - * * - * This routine will try to center the radar map around the cell position specified. * - * * - * INPUT: cell -- The cell to try and position the radar map around. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void RadarClass::Set_Radar_Position(CELL cell) -{ - int oldx, oldy; - int newx, newy; - int newcell; - - if (ZoomFactor != 1) { -#if(FALSE) - oldx = (Cell_X(cell) - MapCellX) - (RadarCellWidth / 2); - oldy = (Cell_Y(cell) - MapCellY) - (RadarCellHeight / 2); -#else - oldx = (Cell_X(cell) - MapCellX); - oldy = (Cell_Y(cell) - MapCellY); -#endif - } else { - oldx = 0; - oldy = 0; - } - - Confine_Rect(&oldx, &oldy, RadarCellWidth, RadarCellHeight, MapCellWidth, MapCellHeight); - - newx = oldx + MapCellX; - newy = oldy + MapCellY; - newcell = XY_Cell(newx, newy); - - if (RadarCell != newcell) { - int forced = FALSE; - int xmod = newx; - int ymod = newy; - - int radx = (Cell_X(RadarCell)) - xmod; - int rady = (Cell_Y(RadarCell)) - ymod; - - RadarX = newx; - RadarY = newy; - RadarCell = newcell; - - if (Map.IsSidebarActive&& Map.IsRadarActive) { - int radw = RadarCellWidth-ABS(radx); // Replicable width. - int radh = RadarCellHeight-ABS(rady); // Replicable height. - - if (radw < 1) forced = true; - if (radh < 1) forced = true; - - if (!forced && (radw != RadarWidth || radh != RadarHeight)) { - /* - ** Blit the section that is actually overlapping. - */ - if (OverlappedVideoBlits || !HidPage.Get_IsDirectDraw()){ - HidPage.Blit(HidPage, - (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, - (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, - (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX+ RadOffX + BaseX, - (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY, - radw * ZoomFactor, - radh * ZoomFactor); - }else{ - /* - ** System does not support overlapped blitting of video surfaces. - ** Blit it in 2 stages using an intermediate buffer. - */ - GraphicBufferClass temp_surface; - temp_surface.Init((RadarWidth + 16) & 0xfffffff0, - (RadarHeight + 16) & 0xfffffff0, - NULL, 0, (GBC_Enum) GBC_VIDEOMEM); - - HidPage.Blit(temp_surface, (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, - (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, - 0, - 0, - RadarWidth, - RadarHeight); - - temp_surface.Blit (HidPage,0, - 0, - (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX + RadOffX + BaseX, - (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY, - radw * ZoomFactor, - radh * ZoomFactor); - } - - /* - ** Now we need to flag the section of the map that is going to redraw. - */ - if ( radx != 0 ) { - int min; - int max; - if ( radx < 0 ) { // this mean regen the right edge - min = radw; - max = radw+ABS(radx); - } else { // this mean regen the left edge - min = 0; - max = radx; - } - for (int x = min; x < max; x++ ) { - for (unsigned int y = 0; y < RadarCellHeight; y++ ) { - Radar_Pixel(XY_Cell(newx + x, newy + y)); - } - } - } - if ( newy != 0 ) { - int min; - int max; - if ( rady < 0 ) { // this mean regen the bottom edge - min = radh; - max = radh+ABS(rady); - } else { // this mean regen the top edge - min = 0; - max = rady; - } - for (int y = min; y < max; y++ ) { - for ( unsigned int x = 0; x < RadarCellWidth; x++ ) { - Radar_Pixel(XY_Cell(newx + x, newy + y)); - } - } - } - } - } - RadarCursorRedraw = IsRadarActive; - IsToRedraw = IsRadarActive; - Flag_To_Redraw(false); - if (ZoomFactor > 4) { - FullRedraw = forced; - } - } else { - RadarCursorRedraw = IsRadarActive; - IsToRedraw = IsRadarActive; - Flag_To_Redraw(false); - } -} - - -/*********************************************************************************************** - * RadarClass::Radar_Position -- Returns with the current position of the radar map. * - * * - * This returns the cell number of the upper left corner of the radar map. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the radar map upper left corner cell position. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -CELL RadarClass::Radar_Position(void) -{ - return(RadarCell); -} - - -/*********************************************************************************************** - * RadarClass::Set_Map_Dimensions -- Sets the tactical map dimensions. * - * * - * This routine is called when the tactical map changes its dimensions. This occurs when * - * the tactical map moves and when the sidebar pops on or off. * - * * - * INPUT: x,y -- The cell coordinate of the upper left corner of the tactical map. * - * * - * w,y -- The cell width and height of the tactical map. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void RadarClass::Set_Map_Dimensions(int x, int y, int w, int h) -{ - Set_Radar_Position(XY_Cell(x, y)); - DisplayClass::Set_Map_Dimensions(x, y, w, h); -} - - -/*********************************************************************************************** - * RadarClass::Set_Tactical_Position -- Sets the map's tactical position and adjusts radar to * - * * - * This routine is called when the tactical map is to change position. The radar map might * - * be adjusted as well by this routine. * - * * - * INPUT: coord -- The new coordinate to use for the upper left corner of the tactical * - * map. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/17/1995 JLB : Created. * - *=============================================================================================*/ -void RadarClass::Set_Tactical_Position(COORDINATE coord) -{ - DisplayClass::Set_Tactical_Position(coord); - Set_Radar_Position(Coord_Cell(DesiredTacticalCoord)); -} - - -/*********************************************************************************************** - * RadarClass::Cell_On_Radar -- Determines if a cell is currently visible on radar. * - * * - * This routine will examine the specified cell number and return whether it is visible * - * on the radar map. This depends on the radar map position. * - * * - * INPUT: cell -- The cell number to check. * - * * - * OUTPUT: Is the specified cell visible on the radar map currently? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/03/1995 JLB : Created. * - *=============================================================================================*/ -bool RadarClass::Cell_On_Radar(CELL cell) -{ - if ((unsigned)cell > MAP_CELL_TOTAL) - return(false); - - int x = Cell_X(cell) - RadarX; - int y = Cell_Y(cell) - RadarY; - return (!((unsigned)x >= RadarCellWidth || (unsigned)y >= RadarCellHeight)); - -// if (!IsZoomed) { -// return(true); -// } -// return(!(((Cell_X(cell) - RadarX) > RadarCellWidth) || ((Cell_Y(cell) - RadarY) > RadarCellHeight))); -} - -/*********************************************************************************************** - * RadarClass::Player_Names -- toggles the Player-Names mode of the radar map * - * * - * INPUT: * - * on true = turn on; false = turn off * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/07/1995 BRR : Created. * - *=============================================================================================*/ -void RadarClass::Player_Names(bool on) -{ - IsPlayerNames = on; - IsToRedraw = true; - if (on) { - Flag_To_Redraw(true); -// Flag_To_Redraw(false); - } else { - Flag_To_Redraw(true); // force drawing of the plate - } -} - - -/*********************************************************************************************** - * Draw_Names -- draws players' names on the radar map * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 06/07/1995 BRR : Created. * - *=============================================================================================*/ -void RadarClass::Draw_Names(void) -{ - int c_idx; - HousesType house; - HouseClass *ptr; - int y; - char txt[40]; - unsigned char id; - int i; - HousesType h; - int kills; - int color; - TextPrintType style; - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - /* - ** Do nothing if the sidebar isn't there - */ - if (!Map.IsSidebarActive) { - return; - } - - CC_Draw_Shape(RadarAnim, RADAR_ACTIVATED_FRAME, RadX, RadY+1, WINDOW_MAIN, SHAPE_NORMAL); - LogicPage->Fill_Rect( RadX + RadOffX, - RadY + RadOffY, - RadX + RadOffX + RadIWidth - 1, - RadY + RadOffY + RadIHeight - 1, - BLACK); - - y = RadY + RadOffY; - - Fancy_Text_Print (TXT_NAME_COLON, RadX + RadOffX, y, LTGREY, TBLACK, - TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); - - - Fancy_Text_Print (TXT_KILLS_COLON, RadX + RadOffX + RadIWidth - 2, y, - LTGREY, TBLACK, TPF_RIGHT | TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL); - - y += 6*factor+1; - - LogicPage->Draw_Line(RadX + RadOffX, y, - RadX + RadOffX + RadIWidth - 1, y, LTGREY); - - y += 2*factor; - - for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { - ptr = HouseClass::As_Pointer(house); - - if (!ptr) - continue; - - /* - ** Decode this house's color - */ - c_idx = ptr->RemapColor; - - if (ptr->IsDefeated) { - color = GREY; - style = TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL; - } else { - color = MPlayerTColors[c_idx]; - style = TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW; - } - - /* - ** Initialize our message - */ - txt[0] = 0; - - /* - ** If the house is non-human, generate the message - */ - if (!ptr->IsHuman) { - sprintf(txt,"%s", Text_String(TXT_COMPUTER)); - } else { - - /* - ** For a human house: - ** - Compute the multiplayer ID for this house - ** - find the name for this player - */ - id = Build_MPlayerID (c_idx,ptr->ActLike); - for (i = 0; i < MPlayerCount; i++) { - if (id == MPlayerID[i]) { - sprintf(txt,"%s",MPlayerNames[i]); - break; - } - } - } - - /* - ** Print the player name, and the # of kills - */ - if (strlen(txt)) { - if (strlen(txt) > 9) { - txt[9] = '.'; - txt[10] = '\0'; - } - Fancy_Text_Print (txt, RadX + RadOffX, y, color, BLACK, style); - - kills = 0; - for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { - kills += ptr->UnitsKilled[h]; - kills += ptr->BuildingsKilled[h]; - } - sprintf(txt, "%2d", kills); - Fancy_Text_Print (txt, RadX + RadOffX + RadIWidth - 2, y, - color, BLACK, style | TPF_RIGHT); - - y += 6*factor+1; - - } - } -} diff --git a/code/TIBERIANDAWN/RADAR.H b/code/TIBERIANDAWN/RADAR.H deleted file mode 100644 index ca7b59d..0000000 --- a/code/TIBERIANDAWN/RADAR.H +++ /dev/null @@ -1,211 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\radar.h_v 2.17 16 Oct 1995 16:48:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RADAR.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : December 15, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef RADAR_H -#define RADAR_H - -#include "display.h" - -class RadarClass: public DisplayClass -{ - public: - int RadX; - int RadOffX; - int RadY; - int RadOffY; - int RadWidth; - int RadHeight; - int RadIWidth; - int RadIHeight; - int RadPWidth; - int RadPHeight; - - RadarClass(void); - - /* - ** Initialization - */ - virtual void One_Time(void); // One-time inits - virtual void Init_Clear(void); // Clears all to known state - - virtual bool Map_Cell(CELL cell, HouseClass * house, bool and_for_allies); - virtual CELL Click_Cell_Calc(int x, int y); - virtual void AI(KeyNumType &input, int x, int y); - virtual void Draw_It(bool complete=false); - virtual void Refresh_Cells(CELL cell, short const *list); - virtual void Set_Map_Dimensions(int x, int y, int w, int h); -// virtual void Set_Tactical_Position(int x, int y, int leptonx=0, int leptony=0); -// virtual void Set_Tactical_Position(CELL cell); - virtual void Set_Tactical_Position(COORDINATE coord); - void Zoom_Mode(CELL cell); - int Click_In_Radar(int &x, int &y, bool change=false); - void Cell_XY_To_Radar_Pixel(int cellx, int celly, int &x, int &y); - - void Set_Radar_Position(CELL cell); - CELL Radar_Position(void); - bool Radar_Activate(int control); - void Plot_Radar_Pixel(CELL cell); - void Radar_Pixel(CELL cell); - void Coord_To_Radar_Pixel(COORDINATE coord, int &x, int &y); - void Cursor_Cell(CELL cell, int value); - void RadarClass::Mark_Radar(int x1, int y1, int x2, int y2, int value, int barlen); - void Radar_Cursor(int forced = false); - void Render_Terrain(CELL cell, int x, int y, int size); - bool Cell_On_Radar(CELL cell); - void Render_Infantry(CELL cell, int x, int y, int size); - void Render_Overlay(CELL cell, int x, int y, int size); - void Radar_Anim(void); - bool Is_Radar_Active(void) {return IsRadarActive;}; - bool Is_Radar_Activating(void) {return IsRadarActivating;}; - bool Is_Radar_Existing(void) {return(DoesRadarExist);}; - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Toggles player names on & off - */ - void Player_Names(bool on); - int Is_Player_Names(void) {return IsPlayerNames;} - void Draw_Names(void); - int Is_Zoomed(void) {return IsZoomed;} - - protected: - - /* - ** Radar map constant values. - */ - enum RadarClassEnums { - RADAR_ACTIVATED_FRAME=22, - MAX_RADAR_FRAMES = 41 - }; - - /* - ** If the radar map must be completely redrawn, then this flag will be true. - ** Typical causes of this would be when the radar first appears, or when the - ** screen has been damaged. - */ - unsigned IsToRedraw:1; - unsigned RadarCursorRedraw:1; - - /* - ** If the radar map is visible then this flag is true. - */ - unsigned DoesRadarExist:1; - unsigned IsRadarActive:1; - unsigned IsRadarActivating:1; - unsigned IsRadarDeactivating:1; - - /* - ** Special radar frame is set when a new location is selected on the - ** radar map. It counts down through the special radar cursors until - ** either the radar cursor becomes normal or the radar cursor is moved - ** again. - */ - unsigned SpecialRadarFrame:3; - unsigned RadarAnimFrame:6; - - static void const * RadarAnim; - - /* - ** This gadget class is used for capturing input to the tactical map. All mouse input - ** will be routed through this gadget. - */ - class TacticalClass : public GadgetClass { - public: - TacticalClass(void) : GadgetClass(0,0,0,0,LEFTPRESS|LEFTRELEASE|LEFTHELD|LEFTUP|RIGHTPRESS,true) {}; - - protected: - virtual int Action(unsigned flags, KeyNumType & key); - friend class RadarClass; - }; - friend class TacticalClass; - - /* - ** This is the "button" that tracks all input to the tactical map. - ** It must be available to derived classes, for Save/Load purposes. - */ - static TacticalClass RadarButton; - - private: - - /* - ** The current radar position as the upper left corner cell for the - ** radar map display. The width and height is controlled by the - ** actual dimensions of the radar map display box (in pixels). - */ - unsigned RadarX; - unsigned RadarY; - unsigned RadarCell; - - /* - ** This is the origin (pixel offsets) for the upper left corner - ** of the radar map within the full radar map area of the screen. - ** This is biased so that the radar map, when smaller than full - ** size will appear centered. - */ - unsigned BaseX; - unsigned BaseY; - - unsigned RadarWidth; - unsigned RadarCellWidth; - unsigned RadarHeight; - unsigned RadarCellHeight; - - /* - ** If the radar map is in zoom mode, then this value will be true. - */ - unsigned IsZoomed:1; - - /* - ** This flag is true if the radar map is in its special show-the-player - ** names mode. - */ - unsigned IsPlayerNames:1; - - /* - ** This is the list of radar pixels that need to be updated. Only a partial - ** list is maintained for maximum speed. - */ - unsigned PixelPtr; - int ZoomFactor; - enum PixelStackEnums {PIXELSTACK=200}; - CELL PixelStack[PIXELSTACK]; -}; - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/RADIO.CPP b/code/TIBERIANDAWN/RADIO.CPP deleted file mode 100644 index 3ab7b6f..0000000 --- a/code/TIBERIANDAWN/RADIO.CPP +++ /dev/null @@ -1,249 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\radio.cpv 2.19 16 Oct 1995 16:50:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RADIO.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : June 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * RadioClass::Debug_Dump -- Displays the current status of the radio to the mono monitor. * - * RadioClass::Receive_Message -- Handles receipt of a radio message. * - * RadioClass::Transmit_Message -- Transmit message from one object to another. * - * RadioClass::Limbo -- When limboing a unit will always break radio contact. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -** These are the text representations of the radio messages that can be transmitted. -*/ -char const * RadioClass::Messages[RADIO_COUNT] = { - "hisssss", - "Roger.", - "Come in.", - "Over and out.", - "Requesting transport.", - "Attach to transport.", - "I've got a delivery for you.", - "I'm performing load/unload maneuver. Be careful.", - "I'm clear.", - "You are clear to unload. Driving away now.", - "Am unable to comply.", - "I'm starting construction now... act busy.", - "I've finished construction. You are free.", - "We bumped, redraw yourself please.", - "I'm trying to load up now.", - "May I become a passenger?", - "Are you ready to receive shipment?", - "Are you trying to become a passenger?", - "Move to location X.", - "Do you need to move?", - "All right already. Now what?", - "I'm a passenger now.", - "Backup into refinery now.", - "Run away!", - "Tether established.", - "Tether broken.", - "Repair one step.", - "Are you prepared to fight?", - "Attack this target please.", - "Reload one step.", - "Take this kick! You... You...", - "Take this punch! You... You...", - "Fancy a little fisticuffs, eh?" -}; - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * RadioClass::Debug_Dump -- Displays the current status of the radio to the mono monitor. * - * * - * This displays the radio connection value to the monochrome monitor. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void RadioClass::Debug_Dump(MonoClass *mono) const -{ - mono->Set_Cursor(34, 5);mono->Printf(Messages[LastMessage]); - if (Radio) { - mono->Set_Cursor(50, 1);mono->Printf("%04X", Radio->As_Target()); - } - MissionClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * RadioClass::Receive_Message -- Handles receipt of a radio message. * - * * - * This is the base version of what should happen when a radio message is received. It * - * turns the radio off when the "OVER_OUT" message is received. All other messages are * - * merely acknowledged with a "ROGER". * - * * - * INPUT: from -- The object that is initiating this radio message (always valid). * - * * - * message -- The radio message received. * - * * - * param -- Reference to optional value that might be used to return more * - * information than can be conveyed in the simple radio response * - * messages. * - * * - * OUTPUT: Returns with the response radio message. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - * 09/24/1994 JLB : Streamlined to be only a communications carrier. * - * 05/22/1995 JLB : Recognized who is sending the message * - *=============================================================================================*/ -RadioMessageType RadioClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - /* - ** Keep a record of the last message received by this radio. - */ - LastMessage = message; - - /* - ** When this message is received, it means that the other object - ** has already turned its radio off. Turn this radio off as well. - ** This only applies if the message is coming from the object that - ** has an established conversation with this object. - */ - if (from == Radio && message == RADIO_OVER_OUT) { - MissionClass::Receive_Message(from, message, param); - Radio_Off(); - return(RADIO_ROGER); - } - - /* - ** The "hello" message is an attempt to establish contact. If this radio - ** is already in an established conversation with another object, then - ** return with "negative". If all is well, return with "roger". - */ - if (message == RADIO_HELLO && Strength) { - if (Radio == from || !Radio) { - Radio = from; - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - } - - return(MissionClass::Receive_Message(from, message, param)); -} - - -/*********************************************************************************************** - * RadioClass::Transmit_Message -- Transmit message from one object to another. * - * * - * This routine is used to transmit a radio message from this object to another. Most * - * inter object coordination is handled through this mechanism. * - * * - * INPUT: to -- Pointer to the object that will receive the radio message. * - * * - * message -- The message itself (see RadioType). * - * * - * param -- Optional reference to parameter that might be used to pass or * - * receive additional information. * - * * - * OUTPUT: Returns with the response radio message from the receiving object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - *=============================================================================================*/ -RadioMessageType RadioClass::Transmit_Message(RadioMessageType message, long & param, RadioClass * to) -{ - if (!to) { - to = Contact_With_Whom(); - } - - /* - ** If there is no target for the radio message, then always return static. - */ - if (!to) return(RADIO_STATIC); - - /* - ** Handle some special case processing that occurs when certain messages - ** are transmitted. - */ - if (to == Radio && message == RADIO_OVER_OUT) { - Radio = 0; - } - - /* - ** If this object is not in radio contact but the message - ** indicates that radio contact should be established, then - ** try to do so. If the other party agrees then contact - ** is established. - */ - if (/*!Radio &&*/ message == RADIO_HELLO) { - Transmit_Message(RADIO_OVER_OUT); - if (to->Receive_Message(this, message, param) == RADIO_ROGER) { - Radio = to; - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - } - - return(to->Receive_Message(this, message, param)); -} - - -/*********************************************************************************************** - * RadioClass::Limbo -- When limboing a unit will always break radio contact. * - * * - * This routine will break radio contact as the object is entering limbo state. * - * * - * INPUT: none * - * * - * OUTPUT: Was the object successfully limboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -bool RadioClass::Limbo(void) -{ - if (!IsInLimbo) { - Transmit_Message(RADIO_OVER_OUT); - } - return(MissionClass::Limbo()); -} - - -RadioMessageType RadioClass::Transmit_Message(RadioMessageType message, RadioClass * to) {return(Transmit_Message(message, LParam, to));}; diff --git a/code/TIBERIANDAWN/RADIO.H b/code/TIBERIANDAWN/RADIO.H deleted file mode 100644 index ce0fe05..0000000 --- a/code/TIBERIANDAWN/RADIO.H +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\radio.h_v 2.15 16 Oct 1995 16:45:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RADIO.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef RADIO_H -#define RADIO_H - -//#include "object.h" -#include "mission.h" -//#include "flasher.h" - -class ObjectClass; -class TechnoClass; - - -/**************************************************************************** -** Radio contact is controlled by this class. It handles the mundane chore -** of keeping the radio contact alive as well as broadcasting messages -** to the receiving radio. Radio contact is primarily used when one object -** is in "command" of another. -*/ -class RadioClass : public MissionClass { - private: - - /* - ** This is a record of the last message received by this receiver. - */ - RadioMessageType LastMessage; - - /* - ** This is the object that radio communication has been established - ** with. Although is is only a one-way reference, it is required that - ** the receiving radio is also tuned to the object that contains this - ** radio set. - */ - RadioClass * Radio; - - /* - ** This is a text representation of all the possible radio messages. This - ** text is used for monochrome debug printing. - */ - static char const * Messages[RADIO_COUNT]; - - public: - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - RadioClass(void) {Radio = 0;LastMessage = RADIO_STATIC;}; - virtual ~RadioClass(void) {}; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - bool In_Radio_Contact(void) const {return (Radio != 0);}; - void Radio_Off(void) {Radio = 0;}; - TechnoClass * Contact_With_Whom(void) const {return (TechnoClass*)Radio;}; - - // Inherited from base class(es). - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual RadioMessageType Transmit_Message(RadioMessageType message, long & param=LParam, RadioClass * to=NULL); - virtual RadioMessageType Transmit_Message(RadioMessageType message, RadioClass * to); - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - virtual bool Limbo(void); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); -}; - -#endif diff --git a/code/TIBERIANDAWN/RAND.CPP b/code/TIBERIANDAWN/RAND.CPP deleted file mode 100644 index 6557f9b..0000000 --- a/code/TIBERIANDAWN/RAND.CPP +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\rand.cpv 1.6 16 Oct 1995 16:51:10 JOE_BOSTIC $ */ -/*************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RAND.CPP * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 04/25/95 * - * * - * Last Update : June 17, 1995 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Sim_Random -- Returns 0 - 255 * - * Sim_IRandom -- Returns minval to maxval, inclusive * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -int SimRandIndex = 0; - -/*************************************************************************** - * Sim_Random -- Returns 0 - 255 * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 0 - 255, at random * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/25/1995 BRR : Created. * - * 06/17/1995 JLB : Takes advantage of character math wrap. * - *=========================================================================*/ -int Sim_Random(void) -{ - static unsigned char _randvals[] = { - 0x47, 0xce, 0xc6, 0x6e, 0xd7, 0x9f, 0x98, 0x29, 0x92, 0x0c, 0x74, 0xa2, - 0x65, 0x20, 0x4b, 0x4f, 0x1e, 0xed, 0x3a, 0xdf, 0xa5, 0x7d, 0xb5, 0xc8, - 0x86, 0x01, 0x81, 0xca, 0xf1, 0x17, 0xd6, 0x23, 0xe1, 0xbd, 0x0e, 0xe4, - 0x62, 0xfa, 0xd9, 0x5c, 0x68, 0xf5, 0x7f, 0xdc, 0xe7, 0xb9, 0xc4, 0xb3, - 0x7a, 0xd8, 0x06, 0x3e, 0xeb, 0x09, 0x1a, 0x31, 0x3f, 0x46, 0x28, 0x12, - 0xf0, 0x10, 0x84, 0x76, 0x3b, 0xc5, 0x53, 0x18, 0x14, 0x73, 0x7e, 0x59, - 0x48, 0x93, 0xaa, 0x1d, 0x5d, 0x79, 0x24, 0x61, 0x1b, 0xfd, 0x2b, 0xa8, - 0xc2, 0xdb, 0xe8, 0x2a, 0xb0, 0x25, 0x95, 0xab, 0x96, 0x83, 0xfc, 0x5f, - 0x9c, 0x32, 0x78, 0x9a, 0x9e, 0xe2, 0x8e, 0x35, 0x4c, 0x41, 0xa1, 0x69, - 0x5a, 0xfe, 0xa7, 0xa4, 0xf6, 0x6d, 0xc1, 0x58, 0x0a, 0xcf, 0xea, 0xc3, - 0xba, 0x85, 0x99, 0x8d, 0x36, 0xb6, 0xdd, 0xd3, 0x04, 0xe6, 0x45, 0x0d, - 0x60, 0xae, 0xa3, 0x22, 0x4d, 0xe9, 0xc9, 0x9b, 0xb7, 0x0f, 0x02, 0x42, - 0xf9, 0x0b, 0x8f, 0x43, 0x44, 0x87, 0x70, 0xbe, 0xe3, 0xf8, 0xee, 0xa9, - 0xbc, 0xc0, 0x67, 0x33, 0x16, 0x37, 0x57, 0xad, 0x5e, 0x9d, 0x64, 0x40, - 0x54, 0x05, 0x2c, 0xe0, 0xb2, 0x97, 0x08, 0xaf, 0x75, 0x8a, 0x5b, 0xfb, - 0x4e, 0xbf, 0x91, 0xf3, 0xcb, 0x7c, 0x63, 0xef, 0x89, 0x52, 0x6c, 0x2f, - 0x21, 0x4a, 0xf7, 0xcd, 0x2e, 0xf4, 0xc7, 0x6f, 0x19, 0xb1, 0x66, 0xcc, - 0x90, 0x8c, 0x50, 0x51, 0x26, 0x7b, 0xda, 0x49, 0x80, 0x30, 0x55, 0x1f, - 0xd2, 0xb4, 0xd1, 0xd5, 0x6b, 0xf2, 0x72, 0xbb, 0x13, 0x3d, 0xff, 0x15, - 0x38, 0xe5, 0xd4, 0xde, 0x2d, 0x27, 0x94, 0xa0, 0xd0, 0x39, 0x82, 0x8b, - 0x03, 0xac, 0x3c, 0x34, 0x77, 0xb8, 0xec, 0x00, 0x07, 0x1c, 0x88, 0xa6, - 0x56, 0x11, 0x71, 0x6a, - }; - - ((unsigned char&)SimRandIndex)++; -// SimRandIndex &= 0xff; - return(_randvals[SimRandIndex]); -} - - -/*************************************************************************** - * Sim_IRandom -- returns minval to maxval, inclusive * - * * - * INPUT: * - * minval,maxval range limits * - * * - * OUTPUT: * - * random value * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 04/25/1995 BRR : Created. * - * 06/17/1995 JLB : Uses fixed point math helper routine. * - *=========================================================================*/ -int Sim_IRandom(int minval, int maxval) -{ - return(Fixed_To_Cardinal((maxval-minval), Sim_Random()) + minval); -} - - -/*--------------------------------------------------------------------------- -This routine can be used to create the _RandVals[] table. It will be -different every time it's run. ----------------------------------------------------------------------------*/ -#if 0 -#include -#include -#include -#include - -void main(void); - -void main(void) -{ - int i; - FILE *fp; - int r; - char is_used[256]; - char rand_val[256]; - - srand ( time ( NULL ) ) ; - - for (i = 0; i < 256; i++) { - is_used[i] = 0; - } - - /* - ** Store the digits 0 to 255 in a random order within the 'rand_val' array - ** This ensures our random number sequence represents every value. - */ - for (i = 0; i < 256; i++) { - if (kbhit()!=0) { - printf("ABORTED!\n"); - break; - } - r = (rand() * 256) / RAND_MAX; // r is the index into array - if (is_used[r]==0) { - is_used[r] = 1; - rand_val[r] = i; - } else { - i--; - } - } - - fp = fopen("rand.cpp","wt"); - if (fp==NULL) { - printf("File error\n"); - exit(0); - } - - fprintf(fp, "unsigned char _RandVals[] = {\n"); - for (i = 0; i < 256; i++) { - fprintf(fp,"0x%02x,\n",rand_val[i]); - } - fprintf(fp,"};\n"); - fclose(fp); - -} - -#endif - diff --git a/code/TIBERIANDAWN/RAWFILE.CPP b/code/TIBERIANDAWN/RAWFILE.CPP deleted file mode 100644 index 90057bc..0000000 --- a/code/TIBERIANDAWN/RAWFILE.CPP +++ /dev/null @@ -1,1346 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: /CounterStrike/RAWFILE.CPP 1 3/03/97 10:25a Joe_bostic $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : RAWFILE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : August 4, 1996 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * RawFileClass::Bias -- Bias a file with a specific starting position and length. * - * RawFileClass::Close -- Perform a closure of the file. * - * RawFileClass::Create -- Creates an empty file. * - * RawFileClass::Delete -- Deletes the file object from the disk. * - * RawFileClass::Error -- Handles displaying a file error message. * - * RawFileClass::Get_Date_Time -- Gets the date and time the file was last modified. * - * RawFileClass::Is_Available -- Checks to see if the specified file is available to open. * - * RawFileClass::Open -- Assigns name and opens file in one operation. * - * RawFileClass::Open -- Opens the file object with the rights specified. * - * RawFileClass::RawFileClass -- Simple constructor for a file object. * - * RawFileClass::Raw_Seek -- Performs a seek on the unbiased file * - * RawFileClass::Read -- Reads the specified number of bytes into a memory buffer. * - * RawFileClass::Seek -- Reposition the file pointer as indicated. * - * RawFileClass::Set_Date_Time -- Sets the date and time the file was last modified. * - * RawFileClass::Set_Name -- Manually sets the name for a file object. * - * RawFileClass::Size -- Determines size of file (in bytes). * - * RawFileClass::Write -- Writes the specified data to the buffer specified. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include -#include -#include -#include -#include -#include - -#include "rawfile.h" - -#ifndef WIN32 -#include -#include -#include -extern short Hard_Error_Occured; -#endif - - -/*********************************************************************************************** - * RawFileClass::Error -- Handles displaying a file error message. * - * * - * Display an error message as indicated. If it is allowed to retry, then pressing a key * - * will return from this function. Otherwise, it will exit the program with "exit()". * - * * - * INPUT: error -- The error number (same as the DOSERR.H error numbers). * - * * - * canretry -- Can this routine exit normally so that retrying can occur? If this is * - * false, then the program WILL exit in this routine. * - * * - * filename -- Optional filename to report with this error. If no filename is * - * supplied, then no filename is listed in the error message. * - * * - * OUTPUT: none, but this routine might not return at all if the "canretry" parameter is * - * false or the player pressed ESC. * - * * - * WARNINGS: This routine may not return at all. It handles being in text mode as well as * - * if in a graphic mode. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -void RawFileClass::Error(int , int , char const * ) -{ -} - - -/*********************************************************************************************** - * RawFileClass::RawFileClass -- Simple constructor for a file object. * - * * - * This constructor is called when a file object is created with a supplied filename, but * - * not opened at the same time. In this case, an assumption is made that the supplied * - * filename is a constant string. A duplicate of the filename string is not created since * - * it would be wasteful in that case. * - * * - * INPUT: filename -- The filename to assign to this file object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -RawFileClass::RawFileClass(char const * filename) : - Rights(0), - BiasStart(0), - BiasLength(-1), - Handle(NULL_HANDLE), - Filename(filename), - Date(0), - Time(0), - Allocated(false) -{ -} - - -/*********************************************************************************************** - * RawFileClass::Set_Name -- Manually sets the name for a file object. * - * * - * This routine will set the name for the file object to the name specified. This name is * - * duplicated in free store. This allows the supplied name to be a temporarily constructed * - * text string. Setting the name in this fashion doesn't affect the closed or opened state * - * of the file. * - * * - * INPUT: filename -- The filename to assign to this file object. * - * * - * OUTPUT: Returns with a pointer to the allocated copy of this filename. This pointer is * - * guaranteed to remain valid for the duration of this file object or until the name * - * is changed -- whichever is sooner. * - * * - * WARNINGS: Because of the allocation this routine must perform, memory could become * - * fragmented. * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -#pragma warning(disable:4996) -char const * RawFileClass::Set_Name(char const * filename) -{ - if (Filename != NULL && Allocated) { - free((char *)Filename); - ((char *&)Filename) = 0; - Allocated = false; - } - - if (filename == NULL) return(NULL); - - Bias(0); - - Filename = strdup(filename); - if (Filename == NULL) { - Error(ENOMEM, false, filename); - } - Allocated = true; - return(Filename); -} - - -/*********************************************************************************************** - * RawFileClass::Open -- Assigns name and opens file in one operation. * - * * - * This routine will assign the specified filename to the file object and open it at the * - * same time. If the file object was already open, then it will be closed first. If the * - * file object was previously assigned a filename, then it will be replaced with the new * - * name. Typically, this routine is used when an anonymous file object has been crated and * - * now it needs to be assigned a name and opened. * - * * - * INPUT: filename -- The filename to assign to this file object. * - * * - * rights -- The open file access rights to use. * - * * - * OUTPUT: bool; Was the file opened? The return value of this is moot, since the open file * - * is designed to never return unless it succeeded. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -int RawFileClass::Open(char const * filename, int rights) -{ - Set_Name(filename); - return(Open(rights)); -} - - -/*********************************************************************************************** - * RawFileClass::Open -- Opens the file object with the rights specified. * - * * - * This routine is used to open the specified file object with the access rights indicated. * - * This only works if the file has already been assigned a filename. It is guaranteed, by * - * the error handler, that this routine will always return with success. * - * * - * INPUT: rights -- The file access rights to use when opening this file. This is a * - * combination of READ and/or WRITE bit flags. * - * * - * OUTPUT: bool; Was the file opened successfully? This will always return true by reason of * - * the error handler. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -int RawFileClass::Open(int rights) -{ - Close(); - - /* - ** Verify that there is a filename associated with this file object. If not, then this is a - ** big error condition. - */ - if (Filename == NULL) { - Error(ENOENT, false); - } - - /* - ** Record the access rights used for this open call. These rights will be used if the - ** file object is duplicated. - */ - Rights = rights; - - /* - ** Repetitively try to open the file. Abort if a fatal error condition occurs. - */ - for (;;) { - - /* - ** Try to open the file according to the access rights specified. - */ - #ifndef WIN32 - Hard_Error_Occured = 0; - #endif - switch (rights) { - - /* - ** If the access rights are not recognized, then report this as - ** an invalid access code. - */ - default: - errno = EINVAL; - break; - - case READ: - #ifdef WIN32 - Handle = CreateFile(Filename, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - #else - _dos_open(Filename, O_RDONLY|SH_DENYNO, &Handle); - #endif - break; - - case WRITE: - #ifdef WIN32 - Handle = CreateFile(Filename, GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - #else - _dos_creat(Filename, 0, &Handle); - #endif - break; - - case READ|WRITE: - #ifdef WIN32 - Handle = CreateFile(Filename, GENERIC_READ | GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - #else - _dos_open(Filename, O_RDWR|O_CREAT|SH_DENYWR, &Handle); - #endif - break; - } - - /* - ** Biased files must be positioned past the bias start position. - */ - if (BiasStart != 0 || BiasLength != -1) { - Seek(0, SEEK_SET); - } - - /* - ** If the handle indicates the file is not open, then this is an error condition. - ** For the case of the file cannot be found, then allow a retry. All other cases - ** are fatal. - */ - if (Handle == NULL_HANDLE) { - -#ifdef WIN32 -// return(false); - Error(GetLastError(), false, Filename); -// continue; -#else - /* - ** If this flag is set, then some hard error occurred. Just assume that the error - ** is probably a removed CD-ROM and allow a retry. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - } else { - if (errno == ENOENT) { - Error(ENOENT, true, Filename); - } else { - Error(errno, false, Filename); - } - } - continue; -#endif - } - break; - } - - return(true); -} - - -/*********************************************************************************************** - * RawFileClass::Is_Available -- Checks to see if the specified file is available to open. * - * * - * This routine will examine the disk system to see if the specified file can be opened * - * or not. Use this routine before opening a file in order to make sure that is available * - * or to perform other necessary actions. * - * * - * INPUT: force -- Should this routine keep retrying until the file becomes available? If * - * in this case it doesn't become available, then the program will abort. * - * * - * OUTPUT: bool; Is the file available to be opened? * - * * - * WARNINGS: Depending on the parameter passed in, this routine may never return. * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -int RawFileClass::Is_Available(int forced) -{ -#ifndef WIN32 - bool open_failed; -#endif - - if (Filename == NULL) return(false); - - /* - ** If the file is already open, then is must have already passed the availability check. - ** Return true in this case. - */ - if (Is_Open()) return(true); - - /* - ** If this is a forced check, then go through the normal open channels, since those - ** channels ensure that the file must exist. - */ - if (forced) { - RawFileClass::Open(READ); - RawFileClass::Close(); - return(true); - } - - /* - ** Perform a raw open of the file. If this open fails for ANY REASON, including a missing - ** CD-ROM, this routine will return a failure condition. In all but the missing file - ** condition, go through the normal error recover channels. - */ - for (;;) { - -#ifdef WIN32 - Handle = CreateFile(Filename, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (Handle == NULL_HANDLE) { - return(false); - } - break; -#else - - Hard_Error_Occured = 0; - open_failed = _dos_open(Filename, O_RDONLY|SH_DENYNO, &Handle); - - /* - ** If DOS reports that everything is just fine except that the file is not present, - ** then return with this fact. Any other case will fall through to the error handler - ** routine. - */ - if (open_failed && errno == ENOENT) return(false); - - /* - ** If we got an access error it could be because there is no cd in - ** the drive. Call the error handler but allow a continue if it - ** returns. - */ - if (open_failed && errno == EACCES) { - Error(errno, true, Filename); - continue; - } - - /* - ** If the file could not be found, then return with this information. If a more - ** serious error occurred, then display the error message and abort. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; - } else { - if (open_failed) { - /* - ** An unhandled error condition is fatal. Display the error message and then - ** abort. - */ - Error(errno, false, Filename); - } - } - if (!open_failed) break; -#endif - } - - /* - ** Since the file could be opened, then close it and return that the file exists. - */ -#ifdef WIN32 - if (!CloseHandle(Handle)) { - Error(GetLastError(), false, Filename); - } -#else - if (_dos_close(Handle)) { - Error(errno, false, Filename); - } -#endif - Handle = NULL_HANDLE; - - return(true); -} - - -/*********************************************************************************************** - * RawFileClass::Close -- Perform a closure of the file. * - * * - * Close the file object. In the rare case of an error, handle it as appropriate. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Some rare error conditions may cause this routine to abort the program. * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -void RawFileClass::Close(void) -{ - /* - ** If the file is open, then close it. If the file is already closed, then just return. This - ** isn't considered an error condition. - */ - if (Is_Open()) { - -#ifdef WIN32 - /* - ** Try to close the file. If there was an error (who knows what that could be), then - ** call the error routine. - */ - if (!CloseHandle(Handle)) { - Error(GetLastError(), false, Filename); - } -#else - for (;;) { - /* - ** Close the file. If there was an error in the close operation -- abort. - */ - Hard_Error_Occured = 0; - if (_dos_close(Handle)) { - - /* - ** By definition, this error can only be a bad file handle. This a fatal condition - ** of course, so abort with an error message. - */ - Error(errno, false, Filename); - } - - /* - ** In the condition (if it is even possible) of a hard error occurring, then - ** assume it is the case of missing media. Display an error message and try - ** again if indicated. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; - } - break; - } - -#endif - - /* - ** At this point the file must have been closed. Mark the file as empty and return. - */ - Handle = NULL_HANDLE; - } -} - - -/*********************************************************************************************** - * RawFileClass::Read -- Reads the specified number of bytes into a memory buffer. * - * * - * This routine will read the specified number of bytes and place the data into the buffer * - * indicated. It is legal to call this routine with a request for more bytes than are in * - * the file. This condition can result in fewer bytes being read than requested. Determine * - * this by examining the return value. * - * * - * INPUT: buffer -- Pointer to the buffer to read data into. If NULL is passed, no read * - * is performed. * - * * - * size -- The number of bytes to read. If NULL is passed, then no read is * - * performed. * - * * - * OUTPUT: Returns with the number of bytes read into the buffer. If this number is less * - * than requested, it indicates that the file has been exhausted. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -long RawFileClass::Read(void * buffer, long size) -{ - long bytesread = 0; // Running count of the number of bytes read into the buffer. - int opened = false; // Was the file opened by this routine? - - /* - ** If the file isn't opened, open it. This serves as a convenience - ** for the programmer. - */ - if (!Is_Open()) { - - /* - ** The error check here is moot. Open will never return unless it succeeded. - */ - if (!Open(READ)) { - return(0); - } - opened = true; - } - - /* - ** A biased file has the requested read length limited to the bias length of - ** the file. - */ - if (BiasLength != -1) { - int remainder = BiasLength - Seek(0); - size = size < remainder ? size : remainder; - } - -#ifdef WIN32 - long total = 0; - while (size > 0) { - bytesread = 0; - - SetErrorMode(SEM_FAILCRITICALERRORS); - if (!ReadFile(Handle, buffer, size, &(unsigned long&)bytesread, NULL)) { - size -= bytesread; - total += bytesread; - Error(GetLastError(), true, Filename); - SetErrorMode(0); - continue; - } - SetErrorMode(0); - size -= bytesread; - total += bytesread; - if (bytesread == 0) break; - } - bytesread = total; - -#else - - int readresult; - - /* - ** Read the file in convenient chunk sizes. When the actual number - ** of bytes read does not match the desired, then assume that the file - ** is exhausted and bail. This loop was adjusted to take into - ** consideration the fact that "read" returns a SIGNED value whereas - ** it takes an UNSIGNED value as the byte count. - */ - while (size) { - unsigned desired; // Bytes desired to be read this pass. - unsigned actual; // Actual number of bytes read. - - /* - ** Break the read request into chunks no bigger than the low level DOS read - ** can handle. - */ - desired = size < 32000L ? size : 32000L; - - Hard_Error_Occured = 0; - readresult = _dos_read(Handle, buffer, desired, &actual); - - /* - ** If a hard error occurred, then assume that it is the case of the CD-ROM or - ** floppy media having been removed. Display the error and retry as directed. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; // Not technically needed, but to be consistent... - } else { - - /* - ** If negative one is returned from the read operation, then this indicates - ** either a bad file number or invalid access. These are fatal conditions, so - ** display the error and then abort. - */ - if (readresult != 0) { - Error(errno, false, Filename); - } else { - - /* - ** No error occurred during the read. Adjust the pointers and size counters and - ** loop again if more data is needed to be read. - */ - buffer = (char *)buffer + actual; - bytesread += actual; - size -= actual; - if (actual != desired) break; // No more data? - } - } - } -#endif //WIN32 - - /* - ** Close the file if it was opened by this routine and return - ** the actual number of bytes read into the buffer. - */ - if (opened) Close(); - return(bytesread); -} - - -/*********************************************************************************************** - * RawFileClass::Write -- Writes the specified data to the buffer specified. * - * * - * This routine will write the data specified to the file. * - * * - * INPUT: buffer -- The buffer that holds the data to write. * - * * - * size -- The number of bytes to write to the file. * - * * - * OUTPUT: Returns with the number of bytes written to the file. This routine catches the * - * case of a disk full condition, so this routine will always return with the number * - * matching the size request. * - * * - * WARNINGS: A fatal file condition could cause this routine to never return. * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -long RawFileClass::Write(void const * buffer, long size) -{ - long bytesread = 0; - int opened = false; // Was the file manually opened? - - /* - ** Check to open status of the file. If the file is open, then merely write to - ** it. Otherwise, open the file for writing and then close the file when the - ** output is finished. - */ - if (!Is_Open()) { - if (!Open(WRITE)) { - return(0); - } - opened = true; - } - -#ifdef WIN32 - if (!WriteFile(Handle, buffer, size, &(unsigned long&)bytesread, NULL)) { - Error(GetLastError(), false, Filename); - } - -#else - - int writeresult; - /* - ** Write the data to the file in chunks no bigger than what the low level DOS write - ** can handle. - */ - while (size) { - unsigned desired; // Bytes desired to be write this pass. - unsigned actual; // Actual number of bytes written. - - Hard_Error_Occured = 0; -// desired = (unsigned)MIN(size, Transfer_Block_Size()); - desired = size; - writeresult = _dos_write(Handle, buffer, desired, &actual); - - /* - ** If a hard error occurred, then assume it is the case of the media being - ** removed. Print the error message an retry as directed. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; // Not technically needed, but to be consistent... - } else { - - /* - ** If negative one is returned by the DOS read, then this indicates a bad file - ** handle or invalid access. Either condition is fatal -- display error condition - ** and abort. - */ - if (writeresult != 0) { - Error(errno, false, Filename); - } else { - - /* - ** A successful write occurred. Update pointers and byte counter as appropriate. - */ - buffer = (char *)buffer + actual; - bytesread += actual; - size -= actual; - - /* - ** If the actual bytes written is less than requested, assume this is a case of - ** the disk being full. Consider this a fatal error condition. - */ - if (actual != desired) { - Error(ENOSPC, false, Filename); - } - } - } - } -#endif //WIN32 - - /* - ** Fixup the bias length if necessary. - */ - if (BiasLength != -1) { - if (Raw_Seek(0) > BiasStart+BiasLength) { - BiasLength = Raw_Seek(0) - BiasStart; - } - } - - /* - ** If this routine had to open the file, then close it before returning. - */ - if (opened) { - Close(); - } - - /* - ** Return with the number of bytes written. This will always be the number of bytes - ** requested, since the case of the disk being full is caught by this routine. - */ - return(bytesread); -} - - -/*********************************************************************************************** - * RawFileClass::Seek -- Reposition the file pointer as indicated. * - * * - * Use this routine to move the filepointer to the position indicated. It can move either * - * relative to current position or absolute from the beginning or ending of the file. This * - * routine will only return if it successfully performed the seek. * - * * - * INPUT: pos -- The position to seek to. This is interpreted as relative to the position * - * indicated by the "dir" parameter. * - * * - * dir -- The relative position to relate the seek to. This can be either SEEK_SET * - * for the beginning of the file, SEEK_CUR for the current position, or * - * SEEK_END for the end of the file. * - * * - * OUTPUT: This routine returns the position that the seek ended up at. * - * * - * WARNINGS: If there was a file error, then this routine might never return. * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -long RawFileClass::Seek(long pos, int dir) -{ - - /* - ** A file that is biased will have a seek operation modified so that the file appears to - ** exist only within the bias range. All bytes outside of this range appear to be - ** non-existant. - */ - if (BiasLength != -1) { - switch (dir) { - case SEEK_SET: - if (pos > BiasLength) { - pos = BiasLength; - } - pos += BiasStart; - break; - - case SEEK_CUR: - break; - - case SEEK_END: - dir = SEEK_SET; - pos += BiasStart + BiasLength; -// pos = (pos <= BiasStart+BiasLength) ? pos : BiasStart+BiasLength; -// pos = (pos >= BiasStart) ? pos : BiasStart; - break; - } - - /* - ** Perform the modified raw seek into the file. - */ - long newpos = Raw_Seek(pos, dir) - BiasStart; - - /* - ** Perform a final double check to make sure the file position fits with the bias range. - */ - if (newpos < 0) { - newpos = Raw_Seek(BiasStart, SEEK_SET) - BiasStart; - } - if (newpos > BiasLength) { - newpos = Raw_Seek(BiasStart+BiasLength, SEEK_SET) - BiasStart; - } - return(newpos); - } - - /* - ** If the file is not biased in any fashion, then the normal seek logic will - ** work just fine. - */ - return(Raw_Seek(pos, dir)); -} - - -/*********************************************************************************************** - * RawFileClass::Size -- Determines size of file (in bytes). * - * * - * Use this routine to determine the size of the file. The file must exist or this is an * - * error condition. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of bytes in the file. * - * * - * WARNINGS: This routine handles error conditions and will not return unless the file * - * exists and can successfully be queried for file length. * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -long RawFileClass::Size(void) -{ - long size = 0; - - /* - ** A biased file already has its length determined. - */ - if (BiasLength != -1) { - return(BiasLength); - } - - /* - ** If the file is open, then proceed normally. - */ - if (Is_Open()) { - -#ifdef WIN32 - size = GetFileSize(Handle, NULL); - - /* - ** If there was in internal error, then call the error function. - */ - if (size == 0xFFFFFFFF) { - Error(GetLastError(), false, Filename); - } -#else - - /* - ** Repetitively try to determine the file size until a fatal error condition or success - ** is achieved. - */ - for (;;) { - Hard_Error_Occured = 0; - size = filelength(Handle); - - /* - ** If a hard error occurred, then assume it is the case of removed media. Display an - ** error condition and allow retry. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; - } else { - if (size == -1) { - Error(errno, false, Filename); - } - } - break; - } -#endif - - } else { - - /* - ** If the file wasn't open, then open the file and call this routine again. Count on - ** the fact that the open function must succeed. - */ - if (Open()) { - size = Size(); - - /* - ** Since we needed to open the file we must remember to close the file when the - ** size has been determined. - */ - Close(); - } - } - - BiasLength = size-BiasStart; - return(BiasLength); -} - - -/*********************************************************************************************** - * RawFileClass::Create -- Creates an empty file. * - * * - * This routine will create an empty file from the file object. The file object's filename * - * must already have been assigned before this routine will function. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the file successfully created? This routine will always return true. * - * * - * WARNINGS: A fatal error condition could occur with this routine. Especially if the disk * - * is full or a read-only media was selected. * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -int RawFileClass::Create(void) -{ - Close(); - if (Open(WRITE)) { - - /* - ** A biased file must be at least as long as the bias offset. Seeking to the - ** appropriate start offset has the effect of lengthening the file to the - ** correct length. - */ - if (BiasLength != -1) { - Seek(0, SEEK_SET); - } - - Close(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * RawFileClass::Delete -- Deletes the file object from the disk. * - * * - * This routine will delete the file object from the disk. If the file object doesn't * - * exist, then this routine will return as if it had succeeded (since the effect is the * - * same). * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the file deleted? If the file was already missing, the this value will * - * be false. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -int RawFileClass::Delete(void) -{ - /* - ** If the file was open, then it must be closed first. - */ - Close(); - - /* - ** If there is no filename associated with this object, then this indicates a fatal error - ** condition. Report this and abort. - */ - if (!Filename) { - Error(ENOENT, false); - } - - /* - ** Repetitively try to delete the file if possible. Either return with success, or - ** abort the program with an error. - */ - for (;;) { - - /* - ** If the file is already missing, then return with this fact. No action is necessary. - ** This can occur as this section loops if the file exists on a floppy and the floppy - ** was removed, the file deleted on another machine, and then the floppy was - ** reinserted. Admittedly, this is a rare case, but is handled here. - */ - if (!Is_Available()) { - return(false); - } - -#ifdef WIN32 - if (!DeleteFile(Filename)) { - Error(GetLastError(), false, Filename); - return(false); - } -#else - Hard_Error_Occured = 0; - if (remove(Filename) == -1) { - - /* - ** If a hard error occurred, then assume that the media has been removed. Display - ** error message and retry as directed. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; - } - - /* - ** If at this point, DOS says the file doesn't exist, then just exit with this - ** fact. It should have been caught earlier, but in any case, this is a legal - ** condition. - */ - if (errno == ENOENT) break; - - /* - ** The only way it can reach this point is if DOS indicates that access is denied - ** on the file. This occurs when trying to delete a file on a read-only media such - ** as a CD-ROM. Report this as a fatal error and then abort. - */ - Error(errno, false, Filename); - } -#endif - break; - } - - /* - ** DOS reports that the file was successfully deleted. Return with this fact. - */ - return(true); -} - - -/*********************************************************************************************** - * RawFileClass::Get_Date_Time -- Gets the date and time the file was last modified. * - * * - * Use this routine to get the date and time of the file. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the file date and time as a long. * - * Use the YEAR(long), MONTH(),.... * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/14/1995 DRD : Created. * - * 07/13/1996 JLB : Handles win32 method. * - *=============================================================================================*/ -unsigned long RawFileClass::Get_Date_Time(void) -{ -#ifdef WIN32 - BY_HANDLE_FILE_INFORMATION info; - - if (GetFileInformationByHandle(Handle, &info)) { - WORD dosdate; - WORD dostime; - FileTimeToDosDateTime(&info.ftLastWriteTime, &dosdate, &dostime); - return((dosdate << 16) | dostime); - } - return(0); -#else - unsigned short time; - unsigned short date; - unsigned long datetime = 0; - - - // - // If the file is open, then proceed normally. - // - if ( RawFileClass::Is_Open() ) { - if ( _dos_getftime( Handle, &date, &time ) ) { - // - // return 0 indicating error with no date and time - // - return( datetime ); - } - } else { - - // - // If the file wasn't open, then see if the file exists. - // - if ( RawFileClass::Is_Available() ) { - RawFileClass::Open(); - - if ( _dos_getftime( Handle, &date, &time ) ) { - RawFileClass::Close(); - // - // return 0 indicating error with no date and time - // - return( datetime ); - } - - RawFileClass::Close(); - } else { - // - // return 0 indicating error with no date and time - // - return( datetime ); - } - } - - // - // combine the date and time as a long - // - datetime = (date << 16) + time; - - return( datetime ); -#endif -} - - -/*********************************************************************************************** - * RawFileClass::Set_Date_Time -- Sets the date and time the file was last modified. * - * * - * Use this routine to set the date and time of the file. * - * * - * INPUT: the file date and time as a long * - * * - * OUTPUT: successful or not if the file date and time was changed. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/14/1995 DRD : Created. * - * 07/13/1996 JLB : Handles win 32 method * - *=============================================================================================*/ -bool RawFileClass::Set_Date_Time(unsigned long datetime) -{ -#ifdef WIN32 - if (RawFileClass::Is_Open()) { - BY_HANDLE_FILE_INFORMATION info; - - if (GetFileInformationByHandle(Handle, &info)) { - FILETIME filetime; - if (DosDateTimeToFileTime((WORD)(datetime >> 16), (WORD)(datetime & 0x0FFFF), &filetime)) { - return(SetFileTime(Handle, &info.ftCreationTime, &filetime, &filetime)); - } - } - } - return(false); -#else - unsigned short time; - unsigned short date; - - // - // If the file is open, then proceed normally. - // - if ( RawFileClass::Is_Open() ) { - // - // only set the date and time if open for READ only - // - if ( Rights == READ ) { - time = (unsigned short)(datetime & 0xFFFF); - date = (unsigned short)((datetime >> 16) & 0xFFFF); - - if ( !_dos_setftime( Handle, date, time ) ) { - // - // return true indicating success - // - return( true ); - } - } - } else { - - // - // If the file wasn't open, then see if the file exists. - // - if ( RawFileClass::Is_Available() ) { - RawFileClass::Open(); - - time = (unsigned short)(datetime & 0xFFFF); - date = (unsigned short)((datetime >> 16) & 0xFFFF); - - if ( !_dos_setftime( Handle, date, time ) ) { - RawFileClass::Close(); - // - // return true indicating success - // - return( true ); - } - - RawFileClass::Close(); - } - } - - // - // return false indicating error - // - return( false ); -#endif -} - - -/*********************************************************************************************** - * RawFileClass::Bias -- Bias a file with a specific starting position and length. * - * * - * This will bias a file by giving it an artificial starting position and length. By * - * using this routine, it is possible to 'fool' the file into ignoring a header and * - * trailing extra data. An example of this would be a file inside of a mixfile. * - * * - * INPUT: start -- The starting offset that will now be considered the start of the * - * file. * - * * - * length -- The forced length of the file. For files that are opened for write, * - * this serves as the artificial constraint on the file's length. For * - * files opened for read, this limits the usable file size. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1996 JLB : Created. * - *=============================================================================================*/ -void RawFileClass::Bias(int start, int length) -{ - if (start == 0) { - BiasStart = 0; - BiasLength = -1; - return; - } - - BiasLength = RawFileClass::Size(); - BiasStart += start; - if (length != -1) { - BiasLength = BiasLength < length ? BiasLength : length; - } - BiasLength = BiasLength > 0 ? BiasLength : 0; - - /* - ** Move the current file offset to a legal position if necessary and the - ** file was open. - */ - if (Is_Open()) { - RawFileClass::Seek(0, SEEK_SET); - } -} - - -/*********************************************************************************************** - * RawFileClass::Raw_Seek -- Performs a seek on the unbiased file * - * * - * This will perform a seek on the file as if it were unbiased. This is in spite of any * - * bias setting the file may have. The ability to perform a raw seek in this fasion is * - * necessary to maintain the bias ability. * - * * - * INPUT: pos -- The position to seek the file relative to the "dir" parameter. * - * * - * dir -- The origin of the seek operation. * - * * - * OUTPUT: Returns with the new position of the seek operation. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/04/1996 JLB : Created. * - *=============================================================================================*/ -long RawFileClass::Raw_Seek(long pos, int dir) -{ - /* - ** If the file isn't opened, then this is a fatal error condition. - */ - if (!Is_Open()) { - Error(EBADF, false, Filename); - } - -#ifdef WIN32 - switch (dir) { - case SEEK_SET: - dir = FILE_BEGIN; - break; - - case SEEK_CUR: - dir = FILE_CURRENT; - break; - - case SEEK_END: - dir = FILE_END; - break; - } - - pos = SetFilePointer(Handle, pos, NULL, dir); - - /* - ** If there was an error in the seek, then bail with an error condition. - */ - if (pos == 0xFFFFFFFF) { - Error(GetLastError(), false, Filename); - } -#else - - /* - ** Keep trying to seek until a non-retry condition occurs. - */ - for (;;) { - - /* - ** Perform the low level seek on the file. - */ - Hard_Error_Occured = 0; - pos = lseek(Handle, pos, dir); - - /* - ** If a hard error occurred, then assume that it is the case of removed media. Display - ** error message and retry. - */ - if (Hard_Error_Occured) { - Error(Hard_Error_Occured, true, Filename); - continue; - } else { - - /* - ** A negative one indicates a fatal error with the seek operation. Display error - ** condition and then abort. - */ - if (pos == -1) { - Error(errno, false, Filename); - } - } - break; - } -#endif - - /* - ** Return with the new position of the file. This will range between zero and the number of - ** bytes the file contains. - */ - return(pos); -} diff --git a/code/TIBERIANDAWN/RAWFILE.H b/code/TIBERIANDAWN/RAWFILE.H deleted file mode 100644 index c17f35c..0000000 --- a/code/TIBERIANDAWN/RAWFILE.H +++ /dev/null @@ -1,332 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: /CounterStrike/RAWFILE.H 1 3/03/97 10:25a Joe_bostic $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : RAWFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : October 18, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * RawFileClass::File_Name -- Returns with the filename associate with the file object. * - * RawFileClass::RawFileClass -- Default constructor for a file object. * - * RawFileClass::~RawFileClass -- Default deconstructor for a file object. * - * RawFileClass::Is_Open -- Checks to see if the file is open or not. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef RAWFILE_H -#define RAWFILE_H - -#include -#include -#include -#include - -#ifdef WIN32 -#include - -#define NULL_HANDLE INVALID_HANDLE_VALUE -#define HANDLE_TYPE HANDLE -#else -#define NULL_HANDLE -1 -#define HANDLE_TYPE int -#endif - -#include "wwfile.h" - -#ifdef NEVER - /* - ** This is a duplicate of the error numbers. The error handler for the RawFileClass handles - ** these errors. If the error routine is overridden and additional errors are defined, then - ** use numbers starting with 100. Note that these errors here are listed in numerical order. - ** These errors are defined in the standard header file "ERRNO.H". - */ - EZERO, // Non-error. - EINVFNC, // Invalid function number. - ENOFILE, // File not found. - ENOENT=ENOFILE, // No such file or directory. - ENOPATH, // Path not found. - EMFILE, // Too many open files. - EACCES, // Permission denied. - EBADF, // Bad file number. - ECONTR, // Memory blocks destroyed. - ENOMEM, // Not enough core memory. - EINVMEM, // Invalid memory block address. - EINVENV, // Invalid environment. - EINVFMT, // Invalid format. - EINVACC, // Invalid access code. - EINVDAT, // Invalid data. - EFAULT, // Unknown error. - EINVDRV, // Invalid drive specified. - ENODEV=EINVDRV, // No such device. - ECURDIR, // Attempt to remove CurDir. - ENOTSAM, // Not same device. - ENMFILE, // No more files. - EINVAL, // Invalid argument. - E2BIG, // Argument list too long. - ENOEXEC, // exec format error. - EXDEV, // Cross-device link. - ENFILE, // Too many open files. - ECHILD, // No child process. - ENOTTY, // not used - ETXTBSY, // not used - EFBIG, // not used - ENOSPC, // No space left on device. - ESPIPE, // Illegal seek. - EROFS, // Read-only file system. - EMLINK, // not used - EPIPE, // Broken pipe. - EDOM, // Math argument. - ERANGE, // Result too large. - EEXIST, // File already exists. - EDEADLOCK, // Locking violation. - EPERM, // Operation not permitted. - ESRCH, // not used - EINTR, // Interrupted function call. - EIO, // Input/output error. - ENXIO, // No such device or address. - EAGAIN, // Resource temporarily unavailable. - ENOTBLK, // not used - EBUSY, // Resource busy. - ENOTDIR, // not used - EISDIR, // not used - EUCLEAN, // not used -#endif - -#ifndef WWERROR -#define WWERROR -1 -#endif - -/* -** This is the definition of the raw file class. It is derived from the abstract base FileClass -** and handles the interface to the low level DOS routines. This is the first class in the -** chain of derived file classes that actually performs a useful function. With this class, -** I/O is possible. More sophisticated features, such as packed files, CD-ROM support, -** file caching, and XMS/EMS memory support, are handled by derived classes. -** -** Of particular importance is the need to override the error routine if more sophisticated -** error handling is required. This is more than likely if greater functionality is derived -** from this base class. -*/ -class RawFileClass : public FileClass -{ - public: - - /* - ** This is a record of the access rights used to open the file. These rights are - ** used if the file object is duplicated. - */ - int Rights; - - RawFileClass(char const *filename); - RawFileClass(void); - RawFileClass (RawFileClass const & f); - RawFileClass & operator = (RawFileClass const & f); - virtual ~RawFileClass(void); - - virtual char const * File_Name(void) const; - virtual char const * Set_Name(char const *filename); - virtual int Create(void); - virtual int Delete(void); - virtual int Is_Available(int forced=false); - virtual int Is_Open(void) const; - virtual int Open(char const *filename, int rights=READ); - virtual int Open(int rights=READ); - virtual long Read(void *buffer, long size); - virtual long Seek(long pos, int dir=SEEK_CUR); - virtual long Size(void); - virtual long Write(void const *buffer, long size); - virtual void Close(void); - virtual unsigned long Get_Date_Time(void); - virtual bool Set_Date_Time(unsigned long datetime); - virtual void Error(int error, int canretry = false, char const * filename=NULL); - - void Bias(int start, int length=-1); - - HANDLE_TYPE Get_File_Handle(void) { return (Handle); }; - - /* - ** These bias values enable a sub-portion of a file to appear as if it - ** were the whole file. This comes in very handy for multi-part files such as - ** mixfiles. - */ - int BiasStart; - int BiasLength; - - protected: - - /* - ** This function returns the largest size a low level DOS read or write may - ** perform. Larger file transfers are performed in chunks of this size or less. - */ - long Transfer_Block_Size(void) {return (long)((unsigned)UINT_MAX)-16L;}; - - long Raw_Seek(long pos, int dir=SEEK_CUR); - - private: - - /* - ** This is the low level DOS handle. A -1 indicates an empty condition. - */ - HANDLE_TYPE Handle; - - /* - ** This points to the filename as a NULL terminated string. It may point to either a - ** constant or an allocated string as indicated by the "Allocated" flag. - */ - const char *Filename; - - // - // file date and time are in the following formats: - // - // date bits 0-4 day (0-31) - // bits 5-8 month (1-12) - // bits 9-15 year (0-119 representing 1980-2099) - // - // time bits 0-4 second/2 (0-29) - // bits 5-10 minutes (0-59) - // bits 11-15 hours (0-23) - // - unsigned short Date; - unsigned short Time; - - /* - ** Filenames that were assigned as part of the construction process - ** are not allocated. It is assumed that the filename string is a - ** constant in that case and thus making duplication unnecessary. - ** This value will be non-zero if the filename has be allocated - ** (using strdup()). - */ - unsigned Allocated:1; -}; - - -/*********************************************************************************************** - * RawFileClass::File_Name -- Returns with the filename associate with the file object. * - * * - * Use this routine to determine what filename is associated with this file object. If no * - * filename has yet been assigned, then this routing will return NULL. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the file name associated with this file object or NULL * - * if one doesn't exist. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline char const * RawFileClass::File_Name(void) const -{ - return(Filename); -} - - -/*********************************************************************************************** - * RawFileClass::RawFileClass -- Default constructor for a file object. * - * * - * This constructs a null file object. A null file object has no file handle or filename * - * associated with it. In order to use a file object created in this fashion it must be * - * assigned a name and then opened. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline RawFileClass::RawFileClass(void) : - Rights(READ), - BiasStart(0), - BiasLength(-1), - #ifdef WIN32 - Handle(INVALID_HANDLE_VALUE), - #else - Handle(-1), - #endif - Filename(0), - Date(0), - Time(0), - Allocated(false) -{ -} - - -/*********************************************************************************************** - * RawFileClass::~RawFileClass -- Default deconstructor for a file object. * - * * - * This constructs a null file object. A null file object has no file handle or filename * - * associated with it. In order to use a file object created in this fashion it must be * - * assigned a name and then opened. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline RawFileClass::~RawFileClass(void) -{ - Close(); - if (Allocated && Filename) { - free((char *)Filename); - ((char *&)Filename) = 0; - Allocated = false; - } -} - - -/*********************************************************************************************** - * RawFileClass::Is_Open -- Checks to see if the file is open or not. * - * * - * Use this routine to determine if the file is open. It returns true if it is. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the file open? * - * * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline int RawFileClass::Is_Open(void) const -{ -#ifdef WIN32 - return(Handle != INVALID_HANDLE_VALUE); -#else - return (Handle >= 0); -#endif -} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/REAL.H b/code/TIBERIANDAWN/REAL.H deleted file mode 100644 index 39265bf..0000000 --- a/code/TIBERIANDAWN/REAL.H +++ /dev/null @@ -1,911 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\function.h_v 2.21 16 Oct 1995 16:46:44 JOE_BOSTIC $*/ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : FUNCTION.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 27, 1994 * - * * - * Last Update : May 27, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FUNCTION_H -#define FUNCTION_H - -#ifdef NEVER -Map (screen) class heirarchy. - - MapeditClass (most derived class) -- scenario editor - ³ - MouseClass -- handles mouse animation and display control - ³ - ScrollClass -- map scroll handler - ³ - HelpClass -- pop-up help text handler - ³ - TabClass -- file folder tab screen mode control dispatcher - ³ - SidebarClass -- displays and controls construction list sidebar - ³ - PowerClass -- display power production/consumption bargraph - ³ - RadarClass -- displays and controls radar map - ³ - DisplayClass -- general tactical map display handler - ³ - MapClass -- general tactical map data handler - ³ - GScreenClass (pure virtual base class) -- generic screen control - - AbstractClass - ³ - ³ - ³ - ³ - ObjectClass - ³ - ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄ¿ - AnimClass ³ TemplateClass ³ ÃÄ FuseClass ³ TerrainClass - ³ ³ ÃÄ FlyClass ³ - ³ ³ BulletClass ³ - OverlayClass MissionClass SmudgeClass - ³ - RadioClass - ³ - ÃÄ CrewClass - ÃÄ FlasherClass - ÃÄ StageClass - ÃÄ CargoClass - TechnoClass - ³ - ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - FootClass BuildingClass - ³ - ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - DriveClass InfantryClass ÃÄ FlyClass - ³ AircraftClass - TurretClass - ³ - TarComClass - ³ - UnitClass - - - AbstractTypeClass - ³ - ObjectTypeClass - ³ - ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - ³ ³ ³ ³ - TechnoTypeClass ³ ³ ³ - ³ BulletTypeClass ³ ³ - ³ TemplateTypeClass ³ - ÚÄÄÄÄÄÄÄÄÁÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ TerrainTypeClass - ³ ³ ³ ³ -UnitTypeClass ³ BuildingTypeClass ³ - ³ InfantryTypeClass - AircraftTypeClass -#endif - -/* -** The "bool" integral type was defined by the C++ comittee in -** November of '94. Until the compiler supports this, use the following -** definition. -*/ -enum {false=0,true=1}; -typedef int bool; - - - -#define _WIN32 -#define WIN32 //_LEAN_AND_MEAN -#include - - -/********************************************************************** -** If the following define is enabled, then the memory checking code -** will be disabled. -*/ -#define NOMEMCHECK - -#include "watcom.h" -#define FILE_H -#define WWMEM_H -#include "compat.h" -#include -#include "jshell.h" - -#ifdef -#undef -#endif -#ifdef _pascal -#undef _pascal -#endif -#ifdef pascal -#undef pascal -#endif - -#define pascal -#define _pascal -#define - - - - -// Should be part of WWLIB.H. This is used in JSHELL.CPP. -typedef struct { - unsigned char SourceColor; - unsigned char DestColor; - unsigned char Fading; - unsigned char reserved; -} TLucentType; - - -// Don't complain if these headers aren't referenced. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* -** VQ player specific includes. -*/ -#include -#include - -extern bool GameActive; -extern long LParam; - -#include "vector.h" -#include "heap.h" -#include "ccfile.h" -#include "monoc.h" -#include "conquer.h" -//#include "debug.h" -#include "special.h" -#include "defines.h" - - -/* -** Greenleaf specific includes. -*/ -#include -#include - - -extern long Frame; -inline CELL Coord_XCell(COORDINATE coord) {return (CELL)(*(((unsigned char*)&coord)+1));} -inline CELL Coord_YCell(COORDINATE coord) {return (CELL)(*(((unsigned char*)&coord)+3));} -//inline CELL Coord_Cell(COORD coord){return (CELL)(((*(((unsigned short *)&coord)+1) & 0xFF00) >> 2) | *(((unsigned char *)&coord)+1));} -CELL Coord_Cell(COORDINATE coord); -#pragma aux Coord_Cell parm [eax] \ - modify [ebx] \ - value [ax] = \ - "mov ebx,eax" \ - "shr eax,010h" \ - "xor al,al" \ - "shr eax,2" \ - "or al,bh" - - -#include "facing.h" -#include "ftimer.h" -#include "theme.h" -#include "link.h" -#include "gadget.h" -#include "control.h" -#include "toggle.h" -#include "checkbox.h" -#include "shapebtn.h" -#include "textbtn.h" -#include "slider.h" -#include "list.h" -#include "cheklist.h" -#include "colrlist.h" -#include "edit.h" -#include "gauge.h" -#include "msgbox.h" -#include "dial8.h" -#include "txtlabel.h" -#include "super.h" -#include "house.h" -#include "gscreen.h" -#include "map.h" -#include "display.h" -#include "radar.h" -#include "power.h" -#include "sidebar.h" -#include "tab.h" -#include "help.h" -#include "mouse.h" -//#include "mapedit.h" -#include "help.h" -#include "target.h" -#include "theme.h" -#include "team.h" // Team objects. -#include "teamtype.h" // Team type objects. -#include "trigger.h" // Trigger event objects. -#include "mapedit.h" // ??? -#include "abstract.h" -#include "object.h" -#include "mission.h" -#include "door.h" -#include "bullet.h" // Bullet objects. -#include "terrain.h" // Terrain objects. -#include "anim.h" // Animation objects. -#include "template.h" // Icon template objects. -#include "overlay.h" // Overlay objects. -#include "smudge.h" // Stains on the terrain objects. -#include "aircraft.h" // Aircraft objects. -#include "unit.h" // Ground unit objects. -#include "infantry.h" // Infantry objects. -#include "credits.h" // Credit counter class. -#include "score.h" // Scoring system class. -#include "factory.h" // Production manager class. -#include "intro.h" -#include "ending.h" -#include "logic.h" -#include "queue.h" -#include "event.h" -#include "base.h" // defines the AI's pre-built base -#include "ipxmgr.h" -#include "combuf.h" -#include "connect.h" -#include "connmgr.h" -#include "noseqcon.h" -#include "msglist.h" -#include "nullconn.h" -#include "nullmgr.h" -#include "phone.h" -#include "loaddlg.h" -#include "ipxaddr.h" - -/**************************************************************************** -** This is a "node", used for the lists of available games & players. The -** 'Game' structure is used for games; the 'Player' structure for players. -*/ -typedef struct NodeNameTag { - char Name[MPLAYER_NAME_MAX]; - IPXAddressClass Address; - union { - struct { - int Version; - unsigned char IsOpen; - unsigned long LastTime; - } Game; - struct { - HousesType House; - unsigned char Color; - } Player; - }; -} NodeNameType; - - -#include "externs.h" - - -extern int Get_CD_Drive(void); -extern void Fatal(char const *message, ...); - - -/* -** ANIM.CPP -*/ -void Shorten_Attached_Anims(ObjectClass * obj); - -/* -** AUDIO.CPP -*/ -int Sound_Effect(VocType voc, VolType volume, int variation=1, signed short panvalue=0); -void Speak(VoxType voice); -void Speak_AI(void); -void Stop_Speaking(void); -void Sound_Effect(VocType voc, COORDINATE coord=NULL, int variation=1); -bool Is_Speaking(void); - -/* -** COMBAT.CPP -*/ -int Modify_Damage(int damage, WarheadType warhead, ArmorType armor, int distance); -void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass * source, WarheadType warhead); - -/* -** CONQUER.CPP -*/ -void Center_About_Objects(void); -bool Force_CD_Available(int cd); -void Handle_View(int view, int action=0); -void Handle_Team(int team, int action=0); -TechnoTypeClass const * Fetch_Techno_Type(RTTIType type, int id); -char const * Fading_Table_Name(char const * base, TheaterType theater); -void Unselect_All(void); -void Play_Movie(char const * name, ThemeType theme=THEME_NONE, bool clrscrn=true); -bool Main_Loop(); -TheaterType Theater_From_Name(char const *name); -//DirType Rotation_Calc(DirType current, DirType desired, int rate); -void Main_Game(int argc, char *argv[]); -long VQ_Call_Back(unsigned char * buffer=NULL, long frame=0); -void Call_Back(void); -char const *Language_Name(char const *basename); -SourceType Source_From_Name(char const *name); -char const *Name_From_Source(SourceType source); -FacingType KN_To_Facing(int input); -void const *Get_Radar_Icon(void const *shapefile, int shapenum, int frames, int zoomfactor); -void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata=0, void const * ghostdata=0); -void Go_Editor(bool flag); -long MixFileHandler(VQAHandle *vqa, long action, void *buffer, long nbytes); - -char *CC_Get_Shape_Filename(void const *shapeptr ); -void CC_Add_Shape_To_Global(void const *shapeptr, char *filename, char code ); - -void Bubba_Print(char *format,...); - -void Heap_Dump_Check( char *string ); -void Dump_Heap_Pointers( void ); -unsigned long Disk_Space_Available(void); - -void Validate_Error(char *name); -void const * Hires_Retrieve(char *name); -int Get_Resolution_Factor(void); - - -/* -** INTERPAL.CPP -*/ -#define SIZE_OF_PALETTE 256 -extern "C" unsigned char *InterpolationPalette; -extern BOOL InterpolationPaletteChanged; -extern void Interpolate_2X_Scale( GraphicBufferClass *source, GraphicBufferClass *dest ,char const *palette_file_name); -void Read_Interpolation_Palette (char const *palette_file_name); -void Write_Interpolation_Palette (char const *palette_file_name); -void Increase_Palette_Luminance(unsigned char *InterpolationPalette , int RedPercentage ,int GreenPercentage ,int BluePercentage ,int cap); -extern "C"{ - extern unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE]; - extern unsigned char *InterpolationPalette; - void __cdecl Asm_Create_Palette_Interpolation_Table(void); -} - - -/* -** COORD.CPP -*/ -void Move_Point(short &x, short &y, register DirType dir, unsigned short distance); -COORDINATE Adjacent_Cell(COORDINATE coord, FacingType dir); -COORDINATE Coord_Move(COORDINATE start, DirType facing, unsigned short distance); -COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock=false); -DirType Direction(CELL cell1, CELL cell2); -DirType Direction(COORDINATE coord1, COORDINATE coord2); -DirType Direction256(COORDINATE coord1, COORDINATE coord2); -DirType Direction8(COORDINATE coord1, COORDINATE coord2); -int Distance(CELL coord1, CELL coord2); -int Distance(COORDINATE coord1, COORDINATE coord2); -short const * Coord_Spillage_List(COORDINATE coord, int maxsize); -//void Move_Point(unsigned short &x, unsigned short &y, DirType dir, unsigned short distance); - -/* -** COORDA.CPP -*/ -//extern "C" { -//unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal); -//unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed); -//} - -/* -** DEBUG.CPP -*/ -void Log_Event(char const *text, ...); -void Debug_Key(unsigned input); -void Self_Regulate(void); - -/* -** DIALOG.CPP -*/ -int Format_Window_String(char * string, int maxlinelen, int & width, int & height); -extern void Dialog_Box(int x, int y, int w, int h); -void Conquer_Clip_Text_Print(char const *, unsigned x, unsigned y, unsigned fore, unsigned back=(unsigned)TBLACK, TextPrintType flag=TPF_8POINT|TPF_DROPSHADOW, unsigned width=-1, int const * tabs=0); -void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled); -int __cdecl Dialog_Message(char *errormsg, ...); -void Window_Box(WindowNumberType window, BoxStyleEnum style); -void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...); -void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...); -void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag); - -/* -** DISPLAY.CPP -*/ - -/* -** ENDING.CPP -*/ -void GDI_Ending(void); -void Nod_Ending(void); - -/* -** EXPAND.CPP -*/ -bool Expansion_Present(void); -bool Expansion_Dialog(void); - -/* -** FINDPATH.CPP -*/ -//PathType * Find_Path(CELL source, CELL dest, FacingType *final_moves, int maxlen, int (*callback)(CELL, FacingType), int threshhold); -int Optimize_Moves(PathType *path, int (*callback)(CELL, FacingType), int threshhold); - -/* -** GOPTIONS.CPP -*/ -void Draw_Caption(int text, int x, int y, int w); - -/* -** INI.CPP -*/ -void Set_Scenario_Name(char *buf, int scenario, ScenarioPlayerType player, ScenarioDirType dir = SCEN_DIR_NONE, ScenarioVarType var = SCEN_VAR_NONE); -void Write_Scenario_Ini(char *root); -bool Read_Scenario_Ini(char *root, bool fresh=true); -int Scan_Place_Object(ObjectClass *obj, CELL cell); - -//10/28/2019 JAS - Need ability to read scenarios in any directory -bool Read_Scenario_Ini_File(char *scenario_file_name, char* bin_file_name, const char* root, bool fresh); - -//10/14/2019 JAS - Need ability to read the movies out of each scenario file. -bool Read_Movies_From_Scenario_Ini(char *root, bool fresh = true); - -/* -** INIT.CPP -*/ -void Uninit_Game(void); -long Obfuscate(char const * string); -void Anim_Init(void); -bool Init_Game(int argc, char *argv[]); -bool Select_Game(bool fade = false); -bool Parse_Command_Line(int argc, char *argv[]); -void Parse_INI_File(void); -int Version_Number(void); -void Save_Recording_Values(void); -void Load_Recording_Values(void); - -/* -** JSHELL.CPP -*/ -void * Small_Icon(void const * iconptr, int iconnum); -void Set_Window(int window, int x, int y, int w, int h); -void * Load_Alloc_Data(FileClass &file); -long Load_Uncompress(FileClass &file, BuffType &uncomp_buff, BuffType &dest_buff, void *reserved_data); -long Translucent_Table_Size(int count); -void *Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer); -void *Conquer_Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer); - -/* -** KEYFBUFF.ASM -*/ -#ifdef __cplusplus -extern "C" { -#endif -long __cdecl Buffer_Frame_To_Page(int x, int y, int w, int h, void *Buffer, GraphicViewPortClass &view, int flags, ...); -#ifdef __cplusplus -} -#endif - -/* -** KEYFRAME.CPP -*/ -int Get_Last_Frame_Length(void); -unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr); -unsigned short Get_Build_Frame_Count(void const *dataptr); -unsigned short Get_Build_Frame_X(void const *dataptr); -unsigned short Get_Build_Frame_Y(void const *dataptr); -unsigned short Get_Build_Frame_Width(void const *dataptr); -unsigned short Get_Build_Frame_Height(void const *dataptr); -bool Get_Build_Frame_Palette(void const *dataptr, void *palette); - -/* -** MAP.CPP -*/ -int Terrain_Cost(CELL cell, FacingType facing); -int Coord_Spillage_Number(COORDINATE coord, int maxsize); - -/* -** MENUS.CPP -*/ -void Setup_Menu(int menu, char const *text[], unsigned long field, int index, int skip); -int Check_Menu(int menu, char const *text[], char *selection, long field, int index); -int Do_Menu(char const **strings, bool blue); -extern int UnknownKey; -int Main_Menu(unsigned long timeout); - -/* -** MPLAYER.CPP -*/ -GameType Select_MPlayer_Game (void); -void Read_MultiPlayer_Settings (void); -void Write_MultiPlayer_Settings (void); -void Read_Scenario_Descriptions (void); -void Free_Scenario_Descriptions(void); -void Computer_Message(void); -int Surrender_Dialog(void); - -/* -** NETDLG.CPP -*/ -bool Init_Network (void); -void Shutdown_Network (void); -bool Remote_Connect (void); -void Destroy_Connection(int id, int error); -bool Process_Global_Packet(GlobalPacketType *packet, IPXAddressClass *address); -unsigned long Compute_Name_CRC(char *name); -void Net_Reconnect_Dialog(int reconn, int fresh, int oldest_index, unsigned long timeval); - -/* -** NULLDLG.CPP -*/ -int Init_Null_Modem( SerialSettingsType *settings ); -void Shutdown_Modem( void ); -void Modem_Signoff( void ); -int Test_Null_Modem( void ); -int Reconnect_Modem( void ); -void Destroy_Null_Connection(int id, int error); -GameType Select_Serial_Dialog( void ); -int Com_Scenario_Dialog(void); -int Com_Show_Scenario_Dialog(void); - -void Smart_Printf( char *format, ... ); -void Hex_Dump_Data( char *buffer, int length ); -void itoh( int i, char *s); - -/* -** PROFILE.CPP -*/ -int WWGetPrivateProfileInt(char const *section, char const *entry, int def, char *profile); -bool WWWritePrivateProfileInt(char const *section, char const *entry, int value, char *profile); -bool WWWritePrivateProfileString(char const *section, char const *entry, char const *string, char *profile); -char * WWGetPrivateProfileString(char const *section, char const *entry, char const *def, char *retbuffer, int retlen, char *profile); -unsigned WWGetPrivateProfileHex (char const *section, char const *entry, char *profile); - -/* -** QUEUE.CPP -*/ -bool Queue_Target(TARGET whom, TARGET target); -bool Queue_Destination(TARGET whom, TARGET target); -bool Queue_Mission(TARGET whom, MissionType mission); -bool Queue_Mission(TARGET whom, MissionType mission, TARGET target, TARGET destination); -bool Queue_Options(void); -bool Queue_Exit(void); -void Queue_AI(void); -void Add_CRC(unsigned long *crc, unsigned long val); - -/* -** RAND.CPP -*/ -int Sim_IRandom(int minval, int maxval); -int Sim_Random(void); - -/* -** REINF.CPP -*/ -bool Do_Reinforcements(TeamTypeClass *team); -bool Create_Special_Reinforcement(HouseClass * house, TechnoTypeClass const * type, TechnoTypeClass const * another, TeamMissionType mission = TMISSION_NONE, int argument =0); -int Create_Air_Reinforcement(HouseClass *house, AircraftType air, int number, MissionType mission, TARGET tarcom, TARGET navcom); - -/* -** SAVELOAD.CPP -*/ -bool Load_Misc_Values(FileClass &file); -bool Save_Misc_Values(FileClass &file); -bool Get_Savefile_Info(int id, char *buf, unsigned *scenp, HousesType *housep); -bool Load_Game(int id); -bool Read_Object (void *ptr, int base_size, int class_size, FileClass & file, void * vtable); -bool Save_Game(int id,char *descr); -bool Write_Object (void *ptr, int class_size, FileClass & file); -TARGET TechnoType_To_Target(TechnoTypeClass const * ptr); -TechnoTypeClass const * Target_To_TechnoType(TARGET target); -void * Get_VTable(void *ptr, int base_size); -void Code_All_Pointers(void); -void Decode_All_Pointers(void); -void Dump(void); -void Set_VTable(void *ptr, int base_size, void *vtable); - -/* -** SCENARIO.CPP -*/ -bool End_Game(void); -bool Read_Scenario(char *root); -bool Start_Scenario(char *root, bool briefing=true); -HousesType Select_House(void); -void Clear_Scenario(void); -void Do_Briefing(char const * text); -void Do_Lose(void); -void Do_Win(void); -void Do_Restart(void); -void Fill_In_Data(void); -bool Restate_Mission(char const * name, int button1, int button2); - -/* -** SCORE.CPP -*/ -void Map_Selection(void); -void Bit_It_In_Scale(int x, int y, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest, GraphicBufferClass *seen , int delay=0, int dagger=0); -void Bit_It_In(int x, int y, int w, int h, GraphicBufferClass *src, GraphicBufferClass *dest, int delay=0, int dagger=0); -void Call_Back_Delay(int time); -int Alloc_Object(ScoreAnimClass *obj); -extern GraphicBufferClass *PseudoSeenBuff; - -void Window_Dialog_Box(HANDLE hinst, LPCTSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc); - -/* -** SPECIAL.CPP -*/ -void Special_Dialog(void); - -/* -** SUPPORT.ASM -*/ -#ifdef __cplusplus -extern "C" { -#endif -void __cdecl Remove_From_List(void **list, int *index, void * ptr); -void * __cdecl Conquer_Build_Fading_Table(void const *palette, void *dest, int color, int frac); -void __cdecl Fat_Put_Pixel(int x, int y, int color, int size, GraphicViewPortClass &); -void __cdecl strtrim(char *buffer); -long __cdecl Get_EAX( void ); -#ifdef __cplusplus -} -#endif - -/* -** TARCOM.CPP -*/ - -/* -** TARGET.CPP -*/ -COORDINATE As_Movement_Coord(TARGET target); -AircraftClass * As_Aircraft(TARGET target); -AnimClass * As_Animation(TARGET target); -BuildingClass * As_Building(TARGET target); -BulletClass * As_Bullet(TARGET target); -CELL As_Cell(TARGET target); -COORDINATE As_Coord(TARGET target); -InfantryClass * As_Infantry(TARGET target); -TeamClass * As_Team(TARGET target); -TeamTypeClass * As_TeamType(TARGET target); -TechnoClass * As_Techno(TARGET target); -//TerrainClass * As_Terrain(TARGET target); -TriggerClass * As_Trigger(TARGET target); -UnitClass * As_Unit(TARGET target); -bool Target_Legal(TARGET target); -ObjectClass * As_Object(TARGET target); - -/* -** ULOGIC.CPP -*/ -int Terrain_Cost(CELL cell, FacingType facing); - -/* -** Inline miscellaneous functions. -*/ -#define XYP_COORD(x,y) (((x)*ICON_LEPTON_W)/CELL_PIXEL_W + ((((y)*ICON_LEPTON_H)/CELL_PIXEL_H)<<16)) -inline FacingType Dir_Facing(DirType facing) {return (FacingType)(((unsigned char)(facing+0x10)&0xFF)>>5);} -inline DirType Facing_Dir(FacingType facing) {return (DirType)((int)facing << 5);} -inline int Cell_To_Lepton(int cell) {return cell<<8;} -inline int Lepton_To_Cell(int lepton) {return ((unsigned)(lepton + 0x0080))>>8;} -inline CELL XY_Cell(int x, int y) {return ((CELL)(((y)<<6)|(x)));} -inline COORDINATE XY_Coord(int x, int y) {return ((COORDINATE)MAKE_LONG(y, x));} -inline int Coord_X(COORDINATE coord) {return (short)(LOW_WORD(coord));} -inline int Coord_Y(COORDINATE coord) {return (short)(HIGH_WORD(coord));} -inline int Cell_X(CELL cell) {return (int)(((unsigned)cell) & 0x3F);} -inline int Cell_Y(CELL cell) {return (int)(((unsigned)cell) >> 6);} -inline int Dir_Diff(DirType dir1, DirType dir2) {return (int)(*((signed char*)&dir2) - *((signed char*)&dir1));} -inline CELL Coord_XLepton(COORDINATE coord) {return (CELL)(*((unsigned char*)&coord));} -inline CELL Coord_YLepton(COORDINATE coord) {return (CELL)(*(((unsigned char*)&coord)+2));} -//inline COORD CellXY_Coord(unsigned x, unsigned y) {return (COORD)(MAKE_LONG(y<<8, x<<8));} -inline COORDINATE Coord_Add(COORDINATE coord1, COORDINATE coord2) {return (COORDINATE)MAKE_LONG((*((short*)(&coord1)+1) + *((short*)(&coord2)+1)), (*((short*)(&coord1)) + *((short*)(&coord2))));} -inline COORDINATE Coord_Sub(COORDINATE coord1, COORDINATE coord2) {return (COORDINATE)MAKE_LONG((*((short*)(&coord1)+1) - *((short*)(&coord2)+1)), (*((short*)(&coord1)) - *((short*)(&coord2))));} -inline COORDINATE Coord_Snap(COORDINATE coord) {return (COORDINATE)MAKE_LONG((((*(((unsigned short *)&coord)+1))&0xFF00)|0x80), (((*((unsigned short *)&coord))&0xFF00)|0x80));} -inline COORDINATE Coord_Mid(COORDINATE coord1, COORDINATE coord2) {return (COORDINATE)MAKE_LONG((*((unsigned short *)(&coord1)+1) + *((unsigned short *)(&coord2)+1))>>1, (*((unsigned short *)(&coord1)) + *((unsigned short *)(&coord2)))>>1);} -inline COORDINATE Cell_Coord(CELL cell) {return (COORDINATE) MAKE_LONG( (((cell & 0x0FC0)<<2)|0x80), ((((cell & 0x003F)<<1)+1)<<7) );} -inline COORDINATE XYPixel_Coord(int x, int y) {return ((COORDINATE)MAKE_LONG((int)(((long)y*(long)ICON_LEPTON_H)/(long)ICON_PIXEL_H)/*+LEPTON_OFFSET_Y*/, (int)(((long)x*(long)ICON_LEPTON_W)/(long)ICON_PIXEL_W)/*+LEPTON_OFFSET_X*/));} -//inline int Facing_To_16(int facing) {return Facing16[facing];} -inline int Facing_To_32(DirType facing) {return Facing32[facing];} -inline DirType Direction256(COORDINATE coord1, COORDINATE coord2) {return ((DirType)Desired_Facing256(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -inline DirType Direction(COORDINATE coord1, COORDINATE coord2) {return ((DirType)Desired_Facing256(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -inline DirType Direction8(COORDINATE coord1, COORDINATE coord2) {return ((DirType)Desired_Facing8(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -//inline int Direction16(COORDINATE coord1, COORD coord2) {return (Desired_Facing16(Coord_X(coord1), Coord_Y(coord1), Coord_X(coord2), Coord_Y(coord2)));} -inline DirType Direction(CELL cell1, CELL cell2) {return (DirType)(Desired_Facing8(Cell_X(cell1), Cell_Y(cell1), Cell_X(cell2), Cell_Y(cell2)));} -inline COORDINATE Adjacent_Cell(COORDINATE coord, FacingType dir) {return (Coord_Snap(Coord_Add(AdjacentCoord[dir & 0x07], coord)));} -inline COORDINATE Adjacent_Cell(COORDINATE coord, DirType dir) {return Adjacent_Cell(coord, Dir_Facing(dir));} -inline CELL Adjacent_Cell(CELL cell, FacingType dir) {return (CELL)(cell + AdjacentCell[dir]);} -inline CELL Adjacent_Cell(CELL cell, DirType dir) {return (CELL)(cell + AdjacentCell[Dir_Facing(dir)]);} -inline int Lepton_To_Pixel(int lepton) {return ((lepton * ICON_PIXEL_W) + (ICON_LEPTON_W / 2)) / ICON_LEPTON_W;} -inline int Pixel_To_Lepton(int pixel) {return ((pixel * ICON_LEPTON_W) + (ICON_PIXEL_W / 2)) / ICON_PIXEL_W;} -//inline FacingType Facing_To_8(DirType facing) {return (FacingType)(((unsigned char)(facing|0x10))>>5);} -inline COORDINATE XYP_Coord(int x,int y) {return XY_Coord(Pixel_To_Lepton(x), Pixel_To_Lepton(y));}; -inline char const * Text_String(int string) {return(Extract_String(SystemStrings, string));}; - - -template inline T Random_Pick(T a, T b) -{ - return (T)IRandom((int)a, (int)b); -}; - -template inline T Sim_Random_Pick(T a, T b) -{ - return (T)Sim_IRandom((int)a, (int)b); -}; - - -#ifdef CHEAT_KEYS -#define Check_Ptr(ptr,file,line) \ -{ \ - if (!ptr) { \ - Mono_Clear_Screen(); \ - Mono_Printf("NULL Pointer, Module:%s, line:%d!\n",file,line); \ - Prog_End(); \ - exit(EXIT_SUCCESS); \ - } \ -} -#else -#define Check_Ptr(ptr,file,line) -#endif - -/* -** These routines are for coding & decoding multiplayer ID's -*/ -inline PlayerColorType MPlayerID_To_ColorIndex(unsigned short id) {return (PlayerColorType)(id >> 4);} -inline HousesType MPlayerID_To_HousesType(unsigned short id) {return ((HousesType)(id & 0x000f)); } -inline unsigned short Build_MPlayerID(int c_idx, HousesType htype) { return ((c_idx << 4) | htype); } - - - - -// -// True if we are the currently in focus windows app -// -extern bool GameInFocus; - -extern int ScreenWidth; -extern int ScreenHeight; -extern "C" void ModeX_Blit (GraphicBufferClass *source); -extern void Colour_Debug (int call_number); - - -extern unsigned char *InterpolatedPalettes[50]; -extern BOOL PalettesRead; -extern unsigned PaletteCounter; - -extern "C"{ - extern unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE]; - extern unsigned char *InterpolationPalette; -} - -extern void Free_Interpolated_Palettes(void); -extern int Load_Interpolated_Palettes(char const *filename, BOOL add=FALSE); - - -#define CELL_BLIT_ONLY 1 -#define CELL_DRAW_ONLY 2 - -/*********************************************************************************************** - * Distance -- Determines the lepton distance between two coordinates. * - * * - * This routine is used to determine the distance between two coordinates. It uses the * - * Dragon Strike method of distance determination and thus it is very fast. * - * * - * INPUT: coord1 -- First coordinate. * - * * - * coord2 -- Second coordinate. * - * * - * OUTPUT: Returns the lepton distance between the two coordinates. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -inline int Distance(COORDINATE coord1, COORDINATE coord2) -{ - int diff1, diff2; - - diff1 = Coord_Y(coord1) - Coord_Y(coord2); - if (diff1 < 0) diff1 = -diff1; - diff2 = Coord_X(coord1) - Coord_X(coord2); - if (diff2 < 0) diff2 = -diff2; - if (diff1 > diff2) { - return(diff1 + (diff2>>1)); - } - return(diff2 + (diff1>>1)); -} - - - -/*********************************************************************************************** - * Distance -- Determines the cell distance between two cells. * - * * - * Use this routine to determine the distance between the two cells specified. The distance * - * is returned in cells. * - * * - * INPUT: cell1, cell2 -- The two cells to determine the distance between. * - * * - * OUTPUT: Returns with the distance between the two cells in units of cell size. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -inline int Distance(CELL coord1, CELL coord2) -{ - int diff1, diff2; - - diff1 = Cell_Y(coord1) - Cell_Y(coord2); - if (diff1 < 0) diff1 = -diff1; - diff2 = Cell_X(coord1) - Cell_X(coord2); - if (diff2 < 0) diff2 = -diff2; - if (diff1 > diff2) { - return(diff1 + (diff2>>1)); - } - return(diff2 + (diff1>>1)); -} - - -/*********************************************************************************************** - * CellClass::Cell_Number -- Returns the cell ID number for this cell object. * - * * - * Call this routine if you wish to determine what the cell number ID is for the currrent * - * cell object. This ID number is the index number into the cell array. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the cell number for this cell object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -inline CELL CellClass::Cell_Number(void) const -{ - return(Map.ID(this)); -} - -#ifndef NOMEMCHECK -#define NO_INTERCEPT -#include "memcheck.h" -#endif - - -void WWDOS_Shutdown(void); - -#endif - diff --git a/code/TIBERIANDAWN/REGION.H b/code/TIBERIANDAWN/REGION.H deleted file mode 100644 index cbcc928..0000000 --- a/code/TIBERIANDAWN/REGION.H +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\region.h_v 2.13 16 Oct 1995 16:45:10 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : REGION.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/09/95 * - * * - * Last Update : March 9, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef REGION_H -#define REGION_H - - -class RegionClass { - public: - RegionClass(void) {Threat = 0;}; - ~RegionClass(void) {}; - int operator != (RegionClass const & region) {return memcmp(this, ®ion, sizeof(RegionClass));}; - int operator == (RegionClass const & region) {return !memcmp(this, ®ion, sizeof(RegionClass));}; - int operator > (RegionClass const & region) {return memcmp(this, ®ion, sizeof(RegionClass)) > 0;}; - int operator < (RegionClass const & region) {return memcmp(this, ®ion, sizeof(RegionClass)) < 0;}; - - void Reset_Threat(void) {Threat = 0;}; - void Adjust_Threat(int threat, int neg) {if (neg) Threat -= threat; else Threat+= threat;}; - int Threat_Value(void) const {return Threat;}; - - protected: - long Threat; -}; - -#endif diff --git a/code/TIBERIANDAWN/REG_ICON.RC b/code/TIBERIANDAWN/REG_ICON.RC deleted file mode 100644 index e8543d8..0000000 --- a/code/TIBERIANDAWN/REG_ICON.RC +++ /dev/null @@ -1,16 +0,0 @@ -/**************************************************************************** - - -REG_ICON.RC - -produced by Borland Resource Workshop - - -*****************************************************************************/ - -#include "reg_icon.rh" - - - -ICON_1 ICON "conquer.ico" - diff --git a/code/TIBERIANDAWN/REINF.CPP b/code/TIBERIANDAWN/REINF.CPP deleted file mode 100644 index 2731582..0000000 --- a/code/TIBERIANDAWN/REINF.CPP +++ /dev/null @@ -1,663 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\reinf.cpv 2.17 16 Oct 1995 16:48:58 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : REINF.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 24, 1994 * - * * - * Last Update : July 4, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Create_Air_Reinforcement -- Creates air strike reinforcement * - * Create_Special_Reinforcement -- Ad hoc reinforcement handler. * - * Do_Reinforcements -- Create and place a reinforcement team. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * Do_Reinforcements -- Create and place a reinforcement team. * - * * - * This routine is called when a reinforcement team must be created and placed on the map. * - * It will create all members of the team and place them at the location determined from * - * the team composition. The reinforcement team should follow team orders until overriden * - * by AI or player intervention. * - * * - * INPUT: teamtype -- Pointer to the team type to create as a reinforcement. * - * * - * OUTPUT: Was the reinforcement successfully created and placed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - * 05/18/1995 JLB : Returns success or failure condition. * - * 06/19/1995 JLB : Announces reinforcements. * - *=============================================================================================*/ -bool Do_Reinforcements(TeamTypeClass *teamtype) -{ - /* - ** preform some preliminary checks for validity. - */ - if (!teamtype || !teamtype->ClassCount) return(false); - - /* - ** Create the controlling team. All the objects are grouped - ** under this team control. If there are no missions for this team - ** then don't actually create the team -- it won't serve a purpose. - */ - TeamClass * team = NULL; - if (teamtype->MissionCount) { - team = new TeamClass(teamtype, HouseClass::As_Pointer(teamtype->House)); - if (!team) return(false); - team->Force_Active(); - } - - /* - ** Determine if this team contains its own transport. In such a case, the - ** transport is used as a loaner. This is only true, if there is other - ** objects to be transport. Without such cargo objects, then the transport - ** is presumed to be the reinforcement itself and thus should not be a - ** loaner. - */ - bool okvoice = true; // Presume ok to announce reinforcement? - bool airtransport = false; // Transport can fly in? - bool watertransport = false; // Transport needs a beach to land at? - bool onlytransport = true; // Just transport is in reinforcement? - bool hastransport = false; // Group comes with transport? - int index; - for (index=0; index < teamtype->ClassCount; index++) { - if (teamtype->Class[index]->IsTransporter || teamtype->Class[index]->What_Am_I() == RTTI_AIRCRAFTTYPE) { - hastransport = true; - if (teamtype->Class[index]->What_Am_I() == RTTI_AIRCRAFTTYPE) { - airtransport = true; - } else { - watertransport = (((UnitTypeClass const *)teamtype->Class[index])->Type == UNIT_HOVER); - } - } else { - onlytransport = false; - } - } - - /* - ** Now determine how the reinforcement should be delivered. This is largely determined - ** by whether there is a transport with the reinforcements. - */ - SourceType source = SOURCE_NONE; - if (airtransport) { - source = SOURCE_AIR; - } else { - - if (watertransport) { - source = SOURCE_BEACH; - } else { - - /* - ** Special case for the gunboat. It always arrives according to the shipping source. - */ - if (teamtype->Class[0]->What_Am_I() == RTTI_UNITTYPE && ((UnitTypeClass const *)teamtype->Class[0])->Type == UNIT_GUNBOAT) { - source = SOURCE_SHIPPING; - } else { - source = HouseClass::As_Pointer(teamtype->House)->Edge; - } - } - } - - /* - ** If we can't determine where the reinforcement should come from, then delete it - ** and return a failure condition. - */ - if (source == SOURCE_NONE) { - if (team) delete team; - return(false); - } - - /* - ** Now that the official source for the reinforcement has been determined, the - ** objects themselves must be created. - */ - TechnoClass * transport = NULL; - TechnoClass * object = NULL; - for (index = 0; index < teamtype->ClassCount; index++) { - TechnoTypeClass const * tclass = teamtype->Class[index]; - - for (int sub = 0; sub < teamtype->DesiredNum[index]; sub++) { - ScenarioInit++; - FootClass * temp = (FootClass *)tclass->Create_One_Of(HouseClass::As_Pointer(teamtype->House)); - ScenarioInit--; - - if (temp) { - - /* - ** Add the object to the team. This is true even for the transports. The one - ** exception is for the hover lander which never becomes part of the team. - */ - if (team && (temp->What_Am_I() != RTTI_UNIT || *((UnitClass*)temp) != UNIT_HOVER)) { - ScenarioInit++; - team->Add(temp); - ScenarioInit--; - } - - /* - ** Build the list of transporters and passengers. - */ - if (tclass->IsTransporter && (!airtransport || tclass->What_Am_I() == RTTI_AIRCRAFTTYPE)) { - - /* - ** Transports are considered loaners if they are transporting - ** something. They are presumed to only serve as a delivery - ** agent. - */ - if (!onlytransport && temp->What_Am_I() != RTTI_UNIT) { - temp->IsALoaner = true; - } - - /* - ** Link to the list of transports. - */ - temp->Next = transport; - transport = temp; - } else { - - /* - ** A-10s are always considered loaners since the player should - ** never be allowed to control them. - */ - if (temp->What_Am_I() == RTTI_AIRCRAFT && *((AircraftClass *)temp) == AIRCRAFT_A10) { - temp->IsALoaner = true; - } - - /* - ** Link to the list of normal objects. - */ - temp->Next = object; - object = temp; - } - } - } - } - - /* - ** Bail on this reinforcement if no reinforcements could be created. - ** This is probably because the object maximum was reached. - */ - if (!object && !transport) { - if (team) delete team; - return(false); - } - - /* - ** Now it is time to place the objects on the map. If there is a transport, then the - ** transported objects must be placed inside the transport at this time as well. - */ - if (transport) { - if (object) { - - /* - ** For cargo planes that carry reinforcements, don't announce arrival - ** when the transport is created. The announcement will occur when the - ** transport unloads. - */ - if (transport->What_Am_I() == RTTI_AIRCRAFT && *((AircraftClass *)transport) == AIRCRAFT_CARGO) { - okvoice = false; - } - - transport->Attach((FootClass *)object); - } - object = transport; - } - - /* - ** Pick the location where the reinforcements appear and then place - ** them there. - */ - bool placed = false; - CELL cell = 0; - FacingType eface; - switch (source) { - - case SOURCE_SHIPPING: - cell = Map.Calculated_Cell(source, teamtype->House); - object->IsALoaner = true; - if (object->Unlimbo(Cell_Coord(cell), DIR_W)) { - object->Assign_Mission(MISSION_GUARD); - object->Assign_Destination(::As_Target(XY_Cell(Map.MapCellX-1, Cell_Y(Coord_Cell(object->Coord)) ))); - } else { - if (team) delete team; - delete object; - return(false); - } - break; - - case SOURCE_NORTH: - case SOURCE_SOUTH: - case SOURCE_EAST: - case SOURCE_WEST: { - eface = (FacingType)(source << 1); // Facing to enter map. - - if (airtransport) ScenarioInit++; - cell = Map.Calculated_Cell(source, teamtype->House); - if (airtransport) ScenarioInit--; - CELL newcell = cell; - - FootClass * o = (FootClass *)object->Next; - object->Next = 0; - bool ok = true; - while (newcell > 0 && object) { - DirType desiredfacing = Facing_Dir(eface); - if (object->What_Am_I() == RTTI_AIRCRAFT) { - desiredfacing = Random_Pick(DIR_N, DIR_MAX); - } - - if (ok && object->Unlimbo(Cell_Coord(newcell), desiredfacing)) { - - /* - ** If this object is part of a team, then the mission for this - ** object will be guard. The team handler will assign the proper - ** mission that it should follow. - */ - if (object->What_Am_I() == RTTI_AIRCRAFT) { - ok = false; - } else { - if (team) { - object->Assign_Mission(MISSION_GUARD); - } else { - object->Assign_Mission(MISSION_MOVE); - object->Assign_Destination(Adjacent_Cell(newcell, eface)); - } - object->Commence(); - } - - } else { - ok = true; - - /* - ** Could not unlimbo at location specified so find an adjacent location that it can - ** be unlimboed at. If this fails, then abort the whole placement process. - */ - FacingType adj; - for (adj = FACING_N; adj < FACING_COUNT; adj++) { - CELL trycell = Adjacent_Cell(newcell, adj); - if (!Map.In_Radar(trycell) && object->Can_Enter_Cell(trycell, adj) == MOVE_OK) { - newcell = trycell; - break; - } - } - if (adj < FACING_COUNT) continue; - newcell = -1; - } - - object = o; - if (object) { - o = (FootClass *)object->Next; - object->Next = 0; - } - } - - /* - ** If there are still objects that could not be placed, then delete them. - */ - if (o) { - while (o) { - FootClass * old = o; - o = (FootClass *)o->Next; - old->Next = 0; - - delete old; - } - - } - } - break; - - /* - ** Bring out the aircraft as separate "groups" of one. - */ - case SOURCE_AIR: { - AircraftClass * thisone = (AircraftClass *)object; - while (thisone) { - AircraftClass * next = (AircraftClass *)thisone->Next; - - /* - ** Find a suitable map entry location. Cargo planes will try to find a cell that - ** exactly lines up with the airfield they will unload at. - */ - CELL newcell; - ScenarioInit++; - newcell = Map.Calculated_Cell(HouseClass::As_Pointer(teamtype->House)->Edge, teamtype->House); - ScenarioInit--; - if (*thisone == AIRCRAFT_CARGO) { - BuildingClass const * building = thisone->Find_Docking_Bay(STRUCT_AIRSTRIP, false); - if (building) { - newcell = XY_Cell(Map.MapCellX+Map.MapCellWidth, Coord_YCell(building->Docking_Coord()+2)); - } - } - thisone->Next = 0; - - ScenarioInit++; - placed = thisone->Unlimbo(Cell_Coord(newcell), DIR_W); - ScenarioInit--; - if (placed) { - if (!team) { - if (thisone->Class->IsFixedWing) { - thisone->Assign_Mission(MISSION_HUNT); - } else { - if (thisone->Class->IsTransporter && thisone->Is_Something_Attached()) { - thisone->Assign_Mission(MISSION_UNLOAD); - } else { - thisone->Assign_Mission(MISSION_MOVE); - } - thisone->Assign_Destination(::As_Target(Map.Calculated_Cell(source, teamtype->House))); - } - thisone->Commence(); - } - } else { - delete thisone; - } - - thisone = next; - } - if (!placed && team) delete team; - - - /* - ** Fixes bug that can happen if the reinforcement cannot be created. - ** This prevent "phantom" teams and team types from being left around. - */ - if (GameToPlay == GAME_NORMAL && !placed) return(false); - - } - break; - - case SOURCE_OCEAN: - case SOURCE_BEACH: - cell = Map.Calculated_Cell(SOURCE_BEACH, teamtype->House); - if (cell) { - CELL edge = XY_Cell(Cell_X(cell), Map.MapCellY+Map.MapCellHeight); - - placed = object->Unlimbo(Cell_Coord(edge), DIR_N); - if (placed) { - if (!team) { - object->IsLocked = false; - object->Assign_Mission(MISSION_UNLOAD); - object->Commence(); - object->Assign_Destination(::As_Target(cell)); - } - } else { - if (team) delete team; - delete object; - return(false); - } - } - break; - - default: - break; - } - - /* - ** Announce when the reinforcements have arrived. - */ - if (okvoice && teamtype->House == PlayerPtr->Class->House) { - Speak(VOX_REINFORCEMENTS, NULL, cell ? Cell_Coord(cell) : 0); - } - - return(true); -} - - -/*********************************************************************************************** - * Create_Special_Reinforcement -- Ad hoc reinforcement handler. * - * * - * Use this routine to bring on a reinforcement that hasn't been anticipated by the trigger * - * system. An example of this would be replacement harvesters or airfield ordered units. * - * The appropriate transport is created (if necessary) and a mission is assigned such that * - * the object will legally bring itself onto the playing field. * - * * - * INPUT: house -- The owner of this reinforcement. * - * * - * type -- The object to bring on. * - * * - * another -- This is reserved for the transport class in those cases where the * - * transport MUST be forced to a specific type. * - * * - * mission -- The mission to assign this reinforcement team. * - * * - * argument -- Optional team mission argument (usually a waypoint). * - * * - * OUTPUT: Was the special reinforcement created without error? * - * * - * WARNINGS: This routine will fail if a team type cannot be created. * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -bool Create_Special_Reinforcement(HouseClass * house, TechnoTypeClass const * type, TechnoTypeClass const * another, TeamMissionType mission, int argument) -{ - if (house && type) { - TeamTypeClass * team = new TeamTypeClass(); - - if (team) { - - /* - ** If a ground based reinforcement is desired, but the edge of the map that the - ** reinforcement will arrive at is completely covered with water, then add - ** a hover lander for transport. - */ - if (!another && (type->What_Am_I() == RTTI_UNITTYPE || type->What_Am_I() == RTTI_INFANTRYTYPE)) { - - /* - ** Hover lander reinforcements can only arrive from the south. Yes, this is an - ** arbitrary limitation, but that's the way it is (for now). - */ - if (house->Edge == SOURCE_SOUTH) { - bool found = false; - for (int index = Map.MapCellX; index < Map.MapCellX+Map.MapCellWidth-1; index++) { - CELL cell = XY_Cell(index, Map.MapCellY+Map.MapCellHeight); - if (Map[cell].Is_Generally_Clear() && Map[cell-MAP_CELL_W].Is_Generally_Clear()) { - found = true; - break; - } - } - - /* - ** No land route was found for the reinforcement to drive itself onto the - ** map. Assign it a hover lander. This presumes that if the south edge is - ** non drivable, it will have water there instead. Risky, but is not a - ** problem with the current C&C maps. - */ - if (!found) { - mission = TMISSION_NONE; - another = &UnitTypeClass::As_Reference(UNIT_HOVER); - } - } - - if (!another) { - mission = TMISSION_MOVECELL; - argument = Map.Calculated_Cell(SOURCE_AIR, house->Class->House); - } - } - - /* - ** If there is no overridden mission assign to this special reinforcement, then - ** we must assign something. If not, the reinforcement will just sit at the edge - ** of the map. - */ - if (!another && mission == TMISSION_NONE) { - mission = TMISSION_MOVECELL; - argument = Map.Calculated_Cell(SOURCE_AIR, house->Class->House); - } - - /* - ** Fill in the team characteristics. - */ - strcpy((char *)&team->IniName[0], "TEMP"); - team->IsReinforcable = false; - team->IsTransient = true; - team->ClassCount = 1; - team->Class[0] = type; - team->DesiredNum[0] = 1; - team->MissionCount = 1; - if (mission == TMISSION_NONE) { - if (another && (another->What_Am_I() != RTTI_UNITTYPE || ((UnitTypeClass const *)another)->Type != UNIT_HOVER)) { - team->MissionList[0].Mission = TMISSION_UNLOAD; - team->MissionList[0].Argument = WAYPT_REINF; - } - } else { - team->MissionList[0].Mission = mission; - team->MissionList[0].Argument = argument; - } - team->House = house->Class->House; - if (another) { - team->ClassCount++; - team->Class[1] = another; - team->DesiredNum[1] = 1; - } - - bool ok = Do_Reinforcements(team); - if (!ok && GameToPlay == GAME_NORMAL) { - delete team; - } - return(ok); - } - } - return(false); -} - - -/*********************************************************************************************** - * Create_Air_Reinforcement -- Creates air strike reinforcement * - * * - * This routine is used to launch an airstrike. It will create the necessary aircraft and * - * assign them to attack the target specified. This routine bypasses the normal * - * reinforcement logic since it doesn't need the sophistication of unloading and following * - * team mission lists. * - * * - * INPUT: house -- The purpetrator of this air strike. * - * * - * air -- The type of aircraft to make up this airstrike. * - * * - * number -- The number of aircraft in this airstrike. * - * * - * mission -- The mission to assign the aircraft. * - * * - * tarcom -- The target to assign these aircraft. * - * * - * navcom -- The navigation target to assign (if necessary). * - * * - * OUTPUT: Returns the number of aircraft created for this airstrike. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Commented. * - *=============================================================================================*/ -int Create_Air_Reinforcement(HouseClass *house, AircraftType air, int number, MissionType mission, TARGET tarcom, TARGET navcom) -{ - /* - ** Get a pointer to the class of the object that we are going to create. - */ - TechnoTypeClass const * type = (TechnoTypeClass *)&AircraftTypeClass::As_Reference(air); - - /* - ** Loop through the number of objects we are supposed to create and - ** create and place them on the map. - */ - int sub; - for (sub = 0; sub < number; sub++) { - - /* - ** Create one of the required objects. If this fails we could have - ** a real problem. - */ - ScenarioInit++; - TechnoClass * obj = (TechnoClass *)type->Create_One_Of(house); - ScenarioInit--; - if (!obj) return(sub); - - /* - ** Flying objects always have the IsALoaner bit set. - */ - obj->IsALoaner = true; - - /* - ** Find a cell for the object to come in on. This is stolen from the - ** the code that handles a SOURCE_AIR in the normal logic. - */ - SourceType source = house->Edge; - switch (source) { - case SOURCE_NORTH: - case SOURCE_EAST: - case SOURCE_SOUTH: - case SOURCE_WEST: - break; - - default: - source = SOURCE_NORTH; - break; - } - CELL newcell = Map.Calculated_Cell(source, house->Class->House); - - /* - ** Try and place the object onto the map. - */ - ScenarioInit++; - int placed = obj->Unlimbo(Cell_Coord(newcell), DIR_N); - ScenarioInit--; - if (placed) { - - /* - ** If we suceeded in placing the obj onto the map then - ** now we need to give it a mission and destination. - */ - obj->Assign_Mission(mission); - - /* - ** If a navcom was specified then set it. - */ - if (navcom != TARGET_NONE) { - obj->Assign_Destination(navcom); - } - - /* - ** If a tarcom was specified then set it. - */ - if (tarcom != TARGET_NONE) { - obj->Assign_Target(tarcom); - } - - /* - ** Start the object into action. - */ - obj->Commence(); - } else { - delete obj; - sub--; - return(sub); - } - } - return(sub); -} diff --git a/code/TIBERIANDAWN/RESOURCE/TiberianDawn.rc b/code/TIBERIANDAWN/RESOURCE/TiberianDawn.rc deleted file mode 100644 index 0082a2f..0000000 --- a/code/TIBERIANDAWN/RESOURCE/TiberianDawn.rc +++ /dev/null @@ -1,102 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Petroglyph Games Inc." - VALUE "FileDescription", "Command & Conquer(TM) Remastered Collection TiberianDawn DLL" - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "InternalName", "Command & Conquer(TM) Remastered Collection" - VALUE "LegalCopyright", "(C) 2020 Electronic Arts Inc. All rights reserved." - VALUE "OriginalFilename", "TiberianDawn.dll" - VALUE "ProductName", "Command & Conquer(TM) Remastered Collection" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/code/TIBERIANDAWN/RESOURCE/resource.h b/code/TIBERIANDAWN/RESOURCE/resource.h deleted file mode 100644 index 5aa3842..0000000 --- a/code/TIBERIANDAWN/RESOURCE/resource.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by TiberianDawn.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/code/TIBERIANDAWN/RULES.CPP b/code/TIBERIANDAWN/RULES.CPP deleted file mode 100644 index 5da69ef..0000000 --- a/code/TIBERIANDAWN/RULES.CPP +++ /dev/null @@ -1,126 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: /CounterStrike/RULES.CPP 1 3/03/97 10:25a Joe_bostic $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RULES.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 05/12/96 * - * * - * Last Update : September 10, 1996 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * DifficultyClass::DifficultyClass -- Default constructor for difficulty class object. * - * RulesClass::RulesClass -- Default constructor for rules class object. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" - - - /*********************************************************************************************** - * DifficultyClass::DifficultyClass -- Default constructor for difficulty class object. * - * * - * This is the default constructor for the difficulty class object. Although it initializes * - * the rule data with default values, it is expected that they will all be overridden by * - * the rules control file. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/18/2019 SKY : Created. * - *=============================================================================================*/ -DifficultyClass::DifficultyClass(void) : - FirepowerBias(1), - GroundspeedBias(1), - AirspeedBias(1), - ArmorBias(1), - ROFBias(1), - CostBias(1), - BuildSpeedBias(1), - RepairDelay(0.02f), - BuildDelay(0.03f), - IsBuildSlowdown(false), - IsWallDestroyer(true), - IsContentScan(false) -{ -} - - -/*********************************************************************************************** - * RulesClass::RulesClass -- Default constructor for rules class object. * - * * - * This is the default constructor for the rules class object. Although it initializes the * - * rule data with default values, it is expected that they will all be overridden by the * - * rules control file. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/17/1996 JLB : Created. * - *=============================================================================================*/ -RulesClass::RulesClass(void) : - AttackInterval(3), - BaseSizeAdd(3), - PowerSurplus(50), - AttackDelay(5), - PowerEmergencyFraction(0x00C0), - HelipadRatio(0x1E), - HelipadLimit(5), - AARatio(0x0024), - AALimit(10), - DefenseRatio(0x0066), - DefenseLimit(40), - WarRatio(0x0019), - WarLimit(2), - BarracksRatio(0x0028), - BarracksLimit(2), - RefineryLimit(4), - RefineryRatio(0x0028), - AirstripRatio(0x001E), - AirstripLimit(5), - MaxIQ(5), - IQSuperWeapons(4), - IQProduction(5), - IQGuardArea(4), - IQRepairSell(1), - IQCrush(2), - IQScatter(3), - IQContentScan(4), - IQAircraft(4), - IQHarvester(2), - IQSellBack(2), - InfantryReserve(3000), - InfantryBaseMult(1), - IsComputerParanoid(true), - AllowSuperWeapons(true) -{ -} diff --git a/code/TIBERIANDAWN/RULES.H b/code/TIBERIANDAWN/RULES.H deleted file mode 100644 index 3bc424c..0000000 --- a/code/TIBERIANDAWN/RULES.H +++ /dev/null @@ -1,275 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: /CounterStrike/RULES.H 1 3/03/97 10:25a Joe_bostic $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : RULES.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 05/12/96 * - * * - * Last Update : May 12, 1996 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#ifndef RULES_H -#define RULES_H - -class DifficultyClass -{ - public: - DifficultyClass(void); - - float FirepowerBias; - float GroundspeedBias; - float AirspeedBias; - float ArmorBias; - float ROFBias; - float CostBias; - float BuildSpeedBias; - - float RepairDelay; - float BuildDelay; - - unsigned IsBuildSlowdown:1; - unsigned IsWallDestroyer:1; - unsigned IsContentScan:1; -}; - -class RulesClass { - public: - - RulesClass(void); - - /* - ** The computer is limited in the size of the base it can build. It is limited to the - ** size of the largest human opponent base plus this surplus count. - */ - int BaseSizeAdd; - - /* - ** If the power surplus is less than this amount, then the computer will - ** build power plants. - */ - int PowerSurplus; - - /* - ** This specifies the average number of minutes between each computer attack. - */ - int AttackInterval; - - /* - ** This specifies the average minutes delay before the computer will begin - ** its first attack upon the player. The duration is also modified by the - ** difficulty level. - */ - int AttackDelay; - - /* - ** If the power ratio falls below this percentage, then a power emergency is - ** in effect. At such times, the computer might decide to sell off some - ** power hungry buildings in order to alleviate the situation. - */ - unsigned short PowerEmergencyFraction; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of helipads. - */ - unsigned short HelipadRatio; - - /* - ** Limit the number of helipads to this amount. - */ - int HelipadLimit; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of Tesla Coils. - */ - unsigned short TeslaRatio; - - /* - ** Limit tesla coil production to this maximum. - */ - int TeslaLimit; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of anti-aircraft defense. - */ - unsigned short AARatio; - - /* - ** Limit anti-aircraft building quantity to this amount. - */ - int AALimit; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of defensive structures. - */ - unsigned short DefenseRatio; - - /* - ** This is the limit to the number of defensive building that can be built. - */ - int DefenseLimit; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of war factories. - */ - unsigned short WarRatio; - - /* - ** War factories are limited to this quantity for the computer controlled player. - */ - int WarLimit; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of infantry producing structures. - */ - unsigned short BarracksRatio; - - /* - ** No more than this many barracks can be built. - */ - int BarracksLimit; - - /* - ** Refinery building is limited to this many refineries. - */ - int RefineryLimit; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of refineries. - */ - unsigned short RefineryRatio; - - /* - ** This specifies the percentage of the base (by building quantity) that should - ** be composed of airstrips. - */ - unsigned short AirstripRatio; - - /* - ** Limit the number of airstrips to this amount. - */ - int AirstripLimit; - - /* - ** This is the maximum number of IQ settings available. The human player is - ** presumed to be at IQ level zero. - */ - int MaxIQ; - - /* - ** The IQ level at which super weapons will be automatically fired by the computer. - */ - int IQSuperWeapons; - - /* - ** The IQ level at which production is automatically controlled by the computer. - */ - int IQProduction; - - /* - ** The IQ level at which newly produced units start out in guard area mode instead - ** of normal guard mode. - */ - int IQGuardArea; - - /* - ** The IQ level at which the computer will be able to decide what gets repaired - ** or sold. - */ - int IQRepairSell; - - /* - ** At this IQ level or higher, a unit is allowed to automatically try to crush - ** an atagonist if possible. - */ - int IQCrush; - - /* - ** The unit/infantry will try to scatter if an incoming threat - ** is detected. - */ - int IQScatter; - - /* - ** Tech level at which the computer will scan the contents of a transport - ** in order to pick the best target to fire upon. - */ - int IQContentScan; - - /* - ** Aircraft replacement production occurs at this IQ level or higher. - */ - int IQAircraft; - - /* - ** Checks for and replaces lost harvesters. - */ - int IQHarvester; - - /* - ** Is allowed to sell a structure being damaged. - */ - int IQSellBack; - - /* - ** The computer will build infantry if their cash reserve is greater than this amount. - */ - int InfantryReserve; - - /* - ** This factor is multiplied by the number of buildings in the computer's base and infantry - ** are always built until it matches that number. - */ - int InfantryBaseMult; - - /* - ** Is the computer paranoid? If so, then it will band together with other computer - ** paranoid players when the situation looks rough. - */ - bool IsComputerParanoid; - - /* - ** Are superweapons allowed? - */ - bool AllowSuperWeapons; - - /* - ** This array controls the difficulty affects on the game. There is one - ** difficulty class object for each difficulty level. - */ - DifficultyClass Diff[DIFF_COUNT]; -}; - - -#endif diff --git a/code/TIBERIANDAWN/SAVEDLG.H b/code/TIBERIANDAWN/SAVEDLG.H deleted file mode 100644 index b025058..0000000 --- a/code/TIBERIANDAWN/SAVEDLG.H +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\savedlg.h_v 2.14 16 Oct 1995 16:45:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SAVEDLG.H * - * * - * Programmer : Maria del Mar McCready Legg, Joe L. Bostic * - * * - * Start Date : Jan 8, 1995 * - * * - * Last Update : Jan 18, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SAVEDLG_H -#define SAVEDLG_H - -#include "gadget.h" - -class SaveOptionsClass -{ - private: - - enum SaveOptionsClassEnums { - BUTTON_CANCEL=200, - BUTTON_SAVE, - OPTION_WIDTH=216, - OPTION_HEIGHT=122, - OPTION_X=((320 - OPTION_WIDTH) / 2) & ~7, - OPTION_Y=(200 - OPTION_HEIGHT) / 2, - NUMBER_OF_BUTTONS=2, - CAPTION_Y_POS=5, - BORDER1_LEN=49, - BUTTON_CANCEL_X=90, - BUTTON_CANCEL_Y=103, - LISTBOX_X=40, - LISTBOX_Y=24, - LISTBOX_W=136, - LISTBOX_H=72 - }; - - public: - SaveOptionsClass (void) { }; - void Process (void); -}; - - -#endif diff --git a/code/TIBERIANDAWN/SAVELOAD.CPP b/code/TIBERIANDAWN/SAVELOAD.CPP deleted file mode 100644 index 8f477c2..0000000 --- a/code/TIBERIANDAWN/SAVELOAD.CPP +++ /dev/null @@ -1,1616 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\saveload.cpv 2.18 16 Oct 1995 16:48:44 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SAVELOAD.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 23, 1994 * - * * - * Last Update : June 24, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Code_All_Pointers -- Code all pointers. * - * Decode_All_Pointers -- Decodes all pointers. * - * Get_Savefile_Info -- gets description, scenario #, house * - * Load_Game -- loads a saved game * - * Load_Misc_Values -- Loads miscellaneous variables. * - * Load_Misc_Values -- loads miscellaneous variables * - * Read_Object -- reads an object from disk, in a safe way * - * Save_Game -- saves a game to disk * - * Save_Misc_Values -- saves miscellaneous variables * - * Target_To_TechnoType -- converts TARGET to TechnoTypeClass * - * TechnoType_To_Target -- converts TechnoTypeClass to TARGET * - * Write_Object -- reads an object from disk, in a safe way * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -extern bool DLLSave(FileClass &file); -extern bool DLLLoad(FileClass &file); - - -/* -********************************** Defines ********************************** -*/ -#define SAVEGAME_VERSION (DESCRIP_MAX + \ - 0x01000003 + ( \ - sizeof(AircraftClass) + \ - sizeof(AircraftTypeClass) + \ - sizeof(AnimClass) + \ - sizeof(AnimTypeClass) + \ - sizeof(BuildingClass) + \ - sizeof(BuildingTypeClass) + \ - sizeof(BulletClass) + \ - sizeof(BulletTypeClass) + \ - sizeof(HouseClass) + \ - sizeof(HouseTypeClass) + \ - sizeof(InfantryClass) + \ - sizeof(InfantryTypeClass) + \ - sizeof(OverlayClass) + \ - sizeof(OverlayTypeClass) + \ - sizeof(SmudgeClass) + \ - sizeof(SmudgeTypeClass) + \ - sizeof(TeamClass) + \ - sizeof(TeamTypeClass) + \ - sizeof(TemplateClass) + \ - sizeof(TemplateTypeClass) + \ - sizeof(TerrainClass) + \ - sizeof(TerrainTypeClass) + \ - sizeof(UnitClass) + \ - sizeof(UnitTypeClass) + \ - sizeof(MouseClass) + \ - sizeof(CellClass) + \ - sizeof(FactoryClass) + \ - sizeof(BaseClass) + \ - sizeof(LayerClass) + \ - sizeof(BriefingText) + \ - sizeof(Waypoint))) - - -/*************************************************************************** - * Save_Game -- saves a game to disk * - * * - * Saving the Map: * - * DisplayClass::Save() invokes CellClass's Write() for every cell * - * that needs to be saved. A cell needs to be saved if it contains * - * any special data at all, such as a TIcon, or an Occupier. * - * The cell saves its own CellTrigger pointer, converted to a TARGET. * - * * - * Saving game objects: * - * - Any object stored in an ArrayOf class needs to be saved. The ArrayOf* - * Save() routine invokes each object's Write() routine, if that * - * object's IsActive is set. * - * * - * Saving the layers: * - * The Map's Layers (Ground, Air, etc) of things that are on the map, * - * and the Logic's Layer of things to process both need to be saved. * - * LayerClass::Save() writes the entire layer array to disk * - * * - * Saving the houses: * - * Each house needs to be saved, to record its Credits, Power, etc. * - * * - * Saving miscellaneous data: * - * There are a lot of miscellaneous variables to save, such as the * - * map's dimensions, the player's house, etc. * - * * - * INPUT: * - * id numerical ID, for the file extension * - * * - * OUTPUT: * - * true = OK, false = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/28/1994 BR : Created. * - *=========================================================================*/ -bool Save_Game(int id,char *descr) -{ - char name[_MAX_FNAME+_MAX_EXT]; - - /* - ** Generate the filename to save - */ - sprintf(name, "SAVEGAME.%03d", id); - - return Save_Game(name, descr); -} - - -/* -** Version that takes file name. ST - 9/9/2019 11:10AM -*/ -bool Save_Game(const char *file_name, const char *descr) -{ - RawFileClass file; - int i; - unsigned long version; - unsigned scenario; - HousesType house; - char descr_buf[DESCRIP_MAX]; - - scenario = Scenario; // get current scenario # - house = PlayerPtr->Class->House; // get current house - - /* - ** Code everybody's pointers - */ - Code_All_Pointers(); - - /* - ** Open the file - */ - if (!file.Open(file_name, WRITE)) { - Decode_All_Pointers(); - return(false); - } - - /* - ** Save the DLLs variables first, so we can do a version check in the DLL when we begin the load - */ - if (RunningAsDLL) { - if (!DLLSave(file)) { - file.Close(); - Decode_All_Pointers(); - return false; - } - } - - /* - ** Save the description, scenario #, and house - ** (scenario # & house are saved separately from the actual Scenario & - ** PlayerPtr globals for convenience; we can quickly find out which - ** house & scenario this save-game file is for by reading these values. - ** Also, PlayerPtr is stored in a coded form in Save_Misc_Values(), - ** which may or may not be a HousesType number; so, saving 'house' - ** here ensures we can always pull out the house for this file.) - */ - sprintf(descr_buf, "%s\r\n",descr); // put CR-LF after text - descr_buf[strlen(descr_buf) + 1] = 26; // put CTRL-Z after NULL - - if (file.Write(descr_buf, DESCRIP_MAX) != DESCRIP_MAX) { - file.Close(); - return(false); - } - - if (file.Write(&scenario, sizeof(scenario)) != sizeof(scenario)) { - file.Close(); - return(false); - } - - if (file.Write(&house, sizeof(house)) != sizeof(house)) { - file.Close(); - return(false); - } - - /* - ** Save the save-game version, for loading verification - */ - version = SAVEGAME_VERSION; - - if (file.Write(&version, sizeof(version)) != sizeof(version)) { - file.Close(); - return(false); - } - - Call_Back(); - /* - ** Save the map. The map must be saved first, since it saves the Theater. - */ - Map.Save(file); - - Call_Back(); - /* - ** Save all game objects. This code saves every object that's stored in a - ** TFixedIHeap class. - */ - if (!Houses.Save(file) || - !TeamTypes.Save(file) || - !Teams.Save(file) || - !Triggers.Save(file) || - !Aircraft.Save(file) || - !Anims.Save(file) || - !Buildings.Save(file) || - !Bullets.Save(file) || - !Infantry.Save(file) || - !Overlays.Save(file) || - !Smudges.Save(file) || - !Templates.Save(file) || - !Terrains.Save(file) || - !Units.Save(file) || - !Factories.Save(file)) { - file.Close(); - - Decode_All_Pointers(); - - return(false); - } - - Call_Back(); - /* - ** Save the Logic & Map layers - */ - if (!Logic.Save(file)) { - file.Close(); - Decode_All_Pointers(); - return(false); - } - - for (i = 0; i < LAYER_COUNT; i++) { - if (!Map.Layer[i].Save(file)) { - file.Close(); - Decode_All_Pointers(); - return(false); - } - } - - /* - ** Save the Score - */ - if (!Score.Save(file)) { - file.Close(); - Decode_All_Pointers(); - return(false); - } - - /* - ** Save the AI Base - */ - if (!Base.Save(file)) { - file.Close(); - Decode_All_Pointers(); - return(false); - } - - /* - ** Save miscellaneous variables. - */ - if (!Save_Misc_Values(file)) { - file.Close(); - Decode_All_Pointers(); - return(false); - } - - Call_Back(); - - /* - ** Close the file; we're done - */ - file.Close(); - Decode_All_Pointers(); - - return(true); -} - - -/*************************************************************************** - * Load_Game -- loads a saved game * - * * - * This routine loads the data in the same way it was saved out. * - * * - * Loading the Map: * - * - DisplayClass::Load() invokes CellClass's Load() for every cell * - * that was saved. * - * - The cell loads its own CellTrigger pointer. * - * * - * Loading game objects: * - * - IHeap's Load() routine loads the # of objects stored, and loads * - * each object. * - * - Triggers: Add themselves to the HouseTriggers if they're associated * - * with a house * - * * - * Loading the layers: * - * LayerClass::Load() reads the entire layer array to disk * - * * - * Loading the houses: * - * Each house is loaded in its entirety. * - * * - * Loading miscellaneous data: * - * There are a lot of miscellaneous variables to load, such as the * - * map's dimensions, the player's house, etc. * - * * - * INPUT: * - * id numerical ID, for the file extension * - * * - * OUTPUT: * - * true = OK, false = error * - * * - * WARNINGS: * - * If this routine returns false, the entire game will be in an * - * unknown state, so the scenario will have to be re-initialized. * - * * - * HISTORY: * - * 12/28/1994 BR : Created. * - *=========================================================================*/ -bool Load_Game(int id) -{ - char name[_MAX_FNAME+_MAX_EXT]; - - /* - ** Generate the filename to load - */ - sprintf(name, "SAVEGAME.%03d", id); - - return Load_Game(name); -} - -/* -** Version that takes a file name instead. ST - 9/9/2019 11:13AM -*/ -bool Load_Game(const char *file_name) -{ - RawFileClass file; - int i; - unsigned long version; - unsigned scenario; - HousesType house; - char descr_buf[DESCRIP_MAX]; - - /* - ** Open the file - */ - if (!file.Open(file_name, READ)) { - return(false); - } - - /* - ** Load the DLLs variables first, in case we need to do something different based on version - */ - if (RunningAsDLL) { - if (!DLLLoad(file)) { - file.Close(); - return false; - } - } - - /* - ** Read & discard the save-game's header info - */ - if (file.Read(descr_buf, DESCRIP_MAX) != DESCRIP_MAX) { - file.Close(); - return(false); - } - - if (file.Read(&scenario, sizeof(scenario)) != sizeof(scenario)) { - file.Close(); - return(false); - } - - if (file.Read(&house, sizeof(house)) != sizeof(house)) { - file.Close(); - return(false); - } - - Call_Back(); - /* - ** Clear the scenario so we start fresh; this calls the Init_Clear() routine - ** for the Map, and all object arrays. It has the following important - ** effects: - ** - Every cell is cleared to 0's, via MapClass::Init_Clear() - ** - All heap elements' are cleared - ** - The Houses are Initialized, which also clears their HouseTriggers - ** array - ** - The map's Layers & Logic Layer are cleared to empty - ** - The list of currently-selected objects is cleared - */ - Clear_Scenario(); - - /* - ** Read in & verify the save-game ID code - */ - if (file.Read(&version,sizeof(version)) != sizeof(version)) { - file.Close(); - return(false); - } - - if (version != SAVEGAME_VERSION) { - file.Close(); - return(false); - } - - Call_Back(); - /* - ** Set the required CD to be in the drive according to the scenario - ** loaded. - */ - if (RequiredCD != -2) { - if (scenario >= 20 && scenario <60 && GameToPlay == GAME_NORMAL) { - RequiredCD = 2; - } else { - if (scenario >= 60){ - /* - ** This is a gateway bonus scenario - */ - RequiredCD = -1; - }else{ - if (house == HOUSE_GOOD) { - RequiredCD = 0; - } else { - RequiredCD = 1; - } - } - } - } - if(!Force_CD_Available(RequiredCD)) { - Prog_End("Load_Game - CD not found", true); - if (!RunningAsDLL) { - exit(EXIT_FAILURE); - } - return false; - } - - Call_Back(); - - /* - ** Load the map. The map comes first, since it loads the Theater & init's - ** mixfiles. The map calls all the type-class's Init routines, telling them - ** what the Theater is; this must be done before any objects are created, so - ** they'll be properly created. - */ - Map.Load(file); - - Call_Back(); - /* - ** Load the object data. - */ - if (!Houses.Load(file) || - !TeamTypes.Load(file) || - !Teams.Load(file) || - !Triggers.Load(file) || - !Aircraft.Load(file) || - !Anims.Load(file) || - !Buildings.Load(file) || - !Bullets.Load(file) || - !Infantry.Load(file) || - !Overlays.Load(file) || - !Smudges.Load(file) || - !Templates.Load(file) || - !Terrains.Load(file) || - !Units.Load(file) || - !Factories.Load(file)) { - file.Close(); - return(false); - } - - Call_Back(); - /* - ** Load the Logic & Map Layers - */ - if (!Logic.Load(file)) { - file.Close(); - return(false); - } - for (i = 0; i < LAYER_COUNT; i++) { - if (!Map.Layer[i].Load(file)) { - file.Close(); - return(false); - } - } - - Call_Back(); - /* - ** Load the Score - */ - if (!Score.Load(file)) { - file.Close(); - return(false); - } - - /* - ** Load the AI Base - */ - if (!Base.Load(file)) { - file.Close(); - return(false); - } - - /* - ** Load miscellaneous variables, including the map size & the Theater - */ - if (!Load_Misc_Values(file)) { - file.Close(); - return(false); - } - - file.Close(); - Decode_All_Pointers(); - Map.Init_IO(); - Map.Flag_To_Redraw(true); - - Fixup_Scenario(); - - ScenarioInit = 0; - - /* - ** Fixup remap tables. ST - 2/28/2020 1:50PM - */ - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - HouseClass * hptr = HouseClass::As_Pointer(house); - if (hptr && hptr->IsActive) { - hptr->Init_Data(hptr->RemapColor, hptr->ActLike, hptr->Credits); - } - } - - /* - ** Re-init unit trackers. They will be garbage pointers after the load - */ - for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { - HouseClass * hptr = HouseClass::As_Pointer(house); - if (hptr && hptr->IsActive) { - hptr->Init_Unit_Trackers(); - } - } - -#ifdef DEMO - if (Scenario != 10 && Scenario != 1 && Scenario != 6) { - Clear_Scenario(); - return(false); - } -#endif - - Call_Back(); - return(true); -} - - -/*************************************************************************** - * Save_Misc_Values -- saves miscellaneous variables * - * * - * INPUT: * - * file file to use for writing * - * * - * OUTPUT: * - * true = success, false = failure * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/29/1994 BR : Created. * - *=========================================================================*/ -bool Save_Misc_Values(FileClass &file) -{ - int i, j; - int count; // # ptrs in 'CurrentObject' - ObjectClass * ptr; // for saving 'CurrentObject' ptrs - - /* - ** Player's House. - */ - if (file.Write(&PlayerPtr, sizeof(PlayerPtr)) != sizeof(PlayerPtr)) { - return(false); - } - - /* - ** Save this scenario number. - */ - if (file.Write(&Scenario, sizeof(Scenario)) != sizeof(Scenario)) { - return(false); - } - - /* - ** Save frame #. - */ - if (file.Write(&Frame, sizeof(Frame)) != sizeof(Frame)) { - return(false); - } - - /* - ** Save VQ Movie names. - */ - if (file.Write(WinMovie, sizeof(WinMovie)) != sizeof(WinMovie)) { - return(false); - } - - if (file.Write(LoseMovie, sizeof(LoseMovie)) != sizeof(LoseMovie)) { - return(false); - } - - /* - ** Save currently-selected objects list. - ** Save the # of ptrs in the list. - */ - for (i = 0; i < SelectedObjectsType::COUNT; i++) { - DynamicVectorClass& selection = CurrentObject.Raw(i); - count = selection.Count(); - if (file.Write(&count, sizeof(count)) != sizeof(count)) { - return(false); - } - - /* - ** Save the pointers. - */ - for (j = 0; j < count; j++) { - ptr = selection[j]; - if (file.Write(&ptr, sizeof(ptr)) != sizeof(ptr)) { - return(false); - } - } - } - - /* - ** Save the list of waypoints. - */ - if (file.Write(Waypoint, sizeof(Waypoint)) != sizeof(Waypoint)) { - return(false); - } - - file.Write(&ScenDir, sizeof(ScenDir)); - file.Write(&ScenVar, sizeof(ScenVar)); - file.Write(&CarryOverMoney, sizeof(CarryOverMoney)); - file.Write(&CarryOverPercent, sizeof(CarryOverPercent)); - file.Write(&BuildLevel, sizeof(BuildLevel)); - file.Write(BriefMovie, sizeof(BriefMovie)); - file.Write(Views, sizeof(Views)); - file.Write(&EndCountDown, sizeof(EndCountDown)); - file.Write(BriefingText, sizeof(BriefingText)); - - // This is new... - file.Write(ActionMovie, sizeof(ActionMovie)); - - return(true); -} - - -/*********************************************************************************************** - * Load_Misc_Values -- Loads miscellaneous variables. * - * * - * INPUT: file -- The file to load the misc values from. * - * * - * OUTPUT: Was the misc load process successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 BRR : Created. * - *=============================================================================================*/ -bool Load_Misc_Values(FileClass &file) -{ - int i, j; - int count; // # ptrs in 'CurrentObject' - ObjectClass * ptr; // for loading 'CurrentObject' ptrs - - /* - ** Player's House. - */ - if (file.Read(&PlayerPtr, sizeof(PlayerPtr)) != sizeof(PlayerPtr)) { - return(false); - } - - /* - ** Read this scenario number. - */ - if (file.Read(&Scenario,sizeof(Scenario)) != sizeof(Scenario)) { - return(false); - } - - /* - ** Load frame #. - */ - if (file.Read(&Frame, sizeof(Frame)) != sizeof(Frame)) { - return(false); - } - - /* - ** Load VQ Movie names. - */ - if (file.Read(WinMovie, sizeof(WinMovie)) != sizeof(WinMovie)) { - return(false); - } - - if (file.Read(LoseMovie, sizeof(LoseMovie)) != sizeof(LoseMovie)) { - return(false); - } - - for (i = 0; i < SelectedObjectsType::COUNT; i++) { - /* - ** Load currently-selected objects list. - ** Load the # of ptrs in the list. - */ - DynamicVectorClass& selection = CurrentObject.Raw(i); - if (file.Read(&count, sizeof(count)) != sizeof(count)) { - return(false); - } - - /* - ** Load the pointers. - */ - for (j = 0; j < count; j++) { - if (file.Read(&ptr, sizeof(ptr)) != sizeof(ptr)) { - return(false); - } - selection.Add(ptr); // add to the list - } - } - - /* - ** Save the list of waypoints. - */ - if (file.Read(Waypoint, sizeof(Waypoint)) != sizeof(Waypoint)) { - return(false); - } - - file.Read(&ScenDir, sizeof(ScenDir)); - file.Read(&ScenVar, sizeof(ScenVar)); - file.Read(&CarryOverMoney, sizeof(CarryOverMoney)); - file.Read(&CarryOverPercent, sizeof(CarryOverPercent)); - file.Read(&BuildLevel, sizeof(BuildLevel)); - file.Read(BriefMovie, sizeof(BriefMovie)); - file.Read(Views, sizeof(Views)); - file.Read(&EndCountDown, sizeof(EndCountDown)); - file.Read(BriefingText, sizeof(BriefingText)); - - if (file.Seek(0, SEEK_CUR) < file.Size()) { - file.Read(ActionMovie, sizeof(ActionMovie)); - } - - return(true); -} - - -/* -** ST - 9/26/2019 11:43AM -*/ -extern void DLL_Code_Pointers(void); -extern void DLL_Decode_Pointers(void); - - -/*********************************************************************************************** - * Code_All_Pointers -- Code all pointers. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 BRR : Created. * - *=============================================================================================*/ -void Code_All_Pointers(void) -{ - int i, j; - - /* - ** The Map. - */ - Map.Code_Pointers(); - - /* - ** The ArrayOf's. - */ - TeamTypes.Code_Pointers(); - Teams.Code_Pointers(); - Triggers.Code_Pointers(); - Aircraft.Code_Pointers(); - Anims.Code_Pointers(); - Buildings.Code_Pointers(); - Bullets.Code_Pointers(); - Infantry.Code_Pointers(); - Overlays.Code_Pointers(); - Smudges.Code_Pointers(); - Templates.Code_Pointers(); - Terrains.Code_Pointers(); - Units.Code_Pointers(); - Factories.Code_Pointers(); - - /* - ** The Layers. - */ - Logic.Code_Pointers(); - for (i = 0; i < LAYER_COUNT; i++) { - Map.Layer[i].Code_Pointers(); - } - - /* - ** The Score. - */ - Score.Code_Pointers(); - - /* - ** The Base. - */ - Base.Code_Pointers(); - - /* - ** PlayerPtr. - */ - PlayerPtr = (HouseClass *)(PlayerPtr->Class->House); - - /* - ** Currently-selected objects. - */ - for (i = 0; i < SelectedObjectsType::COUNT; i++) { - DynamicVectorClass& selection = CurrentObject.Raw(i); - for (j = 0; j < selection.Count(); j++) { - selection[j] = (ObjectClass *)selection[j]->As_Target(); - } - } - - /* - ** DLL data - */ - DLL_Code_Pointers(); - - /* - ** Houses must be coded last, because the Class->House member of the HouseClass - ** is used to code HouseClass pointers for all other objects, and if Class is - ** coded, it will point to a meaningless value. - */ - Houses.Code_Pointers(); -} - - -/*********************************************************************************************** - * Decode_All_Pointers -- Decodes all pointers. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1995 BRR : Created. * - *=============================================================================================*/ -void Decode_All_Pointers(void) -{ - int i, j; - - /* - ** The Map. - */ - Map.Decode_Pointers(); - - /* - ** Decode houses first, so we can properly decode all other objects' - ** House pointers - */ - Houses.Decode_Pointers(); - - /* - ** DLL data - */ - DLL_Decode_Pointers(); - - /* - ** The ArrayOf's. - */ - TeamTypes.Decode_Pointers(); - Teams.Decode_Pointers(); - Triggers.Decode_Pointers(); - Aircraft.Decode_Pointers(); - Anims.Decode_Pointers(); - Buildings.Decode_Pointers(); - Bullets.Decode_Pointers(); - Infantry.Decode_Pointers(); - Overlays.Decode_Pointers(); - Smudges.Decode_Pointers(); - Templates.Decode_Pointers(); - Terrains.Decode_Pointers(); - Units.Decode_Pointers(); - Factories.Decode_Pointers(); - - /* - ** The Layers. - */ - Logic.Decode_Pointers(); - for (i = 0; i < LAYER_COUNT; i++) { - Map.Layer[i].Decode_Pointers(); - } - - /* - ** The Score. - */ - Score.Decode_Pointers(); - - /* - ** The Base. - */ - Base.Decode_Pointers(); - - /* - ** PlayerPtr. - */ - PlayerPtr = HouseClass::As_Pointer(*((HousesType*)&PlayerPtr)); - Whom = PlayerPtr->Class->House; - switch (PlayerPtr->Class->House) { - case HOUSE_GOOD: - ScenPlayer = SCEN_PLAYER_GDI; - break; - - case HOUSE_BAD: - ScenPlayer = SCEN_PLAYER_NOD; - break; - - case HOUSE_JP: - ScenPlayer = SCEN_PLAYER_JP; - break; - } - Check_Ptr(PlayerPtr,__FILE__,__LINE__); - - if (PlayerPtr->ActLike == HOUSE_JP) { - ScenPlayer = SCEN_PLAYER_JP; - } - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir, ScenVar); - - /* - ** Currently-selected objects. - */ - for (i = 0; i < SelectedObjectsType::COUNT; i++) { - DynamicVectorClass& selection = CurrentObject.Raw(i); - for (j = 0; j < selection.Count(); j++) { - unsigned long target_as_object_ptr = reinterpret_cast(selection[j]); - TARGET target = (TARGET)target_as_object_ptr; - selection[j] = As_Object(target); - Check_Ptr(selection[j],__FILE__,__LINE__); - } - } - - /* - ** Last-Minute Fixups; to resolve these pointers properly requires all other - ** pointers to be loaded & decoded. - */ - if (Map.PendingObjectPtr) { - Map.PendingObject = &Map.PendingObjectPtr->Class_Of(); - Check_Ptr((void *)Map.PendingObject, __FILE__, __LINE__); - Map.Set_Cursor_Shape(Map.PendingObject->Occupy_List(true)); - } else { - Map.PendingObject = 0; - Map.Set_Cursor_Shape(0); - } -} - - -/*********************************************************************************************** - * Read_Object -- reads an object from a file * - * * - * Replacement for the original code below, which doesn't work with MSVC * - * We now assume that the vtable is 4 bytes, and is at the beginning of the class * - * It's the caller's responsibility to make sure the VTable is correct * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/10/1995 BR : Created. * - * 9/10/2019 12:34PM ST : Updated for MS compiler * - *=============================================================================================*/ -bool Read_Object(void *ptr, int class_size, FileClass & file, bool has_vtable) -{ - int size; - - /* - ** Read size of this chunk. - */ - if (file.Read(&size,sizeof(size)) != sizeof(size)) { - return(false); - } - - /* - ** Error if incorrect size. - */ - if (size != class_size) { - return false; - } - - int vtable_adjust = has_vtable ? 4 : 0; - unsigned char *object_ptr = static_cast(ptr); - - if (has_vtable) { - /* - ** Need to skip the vtable read. - */ - int dummy; - file.Read(&dummy, vtable_adjust); - } - - /* - ** Read object data. - */ - if (file.Read(object_ptr + vtable_adjust, class_size - vtable_adjust) != (class_size - vtable_adjust)) { - return(false); - } - - return true; -} - - -#if (0) -/*********************************************************************************************** - * Write_Object -- writes an object to a file * - * * - * This routine writes an object, skipping the embedded virtual function table pointer. * - * * - * INPUT: * - * ptr pointer to object to write * - * class_size size of the class itself * - * file file to use for I/O * - * * - * OUTPUT: * - * true = OK, false = error * - * * - * WARNINGS: * - * This routine ASSUMES the program modules are compiled with: * - * -Vb- Always make the virtual function table ptr 2 bytes long * - * -Vt Put the virtual function table after the 1st class's data * - * * - * Also see warnings for Read_Object(). * - * * - * HISTORY: * - * 01/10/1995 BR : Created. * - * 9/10/2019 12:34PM ST : Updated for MS compiler * - *=============================================================================================*/ -bool Write_Object(void *ptr, int class_size, FileClass & file) -{ - /* - ** Test assumptions about class size. - */ - class TestClass { - virtual void Test(void) = 0; - }; - - if (sizeof(TestClass) != 4) { - /* - ** Crash. - */ - *((int*)0) = 0; - } - - /* - ** Save size of this chunk. - */ - if (file.Write(&class_size,sizeof(class_size)) != sizeof(class_size)) { - return(false); - } - - /* - ** Save object data. - */ - if (file.Write(ptr, class_size) != (class_size)) { - return(false); - } - - return(true); -} - - -#endif - - -#if (0) //ST - 9/10/2019 12:43PM - -/*********************************************************************************************** - * Read_Object -- reads an object from disk * - * * - * This routine reads in an object and fills in the virtual function table pointer. * - * * - * INPUT: * - * ptr pointer to object to read * - * base_size size of object's absolute base class * - * class_size size of the class itself * - * file file to use for I/O * - * vtable virtual function table pointer value, NULL if none * - * * - * OUTPUT: * - * true = OK, false = error * - * * - * WARNINGS: * - * This routine ASSUMES the program modules are compiled with: * - * -Vb- Always make the virtual function table ptr 2 bytes long * - * -Vt Put the virtual function table after the 1st class's data * - * * - * ALSO, the class used to compute 'base_size' must come first in a multiple-inheritence * - * hierarchy. AND, if your class multiply-inherits from other classes, only ONE of those * - * classes can contain virtual functions! If you include virtual functions in the other * - * classes, the compiler will generate multiple virtual function tables, and this load/save * - * technique will fail. * - * * - * Each class hierarchy is stored in memory as a chain: first the data for the base-est * - * class, then the virtual function table pointer for this hierarchy, then the data for * - * all derived classes. If any of these derived classes multiply-inherit, the base class * - * for the multiple inheritance is stored as a separate chain following this chain. The * - * new chain will contain its own virtual function table pointer, if the multiply- * - * inherited hierarchy contains any virtual functions. Thus, the declaration * - * class A * - * class B: public A * - * class C: public B, X * - * is stored as: * - * A data * - * A's Virtual Table Pointer * - * B data * - * X data * - * [X's Virtual Table Pointer] * - * C data * - * * - * and * - * class A * - * class B: public A * - * class C: public X, B * - * is stored in memory as: * - * X data * - * [X's Virtual Table Pointer] * - * A data * - * A's Virtual Table Pointer * - * B data * - * C data * - * * - * * - * HISTORY: * - * 01/10/1995 BR : Created. * - *=============================================================================================*/ -bool Read_Object(void *ptr, int base_size, int class_size, FileClass & file, void * vtable) -{ - int size; // object size in bytes - - /* - ** Read size of this chunk. - */ - if (file.Read(&size,sizeof(size)) != sizeof(size)) { - return(false); - } - - /* - ** Error if incorrect size. - */ - if (size != class_size) { - return(false); - } - - /* - ** Read object data. - */ - if (file.Read(ptr, class_size) != (class_size)) { - return(false); - } - - /* - ** Fill in VTable. - */ - if (vtable) { - ((void **)(((char *)ptr) + base_size - 4))[0] = vtable; - } - - return(true); -} - -#endif - - - -/*********************************************************************************************** - * Write_Object -- reads an object from disk, in a safe way * - * * - * This routine writes an object in 2 pieces, skipping the embedded * - * virtual function table pointer. * - * * - * INPUT: * - * ptr pointer to object to write * - * class_size size of the class itself * - * file file to use for I/O * - * * - * OUTPUT: * - * true = OK, false = error * - * * - * WARNINGS: * - * This routine ASSUMES the program modules are compiled with: * - * -Vb- Always make the virtual function table ptr 2 bytes long * - * -Vt Put the virtual function table after the 1st class's data * - * * - * Also see warnings for Read_Object(). * - * * - * HISTORY: * - * 01/10/1995 BR : Created. * - *=============================================================================================*/ -bool Write_Object(void *ptr, int class_size, FileClass & file) -{ - /* - ** Save size of this chunk. - */ - if (file.Write(&class_size,sizeof(class_size)) != sizeof(class_size)) { - return(false); - } - - /* - ** Save object data. - */ - if (file.Write(ptr, class_size) != (class_size)) { - return(false); - } - - return(true); -} - - -/*************************************************************************** - * Get_Savefile_Info -- gets description, scenario #, house * - * * - * INPUT: * - * id numerical ID, for the file extension * - * buf buffer to store description in * - * scenp ptr to variable to hold scenario * - * housep ptr to variable to hold house * - * * - * OUTPUT: * - * true = OK, false = error (save-game file invalid) * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 01/12/1995 BR : Created. * - *=========================================================================*/ -bool Get_Savefile_Info(int id, char *buf, unsigned *scenp, HousesType *housep) -{ - RawFileClass file; - char name[_MAX_FNAME+_MAX_EXT]; - unsigned long version; - char descr_buf[DESCRIP_MAX]; - - /* - ** Generate the filename to load - */ - sprintf(name, "SAVEGAME.%03d", id); - - /* - ** If the file opens OK, read the file - */ - if (file.Open(name, READ)) { - - /* - ** Read in the description, scenario #, and the house - */ - if (file.Read(descr_buf, DESCRIP_MAX) != DESCRIP_MAX) { - file.Close(); - return(false); - } - - descr_buf[strlen(descr_buf) - 2] = '\0'; // trim off CR/LF - strcpy(buf, descr_buf); - - if (file.Read(scenp, sizeof(unsigned)) != sizeof(unsigned)) { - file.Close(); - return(false); - } - - if (file.Read(housep, sizeof(HousesType)) != sizeof(HousesType)) { - file.Close(); - return(false); - } - - /* - ** Read & verify the save-game version # - */ - if (file.Read(&version,sizeof(version)) != sizeof(version)) { - file.Close(); - return(false); - } - - if (version!=SAVEGAME_VERSION) { - file.Close(); - return(false); - } - - file.Close(); - - return(true); - } - return(false); -} - - -/*************************************************************************** - * TechnoType_To_Target -- converts TechnoTypeClass to TARGET * - * * - * INPUT: * - * ptr pointer to convert * - * * - * OUTPUT: * - * target value * - * * - * WARNINGS: * - * Be certain that you only use the returned target value by passing * - * it to Target_To_TechnoType; do NOT call As_Techno, or you'll get * - * a totally invalid pointer. * - * * - * HISTORY: * - * 01/12/1995 BR : Created. * - *=========================================================================*/ -TARGET TechnoType_To_Target(TechnoTypeClass const * ptr) -{ - TARGET target; - - switch (ptr->What_Am_I()) { - case RTTI_INFANTRYTYPE: - target = Build_Target(KIND_INFANTRY, ((InfantryTypeClass const *)ptr)->Type); - break; - - case RTTI_UNITTYPE: - target = Build_Target(KIND_UNIT, ((UnitTypeClass const *)ptr)->Type); - break; - - case RTTI_AIRCRAFTTYPE: - target = Build_Target(KIND_AIRCRAFT, ((AircraftTypeClass const *)ptr)->Type); - break; - - case RTTI_BUILDINGTYPE: - target = Build_Target(KIND_BUILDING, ((BuildingTypeClass const *)ptr)->Type); - break; - - default: - target = 0; - break; - } - - return(target); -} - - -/*************************************************************************** - * Target_To_TechnoType -- converts TARGET to TechnoTypeClass * - * * - * INPUT: * - * target TARGET value to convert * - * * - * OUTPUT: * - * pointer to the TechnoTypeClass for this target value * - * * - * WARNINGS: * - * The TARGET value MUST have been generated with TechnoType_To_Target;* - * If you give this routine a target generated by an As_Target() * - * routine, it will return a bogus pointer. * - * * - * HISTORY: * - * 01/12/1995 BR : Created. * - *=========================================================================*/ -TechnoTypeClass const * Target_To_TechnoType(TARGET target) -{ - switch (Target_Kind(target)) { - case KIND_INFANTRY: - return(&InfantryTypeClass::As_Reference((InfantryType)Target_Value(target))); - - case KIND_UNIT: - return(&UnitTypeClass::As_Reference((UnitType)Target_Value(target))); - - case KIND_AIRCRAFT: - return(&AircraftTypeClass::As_Reference((AircraftType)Target_Value(target))); - - case KIND_BUILDING: - return(&BuildingTypeClass::As_Reference((StructType)Target_Value(target))); - } - return(NULL); -} - - -/*************************************************************************** - * Get_VTable -- gets the VTable pointer for the given object * - * * - * INPUT: * - * ptr pointer to check * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 01/12/1995 BR : Created. * - *=========================================================================*/ -void * Get_VTable(void *ptr, int base_size) -{ - return(((void **)(((char *)ptr) + base_size - 4))[0]); -} - - -/*************************************************************************** - * Set_VTable -- sets the VTable pointer for the given object * - * * - * INPUT: * - * ptr pointer to check * - * base_size size of base class * - * vtable value of VTable to plug in * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 01/12/1995 BR : Created. * - *=========================================================================*/ -void Set_VTable(void *ptr, int base_size, void *vtable) -{ - ((void **)(((char *)ptr) + base_size - 4))[0] = vtable; -} - - -#if 0 -/**************************************************************************** -Dump routine: prints everything about everything related to the Save/Load -process (OK, not exactly everything, but lots of stuff) -****************************************************************************/ -void Dump(void) -{ - int i,j; - FILE *fp; - char *layername[] = { - "Ground", - "Air", - "Top" - }; - - /* - ------------------------------- Open file -------------------------------- - */ - fp = fopen("dump.txt","wt"); - - /* - ------------------------------ Logic Layer ------------------------------- - */ - fprintf(fp,"--------------------- Logic Layer ---------------------\n"); - fprintf(fp,"Count: %d\n",Logic.Count()); - for (j = 0; j < Logic.Count(); j++) { - fprintf(fp, "Entry %d: %x \n",j,Logic[j]); - } - fprintf(fp,"\n"); - - /* - ------------------------------- Map Layers ------------------------------- - */ - for (i = 0; i < LAYER_COUNT; i++) { - fprintf(fp,"----------------- Map Layer %s ---------------------\n", - layername[i]); - fprintf(fp,"Count: %d\n",Map.Layer[i].Count()); - for (j = 0; j < Map.Layer[i].Count(); j++) { - fprintf(fp, "Entry %d: %x \n",j,Map.Layer[i][j]); - } - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ TeamTypes --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",TeamTypes.ActiveCount); - for (i = 0; i < TEAMTYPE_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d Name:%s\n",i,TeamTypes[i].IsActive, - TeamTypes[i].Get_Name()); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Teams --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Teams.ActiveCount); - for (i = 0; i < TEAM_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d Name:%s\n",i,Teams[i].IsActive, - Teams[i].Class->Get_Name()); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Triggers --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Triggers.ActiveCount); - for (i = 0; i < TRIGGER_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d Name:%s\n",i,Triggers[i].IsActive, - Triggers[i].Get_Name()); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Aircraft --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Aircraft.ActiveCount); - for (i = 0; i < AIRCRAFT_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Aircraft[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Anims --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Anims.ActiveCount); - for (i = 0; i < ANIM_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Anims[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Buildings --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Buildings.ActiveCount); - for (i = 0; i < BUILDING_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Buildings[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Bullets --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Bullets.ActiveCount); - for (i = 0; i < BULLET_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Bullets[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Infantry --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Infantry.ActiveCount); - for (i = 0; i < INFANTRY_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Infantry[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Overlays --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Overlays.ActiveCount); - for (i = 0; i < OVERLAY_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Overlays[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Reinforcements --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Reinforcements.ActiveCount); - for (i = 0; i < REINFORCEMENT_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Reinforcements[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Smudges --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Smudges.ActiveCount); - for (i = 0; i < SMUDGE_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Smudges[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Templates --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Templates.ActiveCount); - for (i = 0; i < TEMPLATE_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Templates[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Terrains --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Terrains.ActiveCount); - for (i = 0; i < TERRAIN_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Terrains[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Units --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Units.ActiveCount); - for (i = 0; i < UNIT_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Units[i].IsActive); - } - fprintf(fp,"\n"); - - fprintf(fp,"------------------ Factories --------------------------\n"); - fprintf(fp,"ActiveCount: %d\n",Factories.ActiveCount); - for (i = 0; i < FACTORY_MAX; i++) { - fprintf(fp,"Entry %d: Active:%d \n",i,Factories[i].IsActive); - } - fprintf(fp,"\n"); - - fclose(fp); - - /* - ---------------------------- Flush the cache ----------------------------- - */ - fp = fopen("dummy.bin","wt"); - for (i = 0; i < 100; i++) { - fprintf(fp,"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"); - } - fclose(fp); -} -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/SCENARIO.CPP b/code/TIBERIANDAWN/SCENARIO.CPP deleted file mode 100644 index f4742fa..0000000 --- a/code/TIBERIANDAWN/SCENARIO.CPP +++ /dev/null @@ -1,802 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\scenario.cpv 2.17 16 Oct 1995 16:52:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SCENARIO.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : August 24, 1995 [JLB] * - * * - * This module handles the scenario reading and writing. Scenario related * - * code that is executed between scenario play can also be here. * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Clear_Scenario -- Clears all data in preparation for scenario load. * - * Do_Lose -- Display losing comments. * - * Do_Restart -- Handle the restart mission process. * - * Do_Win -- Display winning congratulations. * - * Fill_In_Data -- Recreate all data that is not loaded with scenario. * - * Read_Scenario -- Reads a scenario from disk. * - * Restate_Mission -- Handles restating the mission objective. * - * Start_Scenario -- Starts the scenario. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -extern int PreserveVQAScreen; - - -/*********************************************************************************************** - * Start_Scenario -- Starts the scenario. * - * * - * This routine will start the scenario. In addition to loading the scenario data, it will * - * play the briefing and action movies. * - * * - * INPUT: root -- Pointer to the filename root for this scenario (e.g., "SCG01EA"). * - * * - * briefing -- Should the briefing be played? Normally this is true except when the * - * scenario is restarting. * - * * - * OUTPUT: Was the scenario started without error? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -bool Start_Scenario(char *root, bool briefing) -{ - - if (!Read_Scenario(root)) { - CCDebugString ("C&C95 - Failed to read scenario.\n"); - return(false); - } - CCDebugString ("C&C95 - Scenario read OK.\n"); - -#ifdef DEMO - - if (briefing) { - Play_Movie(BriefMovie); - Play_Movie(ActionMovie, TransitTheme); - } - Theme.Queue_Song(THEME_AOI); - -#else - - /* - ** Install some hacks around the movie playing to account for the choose- - ** sides introduction. We don't want an intro movie on scenario 1, and - ** we don't want a briefing movie on GDI scenario 1. - */ - if (Scenario < 20 && (!Special.IsJurassic || !AreThingiesEnabled)) { - if (Scenario != 1 || Whom == HOUSE_GOOD) { - Play_Movie(IntroMovie); - } - - if (briefing) { - PreserveVQAScreen = (Scenario == 1); - Play_Movie(BriefMovie); - } - Play_Movie(ActionMovie, TransitTheme); - if (TransitTheme == THEME_NONE) { - Theme.Queue_Song(THEME_AOI); - } - } else { - Play_Movie(BriefMovie); - Play_Movie(ActionMovie, TransitTheme); - -#ifdef NEWMENU - - char buffer[25]; - sprintf(buffer, "%s.VQA", BriefMovie); - CCFileClass file(buffer); - - if (GameToPlay == GAME_NORMAL && !file.Is_Available()) { - VisiblePage.Clear(); - Set_Palette(GamePalette); -// Show_Mouse(); - /* - ** Show the mission briefing. Pretend we are inside the main loop so the palette - ** will be correct on the textured buttons. - */ - bool oldinmain = InMainLoop; - InMainLoop = true; - - // TO_FIX - Covert ops missions want to pop up a dialog box. ST - 9/6/2019 1:48PM - //Restate_Mission(ScenarioName, TXT_OK, TXT_NONE); - - - InMainLoop = oldinmain; -// Hide_Mouse(); - if (TransitTheme == THEME_NONE) { - Theme.Queue_Song(THEME_AOI); - } - } - -#endif - } -#endif - - /* - ** Set the options values, since the palette has been initialized by Read_Scenario - */ - CCDebugString ("C&C95 - About to call Options.Set.\n"); - Options.Set(); - CCDebugString ("C&C95 - About to return from Start_Scenario.\n"); - return(true); -} - - -/*********************************************************************************************** - * Set_Scenario_Difficulty -- Sets the difficulty of the scenario. * - * * - * Updates the player's difficulty in single-player mode. * - * * - * INPUT: difficulty -- Scenario difficulty * - * * - * OUTPUT: none * - * * - * WARNINGS: Only works in single-player. * - * Must call Start_Scenario first to initialize the player. * - * * - * HISTORY: * - * 10/02/2019 SKY : Created. * - *=============================================================================================*/ -void Set_Scenario_Difficulty(int difficulty) -{ - if (GameToPlay == GAME_NORMAL) { - switch (difficulty) { - case 0: - PlayerPtr->Assign_Handicap(DIFF_EASY); - break; - case 1: - PlayerPtr->Assign_Handicap(DIFF_NORMAL); - break; - case 2: - PlayerPtr->Assign_Handicap(DIFF_HARD); - break; - default: - break; - } - } -} - - -/*********************************************************************************************** - * Read_Scenario -- Reads a scenario from disk. * - * * - * This will read a scenario from disk. Use this to begin a scenario. * - * It doesn't perform any rendering, it merely sets up the system * - * with the proper data. Setting of the right game state will start * - * the scenario running. * - * * - * INPUT: root -- Scenario root filename * - * * - * OUTPUT: none * - * * - * WARNINGS: You must clear out the system variables before calling * - * this function. Use the Clear_Scenario() function. * - * It is assumed that Scenario is set to the current scenario number. * - * * - * HISTORY: * - * 07/22/1991 : Created. * - * 02/03/1992 JLB : Uses house identification. * - *=============================================================================================*/ -bool Read_Scenario(char *root) -{ - CCDebugString ("C&C95 - In Read_Scenario.\n"); - Clear_Scenario(); - ScenarioInit++; - if (Read_Scenario_Ini(root)) { - - Fill_In_Data(); - - Map.Set_View_Dimensions(0, Map.Get_Tab_Height(), Map.MapCellWidth, Map.MapCellHeight); - - - /* - ** SPECIAL CASE: - ** Clear out the tutor flags for scenarios one and two. This is designed - ** so that tutorial message will reappear in scenario two. - */ - if (Scenario < 5) { - TutorFlags[0] = 0L; - TutorFlags[1] = 0L; - } - - } else { - -#if (1) - char message[200]; - if (root) { - sprintf(message, "Failed to load scenario %s", root); - GlyphX_Debug_Print(message); - } else { - GlyphX_Debug_Print("Failed to load scenario"); - } -#else - Fade_Palette_To(GamePalette, FADE_PALETTE_FAST, Call_Back); - Show_Mouse(); - CCMessageBox().Process(TXT_UNABLE_READ_SCENARIO); - Hide_Mouse(); -#endif - return(false); - } - ScenarioInit--; - CCDebugString ("C&C95 - Leaving Read_Scenario.\n"); - return(true); -} - - -/*********************************************************************************************** - * Fill_In_Data -- Recreate all data that is not loaded with scenario. * - * * - * This routine is called after the INI file for the scenario has been processed. It will * - * infer the game state from the scenario INI data. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/07/1992 JLB : Created. * - *=============================================================================================*/ -void Fill_In_Data(void) -{ - /* - ** The basic scenario data load does not contain the full set of - ** game data. We now must fill in the missing pieces. - */ - ScenarioInit++; - - for (int index = 0; index < Buildings.Count(); index++) { - Buildings.Ptr(index)->Update_Buildables(); - } - - Map.Flag_To_Redraw(true); - - /* - ** Bring up the score display on the radar map when starting a multiplayer - ** game. - */ - if (GameToPlay != GAME_NORMAL) { - Map.Player_Names(1); - } - - ScenarioInit--; -} - - -/*********************************************************************************************** - * Clear_Scenario -- Clears all data in preparation for scenario load. * - * * - * This routine will clear out all data specific to a scenario in * - * preparation for a subsequent scenario data load. This will free * - * all units, animations, and icon maps. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/22/1991 : Created. * - * 03/21/1992 JLB : Changed buffer allocations, so changes memset code. * - * 07/13/1995 JLB : End count down moved here. * - *=============================================================================================*/ -void Clear_Scenario(void) -{ - EndCountDown = TICKS_PER_SECOND * 30; - CrateCount = 0; - CrateTimer = 0; - CrateMaker = false; - - /* - ** Call everyone's Init routine, except the Map's; for the Map, only call - ** MapClass::Init, which clears the Cell array. The Display::Init requires - ** a Theater argument, and the theater is not known at this point; also, it - ** would reload MixFiles, which isn't desired. Display::Read_INI calls its - ** own Init, which will Init the entire Map hierarchy. - */ - Map.Init_Clear(); - Score.Init(); - Logic.Init(); - - HouseClass::Init(); - ObjectClass::Init(); - TeamTypeClass::Init(); - TeamClass::Init(); - TriggerClass::Init(); - AircraftClass::Init(); - AnimClass::Init(); - BuildingClass::Init(); - BulletClass::Init(); - InfantryClass::Init(); - OverlayClass::Init(); - SmudgeClass::Init(); - TemplateClass::Init(); - TerrainClass::Init(); - UnitClass::Init(); - - FactoryClass::Init(); - - Base.Init(); - - CurrentObject.Clear_All(); - - Invalidate_Cached_Icons(); -} - - -/*********************************************************************************************** - * Do_Win -- Display winning congratulations. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - * 01/01/1995 JLB : Carries money forward into next scenario. * - *=============================================================================================*/ -void Do_Win(void) -{ - Map.Set_Default_Mouse(MOUSE_NORMAL); - Hide_Mouse(); - - /* - ** If this is a multiplayer game, clear the game's name so we won't respond - ** to game queries any more (in Call_Back) - */ - if (GameToPlay != GAME_NORMAL) { - MPlayerGameName[0] = 0; - } - - /* - ** Determine a cosmetic center point for the text. - */ - int x = Map.TacPixelX + (Lepton_To_Pixel(Map.TacLeptonWidth)/2); - int y = Map.TacPixelY + (Lepton_To_Pixel(Map.TacLeptonHeight)/2) -32; - - /* - ** Announce win to player. - */ - Set_Logic_Page(SeenBuff); -#if !(GERMAN | FRENCH) - Fancy_Text_Print(TXT_MISSION, x, y, WHITE, TBLACK, TPF_CENTER|TPF_VCR); -#endif - Fancy_Text_Print(TXT_SCENARIO_WON, x, y+30, WHITE, TBLACK, TPF_CENTER|TPF_VCR); - CountDownTimer.Set(TIMER_SECOND * 3); - Stop_Speaking(); - Speak(VOX_ACCOMPLISHED); - while (CountDownTimer.Time() || Is_Speaking()) { - Call_Back(); - } - - /* - ** Stop here if this is a multiplayer game. - */ - if (GameToPlay != GAME_NORMAL) { - if (!PlaybackGame) { - MPlayerGamesPlayed++; - Multi_Score_Presentation(); - MPlayerCurGame++; - if (MPlayerCurGame >= MAX_MULTI_GAMES) { - MPlayerCurGame = MAX_MULTI_GAMES - 1; - } - } - GameActive = 0; - Show_Mouse(); - return; - } - - /* - ** Play the winning movie and then start the next scenario. - */ - if (RequiredCD != -2) { - if (Scenario >= 20 && Scenario <60 && GameToPlay == GAME_NORMAL) { - RequiredCD = 2; - } else { - if (Scenario >=60){ - RequiredCD = -1; - }else{ - if (PlayerPtr->Class->House == HOUSE_GOOD) { - RequiredCD = 0; - } else { - RequiredCD = 1; - } - } - } - } - -#ifndef DEMO - Play_Movie(WinMovie); -#endif - - Keyboard::Clear(); - - /* - ** Do the ending screens only if not playing back a recorded game. - */ - if (!PlaybackGame) { - -#ifdef DEMO - - switch (Scenario) { - case 1: - Score.Presentation(); - Scenario = 10; - break; - - case 10: - Score.Presentation(); - Scenario = 6; - break; - - default: - Score.Presentation(); - GDI_Ending(); - GameActive = false; - Show_Mouse(); - return; -// Prog_End(); -// exit(0); -// break; - } - -#else - -#ifdef NEWMENU - if (Scenario >= 20) { - Keyboard::Clear(); - Score.Presentation(); - GameActive = false; - Show_Mouse(); - return; - } -#endif - - if (PlayerPtr->Class->House == HOUSE_BAD && Scenario == 13) { - Nod_Ending(); - //Prog_End(); - //exit(0); - SeenBuff.Clear(); - Show_Mouse(); - GameActive = false; - return; - } - if (PlayerPtr->Class->House == HOUSE_GOOD && Scenario == 15) { - GDI_Ending(); - //Prog_End(); - //exit(0); - SeenBuff.Clear(); - Show_Mouse(); - GameActive = false; - return; - } - - if ( (Special.IsJurassic && AreThingiesEnabled) && Scenario == 5) { - Prog_End("Do_Win - Last Jurassic mission complete"); - if (!RunningAsDLL) { - exit(0); - } - return; - } - - if (!Special.IsJurassic || !AreThingiesEnabled) { - Keyboard::Clear(); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = Palette; - Score.Presentation(); - - /* - ** Skip scenario #7 if the airfield was blown up. - */ - if (Scenario == 6 && PlayerPtr->Class->House == HOUSE_GOOD && SabotagedType == STRUCT_AIRSTRIP) { - Scenario++; - } - - Map_Selection(); - } - Scenario++; -#endif - Keyboard::Clear(); - } - - CarryOverMoney = PlayerPtr->Credits; - - int pieces = PlayerPtr->NukePieces; - - /* - ** Generate a new scenario filename - */ - Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir, ScenVar); - Start_Scenario(ScenarioName); - - PlayerPtr->NukePieces = pieces; - - /* - ** Destroy the building that was sabotaged in the previous scenario. This only - ** applies to GDI mission #7. - */ - int index; - if (SabotagedType != STRUCT_NONE && Scenario == 7 && PlayerPtr->Class->House == HOUSE_GOOD) { - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && !building->IsInLimbo && building->House != PlayerPtr && building->Class->Type == SabotagedType) { - building->Limbo(); - delete building; - break; - } - } - - /* - ** Remove the building from the prebuild list. - */ - for (index = 0; index < Base.Nodes.Count(); index++) { - BaseNodeClass * node = Base.Get_Node(index); - - if (node && node->Type == SabotagedType) { - Base.Nodes.Delete(index); - break; - } - } - } - SabotagedType = STRUCT_NONE; - - Map.Render(); - Fade_Palette_To(GamePalette, FADE_PALETTE_FAST, Call_Back); - Show_Mouse(); -} - - -/*********************************************************************************************** - * Do_Lose -- Display losing comments. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 08/05/1992 JLB : Created. * - *=============================================================================================*/ -void Do_Lose(void) -{ - Map.Set_Default_Mouse(MOUSE_NORMAL); - Hide_Mouse(); - - /* - ** If this is a multiplayer game, clear the game's name so we won't respond - ** to game queries any more (in Call_Back) - */ - if (GameToPlay != GAME_NORMAL) { - MPlayerGameName[0] = 0; - } - - /* - ** Determine a cosmetic center point for the text. - */ - int x = Map.TacPixelX + (Lepton_To_Pixel(Map.TacLeptonWidth)/2); - int y = Map.TacPixelY + (Lepton_To_Pixel(Map.TacLeptonHeight)/2) -32; - - /* - ** Announce win to player. - */ - Set_Logic_Page(SeenBuff); - Fancy_Text_Print(TXT_MISSION, x, y, WHITE, TBLACK, TPF_CENTER|TPF_VCR); - Fancy_Text_Print(TXT_SCENARIO_LOST, x, y+30, WHITE, TBLACK, TPF_CENTER|TPF_VCR); - CountDownTimer.Set(TIMER_SECOND * 3); - Stop_Speaking(); - Speak(VOX_FAIL); - while (CountDownTimer.Time() || Is_Speaking()) { - Call_Back(); - } - -#ifdef OBSOLETE - if (Debug_Play_Map) { - Go_Editor(true); - Show_Mouse(); - return; - } -#endif - - /* - ** Stop here if this is a multiplayer game. - */ - if (GameToPlay != GAME_NORMAL) { - if (!PlaybackGame) { - MPlayerGamesPlayed++; - Multi_Score_Presentation(); - MPlayerCurGame++; - if (MPlayerCurGame >= MAX_MULTI_GAMES) { - MPlayerCurGame = MAX_MULTI_GAMES - 1; - } - } - GameActive = 0; - Show_Mouse(); - return; - } - - Play_Movie(LoseMovie); - - /* - ** Start same scenario again - */ - Set_Palette(GamePalette); - Show_Mouse(); - if (!PlaybackGame && !CCMessageBox().Process(TXT_TO_REPLAY, TXT_YES, TXT_NO)) { - Hide_Mouse(); - Keyboard::Clear(); - Start_Scenario(ScenarioName, false); - Map.Render(); - } else { - Hide_Mouse(); - GameActive = 0; - } - - Fade_Palette_To(GamePalette, FADE_PALETTE_FAST, Call_Back); - Show_Mouse(); -} - - -/*********************************************************************************************** - * Do_Restart -- Handle the restart mission process. * - * * - * This routine is called in the main game loop when the mission must be restarted. This * - * routine will throw away the current game and reload the appropriate mission. The * - * game will "resume" at the start of the mission. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/24/1995 JLB : Created. * - *=============================================================================================*/ -void Do_Restart(void) -{ - bool hidden = Get_Mouse_State(); - - if (hidden) Show_Mouse(); - CCMessageBox().Process(TXT_RESTARTING, TXT_NONE); - Map.Set_Default_Mouse(MOUSE_NORMAL); - Keyboard::Clear(); - Start_Scenario(ScenarioName, false); - if (hidden) Hide_Mouse(); - Keyboard::Clear(); - Map.Render(); -} - - -/*********************************************************************************************** - * Restate_Mission -- Handles restating the mission objective. * - * * - * This routine will display the mission objective (as text). It will also give the * - * option to redisplay the mission briefing video. * - * * - * INPUT: name -- The scenario name. This is the unique identifier for the scenario * - * briefing text as it appears in the "MISSION.INI" file. * - * * - * OUTPUT: Returns the response from the dialog. This will either be 1 if the video was * - * requested, or 0 if the return to game options button was selected. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/23/1995 JLB : Created. * - * 08/06/1995 JLB : Uses preloaded briefing text. * - *=============================================================================================*/ -bool Restate_Mission(char const * name, int button1, int button2) -{ - if (name) { -#ifdef JAPANESE - char fname[14]; - strcpy(fname, name); - strcat(fname,".CPS"); - - if(CCFileClass(fname).Is_Available()) { - CCMessageBox box(TXT_NONE, true); - return(box.Process(fname, button1, button2)); - } -#else - /* - ** Make sure that if there is no briefing movie, that the briefing text is - ** the only option available. - */ - bool brief = true; -#ifdef NEWMENU - char buffer[25]; - char buffer1[25]; - sprintf(buffer, "%s.VQA", BriefMovie); - sprintf(buffer1, "%s.VQA", ActionMovie); - CCFileClass file1(buffer); - CCFileClass file2(buffer1); - if (!file1.Is_Available() && !file2.Is_Available()) { - button1 = TXT_OK; - button2 = TXT_NONE; - brief = false; - } -#endif - - /* - ** If mission object text was found, then display it. - */ - if (strlen(BriefingText)) { - static char _buff[512]; - - strcpy(_buff, BriefingText); -// strcpy(_ShapeBuffer, BriefingText); - - bool hidden = Get_Mouse_State(); - if (hidden) Show_Mouse(); - - if (CCMessageBox(TXT_OBJECTIVE).Process(_buff, button1, button2)) { - if (hidden) Hide_Mouse(); - return(true); - } - if (hidden) Hide_Mouse(); - if (!brief) return(true); - return(false); - } -#endif - } - return(false); -} - -void Fixup_Scenario(void) -{ - /* - ** "Fraidycat" civilians avoid wandering into Tiberium for SCG08EB, since they're mission-critical. - */ - bool is_scg08ea = GameToPlay == GAME_NORMAL && PlayerPtr->ActLike == HOUSE_GOOD && Scenario == 8 && ScenVar == SCEN_VAR_B; - for (InfantryType index = INFANTRY_FIRST; index < INFANTRY_COUNT; index++) { - InfantryTypeClass& infantry_type = (InfantryTypeClass&)InfantryTypeClass::As_Reference(index); - if (infantry_type.IsFraidyCat) { - infantry_type.IsAvoidingTiberium = is_scg08ea; - } - } - - /* - ** Laser-firing Orcas in the PATSUX secret mission - */ - if (GameToPlay == GAME_NORMAL && Scenario == 72) { - ((AircraftTypeClass&)AircraftTypeClass::As_Reference(AIRCRAFT_ORCA)).Primary = WEAPON_OBELISK_LASER; - } else { - ((AircraftTypeClass&)AircraftTypeClass::As_Reference(AIRCRAFT_ORCA)).Primary = WEAPON_DRAGON; - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/SCORE.CPP b/code/TIBERIANDAWN/SCORE.CPP deleted file mode 100644 index 37bcfc8..0000000 --- a/code/TIBERIANDAWN/SCORE.CPP +++ /dev/null @@ -1,2322 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\score.cpv 2.17 16 Oct 1995 16:49:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SCORE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 19, 1994 * - * * - * Last Update : May 3, 1995 [BWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Call_Back_Delay -- Combines Call_Back() and Delay() functions * - * Draw_Bar_Graphs -- Draw "Casualties" bar graphs * - * Draw_InfantryMan -- Draw one guy in score screen, update animation * - * Draw_Infantrymen -- Draw all the guys on the score screen * - * New_Infantry_Anim -- Start up a new animation for one of the infantrymen * - * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly * - * ScoreClass::Delay -- Pauses waiting for keypress. * - * ScoreClass::DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen * - * ScoreClass::Presentation -- Main routine to display score screen. * - * ScoreClass::Print_Graph_Title -- Prints title on score screen. * - * ScoreClass::Print_Minutes -- Print out hours/minutes up to max * - * ScoreClass::Pulse_Bar_Graph -- Pulses the bargraph color. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "textblit.h" -#define SCORETEXT_X 184 -#define SCORETEXT_Y 8 -#define CASUALTY_Y 88 -#define BUILDING_X 256 -#define BUILDING_Y 128 -#define BARGRAPH_X 266 -#define MAX_BAR_X 318 // max possible is 319 because of bar's right shadow -#define SIZEGBAR 119 -#define HALLFAME_X 19 -#define HALLFAME_Y 120 - -#define MULTISCOREX 30 - -#define TEDIT_FAME 1 -#define NUMINFANTRYMEN 15 -#define NUMFAMENAMES 7 -#define MAX_FAMENAME_LENGTH 12 - -struct InfantryAnim { - int xpos; - int ypos; - void const *shapefile; - void const *remap; - int anim; - int stage; - char delay; - InfantryTypeClass const *Class; -} InfantryMan[NUMINFANTRYMEN]; -void Draw_InfantryMen(void); -void Draw_InfantryMan(int index); -void New_Infantry_Anim(int index, int anim); -void Draw_Bar_Graphs(int i, int gkilled, int nkilled, int ckilled); -void Animate_Cursor(int pos, int ypos); -void Animate_Score_Objs(void); -void Cycle_Wait_Click(void); -int ScorePass; - -void const * Beepy6; -int ControlQ; // cheat key to skip past score/mapsel screens -bool StillUpdating; - -GraphicBufferClass *PseudoSeenBuff; -GraphicBufferClass *TextPrintBuffer; - -#ifdef WRITE_LBM -PUBLIC bool CCWrite_LBM_File(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes, unsigned char *palette); -#endif - -unsigned char RemapCiv[256]={ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0xD0,0x18,0x19,0xD1,0xD2,0xD3,0xD4,0x1E,0xD5, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0xD6,0xD7,0xD8,0xD9,0x7E,0xDA, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, - 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xDB,0xDC,0xDD,0xDE,0xDB,0xDC,0xDD,0xDE,0xDF, - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}; - -unsigned char const ScoreRemapGrey[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0..15 - 16, 17, 18, 19, 20,176, 22,208, 24, 25,209,210,211,212, 30,213, // 16..31 - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 32..47 - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 48..63 - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 64..79 - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 80..95 - 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,214,215,216,217,149,218, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,108,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,219,220,221,222,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const ScoreRemapYellow[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0..15 - 16, 17, 18, 19, 20,176, 22,208, 24, 25,209,210,211,212, 30,213, // 16..31 - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 32..47 - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 48..63 - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 64..79 - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 80..95 - 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111 - 112,113,114,115,116,117,118,119,120,121,214,215,216,217,149,218, // 112..127 - 128,129,130,131,132,133,134,135,136,137,138,108,140,141,142,143, // 128..143 - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159 - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175 - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191 - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207 - 208,209,210,211,212,213,214,219,220,221,222,219,220,221,222,223, // 208..223 - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239 - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255 -}; - -unsigned char const ScoreRemapBldg[256]={ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, - 0x70,0x71,0xCE,0xC5,0x49,0x48,0x47,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, - 0x80,0x81,0xB8,0x83,0x7C,0x7A,0x76,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, - 0x74,0x91,0x92,0x93,0x94,0x95,0xB5,0x97,0x98,0xCF,0x4B,0x7F,0x9C,0x9D,0x9E,0x9F, - 0xA0,0xA1,0xA2,0x83,0x79,0xA5,0xA6,0xA7,0x43,0x99,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xBB,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF -}; -unsigned char const ScoreRemapFBall[256]={ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, - 0xB0,0xE5,0x82,0xE4,0xE3,0xE2,0xB1,0xD0,0xE1,0xE0,0xD1,0xD2,0xD3,0xD4,0xDF,0xD5, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xE6,0xE7,0xA0,0xE8,0x2E,0x2F, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, - 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF -}; - -TextBlitClass BlitList; - - -char *ScreenNames[2]={"S-GDIIN2.WSA","SCRSCN1.WSA"}; - -//extern short StreamLowImpact; - -// ST - 1/3/2019 10:38AM -int StreamLowImpact = FALSE; - -struct Fame { - char name[MAX_FAMENAME_LENGTH]; - int score; - int level; -}; - -ScoreAnimClass *ScoreObjs[MAXSCOREOBJS]; - - -ScoreAnimClass::ScoreAnimClass(int x, int y, void const * data) -{ - BlitList.Add (x*2, y*2, x*2, y*2, 2* String_Pixel_Width ( (char*)data ) , 16); - XPos = x; - YPos = y; - Timer.Set(0); - Timer.Start(); - DataPtr = data; -} - - -ScoreTimeClass::ScoreTimeClass(int xpos, int ypos, void const * data, int max, int timer) : - ScoreAnimClass(xpos, ypos, data) -{ - Stage = 0; - MaxStage = max; - TimerReset = timer; -} - -void ScoreTimeClass::Update(void) -{ - GraphicViewPortClass *oldpage; - if (!Timer.Time()) { - Timer.Set(TimerReset); - if (++Stage >= MaxStage) Stage = 0; - oldpage = LogicPage; - Set_Logic_Page(PseudoSeenBuff); - CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); - Set_Logic_Page(oldpage); - } -} - -ScoreCredsClass::ScoreCredsClass(int xpos, int ypos, void const * data, int max, int timer) : - ScoreAnimClass(xpos, ypos, data) -{ - Stage = 0; - MaxStage = max; - TimerReset = timer; - Clock1 = MixFileClass::Retrieve("CLOCK1.AUD"); - CashTurn = MixFileClass::Retrieve("CASHTURN.AUD"); -} - - -void ScoreCredsClass::Update(void) -{ - GraphicViewPortClass *oldpage; - if (!Timer.Time()) { - Timer.Set(TimerReset); - if (++Stage >= MaxStage) Stage = 0; - oldpage = LogicPage; - Set_Logic_Page(PseudoSeenBuff); - if (Stage <22) { - Play_Sample(Clock1, 255, Options.Normalize_Sound(70)); - } else { - if (Stage==24) { - Play_Sample(CashTurn, 255, Options.Normalize_Sound(70)); - } - } - CC_Draw_Shape(DataPtr,Stage, XPos, YPos, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0); - Set_Logic_Page(oldpage); - } -} - - -ScorePrintClass::ScorePrintClass(int string, int xpos, int ypos, void const * palette, int background) : - ScoreAnimClass(xpos, ypos, Text_String(string)) -{ - Background = background; - PrimaryPalette = palette; - Stage = 0; -} - - -ScorePrintClass::ScorePrintClass(void const * string, int xpos, int ypos, void const * palette, int background) : - ScoreAnimClass(xpos, ypos, string) -{ - Background = background; - PrimaryPalette = palette; - Stage = 0; -} - - -void ScorePrintClass::Update(void) -{ - static char localstr[2]={0,0}; - static char _whitepal[]={0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}; - - if (Stage && (((char *)DataPtr)[Stage-1]==0) ) { - for (int i = 0; i < MAXSCOREOBJS; i++) { - if (ScoreObjs[i] == this) { - ScoreObjs[i] = 0; - } - } - BlitList.Add (XPos*2, YPos*2, XPos*2, YPos*2,(Stage*6)+14, 8*2); - delete this; - return; - } - - StillUpdating = true; - - if (!Timer.Time()) { - Timer.Set(1); - - int pos = XPos+(Stage*6); - if (Stage) { - - localstr[0]=((char *)DataPtr)[Stage-1]; - - /* - ** Clear out the white letter overlay - */ - static char const _blackpal[]={BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK}; - Set_Font_Palette(_blackpal); - TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos-1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos+1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, 2*(pos-6+1),2*(YPos), TBLACK, TBLACK); - - Set_Font_Palette(PrimaryPalette); - TextPrintBuffer->Print(localstr, 2*(pos-6),2*YPos, TBLACK, TBLACK); - } - if (((char *)DataPtr)[Stage]) { - localstr[0]=((char *)DataPtr)[Stage]; - Set_Font_Palette(_whitepal); - TextPrintBuffer->Print(localstr, pos*2, 2*(YPos-1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, pos*2, 2*(YPos+1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, (pos+1)*2,2*YPos , TBLACK, TBLACK); - } - Stage++; - } -} - - - - - - - - - - - -MultiStagePrintClass::MultiStagePrintClass(int string, int xpos, int ypos, void const * palette, int background) : - ScoreAnimClass(xpos, ypos, Text_String(string)) -{ - Background = background; - PrimaryPalette = palette; - Stage = 0; -} - - -MultiStagePrintClass::MultiStagePrintClass(void const * string, int xpos, int ypos, void const * palette, int background) : - ScoreAnimClass(xpos, ypos, string) -{ - Background = background; - PrimaryPalette = palette; - Stage = 0; -} - - -void MultiStagePrintClass::Update(void) -{ - static char localstr[2]={0,0}; - static char _whitepal[]={0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}; - - if (Stage && (((char *)DataPtr)[Stage-1]==0) ) { - for (int i = 0; i < MAXSCOREOBJS; i++) { - if (ScoreObjs[i] == this) { - ScoreObjs[i] = 0; - } - } - BlitList.Add (XPos*2, YPos*2, XPos*2, YPos*2,(Stage*6)+14, 8*2); - delete this; - return; - } - - StillUpdating = true; - - if (!Timer.Time()) { - Timer.Set(1); - - /* - ** Do 10 stages at once - */ - for (int wibble = 0 ; wibble < 10 ; wibble ++){ - - int pos = XPos+(Stage*6); - if (Stage) { - - localstr[0]=((char *)DataPtr)[Stage-1]; - - /* - ** Clear out the white letter overlay - */ - static char const _blackpal[]={BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK}; - Set_Font_Palette(_blackpal); - TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos-1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos+1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, 2*(pos-6+1),2*(YPos), TBLACK, TBLACK); - - Set_Font_Palette(PrimaryPalette); - TextPrintBuffer->Print(localstr, 2*(pos-6),2*YPos, TBLACK, TBLACK); - } - if (((char *)DataPtr)[Stage]) { - localstr[0]=((char *)DataPtr)[Stage]; - Set_Font_Palette(_whitepal); - TextPrintBuffer->Print(localstr, pos*2, 2*(YPos-1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, pos*2, 2*(YPos+1), TBLACK, TBLACK); - TextPrintBuffer->Print(localstr, (pos+1)*2,2*YPos , TBLACK, TBLACK); - } - Stage++; - - if ( ( (char *) DataPtr) [Stage-1] == 0 ) break; - } - } -} - - - - - - -ScoreScaleClass::ScoreScaleClass(void const * string, int xpos, int ypos, char const palette[]) : - ScoreAnimClass(xpos, ypos, string) -{ - Palette = &palette[0]; - Stage = 5; -} - - -void ScoreScaleClass::Update(void) -{ - static int _destx[]={0,80,107,134,180,228}; - static int _destw[]={6,20, 30, 40, 60, 80}; - - /* - ** Restore the background for the scaled-up letter - */ - if (!Timer.Time()) { - Timer.Set(1); - if (Stage != 5) { - TextPrintBuffer->Blit(HidPage, _destx[Stage+1]*2, YPos*2, _destx[Stage+1]*2, YPos*2, _destw[Stage+1]*2, _destw[Stage+1]*2); - //SysMemPage.Blit(*PseudoSeenBuff, _destx[Stage+1], YPos, _destx[Stage+1], YPos, _destw[Stage+1], _destw[Stage+1]); - } - if (Stage) { - Set_Font_Palette(Palette); - TextPrintBuffer->Fill_Rect(0,0, 7*2,7*2, TBLACK); - TextPrintBuffer->Print((char *)DataPtr, 0,0, TBLACK, TBLACK); - TextPrintBuffer->Scale(HidPage, 0,0, _destx[Stage]*2, YPos*2, 5*2,5*2, _destw[Stage]*2, _destw[Stage]*2, true); - - //SysMemPage.Fill_Rect(0,0, 7,7, TBLACK); - //SysMemPage.Print((char *)DataPtr, 0,0, TBLACK, TBLACK); - //SysMemPage.Scale(*PseudoSeenBuff, 0,0, _destx[Stage], YPos, 5,5, _destw[Stage], _destw[Stage], true); - Stage--; - } else { - Set_Font_Palette(Palette); - for (int i = 0; i < MAXSCOREOBJS; i++) { - if (ScoreObjs[i]==this) ScoreObjs[i] = 0; - } - TextPrintBuffer->Print((char *)DataPtr, XPos*2,YPos*2, TBLACK, TBLACK); - //TextPrintBuffer->Blit(HidPage, XPos*2, YPos*2, XPos*2, YPos*2,2*6,2*6); - //BlitList.Add (XPos, YPos, XPos, YPos, 6,6); - - //SysMemPage.Print((char *)DataPtr, XPos,YPos, TBLACK, TBLACK); - //SysMemPage.Blit(*PseudoSeenBuff, XPos,YPos, XPos, YPos, 6,6); - delete this; - return; - } - } -} - -int Alloc_Object(ScoreAnimClass *obj) -{ - int i,ret; - - for (i = ret = 0; i < MAXSCOREOBJS; i++) { - if (!ScoreObjs[i]) { - ScoreObjs[i] = obj; - ret = i; - break; - } - } - return(ret); -} - - - - - -TextBlitClass::TextBlitClass (void) -{ - Clear(); -} - - - -void TextBlitClass::Add (int x, int y, int dx, int dy, int w, int h) -{ - if ( Count < MAX_ENTRIES ){ - - BlitListo [Count].SourceX = x; - BlitListo [Count].SourceY = y; - BlitListo [Count].DestX = dx; - BlitListo [Count].DestY = dy; - BlitListo [Count].Width = w; - BlitListo [Count].Height = h; - - Count++; - } -} - - -void TextBlitClass::Clear(void) -{ - Count = 0; -} - - - - -void TextBlitClass::Update(void) -{ - if (TextPrintBuffer){ - - if (HidPage.Lock()){ - - for (int i=0 ; iBlit (HidPage, BlitListo[i].SourceX, - BlitListo[i].SourceY, - BlitListo[i].DestX, - BlitListo[i].DestY, - BlitListo[i].Width, - BlitListo[i].Height, - true); - } - - HidPage.Unlock(); - } - } -} - - - -void Disable_Uncompressed_Shapes (void); -void Enable_Uncompressed_Shapes (void); - -/*********************************************************************************************** - * ScoreClass::Presentation -- Main routine to display score screen. * - * * - * This is the main routine that displays the score screen graphics. * - * It gets called at the end of each scenario and is used to present * - * the results and a rating of the player's battle. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 : Created. * - *=============================================================================================*/ -void ScoreClass::Presentation(void) -{ - //static char const _redpal[]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x21,0x2F}; - static char const _redpal[]={0x20,0x22,0x24,0x26,0x28,0x28,0x28,0x28,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x21,0x2F}; - static char const _greenpal[]={0x10,0x12,0x14,0x16,0x18,0x18,0x18,0x18,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x10,0x1F}; - static char const _bluepal[]={0x60,0x62,0x64,0x66,0x68,0x68,0x68,0x68,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x61,0x6F}; - //static char const _bluepal[]={0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x61,0x6F}; - static unsigned char const _yellowpal[]={0x0,0x0,0xEC,0x0,0xEB,0x0,0xEA,0x0,0xE9,0x0,0x0,0x0,0x0,0x0,0xED,0x0}; - static int const _casuax[2]={144,146}; - static int const _casuay[2]={ 78, 90}; - static int const _gditxx[2]={150,224}; - static int const _gditxy[2]={ 90, 90}; - static int const _nodtxx[2]={150,224}; - static int const _nodtxy[2]={102,102}; -// static int _bargrx[2]={297,SCORETEXT_X+64}; -// static int _bargry[2]={ 90,CASUALTY_Y + 2}; - static int const _bldggy[2]={138,128}; - static int const _bldgny[2]={150,140}; - -// int gdikilled, nodkilled, civkilled, max, i, k, shapenum; - int i; - int max; - void const * yellowptr; - void const * redptr; - CCFileClass file(FAME_FILE_NAME); - struct Fame hallfame[NUMFAMENAMES]; - void *anim, *oldfont; - int oldfontxspacing = FontXSpacing; - int house = PlayerPtr->Class->House; // 0 or 1 - char inter_pal[15]; - - /* - ** Choose an appropriate palette file for the interpolation - */ - if (house == HOUSE_GOOD){ - sprintf(inter_pal,"SCORPAL1.PAL"); - }else{ - sprintf(inter_pal,"SNODPAL1.PAL"); - } - - - if (Special.IsJurassic && AreThingiesEnabled) return; - - PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL); - TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height(), (void*)NULL); - TextPrintBuffer->Clear(); - BlitList.Clear(); - Disable_Uncompressed_Shapes (); - - ControlQ = 0; - FontXSpacing = 0; - Map.Override_Mouse_Shape(MOUSE_NORMAL); - Theme.Queue_Song(THEME_WIN1); - - VisiblePage.Clear(); - PseudoSeenBuff->Clear(); - SysMemPage.Clear(); - WWMouse->Erase_Mouse(&HidPage, TRUE); - HiddenPage.Clear(); - Set_Palette(BlackPalette); - - Set_Logic_Page(SysMemPage); - - void const * country4 = MixFileClass::Retrieve("COUNTRY4.AUD"); - void const * sfx4 = MixFileClass::Retrieve("SFX4.AUD"); - Beepy6 = MixFileClass::Retrieve("BEEPY6.AUD"); - - /* - ** Load the background for the score screen - */ - anim = Open_Animation(ScreenNames[house],NULL,0L,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - - unsigned minutes = (unsigned)((ElapsedTime / (long)TIMER_MINUTE))+1; - - /* - ** Determine leadership rating. - */ - unsigned leadership = 0; - int index; - for (index = 0; index < Logic.Count(); index++) { - ObjectClass * object = Logic[index]; - if (object->Owner() == house) { - leadership++; - } - } - - HouseClass *houses[3]; - for (index = 0; index < 3; index++) { - houses[index] =(HouseClass::As_Pointer((HousesType)(HOUSE_GOOD+index))); - } - - GKilled = (HouseClass::As_Pointer(HOUSE_GOOD))->UnitsLost; - NKilled = (HouseClass::As_Pointer(HOUSE_BAD))->UnitsLost; - CKilled = (HouseClass::As_Pointer(HOUSE_NEUTRAL))->UnitsLost; - GBKilled = (HouseClass::As_Pointer(HOUSE_GOOD))->BuildingsLost; - NBKilled = (HouseClass::As_Pointer(HOUSE_BAD))->BuildingsLost; - CBKilled = (HouseClass::As_Pointer(HOUSE_NEUTRAL))->BuildingsLost; - - /* - ** New - ST 6/12/96 2:40PM - */ - GHarvested = (HouseClass::As_Pointer(HOUSE_GOOD))->HarvestedCredits; - NHarvested = (HouseClass::As_Pointer(HOUSE_BAD))->HarvestedCredits; - - if (!leadership) leadership++; - leadership = Cardinal_To_Fixed(GKilled+GBKilled+leadership, leadership); - leadership = Fixed_To_Cardinal(100, leadership); - if (leadership > 100) leadership = 100; - - /* - ** Determine efficiency rating. - */ - int gharv = GHarvested; - int init = PlayerPtr->InitialCredits; - int cred = PlayerPtr->Available_Money(); - - unsigned efficiency = Cardinal_To_Fixed( (house == HOUSE_GOOD ? GHarvested : NHarvested) + (unsigned)PlayerPtr->InitialCredits+1, (unsigned)PlayerPtr->Available_Money()+1); - if (!efficiency) efficiency++; - efficiency = Fixed_To_Cardinal(100, efficiency); - - if (efficiency > 100) efficiency = 100; - /* - ** Calculate total score - */ - long total = ((leadership * 40) + (4600) + (efficiency * 14))/100; - if (!total) total++; - total *= (BuildLevel+1); - -// Load up the shapes for the Nod score screen - if (house == HOUSE_GOOD) { - yellowptr = MixFileClass::Retrieve("BAR3YLW.SHP"); - redptr = MixFileClass::Retrieve("BAR3RED.SHP"); - } - -/* Change to the six-point font for Text_Print */ - oldfont = Set_Font(ScoreFontPtr); - Call_Back(); - -/* --- Now display the background animation --- */ - Hide_Mouse(); - Animate_Frame(anim, SysMemPage, 1); - SysMemPage.Blit(*PseudoSeenBuff); - Increase_Palette_Luminance (Palette , 30,30,30,63); - InterpolationPalette = Palette; - InterpolationPaletteChanged = TRUE; - Read_Interpolation_Palette(inter_pal); - Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , inter_pal); - Fade_Palette_To(Palette, FADE_PALETTE_FAST, Call_Back); - - Play_Sample(country4, 255, Options.Normalize_Sound(90)); - - int frame = 1; - StreamLowImpact = true; - while (frame < Get_Animation_Frame_Count(anim)) { - Animate_Frame(anim, *PseudoSeenBuff, frame++); - ////////////////Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , NULL); - Call_Back_Delay(2); - } - StreamLowImpact = false; - Call_Back(); - Close_Animation(anim); - - /* - ** Background's up, so now load various shapes and animations - */ - void const * timeshape = MixFileClass::Retrieve("TIME.SHP"); - ScoreObjs[0] = new ScoreTimeClass(233, 2, timeshape, 30, 4); - - void const * hiscore1shape = MixFileClass::Retrieve("HISCORE1.SHP"); - void const * hiscore2shape = MixFileClass::Retrieve("HISCORE2.SHP"); - ScoreObjs[1] = new ScoreTimeClass(4, 97, hiscore1shape, 10, 4); - ScoreObjs[2] = new ScoreTimeClass(8, 172, hiscore2shape, 10, 4); - - /* Now display the stuff */ - PseudoSeenBuff->Blit(SysMemPage); - - - if (house == HOUSE_BAD) { - - /* - ** load the logo - */ - void const * logoptr = MixFileClass::Retrieve("LOGOS.SHP"); - CC_Draw_Shape(logoptr, 1, 0, 0, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); - - Bit_It_In_Scale(0,0, 128,104-16, &SysMemPage, PseudoSeenBuff, &SeenBuff , 1); - } - - Set_Logic_Page(PseudoSeenBuff); - -#ifdef FRENCH - Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 200, 3,_greenpal)); -#else - Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 206, 3,_greenpal)); -#endif - Alloc_Object(new ScorePrintClass(TXT_SCORE_LEAD, 182, 26,_greenpal)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_EFFI, 182, 38,_greenpal)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_TOTA, 182, 50,_greenpal)); - Play_Sample(sfx4, 255, Options.Normalize_Sound(120)); - Call_Back_Delay(13); - - max = MAX((long)leadership, (long)efficiency); - int scorecounter = 0; - Keyboard::Clear(); - - BlitList.Add (264*2, 26*2, 264*2, 26*2, 4*12 , 12); - BlitList.Add (264*2, 38*2, 264*2, 38*2, 4*12 , 12); - BlitList.Add (264*2, 50*2, 264*2, 50*2, 4*12 , 12); - BlitList.Add (275*2, 9*2, 275*2, 9*2, 64, 12 ); //Minutes - for (i = 0; i <= 160; i++) { - Set_Font_Palette(_greenpal); - Count_Up_Print("%3d%%", i, leadership, 264, 26); - if (i>=30) Count_Up_Print("%3d%%", i-30, efficiency, 264, 38); - if (i>=60) { - Count_Up_Print("%3d",scorecounter, total, 264, 50); - scorecounter += total/100; - } - Print_Minutes(minutes); - Call_Back_Delay(1); - Play_Sample(Beepy6, 255, Options.Normalize_Sound(60)); - if (Check_Key() && i < (max-5) ) { - i=158; - Keyboard::Clear(); - } - } - Count_Up_Print("%3d", total, total, 264, 50); - - Call_Back_Delay(60); - - if (house == HOUSE_BAD) Show_Credits(house, _greenpal); - - Call_Back_Delay(60); - - /* - ** Show stats on # of units killed - */ - Set_Logic_Page(*PseudoSeenBuff); - Play_Sample(sfx4, 255, Options.Normalize_Sound(90)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_CASU, _casuax[house], _casuay[house],_redpal)); - Call_Back_Delay(9); - if (house == HOUSE_BAD) { - Alloc_Object(new ScorePrintClass(TXT_SCORE_NEUT, 200, 114,_redpal)); - Call_Back_Delay(4); - } - - Alloc_Object(new ScorePrintClass(TXT_SCORE_GDI, _gditxx[house], _gditxy[house],_redpal)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_NOD, _nodtxx[house], _nodtxy[house],_redpal)); - Call_Back_Delay(6); - - Set_Font_Palette(_redpal); - if (house == HOUSE_BAD) { - Do_Nod_Casualties_Graph(); - } else { - Do_GDI_Graph(yellowptr, redptr, GKilled + CKilled, NKilled, 88); - } - - Set_Logic_Page(*PseudoSeenBuff); - - /* - ** Print out stats on buildings destroyed - */ - Play_Sample(sfx4, 255, Options.Normalize_Sound(90)); - if (house == HOUSE_GOOD) { - Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL, 144, 126,_greenpal)); - Call_Back_Delay(9); - } else { - Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL1, 146, 128,_greenpal)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL2, 146, 136,_greenpal)); - Call_Back_Delay(9); - Alloc_Object(new ScorePrintClass(TXT_SCORE_NEUT, 200, 152,_greenpal)); - Call_Back_Delay(4); - } - Alloc_Object(new ScorePrintClass(TXT_SCORE_GDI, _gditxx[house], _bldggy[house],_greenpal)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_NOD, _gditxx[house], _bldgny[house],_greenpal)); - Call_Back_Delay(7); - - if (house==HOUSE_BAD) { - Call_Back_Delay(6); - Set_Font_Palette(_greenpal); - Do_Nod_Buildings_Graph(); - } else { - Do_GDI_Graph(yellowptr, redptr, GBKilled + CBKilled, NBKilled, 136); - } - - // Wait for text printing to complete - while (StillUpdating){ - Call_Back_Delay(1); - } - - if (Keyboard::Check()) Keyboard::Clear(); - - if (house == HOUSE_GOOD) Show_Credits(house, _greenpal); - - /* - ** Hall of fame display and processing - */ - Play_Sample(sfx4, 255, Options.Normalize_Sound(90)); - Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 28, 110,_bluepal)); - Call_Back_Delay(9); - - /* - ** First check for the existence of the file, and if there isn't one, - ** make a new one filled with blanks. - */ - if (!file.Is_Available()) { - - // hall of fame doesn't exist, so blank it out & write it - file.Open(WRITE); - - for (i = 0; i < NUMFAMENAMES; i++) { - hallfame[i].name[0] = - hallfame[i].score = - hallfame[i].level = 0; - file.Write(&hallfame[i], sizeof(struct Fame)); - } - - file.Close(); - } - - file.Open(READ); - for (i = 0; i < NUMFAMENAMES; i++) { - file.Read(&hallfame[i], sizeof(struct Fame)); - } - file.Close(); - - /* - ** If the player's score is good enough to bump someone off the list, - ** remove their data, move everyone down a notch, and set index = where - ** their info goes - */ - if(hallfame[NUMFAMENAMES-1].score >= total) - hallfame[NUMFAMENAMES-1].score = 0; - for (index = 0; index < NUMFAMENAMES; index++) { - if (total > hallfame[index].score) { - if (index < (NUMFAMENAMES-1)) for (i = (NUMFAMENAMES-1); i > index; i--) hallfame[i] = hallfame[i-1]; - hallfame[index].score = total; - hallfame[index].level = Scenario; -// hallfame[index].level = BuildLevel; - //hallfame[index].name[0] = 0; // blank out the name - memset (hallfame[index].name, ' ', sizeof (hallfame[index].name) -1); - hallfame[index].name[sizeof (hallfame[index].name)-1] = 0; - break; - } - } - - /* - ** Now display the hall of fame - */ - Set_Logic_Page(*PseudoSeenBuff); - for (i = 0; i < NUMFAMENAMES; i++) { - Alloc_Object(new ScorePrintClass(hallfame[i].name, HALLFAME_X, HALLFAME_Y + (i*8), _bluepal)); - if (hallfame[i].score) { - char *str = (char *)(SysMemPage.Get_Buffer()) + i*32; - sprintf(str,"%d", hallfame[i].score); - Alloc_Object(new ScorePrintClass(str, HALLFAME_X+(6*15), HALLFAME_Y + (i*8), _bluepal, BLACK)); - if (hallfame[i].level < 20) { - sprintf(str+16,"%d", hallfame[i].level); - } else { - strcpy(str+16, "**"); - } - Alloc_Object(new ScorePrintClass(str+16, HALLFAME_X+(6*12), HALLFAME_Y + (i*8), _bluepal, BLACK)); - Call_Back_Delay(13); - } - } - - // Wait for text printing to complete - while (StillUpdating){ - Call_Back_Delay(1); - } - - /* - ** If the player's on the hall of fame, have him enter his name now - */ - Keyboard::Clear(); - if (index < NUMFAMENAMES) { - Input_Name(hallfame[index].name, HALLFAME_X, HALLFAME_Y + (index*8), _bluepal); - - file.Open(WRITE); - for (i = 0; i < NUMFAMENAMES; i++) { - file.Write(&hallfame[i], sizeof(struct Fame)); - } - file.Close(); - } else { -#ifdef FRENCH - Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 145, 190, _yellowpal)); -#else - Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 149, 190, _yellowpal)); -#endif - Cycle_Wait_Click(); - } - -#ifdef WRITE_LBM - file.Open("e:scorscrn.lbm",WRITE); - SeenBuff.Blit(SysMemPage,0,0, 0,0, 320,200); - CCWrite_LBM_File(file, SysMemPage, 8, Palette); - file.Close(); -#endif - - Keyboard::Clear(); - -/* get rid of all the animating objects */ - for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) { - delete ScoreObjs[i]; - ScoreObjs[i] = 0; - } - Fade_Palette_To(BlackPalette, FADE_PALETTE_FAST, NULL); - VisiblePage.Clear(); - - Show_Mouse(); -// Map_Selection(); - - Theme.Queue_Song(THEME_NONE); - - Fade_Palette_To(BlackPalette, FADE_PALETTE_FAST, NULL); - VisiblePage.Clear(); - Set_Palette(GamePalette); - - Set_Font(oldfont); - FontXSpacing = oldfontxspacing; - ControlQ = 0; - - Set_Logic_Page (SeenBuff); - - delete PseudoSeenBuff; - delete TextPrintBuffer; - TextPrintBuffer = NULL; - BlitList.Clear(); - Enable_Uncompressed_Shapes(); -} - -// ST = 12/17/2018 5:44PM -#ifndef TickCount -extern TimerClass TickCount; -#endif - -void Cycle_Wait_Click(void) -{ - int counter = 0; - int minclicks = 20; - unsigned long timingtime = TickCount.Time(); - //SerialPacketType sendpacket; - //SerialPacketType receivepacket; - //int packetlen; - - - Keyboard::Clear(); - while (minclicks || (!Check_Key() && !ControlQ) ) { - - if (GameToPlay == GAME_NULL_MODEM || - GameToPlay == GAME_MODEM){ - //GameToPlay == GAME_INTERNET) { -#if (0) //PG_TO_FIX - // - // send a timing packet if enough time has gone by. - // - if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { - sendpacket.Command = SERIAL_SCORE_SCREEN; - sendpacket.ResponseTime = NullModem.Response_Time(); - sendpacket.ID = ModemGameToPlay; - - NullModem.Send_Message (&sendpacket, sizeof(sendpacket), 0); - timingtime = TickCount.Time(); - } - - if (NullModem.Get_Message (&receivepacket, &packetlen) > 0) { - // throw packet away - packetlen = packetlen; - } - - NullModem.Service(); -#endif - } - - Call_Back_Delay(1); - if (minclicks) { - minclicks--; - Keyboard::Clear(); - } - - counter = ((++counter) & 7); - - if (!counter) { - unsigned char r,g,b; - - r = Palette[233*3+0]; - g = Palette[233*3+1]; - b = Palette[233*3+2]; - - for (int i = 233; i < 237; i++) { - Palette[i*3+0] = Palette[(i+1)*3+0]; - Palette[i*3+1] = Palette[(i+1)*3+1]; - Palette[i*3+2] = Palette[(i+1)*3+2]; - } - Palette[237*3+0] = r; - Palette[237*3+1] = g; - Palette[237*3+2] = b; - - Set_Palette(Palette); - } - } - Keyboard::Clear(); -} - -void ScoreClass::Do_Nod_Buildings_Graph(void) -{ - int shapenum; - InfantryTypeClass const *ramboclass; - - void const * factptr = MixFileClass::Retrieve("FACT.SHP"); - void const * rmboptr = MixFileClass::Retrieve("RMBO.SHP"); - void const * fball1ptr = MixFileClass::Retrieve("FBALL1.SHP"); - ramboclass = &InfantryTypeClass::As_Reference(INFANTRY_E5); - - /* - ** Print the # of buildings on the hidpage so we only need to do it once - */ - PseudoSeenBuff->Blit(SysMemPage); - Set_Logic_Page(SysMemPage); - Call_Back_Delay(30); - BlitList.Add (2* (BUILDING_X + 8), 2* (BUILDING_Y), 2* (BUILDING_X+8), 2* (BUILDING_Y), 5*12 , 12); - BlitList.Add (2* (BUILDING_X + 8), 2* (BUILDING_Y + 12), 2* (BUILDING_X+8), 2* (BUILDING_Y + 12), 5*12 , 12); - BlitList.Add (2* (BUILDING_X + 8), 2* (BUILDING_Y + 24), 2* (BUILDING_X+8), 2* (BUILDING_Y + 24), 5*12 , 12); - - TextPrintBuffer->Print( 0, (BUILDING_X + 8)*2, BUILDING_Y*2, TBLACK, TBLACK); - TextPrintBuffer->Print( 0, (BUILDING_X + 8)*2, (BUILDING_Y + 12)*2, TBLACK, TBLACK); - TextPrintBuffer->Print( 0, (BUILDING_X + 8)*2, (BUILDING_Y + 24)*2, TBLACK, TBLACK); - - /* - ** Here's the animation/draw loop for blowing up the factory - */ - int i; - for (i=0; i<98; i++) { - SysMemPage.Blit(SysMemPage, BUILDING_X, BUILDING_Y, 0, 0, 320-BUILDING_X,48); - shapenum = 0; // no damage - if (i >= 60) { - shapenum = Extract_Shape_Count(factptr) - 2; // some damage - if (i == 60) { - Shake_The_Screen(6); - Sound_Effect(VOC_CRUMBLE, VOL_FULL, 0); - } - if (i > 65) { - shapenum = Extract_Shape_Count(factptr) - 1; // mega damage - } - } - - /* - ** Draw the building before Rambo - */ - if (i < 68) { - CC_Draw_Shape(factptr,shapenum, 0, 0, WINDOW_MAIN, - SHAPE_FADING|SHAPE_WIN_REL, ScoreRemapBldg,Map.UnitShadow); - - } - - /* - ** Now draw some fires, if appropriate - */ - if (i >= 61) { - int firecount = Extract_Shape_Count(fball1ptr); - int shapeindex = (i-61)>>1; - if (shapeindex < firecount) { - CC_Draw_Shape(fball1ptr, shapeindex, 10, 10, WINDOW_MAIN, - SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST, - ScoreRemapFBall,0); - } - if (i > 64) { - shapeindex = (i-64)>>1; - if (shapeindex < firecount) { - CC_Draw_Shape(fball1ptr, shapeindex, 50, 30, WINDOW_MAIN, - SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST, - ScoreRemapFBall,0); - } - } - } - /* - ** Draw the Rambo character running away from the building - */ - CC_Draw_Shape(rmboptr, (ramboclass->DoControls[DO_WALK].Frame + ramboclass->DoControls[DO_WALK].Jump*6) + ((i>>1)%ramboclass->DoControls[DO_WALK].Count), - i+32, 40, WINDOW_MAIN, - SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST, - ScoreRemapYellow,Map.UnitShadow); - SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BUILDING_X, BUILDING_Y, 320-BUILDING_X,48); - - /* - ** Extra font related stuff. ST - 7/29/96 2:22PM - */ - Interpolate_2X_Scale(PseudoSeenBuff , &HidPage ,NULL); - BlitList.Update(); - WWMouse->Draw_Mouse(&HidPage); - Blit_Hid_Page_To_Seen_Buff(); - WWMouse->Erase_Mouse(&HidPage, TRUE); - //Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , NULL); - - if (!Check_Key()) Call_Back_Delay(1); - } - - i = MAX(GBKilled, NBKilled); - i = MAX(i, CBKilled); - - for (int q = 0; q <= i; q++) { - Count_Up_Print( "%d", q, GBKilled,BUILDING_X + 8,BUILDING_Y ); - Count_Up_Print( "%d", q, NBKilled,BUILDING_X + 8,BUILDING_Y + 12); - Count_Up_Print( "%d", q, CBKilled,BUILDING_X + 8,BUILDING_Y + 24); - if (!Check_Key()) { - Play_Sample(Beepy6, 255, Options.Normalize_Sound(110)); - Call_Back_Delay(1); - } - } -} - - -/*************************************************************************** - * DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen* - * * - * * - * * - * INPUT: yellowptr, redptr = pointers to shape file for graphs * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/03/1995 BWG : Created. * - *=========================================================================*/ - -void ScoreClass::Do_GDI_Graph(void const * yellowptr, void const * redptr, int gkilled, int nkilled, int ypos) -{ - int i, max; - int gdikilled = gkilled, nodkilled=nkilled; - - max = MAX(gdikilled, nodkilled); - if (!max) max=1; - - gdikilled = (gdikilled * SIZEGBAR) / max; - nodkilled = (nodkilled * SIZEGBAR) / max; - if (max < 20) { - gdikilled = gkilled * 5; - nodkilled = nkilled * 5; - } - - max = MAX(gdikilled, nodkilled); - if (!max) max=1; - - // Draw the white-flash shape on the hidpage - Set_Logic_Page(SysMemPage); - SysMemPage.Fill_Rect(0,0, 124,9, TBLACK); - CC_Draw_Shape(redptr, 120, 0,0, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0); - Set_Logic_Page(PseudoSeenBuff); - - BlitList.Add (2* 297, 2* (ypos+2), 2* 297, 2* (ypos+2), 5*12 , 12); - - for (i = 1; i <= gdikilled; i++) { - if (i != gdikilled) { - CC_Draw_Shape(yellowptr,i, 172, ypos, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0); - } else { - SysMemPage.Blit(*PseudoSeenBuff,0,0, 172, ypos, 3+gdikilled,9); - } - - Count_Up_Print("%d", (i*gkilled) / max, gkilled, 297, ypos+2); - if (!Check_Key()) { - Play_Sample(Beepy6, 255, Options.Normalize_Sound(110)); - Call_Back_Delay(2); - } - } - CC_Draw_Shape(yellowptr,gdikilled, 172,ypos , WINDOW_MAIN,SHAPE_WIN_REL, 0, 0); - Count_Up_Print("%d", gkilled, gkilled, 297, ypos+ 2); - if (!Check_Key()) Call_Back_Delay(40); - - BlitList.Add (2* 297, 2* (ypos+14), 2* 297, 2* (ypos+14), 5*12 , 12); - for (i = 1; i <= nodkilled; i++) { - if (i != nodkilled) { - CC_Draw_Shape(redptr, i, 172, ypos+12, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0); - } else { - SysMemPage.Blit(*PseudoSeenBuff,0,0, 172,ypos+12, 3+nodkilled,9); - } - - Count_Up_Print("%d", (i*nkilled) / max, nkilled, 297, ypos+14); - if (!Check_Key()) { - Play_Sample(Beepy6, 255, Options.Normalize_Sound(110)); - Call_Back_Delay(2); - } - } - -// if (Keyboard::Check()) Keyboard::Clear(); - - /* - ** Make sure accurate count is printed at end - */ - CC_Draw_Shape( redptr,nodkilled, 172,ypos+12, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0); - Count_Up_Print("%d", nkilled, nkilled, 297, ypos+14); - if (!Check_Key()) Call_Back_Delay(40); -} - - -void ScoreClass::Do_Nod_Casualties_Graph(void) -{ - int i, gdikilled, nodkilled, civkilled, max; - - void const * e1ptr = MixFileClass::Retrieve("E1.SHP"); - void const * c1ptr = MixFileClass::Retrieve("C1.SHP"); - - gdikilled = GKilled; - nodkilled = NKilled; - civkilled = CKilled; - max = MAX(gdikilled, nodkilled); - max = MAX(max, civkilled); - - if (!max) max=1; - if ((gdikilled > (MAX_BAR_X - BARGRAPH_X)) || (nodkilled > (MAX_BAR_X - BARGRAPH_X)) || (civkilled > (MAX_BAR_X - BARGRAPH_X))) { - gdikilled = (gdikilled * (MAX_BAR_X - BARGRAPH_X)) / max; - nodkilled = (nodkilled * (MAX_BAR_X - BARGRAPH_X)) / max; - civkilled = (civkilled * (MAX_BAR_X - BARGRAPH_X)) / max; - } - - max = MAX(gdikilled, nodkilled); - max = MAX(max, civkilled); - if (!max) max=1; - - /* - ** Initialize a bunch of objects for the infantrymen who pose for the bar - ** graphs of casualties. - */ - int q = NUMINFANTRYMEN/3; - int r = q*2; - for (i = 0; i < NUMINFANTRYMEN/3; i++) { - InfantryMan[i+0].xpos = - InfantryMan[i+q].xpos = - InfantryMan[i+r].xpos = (i*10) + 7; - InfantryMan[i+0].ypos = 11; - InfantryMan[i+q].ypos = 21; - InfantryMan[i+r].ypos = 31; - InfantryMan[i+0].shapefile = - InfantryMan[i+q].shapefile = e1ptr; - InfantryMan[i+r].shapefile = c1ptr; - InfantryMan[i+0].remap = ScoreRemapYellow; - InfantryMan[i+q].remap = ScoreRemapGrey; - InfantryMan[i+r].remap = RemapCiv; - InfantryMan[i+0].anim = - InfantryMan[i+q].anim = - InfantryMan[i+r].anim = 0; - InfantryMan[i+0].stage = - InfantryMan[i+q].stage = - InfantryMan[i+r].stage = 0; - InfantryMan[i+0].delay = - InfantryMan[i+q].delay = - InfantryMan[i+r].delay = Random() & 0x1F; - InfantryMan[i+0].Class = - InfantryMan[i+q].Class = &InfantryTypeClass::As_Reference(INFANTRY_E1); - InfantryMan[i+r].Class = &InfantryTypeClass::As_Reference(INFANTRY_C1); - - } - - /* - ** Draw the infantrymen and pause briefly before running the graph - */ - Draw_InfantryMen(); - SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34); - //Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff, NULL); - /* - ** Extra font related stuff. ST - 7/29/96 2:22PM - */ - Interpolate_2X_Scale(PseudoSeenBuff , &HidPage ,NULL); - BlitList.Update(); - WWMouse->Draw_Mouse(&HidPage); - Blit_Hid_Page_To_Seen_Buff(); - WWMouse->Erase_Mouse(&HidPage, TRUE); - - Call_Back_Delay(40); - - BlitList.Add (2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 2), 2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 2), 5*12 , 12); - BlitList.Add (2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 14), 2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 14), 5*12 , 12); - BlitList.Add (2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 26), 2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 26), 5*12 , 12); - - for (i = 1; i <= max; i++) { - // Draw & update infantrymen 3 times for every tick on the graph (i) - for (int q = 0; q < 3; q++) { - Draw_InfantryMen(); - Draw_Bar_Graphs(i, gdikilled, nodkilled, civkilled); - SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34); - - Count_Up_Print("%d", (i*GKilled) / max, GKilled, SCORETEXT_X+64, CASUALTY_Y + 2); - Count_Up_Print("%d", (i*NKilled) / max, NKilled, SCORETEXT_X+64, CASUALTY_Y + 14); - Count_Up_Print("%d", (i*CKilled) / max, CKilled, SCORETEXT_X+64, CASUALTY_Y + 26); - if (!Check_Key()) Call_Back_Delay(3); - } - Play_Sample(Beepy6, 255, Options.Normalize_Sound(110)); - } - if (Check_Key()) Keyboard::Clear(); - - /* - ** Make sure accurate count is printed at end - */ - Count_Up_Print("%d", GKilled, GKilled, SCORETEXT_X+64, CASUALTY_Y + 2); - Count_Up_Print("%d", NKilled, NKilled, SCORETEXT_X+64, CASUALTY_Y + 14); - Count_Up_Print("%d", CKilled, CKilled, SCORETEXT_X+64, CASUALTY_Y + 26); - - /* - ** Finish up death animations, if there are any active - */ - int k = 1; - while (k) { - for (i=k=0; i= DO_GUN_DEATH) k=1; - if (k) Draw_InfantryMen(); - Draw_Bar_Graphs(max, gdikilled, nodkilled, civkilled); - SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34); - Call_Back_Delay(1); - } -} - - -void ScoreClass::Show_Credits(int house, char const pal[]) -{ - static int _credsx[2]={276,276}; - static int _credsy[2]={173,58}; - static int _credpx[2]={228,236}; -#ifdef GERMAN - static int _credpy[2]={181, 74}; - static int _credtx[2]={162,162}; - static int _credty[2]={173, 62}; -#else - static int _credpy[2]={189-12, 74}; - static int _credtx[2]={182,182}; - static int _credty[2]={179-12, 62}; -#endif - - int credobj,i; - int min,add; - - void const * credshape = MixFileClass::Retrieve("CREDS.SHP"); - - Alloc_Object(new ScorePrintClass(TXT_SCORE_ENDCRED, _credtx[house], _credty[house],pal)); - Call_Back_Delay(15); - - credobj = Alloc_Object(new ScoreCredsClass(_credsx[house], _credsy[house], credshape, 32, 2)); - min = PlayerPtr->Available_Money() / 100; - - /* - ** Print out total credits left at end of scenario - */ - i = -50; - - BlitList.Add (2* (_credpx[house]), 2* (_credpy[house]), 2* (_credpx[house]), 2* (_credpy[house]), 5*12 , 12); - - do { - add = 5; - if ((PlayerPtr->Available_Money() - i) > 100 ) add += 15; - if ((PlayerPtr->Available_Money() - i) > 1000) add += 30; - if (add < min) add = min; - i += add; - - if (i < 0) i=0; - - Set_Font_Palette(pal); - Count_Up_Print("%d", i, PlayerPtr->Available_Money(), _credpx[house], _credpy[house]); - Call_Back_Delay(2); - if (Check_Key()) { - i=PlayerPtr->Available_Money() - 5; - Keyboard::Clear(); - } - } while (i < PlayerPtr->Available_Money()) ; - - // Make sure the credits object doesn't freeze on the white stage - while (((ScoreTimeClass *)ScoreObjs[credobj])->Stage >= 20 && !ControlQ) { - Call_Back_Delay(1); - } - delete ScoreObjs[credobj]; - ScoreObjs[credobj] = 0; -} - - -/*************************************************************************** - * SCORECLASS::PRINT_MINUTES -- Print out hours/minutes up to max * - * * - * Same as count-up-print, but for the time * - * * - * INPUT: current minute count and maximum * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/13/1995 BWG : Created. * - *=========================================================================*/ -void ScoreClass::Print_Minutes(int minutes) -{ - char str[20]; - if (minutes >= 60) { - if ((minutes/60) > 9) minutes = (9*60 + 59); - sprintf(str,Text_String(TXT_SCORE_TIMEFORMAT1), (minutes / 60),(minutes % 60)); - } else { - sprintf(str,Text_String(TXT_SCORE_TIMEFORMAT2), minutes); - } - TextPrintBuffer->Print(str, 275*2, 9*2, TBLACK, TBLACK); -} - - -/*********************************************************************************************** - * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly. * - * * - * This routine prints out a number (like 70) or its maximum number, into a string, onto * - * the screen, on a clean section of the screen, and blits it forward to the seenpage so you* - * can print without flashing and can print over something (to count up %'s). * - * * - * INPUT: str = string to print into * - * percent = # to print * - * max = # to print if percent > max * - * xpos = x pixel coord * - * ypos = y pixel coord * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/07/1995 BWG : Created. * - *=============================================================================================*/ -void ScoreClass::Count_Up_Print(char *str, int percent, int max, int xpos, int ypos) -{ - char destbuf[64]; - int width; - - sprintf(destbuf, str, percent <= max ? percent : max); - width = strlen(destbuf) * 7; - - - - -// HidPage.Blit(HidPage, xpos, ypos, 0, 0, width, 8); -// Set_Logic_Page(HidPage); -// LogicPage->Print( destbuf, 0, 0, WHITE, TBLACK); -// HidPage.Blit(SeenBuff, 0, 0, xpos, ypos, width, 8); - - TextPrintBuffer->Fill_Rect (xpos*2, ypos*2, (xpos + width)*2, (ypos+7)*2, BLACK); - TextPrintBuffer->Print (destbuf, xpos*2, ypos*2, WHITE, TBLACK); - - - //TextPrintBuffer->Blit(*TextPrintBuffer, xpos*2, ypos*2, 0, 0, width*2, 8*2); - //TextPrintBuffer->Print(destbuf, 0, 0, WHITE, TBLACK); - //TextPrintBuffer->Blit(SeenBuff, 0, 0, xpos*2, ypos*2, width*2, 8*2); - -// PseudoSeenBuff->Print( destbuf, xpos, ypos, TBLACK, BLACK); -// Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , NULL); - -} - - -/*********************************************************************************************** - * ScoreClass::Input_Name -- Gets the name from the keyboard * - * * - * This routine handles keyboard input, and does a nifty zooming letter effect too. * - * * - * INPUT: str = string to put user's typing into * - * xpos = x pixel coord * - * ypos = y pixel coord * - * pal = text remapping palette to print using * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/15/1995 BWG : Created. * - *=============================================================================================*/ -void ScoreClass::Input_Name(char str[], int xpos, int ypos, char const pal[]) -{ - int key, ascii, index=0; - - void const * keystrok = MixFileClass::Retrieve("KEYSTROK.AUD"); - - /* - ** Ready the hidpage so it can restore background under zoomed letters - */ - PseudoSeenBuff->Blit(SysMemPage); - - do { - Call_Back(); - Animate_Score_Objs(); - Animate_Cursor(index, ypos); - /* - ** Extra font related stuff. ST - 7/29/96 2:22PM - */ - Interpolate_2X_Scale (PseudoSeenBuff , &HidPage ,NULL); - BlitList.Update(); - Blit_Hid_Page_To_Seen_Buff(); - - if (Check_Key()) { //if (Keyboard::Check()) { - key = Get_Key(); //key = Keyboard::Get(); - - if (index == MAX_FAMENAME_LENGTH-2) { - while (Check_Key()) { - Get_Key(); - } - } - - /* - ** If they hit 'backspace' when they're on the last letter, - ** turn it into a space instead. - */ - if ((key == KA_BACKSPACE) && (index == MAX_FAMENAME_LENGTH-2) ) { - if (str[index] && str[index]!=32) key = 32; - } - if (key == KA_BACKSPACE) { //if (key == KN_BACKSPACE) { - if (index) { - str[--index] = 0; - - int xposindex6 = xpos+(index*6); - - PseudoSeenBuff->Fill_Rect(xposindex6,ypos,xposindex6+6,ypos+6,TBLACK); - SysMemPage.Fill_Rect(xposindex6,ypos,xposindex6+6,ypos+6,TBLACK); - TextPrintBuffer->Fill_Rect(xposindex6*2,ypos*2,(xposindex6+6)*2,(ypos+6)*2, BLACK); - } - - } else if (key!=KA_RETURN) { //else if (key != KN_RETURN && key!=KN_KEYPAD_RETURN) { - ascii = key; //ascii = KN_To_KA(key); - if (ascii >= 'a' && ascii <= 'z') ascii -= ('a' - 'A'); -//if (ascii >='A' && ascii<='Z' || ascii == ' ') { -if ( (ascii >= '!' && ascii <= KA_TILDA) || ascii == ' ') { - PseudoSeenBuff->Fill_Rect(xpos + (index*6), ypos, xpos + (index*6)+6, ypos+5, TBLACK); - SysMemPage.Fill_Rect(xpos + (index*6), ypos, xpos + (index*6)+6, ypos+5, TBLACK); - TextPrintBuffer->Fill_Rect(2*(xpos + (index*6)), ypos*2, 2*(xpos + (index*6)+6), 2*(ypos+6), BLACK); - str[index] = ascii; - str[index+1] = 0; - - int objindex; - Play_Sample(keystrok, 255, Options.Normalize_Sound(255)); - objindex = Alloc_Object(new ScoreScaleClass(str+index,xpos+(index*6), ypos, pal)); - while (ScoreObjs[objindex]) Call_Back_Delay(1); - - if (index < (MAX_FAMENAME_LENGTH-2) ) index++; - } - } - } - } while(key!=KA_RETURN); // } while(key != KN_RETURN && key!=KN_KEYPAD_RETURN); -} - - -void Animate_Cursor(int pos, int ypos) -{ - static int _lastpos, _state; - static CountDownTimerClass _timer; - - ypos += 7; // move cursor to bottom of letter - - // If they moved the cursor, erase old one and force state=0, to make green draw right away - if (pos != _lastpos) { - PseudoSeenBuff->Draw_Line(HALLFAME_X + (_lastpos*6),ypos, HALLFAME_X + (_lastpos*6) + 5, ypos, TBLACK); - TextPrintBuffer->Fill_Rect(2*(HALLFAME_X + (_lastpos*6)),2*ypos, 2*(HALLFAME_X + (_lastpos*6) + 5), 2*ypos+1, BLACK); - _lastpos = pos; - _state = 0; - } - - PseudoSeenBuff->Draw_Line(HALLFAME_X + (pos*6),ypos, HALLFAME_X + (pos*6)+5, ypos, _state ? LTBLUE : TBLACK); - TextPrintBuffer->Fill_Rect(2*(HALLFAME_X + (pos*6)),2*ypos, 2*(HALLFAME_X + (pos*6)+5), 2*ypos+1, _state ? LTBLUE : BLACK); - - /* - ** Toggle the color of the cursor, green or black, if it's time to do so. - */ - if (!_timer.Time()) { - _state ^= 1; - _timer.Set(5); - } -} - - -/*************************************************************************** - * Draw_InfantryMen -- Draw all the guys on the score screen * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/13/1995 BWG : Created. * - *=========================================================================*/ -void Draw_InfantryMen() -{ - int k; - -// Only draw the infantrymen if we're playing Nod... GDI wouldn't execute -// people like that. - - /* - ** First restore the background - */ - SysMemPage.Blit(SysMemPage, BARGRAPH_X, CASUALTY_Y, 0, 0, 320-BARGRAPH_X, 34); - Set_Logic_Page(SysMemPage); - - /* - ** Then draw all the infantrymen on the clean SysMemPage - */ - for (k = 0; k < NUMINFANTRYMEN; k++) Draw_InfantryMan(k); - /* - ** They'll all be blitted over to the seenpage after the graphs are drawn - */ -} - -/*************************************************************************** - * Draw_InfantryMan -- Draw one guy in score screen, update animation * - * * - * This routine draws one of the infantrymen in the "Casualties" area * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/13/1995 BWG : Created. * - *=========================================================================*/ -void Draw_InfantryMan(int index) -{ - int stage; - - /* If the infantryman's dead, just abort this function */ - if (InfantryMan[index].anim == -1) return; - - stage = InfantryMan[index].stage + InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Frame; - - CC_Draw_Shape(InfantryMan[index].shapefile, - stage, - InfantryMan[index].xpos, - InfantryMan[index].ypos, - WINDOW_MAIN, - SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST, - InfantryMan[index].remap, - Map.UnitShadow); - /* - ** see if it's time to run a new anim - */ - if (--InfantryMan[index].delay < 0) { - InfantryMan[index].delay = 3; - if (++InfantryMan[index].stage >= InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Count) { - - /* - ** was he playing a death anim? If so, and it's done, erase him - */ - if (InfantryMan[index].anim >= DO_GUN_DEATH) { - InfantryMan[index].anim = -1; - } else { - New_Infantry_Anim(index, DO_STAND_READY); - } - } - } -} - - -/*************************************************************************** - * New_Infantry_Anim -- Start up a new animation for one of the infantrymen* - * * - * * - * * - * INPUT: index: which of the 30 infantrymen to affect * - * anim: which animation sequence to start him into * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/13/1995 BWG : Created. * - *=========================================================================*/ -void New_Infantry_Anim(int index, int anim) -{ - InfantryMan[index].anim = anim; - InfantryMan[index].stage = 0; - if (anim >= DO_GUN_DEATH) { - InfantryMan[index].delay = 1; // start right away - } else { - InfantryMan[index].delay = Random() & 15; - } -} - - -/*************************************************************************** - * Draw_Bar_Graphs -- Draw "Casualties" bar graphs * - * * - * * - * * - * INPUT: i = current count of how far to draw graph * - * gkilled = # of GDI forces killed (adjusted to fit in space) * - * nkilled = # of Nod forces killed (adjusted to fit in space) * - * ckilled = # of civilians killed (adjusted to fit in space) * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/13/1995 BWG : Created. * - *=========================================================================*/ -void Draw_Bar_Graphs(int i, int gkilled, int nkilled, int ckilled) -{ - if (gkilled) { - LogicPage->Fill_Rect(0, 0+4, 0+MIN(i,gkilled), 0+5, LTCYAN); - LogicPage->Draw_Line(0+1, 0+6, 0+MIN(i,gkilled)+1, 0+6, TBLACK); - LogicPage->Draw_Line(0+MIN(i,gkilled)+1,0+5, 0+MIN(i,gkilled)+1, 0+5, TBLACK); - if (i <= gkilled) { - int anim = InfantryMan[i/11].anim; - if (anim!=-1 && anim < DO_GUN_DEATH) { - if (i/11) { - New_Infantry_Anim(i/11,DO_GUN_DEATH + (Random() & 3)); - } else { - New_Infantry_Anim(i/11,DO_GUN_DEATH); - } -// Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5)); - } - } - } - if (nkilled) { - LogicPage->Fill_Rect(0, 0+16, 0+MIN(i,nkilled), 0+17, RED); - LogicPage->Draw_Line(0+1, 0+18, 0+MIN(i,nkilled)+1, 0+18, TBLACK); - LogicPage->Draw_Line(0+MIN(i,nkilled)+1, 0+17, 0+MIN(i,nkilled)+1, 0+17, TBLACK); - if (i <= nkilled) { - int anim = InfantryMan[(NUMINFANTRYMEN/3)+(i/11)].anim; - if (anim!=-1 && anim < DO_GUN_DEATH) { - if (i/11) { - New_Infantry_Anim((NUMINFANTRYMEN/3)+(i/11),DO_GUN_DEATH + (Random() & 3)); - } else { - New_Infantry_Anim((NUMINFANTRYMEN/3)+(i/11),DO_GUN_DEATH); - } -// Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5)); - } - } - } - - if (ckilled) { - LogicPage->Fill_Rect(0, 0+28, 0+MIN(i,ckilled), 0+29, RED); - LogicPage->Draw_Line(0+1, 0+30, 0+MIN(i,ckilled)+1, 0+30, TBLACK); - LogicPage->Draw_Line(0+MIN(i,ckilled)+1, 0+29, 0+MIN(i,ckilled)+1, 0+29, TBLACK); - if (i <= ckilled) { - int anim = InfantryMan[((NUMINFANTRYMEN*2)/3)+(i/11)].anim; - if (anim!=-1 && anim < DO_GUN_DEATH) { - if (i/11) { - New_Infantry_Anim(((NUMINFANTRYMEN*2)/3)+(i/11),DO_GUN_DEATH + (Random() & 3)); - } else { - New_Infantry_Anim(((NUMINFANTRYMEN*2)/3)+(i/11),DO_GUN_DEATH); - } -// Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5)); - } - } - } -} - - -/*************************************************************************** - * Call_Back_Delay -- Combines Call_Back() and Delay() functions * - * * - * This is just to cut down on code size and typing a little. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/13/1995 BWG : Created. * - *=========================================================================*/ -void Call_Back_Delay(int time) -{ - CountDownTimerClass cd; - - if (!ControlQ) { - if (Keyboard::Down(KN_LCTRL) && Keyboard::Down(KN_Q)) { - ControlQ = 1; - Keyboard::Clear(); - } - } - if (ControlQ) time=0; - - cd.Set(time); - StreamLowImpact = true; - do { - Call_Back(); - //Animate_Score_Objs(); - //Interpolate_2X_Scale(PseudoSeenBuff , &SeenBuff ,NULL); - - //if (Get_Mouse_State()){ - // Interpolate_2X_Scale(PseudoSeenBuff , &SeenBuff ,NULL); - //BlitList.Update(); - //}else{ - Animate_Score_Objs(); - Interpolate_2X_Scale(PseudoSeenBuff , &HidPage ,NULL); - BlitList.Update(); - WWMouse->Draw_Mouse(&HidPage); - Blit_Hid_Page_To_Seen_Buff(); - WWMouse->Erase_Mouse(&HidPage, TRUE); - //} - } while(cd.Time()); - StreamLowImpact = false; -} - - -void Animate_Score_Objs() -{ - StillUpdating = false; - for (int i = 0; i < MAXSCOREOBJS; i++) { - if (ScoreObjs[i]) { - ScoreObjs[i]->Update(); - } - } -} - -char *Int_Print(int a) -{ - static char str[10]; - - sprintf(str,"%d",a); - return str; -} - - -/*********************************************************************************************** - * Multi_Score_Presentation -- Multiplayer routine to display score screen. * - * * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/11/1995 BWG: Created. * - *=============================================================================================*/ -void Multi_Score_Presentation(void) -{ - static unsigned char const _cycleyellowpal[]={0x0,0xec,0xEb,0xea,0xE9,0xe9,0xE9,0x0,0xE9,0x0,0x0,0x0,0x0,0x0,0xED,0x0}; - - static unsigned char const _greenpal[]= {0x0,0x12,0x14,0x16,0x18,0x18,0x18,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x10,0x0}; - static unsigned char const _redpal[]= {0x0,0x22,0x24,0x26,0x28,0x28,0x28,0x0,0x28,0x0,0x0,0x0,0x0,0x0,0x20,0x0}; - static unsigned char const _graypal[]= {0x0,0xca,0xCb,0xcc,0xCd,0xcd,0xCd,0x0,0xCD,0x0,0x0,0x0,0x0,0x0,0xC8,0x0}; - static unsigned char const _orangepal[]={0x0,0xd1,0xD2,0xd3,0xD4,0xd4,0xD4,0x0,0xD4,0x0,0x0,0x0,0x0,0x0,0xD0,0x0}; - static unsigned char const _bluepal[]= {0x0,0x2,0x0a,0xb,0x0b,0xb,0x0B,0x0,0x0B,0x0,0x0,0x0,0x0,0x0,0x09,0x0}; - static unsigned char const _yellowpal[]={0x0,0x5,0xee,0xf1,0xf2,0xf2,0xF2,0xf2,0xF2,0x0,0x0,0x0,0x0,0x0,0x7D,0x0}; - - //static char const _greenpal[]= {0x0,0x0,0x12,0x0,0x14,0x0,0x16,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x10,0x0}; - //static char const _redpal[]= {0x0,0x0,0x22,0x0,0x24,0x0,0x26,0x0,0x28,0x0,0x0,0x0,0x0,0x0,0x20,0x0}; - //static char const _graypal[]= {0x0,0x0,0xCA,0x0,0xCB,0x0,0xCC,0x0,0xCD,0x0,0x0,0x0,0x0,0x0,0xC8,0x0}; - //static char const _orangepal[]={0x0,0x0,0xD1,0x0,0xD2,0x0,0xD3,0x0,0xD4,0x0,0x0,0x0,0x0,0x0,0xD0,0x0}; - //static char const _bluepal[]= {0x0,0x0,0x02,0x0,0x0A,0x0,0x0B,0x0,0x0B,0x0,0x0,0x0,0x0,0x0,0x09,0x0}; - //static char const _yellowpal[]={0x0,0x0,0x05,0x0,0xEE,0x0,0xF1,0x0,0xF2,0x0,0x0,0x0,0x0,0x0,0x7D,0x0}; - - static unsigned char const *_colors[]={_yellowpal,_redpal,_bluepal,_orangepal,_greenpal,_graypal}; - - int i,k; - void *oldfont, *anim; - int oldfontxspacing = FontXSpacing; - char const *pal; - - - FontXSpacing = 0; - Map.Override_Mouse_Shape(MOUSE_NORMAL); - Theme.Queue_Song(THEME_WIN1); - - PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL); - TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height() ,(void*)NULL); - BlitList.Clear(); - - SysMemPage.Clear(); - PseudoSeenBuff->Clear(); - HiddenPage.Clear(); - TextPrintBuffer->Clear(); - - Set_Palette(BlackPalette); - - anim = Open_Animation("MLTIPLYR.WSA",NULL,0L,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette); - Hide_Mouse(); - - /* - ** Display the background animation - */ - VisiblePage.Clear(); - InterpolationPaletteChanged = TRUE; - InterpolationPalette = Palette; - Increase_Palette_Luminance (Palette , 30,30,30,63); - Animate_Frame(anim, *PseudoSeenBuff, 1); - Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , "MULTSCOR.PAL"); - Fade_Palette_To(Palette, FADE_PALETTE_FAST, Call_Back); - - int frame = 1; - while (frame < Get_Animation_Frame_Count(anim)) { - Animate_Frame(anim, *PseudoSeenBuff, frame++); - Call_Back_Delay(2); - } - Close_Animation(anim); - - /* Change to the six-point font for Text_Print */ - oldfont = Set_Font(ScoreFontPtr); - Call_Back(); - - Set_Logic_Page(*PseudoSeenBuff); - - /* - ** Move all the scores over a notch if there's more games than can be - ** shown (which is known by MPlayerCurGame == MAX_MULTI_GAMES-1); - */ - if (MPlayerCurGame == MAX_MULTI_GAMES-1) { - for(i = 0; i < MAX_MULTI_NAMES; i++) { - for(k = 0; k < MAX_MULTI_GAMES-1; k++) { - MPlayerScore[i].Kills[k] = MPlayerScore[i].Kills[k+1]; - } - } - } - - int y = 41; - for(i = 0; i < MAX_MULTI_NAMES; i++) { - if (strlen(MPlayerScore[i].Name)) { - pal = (const char*)_colors[MPlayerScore[i].Color]; - - Alloc_Object(new ScorePrintClass(MPlayerScore[i].Name, 15, y,pal)); - Call_Back_Delay(20); - - Alloc_Object(new ScorePrintClass(Int_Print(MPlayerScore[i].Wins), 118, y, pal)); - Call_Back_Delay(6); - - for(k = 0; k <= MIN(MPlayerCurGame, MAX_MULTI_GAMES-2); k++) { - if (MPlayerScore[i].Kills[k] >= 0) { - Alloc_Object(new ScorePrintClass(Int_Print(MPlayerScore[i].Kills[k]), 225+(24*k), y, pal)); - Call_Back_Delay(6); - } - } - y += 12; - } - } - -#if (FRENCH) - Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 90 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 185, _cycleyellowpal)); -#else - Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 109 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 185, _cycleyellowpal)); -#endif - Cycle_Wait_Click(); - -/* get rid of all the animating objects */ - for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) { - delete ScoreObjs[i]; - ScoreObjs[i] = 0; - } - - Theme.Queue_Song(THEME_NONE); - - Fade_Palette_To(BlackPalette, FADE_PALETTE_FAST, NULL); - VisiblePage.Clear(); - Set_Palette(GamePalette); - - Set_Logic_Page (SeenBuff); - - delete PseudoSeenBuff; - delete TextPrintBuffer; - BlitList.Clear(); - - Set_Font(oldfont); - FontXSpacing = oldfontxspacing; - ControlQ = 0; - Show_Mouse(); -} - -#ifdef WRITE_LBM - // A BitMapHeader is stored in a BMHD chunk. This structure MUST be an even size -typedef struct { - unsigned short w, h; // raster width & height in pixels - unsigned short x, y; // position for this image - unsigned char planes; // # source bitplanes - unsigned char masking; // masking technique - unsigned char compression; // compression algoithm - unsigned char pad1; // UNUSED. For consistency, put 0 here. - unsigned short transcolor; // transparent "color number" - unsigned char xaspect, yaspect; // aspect ratio, a rational number x/y - unsigned short pagewidth, pageheight; // source "page" size in pixels -} BitMapHeaderType; - -// All values in LocalHeader are always the same except planes. This is set in Write_BMHD -// the WORD values must be in low-high order for compatibility. - -static BitMapHeaderType LocalHeader = { - 0x4001, 0xc800, 0, 0, 0, 0, // width, height, x, y, planes, mask - 1, 0, 0xFF00, 5, 6, // compress, pad1, transcolor, xasptect, yaspect - 0x4001, 0xC800 }; // pagewidth, pageheight - -#define BM_HEADER_SIZE (((sizeof(BitMapHeaderType) + 1) & 0xFFFE) + 8L) - -/*=========================================================================*/ -/* The following static functions are in this file: */ -/*=========================================================================*/ - -static long CCWrite_BMHD(CCFileClass &lbmhandle, short bitplanes); -static long CCWrite_CMAP(CCFileClass &lbmhandle, unsigned char * palette, short bitplanes); -static long CCWrite_BODY(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes); -static long CCWrite_Row(CCFileClass &lbmhandle, unsigned char *buffer); - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -/*************************************************************************** - * CCWrite_LBM_File -- Writes out a file in LBM format * - * * - * INPUT: short lbmhandle -- lbm file handle already opened by caller * - * BufferClass buff -- buff where MCGA picture is * - * short bitplane -- number of bitplanes to convert to * - * char *palette -- pointer to palette for buff * - * * - * OUTPUT: Returns bool -- successfull or not * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/18/1991 SB : Created. * - *=========================================================================*/ -bool CCWrite_LBM_File(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes, unsigned char *palette) -{ - long filesize; - - - lbmhandle.Seek(0L, SEEK_SET); // goto beginning of file - - lbmhandle.Write("FORM????ILBM", 12L); // First 12 bytes of all .lbm files - // size is unkown so write ???? - filesize = 12L; // 4 bytes for "ILBM" - - filesize += CCWrite_BMHD(lbmhandle, bitplanes); // write out BMHD (fixed size) - filesize += CCWrite_CMAP(lbmhandle, palette, bitplanes); // write out CMAP - - // Write out the body, or compressed picture image. This size will depend - // on the compression, but the value passed back is what the compressor - // assumed was written to file - - filesize += CCWrite_BODY(lbmhandle, buff, bitplanes); - - // Verify that we were able to write out the file without running out of space - if (lbmhandle.Seek(0L, SEEK_END) != filesize) { - return(false); - } - - lbmhandle.Seek(4L, SEEK_SET); // goto beginning of file - filesize = Reverse_LONG(filesize - 8L); // - 8 because of "FORM" + short (size) - lbmhandle.Write( (char *) &filesize, 4L); // patch in filesize - - return(true); -} - - -/*************************************************************************** - * CCWrite_BMHD -- writes out the bit map header (LocalHeader) * - * * - * INPUT: short lbmhandle -- file handle for lbm file * - * short pitplanes -- number of bitplanes to write out * - * * - * OUTPUT: LONG number of bytes hopefully written out to .LBM file * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/19/1991 SB : Created. * - *=========================================================================*/ -static long CCWrite_BMHD(CCFileClass &lbmhandle, short bitplanes) -{ - long size; - - lbmhandle.Write("BMHD", 4L); // write out chunk title - size = Reverse_LONG(sizeof(LocalHeader)); // write out size of LocalHeader chunk - lbmhandle.Write((char *) &size, 4L); - - LocalHeader.planes = bitplanes; // only nonconstant value in LocalHeader - - // Make sure size is even. Return 8 = "BMHD" + size of the bitmap header structure - - return(lbmhandle.Write((char *) &LocalHeader, - (sizeof(LocalHeader) + 1) & 0xFFFE) + 8L); -} - - -/*************************************************************************** - * CCWrite_CMAP -- Writes out CMAP (palette) information * - * * - * * - * INPUT: short lbmhandle -- file handle of lbm file * - * char * palette -- pointer to paletter information * - * short bitplanes -- used to figure out size of palette * - * * - * OUTPUT: long number of bytes that should have been written out to .LBM. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/19/1991 SB : Created. * - *=========================================================================*/ -static long CCWrite_CMAP(CCFileClass &lbmhandle, unsigned char * palette, short bitplanes) -{ - short color, r, g, b, colors; - long size; - unsigned char *pal_ptr; - char rgb[3]; - - - lbmhandle.Write("CMAP", 4L); // write out palette info - colors = 1 << bitplanes; // colors = 2 to the bitplanes - size = Reverse_LONG(colors * 3L); // size = colors * 3 guns - - lbmhandle.Write((char *) &size, 4L); - - for (pal_ptr = palette, color = 0; color < colors; color++) { // for each color - - if ((r = *pal_ptr++) != 0) { // DPaint changes allows 0 - 100 for gun values - r = (r << 2) | 0x03; // this must be converted to 0 - 256 for LBM - } // so LBM_val = (DP_val * 4) | 3 if DP_val != 0 - if ((g = *pal_ptr++) != 0) { - g = (g << 2) | 0x03; - } - if ((b = *pal_ptr++) != 0) { - b = (b << 2) | 0x03; - } - rgb[0] = r; // assign gun values to an array to write out - rgb[1] = g; - rgb[2] = b; - - lbmhandle.Write(rgb, 3L); - } - // size = colors * 3 - return(((colors << 1) + colors) + 8L); // total size of CMAP 8 = "CMAP" + short (size) -} - - -/*************************************************************************** - * CCWrite_Body -- writes out compressed data in an LBM file * - * * - * INPUT: short lbmhandle -- file handle of lbm file * - * * - * OUTPUT: long - number of byte written * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/19/1991 SB : Created. * - *=========================================================================*/ -static long CCWrite_BODY(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes) -{ - long bodysize = 0; - long actualsize; - long size; - short planebit; - short line, plane; - unsigned char buffer[40]; - unsigned char *buffptr; - - lbmhandle.Write("BODY????", 8L); // BODY chunk ID, ???? reserved for chuncksize - - buffptr = (unsigned char *) buff.Get_Buffer(); // point to beginning of buff - - for (line = 0; line < 200; line++) { - planebit = 1; // start with bit 1 set - - for (plane = 0; plane < bitplanes; plane++) { - Pack_2_Plane(buffer, buffptr, planebit); // convert to planar - bodysize += CCWrite_Row(lbmhandle, buffer); // write to to the BODY in the LBM - - planebit <<= 1; // set next bit - } - - buffptr += 320; // row size is 320 - } - - actualsize = bodysize + (bodysize&0x01); - - if (actualsize != bodysize) { - lbmhandle.Write(buffer, 1); // Padd the block. - } - - lbmhandle.Seek( -(actualsize + 4L), SEEK_CUR); // Patch in chunksize - size = Reverse_LONG(bodysize); - lbmhandle.Write( (char *) &size ,4L); - - return(actualsize + 8L); // total size of BODY, "BODY????" = 8 bytes -} - - -/*************************************************************************** - * CCWrite_Row -- compresses and writes a row plane to .lbm file * - * * - * INPUT: short lbmhandle -- lbm file handle * - * unsigned char *buffer -- pointer to buffer to be written out * - * * - * OUTPUT: long size of chunk that should have been written out * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/19/1991 SB : Created. * - *=========================================================================*/ -static long CCWrite_Row(CCFileClass &lbmhandle, unsigned char *buffer) -{ - short i; - short chunksize = 0; - short dataLength = 40; // 320 rows / 8 ( 1 plane per row) - unsigned char repCode, current, curr_plus_2; - unsigned char *buffptr; - - while (dataLength) { - - // If at least 2 more bytes and they are equal, then replicate - - if ((dataLength >= 2) && (buffer[0] == buffer[1])) { - buffptr = buffer; - for (i = 0; (i <= 128) && (i < (dataLength - 1)); i++) { - if (*buffptr != buffptr[1]) { - break; - } - buffptr++; - } - i++; - repCode = -i + 1; - lbmhandle.Write(&repCode, 1L); // Write count as -count+1 - lbmhandle.Write(buffer, 1L); // Write byte to replicate - buffer += i; - dataLength -= i; - chunksize += 2; - - } else { // Copy literally till 3 byte run or two 2 byte runs found - - for (i = 0; (i <= 128) && (i < dataLength); i++) { - current = buffer[i]; - curr_plus_2 = buffer[i + 2]; - - if (i == dataLength - 1) - continue; - if (current != buffer[i + 1]) - continue; - if (i == dataLength - 2) - continue; - if (current == curr_plus_2) - break; - if (i == dataLength - 3) - continue; - if (curr_plus_2 == buffer[i + 3]) - break; - } - repCode = i - 1; - lbmhandle.Write(&repCode, 1L); // Write count as count-1 - lbmhandle.Write(buffer, (long) i); // Write 'count' bytes - buffer += i; - dataLength -= i; - chunksize += i + 1; - } - } // end while - - return(chunksize); -} -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/SCORE.H b/code/TIBERIANDAWN/SCORE.H deleted file mode 100644 index 55fd22a..0000000 --- a/code/TIBERIANDAWN/SCORE.H +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\score.h_v 2.18 16 Oct 1995 16:46:18 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SCORE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 19, 1994 * - * * - * Last Update : April 19, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SCORE_H -#define SCORE_H - -#include "unit.h" -#include "building.h" - -class ScoreClass { - public: - int Score; - int NKilled; - int GKilled; - int CKilled; - int NBKilled; - int GBKilled; - int CBKilled; - int NHarvested; - int GHarvested; - int CHarvested; - unsigned long ElapsedTime; - - void Init(void) {memset(this, 0, sizeof(ScoreClass));}; - void Presentation(void); - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - protected: - - private: - unsigned char *ChangingGun; - - void ScoreDelay(int ticks); - void Pulse_Bar_Graph(void); - void Print_Graph_Title(int,int); - void Print_Minutes(int minutes); - void Count_Up_Print(char *str, int percent, int max, int xpos, int ypos); - void Show_Credits(int house, char const pal[]); - void Do_GDI_Graph(void const * yellowptr, void const * redptr, int gdikilled, int nodkilled, int ypos); - void Do_Nod_Casualties_Graph(void); - void Do_Nod_Buildings_Graph(void); - void Input_Name(char str[], int xpos, int ypos, char const pal[]); -}; - -class ScoreAnimClass { - public: - ScoreAnimClass(int x, int y, void const * data); - int XPos; - int YPos; - CountDownTimerClass Timer; - void const * DataPtr; - virtual void Update(void) {} ; - virtual ~ScoreAnimClass(void) {} ; -}; - -class ScoreCredsClass : public ScoreAnimClass { - public: - int Stage; - int MaxStage; - int TimerReset; - void const * CashTurn; - void const * Clock1; - - virtual void Update(void); - ScoreCredsClass(int xpos, int ypos, void const * data, int max, int timer); - virtual ~ScoreCredsClass(void) {}; -}; - -class ScoreTimeClass : public ScoreAnimClass { - public: - int Stage; - int MaxStage; - int TimerReset; - virtual void Update(void); - ScoreTimeClass(int xpos, int ypos, void const * data, int max, int timer); - virtual ~ScoreTimeClass(void) {}; -}; - -class ScorePrintClass : public ScoreAnimClass { - public: - int Background; - int Stage; - void const * PrimaryPalette; - virtual void Update(void); - ScorePrintClass(void const * string, int xpos, int ypos, void const * palette, int background=TBLACK); - ScorePrintClass( int string, int xpos, int ypos, void const * palette, int background=TBLACK); - virtual ~ScorePrintClass(void) {}; -}; - - -class MultiStagePrintClass : public ScoreAnimClass { - public: - int Background; - int Stage; - void const * PrimaryPalette; - virtual void Update(void); - MultiStagePrintClass(void const * string, int xpos, int ypos, void const * palette, int background=TBLACK); - MultiStagePrintClass( int string, int xpos, int ypos, void const * palette, int background=TBLACK); - virtual ~MultiStagePrintClass(void) {}; -}; - - -class ScoreScaleClass : public ScoreAnimClass { - public: - int Stage; - char const * Palette; - virtual void Update(void); - ScoreScaleClass(void const * data, int xpos, int ypos, char const pal[]); - virtual ~ScoreScaleClass(void) {}; - -}; - -#define MAXSCOREOBJS 8 -extern ScoreAnimClass *ScoreObjs[MAXSCOREOBJS]; - -void Multi_Score_Presentation(void); - -#endif diff --git a/code/TIBERIANDAWN/SCREEN.H b/code/TIBERIANDAWN/SCREEN.H deleted file mode 100644 index dddb05a..0000000 --- a/code/TIBERIANDAWN/SCREEN.H +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\screen.h_v 2.15 16 Oct 1995 16:47:38 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SCREEN.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 2, 1994 * - * * - * Last Update : June 2, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SCREEN_H -#define SCREEN_H - - -class ScreenClass -{ - /* - ** The mouse shape is controlled by these variables. These - ** hold the current mouse shape (so resetting won't be needlessly performed) and - ** the normal default mouse shape (when arrow shapes are needed). - */ - MouseShapeType CurrentMouseShape; - MouseShapeType NormalMouseShape; - - public: - - ScreenClass(void) { - CurrentMouseShape = SHP_NONE; - NormalMouseShape = SHP_MOUSE; - }; - - - Init(void); - Set_Default_Mouse(MouseShapeType mouse); - Force_Mouse_Shape(MouseShapeType mouse); - - unsigned char *GamePalette; - unsigned char *BlackPalette; -}; - -#endif diff --git a/code/TIBERIANDAWN/SCROLL.CPP b/code/TIBERIANDAWN/SCROLL.CPP deleted file mode 100644 index bb83262..0000000 --- a/code/TIBERIANDAWN/SCROLL.CPP +++ /dev/null @@ -1,255 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\scroll.cpv 2.18 16 Oct 1995 16:49:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SCROLL.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/08/95 * - * * - * Last Update : August 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ScrollClass::AI -- Handles scroll AI processing. * - * ScrollClass::ScrollClass -- Constructor for the scroll class object. * - * ScrollClass::Set_Autoscroll -- Turns autoscrolling on or off. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -#define SCROLL_DELAY 1 - -CountDownTimerClass ScrollClass::Counter; - - -/*********************************************************************************************** - * ScrollClass::ScrollClass -- Constructor for the scroll class object. * - * * - * This is the constructor for the scroll class object. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - *=============================================================================================*/ -ScrollClass::ScrollClass(void) -{ - IsAutoScroll = true; - Counter.Set(SCROLL_DELAY); - Inertia = 0; - Counter.Start(); -} - - -/*********************************************************************************************** - * ScrollClass::AI -- Handles scroll AI processing. * - * * - * This routine is called every game frame for purposes of input processing. * - * * - * INPUT: input -- Reference to the keyboard/mouse event that just occurred. * - * * - * x,y -- The mouse coordinates. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/10/1995 JLB : Created. * - * 08/10/1995 JLB : Revamped for free smooth scrolling. * - * 08/25/1995 JLB : Handles new scrolling option. * - *=============================================================================================*/ -#define EVA_WIDTH 80 -void ScrollClass::AI(KeyNumType &input, int x, int y) -{ - - static DirType direction; - bool player_scrolled=false; - - /* - ** If rubber band mode is in progress, then don't allow scrolling of the tactical map. - */ - if (!IsRubberBand /*&& !IsTentative*/) { - - /* - ** Special check to not scroll within the special no-scroll regions. - */ - bool noscroll = false; - if (Special.IsScrollMod && y == 0 && ((x > 3 && x < EVA_WIDTH) || (x > SeenBuff.Get_Width()-EVA_WIDTH && x < SeenBuff.Get_Width()-3))) { - noscroll = true; - } - - if (!noscroll) { - - /* - ** Verify that the mouse is over a scroll region. - */ - if (Inertia || y == 0 || x == 0 || x == (SeenBuff.Get_Width()-1) || y == (SeenBuff.Get_Height()-1)) { - - if (y == 0 || x == 0 || x == (SeenBuff.Get_Width()-1) || y == (SeenBuff.Get_Height()-1)) { - - player_scrolled=true; - /* - ** Adjust the mouse coordinates to emphasise the - ** cardinal directions over the diagonals. - */ - int altx = x; - if (altx < 50) altx -= (50-altx)*2; - altx = MAX(altx, 0); - if (altx > (SeenBuff.Get_Width()-50)) altx += (altx-(SeenBuff.Get_Width()-50))*2; - altx = MIN(altx, SeenBuff.Get_Width()); - if (altx > 50 && altx < (SeenBuff.Get_Width()-50)) { - altx += ((SeenBuff.Get_Width()/2)-altx)/2; - } - - int alty = y; - if (alty < 50) alty -= (50-alty); - alty = MAX(alty, 0); - if (alty > (SeenBuff.Get_Height()-50)) alty += ((alty-(SeenBuff.Get_Height()-50))); - alty = MIN(alty, SeenBuff.Get_Height()); - - direction = (DirType)Desired_Facing256((SeenBuff.Get_Width())/2, (SeenBuff.Get_Height())/2, altx, alty); - } - int control = Dir_Facing(direction); - - /* - ** The mouse is over a scroll region so set the mouse shape accordingly if the map - ** can be scrolled in the direction indicated. - */ - static int _rate[9] = { - 0x01C0, - 0x0180, - 0x0140, - 0x0100, - 0x00C0, - 0x0080, - 0x0040, - 0x0020, - 0x0010 - }; - - int rate = 8-Inertia; - - if (rateDraw_Stamp(ptr, w + (h*Width), x + w*ICON_PIXEL_W, y + h*ICON_PIXEL_H, NULL, WINDOW_TACTICAL); - } - } - } -} - - -/*********************************************************************************************** - * SmudgeTypeClass::Prep_For_Add -- Prepares the scenario editor for adding a smudge object. * - * * - * This routine adds smudge objects to the list of objects that the scenario editor can * - * place upon the ground. It is only called from the scenario editor. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -void SmudgeTypeClass::Prep_For_Add(void) -{ - for (SmudgeType index = SMUDGE_FIRST; index < SMUDGE_COUNT; index++) { - if (As_Reference(index).Get_Image_Data()) { - Map.Add_To_List(&As_Reference(index)); - } - } -} -#endif - - -/*********************************************************************************************** - * SmudgeTypeClass::Create_And_Place -- Creates and places on map, a smudge object. * - * * - * This routine will, in one motion, create a smudge object and place it upon the map. * - * Since placing a smudge on the map will destroy the object, this routine will leave the * - * smudge object count unchanged. Typically, this routine is used by the scenario editor * - * for creating smudges and placing them on the map. * - * * - * INPUT: cell -- The cell to place the smudge object. * - * * - * OUTPUT: bool; Was the placement successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -bool SmudgeTypeClass::Create_And_Place(CELL cell, HousesType ) const -{ - if (new SmudgeClass(Type, Cell_Coord(cell))) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * SmudgeTypeClass::Create_One_Of -- Creates a smudge object of this type. * - * * - * This routine will create a smudge object of the appropriate type. Smudge objects are * - * transitory in nature. They exist only from the point of creation until they are given * - * a spot on the map to reside. At that time the map data is updated and the smudge * - * object is destroyed. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to a created smudge object. If none could be created, then * - * NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * SmudgeTypeClass::Create_One_Of(HouseClass *) const -{ - return(new SmudgeClass(Type, -1)); -} - - -/*********************************************************************************************** - * SmudgeTypeClass::Draw_It -- Renders the smudge image at the coordinate specified. * - * * - * This routine will draw the smudge overlay image at the coordinate (upper left) * - * specified. The underlying terrain icon is presumed to have already been rendered. * - * * - * INPUT: x,y -- Coordinate of the upper left corner of icon to render the smudge object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -void SmudgeTypeClass::Draw_It(int x, int y, int data) const -{ - void const * ptr = Get_Image_Data(); - if (ptr) { - IsTheaterShape = true; // Smudges are theater specific - CC_Draw_Shape(ptr, data, x, y, WINDOW_TACTICAL, SHAPE_WIN_REL); - IsTheaterShape = false; -// LogicPage->Draw_Stamp(ptr, data, x, y, NULL, WINDOW_TACTICAL); - } -} - - -/*********************************************************************************************** - * SmudgeTypeClass::One_Time -- Performs one-time initialization * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1994 JLB : Created. * - *=============================================================================================*/ -void SmudgeTypeClass::One_Time(void) -{ -} - diff --git a/code/TIBERIANDAWN/SEQCONN.CPP b/code/TIBERIANDAWN/SEQCONN.CPP deleted file mode 100644 index ea9ffee..0000000 --- a/code/TIBERIANDAWN/SEQCONN.CPP +++ /dev/null @@ -1,561 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\seqconn.cpv 1.9 16 Oct 1995 16:51:30 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SEQCONN.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 20, 1994 * - * * - * Last Update : April 9, 1995 [BRR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * SequencedConnClass::SequencedConnClass -- class constructor * - * SequencedConnClass::~SequencedConnClass -- class destructor * - * SequencedConnClass::Init -- Initializes connection queue to empty * - * SequencedConnClass::Send_Packet -- adds a packet to the send queue * - * SequencedConnClass::Receive_Packet -- adds packet to receive queue * - * SequencedConnClass::Get_Packet -- gets a packet from receive queue * - * SequencedConnClass::Service_Send_Queue -- services the send queue * - * SequencedConnClass::Service_Receive_Queue -- services recieve queue * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -// PG_TO_FIX -#if (0) - -/*************************************************************************** - * SequencedConnClass::SequencedConnClass -- class constructor * - * * - * INPUT: * - * numsend desired # of entries for the send queue * - * numreceive desired # of entries for the recieve queue * - * maxlen max length of an application packet * - * magicnum the packet "magic number" for this connection * - * retry_delta the time to wait between sends * - * max_retries the max # of retries allowed for a packet * - * (-1 means retry forever, based on this parameter) * - * timeout the max amount of time before we give up on a packet * - * (-1 means retry forever, based on this parameter) * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -SequencedConnClass::SequencedConnClass (int numsend, int numreceive, - int maxlen, unsigned short magicnum, unsigned long retry_delta, - unsigned long max_retries, unsigned long timeout) : - ConnectionClass (maxlen, magicnum, retry_delta, max_retries, timeout) -{ - NumRecNoAck = 0; - NumRecAck = 0; - NumSendNoAck = 0; - NumSendAck = 0; - - /*------------------------------------------------------------------------ - Allocate the packet Queue. This will store incoming packets (which will - be placed there by the Connection Manager), and outgoing packets (which - are placed there by this class when it "sends" a packet). - ------------------------------------------------------------------------*/ - Queue = new CommQueueClass (numsend, numreceive, MaxPacketLen); - -} /* end of SequencedConnClass */ - - -/*************************************************************************** - * SequencedConnClass::~SequencedConnClass -- class destructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -SequencedConnClass::~SequencedConnClass () -{ - delete Queue; -} - - -/*************************************************************************** - * SequencedConnClass::Init -- Initializes connection queue to empty * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -void SequencedConnClass::Init (void) -{ - Queue->Init(); - -} /* end of Init */ - - -/*************************************************************************** - * SequencedConnClass::Send_Packet -- adds a packet to the send queue * - * * - * This routine prefixes the given buffer with a CommHeaderType and * - * queues the resulting packet into the Send Queue. (It's actually the * - * Service() routine that handles the hardware-dependent Send of the data).* - * The packet's MagicNumber, Code, and PacketID are set here. * - * * - * INPUT: * - * buf buffer to send * - * buflen length of buffer * - * ack_req true = ACK is required for this packet; false = isn't * - * * - * OUTPUT: * - * 1 = packet was queue'd OK, 0 = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int SequencedConnClass::Send_Packet (void * buf, int buflen, int ack_req) -{ - /*........................................................................ - Set the magic # for the packet - ........................................................................*/ - ((CommHeaderType *)PacketBuf)->MagicNumber = MagicNum; - - /*........................................................................ - Set the packet Code: DATA_ACK if it requires an ACK, NOACK if it doesn't - Set the packet ID to the appropriate counter value. - ........................................................................*/ - if (ack_req) { - ((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_ACK; - ((CommHeaderType *)PacketBuf)->PacketID = NumSendAck; - } else { - ((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_NOACK; - ((CommHeaderType *)PacketBuf)->PacketID = NumSendNoAck; - } - - /*........................................................................ - Now build the packet - ........................................................................*/ - memcpy(PacketBuf + sizeof(CommHeaderType), buf, buflen); - - /*........................................................................ - Add it to the queue. - ........................................................................*/ - if (Queue->Queue_Send(PacketBuf,buflen + sizeof(CommHeaderType))) { - if (ack_req) { - NumSendAck++; - } else { - NumSendNoAck++; - } - return(true); - - } else { - return(false); - } -} - - -/*************************************************************************** - * SequencedConnClass::Receive_Packet -- adds packet to the receive queue * - * * - * INPUT: * - * buf buffer to process (already includes CommHeaderType) * - * buflen length of buffer to process * - * * - * OUTPUT: * - * 1 = packet was processed OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int SequencedConnClass::Receive_Packet (void * buf, int buflen) -{ - CommHeaderType *packet; // ptr to this packet - SendQueueType *send_entry; // ptr to send entry header - ReceiveQueueType *rec_entry; // ptr to receive entry header - CommHeaderType *entry_data; // ptr to queue entry data - int save_packet = 1; // 0 = this is a resend, or - // out-of-order packet - - /* - --------------------------- Check the magic # ---------------------------- - */ - packet = (CommHeaderType *)buf; - if (packet->MagicNumber!=MagicNum) - return(false); - - /*------------------------------------------------------------------------ - Process the packet based on its Code - ------------------------------------------------------------------------*/ - switch (packet->Code) { - /*..................................................................... - DATA: If this is a No-Ack packet, always save it. Otherwise, only - save it if it's received in the proper sequence. - .....................................................................*/ - case PACKET_DATA_ACK: - case PACKET_DATA_NOACK: - if (packet->Code == PACKET_DATA_NOACK) { -#ifdef DEBUG_SEQ -printf("PACKET_DATA_NOACK received (%d)\n",packet->PacketID); -#endif - save_packet = 1; - } else { -#ifdef DEBUG_SEQ -printf("PACKET_DATA_ACK received (%d)\n",packet->PacketID); -#endif - if ((packet->PacketID == NumRecAck)) { - save_packet = 1; - } else { - save_packet = 0; - /*............................................................... - If this is a resend of our next-available received message, it - means the other app didn't get our ACK, so mark it as - non-acknowledged to tell Service_Receive_Queue to send an ACK. - ...............................................................*/ - rec_entry = Queue->Next_Receive(); - if (rec_entry) { - entry_data = (CommHeaderType *)rec_entry->Buffer; - if (entry_data->PacketID==packet->PacketID && - entry_data->Code == PACKET_DATA_ACK) { - rec_entry->IsACK = 0; -#ifdef DEBUG_SEQ -printf("(Resend)\n"); -#endif - } - } - } - } - - /* - ...................... queue this packet ........................ - */ - if (save_packet) { - if (!Queue->Queue_Receive(buf, buflen)) { - return(false); - } - if (packet->Code == PACKET_DATA_ACK) { - NumRecAck++; - } else { - NumRecNoAck++; - } - } - break; - - /*..................................................................... - ACK: If this ACK is for the latest-sent packet, mark that packet as - acknowledged, then throw this packet away. Otherwise, ignore the ACK - (if we re-sent before we received the other system's first ACK, this - ACK will be a leftover) - .....................................................................*/ - case PACKET_ACK: -#ifdef DEBUG_SEQ -printf("ACK received (%d)\n",packet->PacketID); -#endif - /* - ....................... Get queue entry ptr ........................ - */ - send_entry = Queue->Next_Send(); - /* - ............... If ptr is valid, get ptr to its data ............... - */ - if (send_entry!=NULL) { - entry_data = (CommHeaderType *)send_entry->Buffer; - - /* - .............. If ACK is for this entry, mark it ................ - */ - if (packet->PacketID==entry_data->PacketID && - entry_data->Code == PACKET_DATA_ACK) { - send_entry->IsACK = 1; - } - } - break; - - /*..................................................................... - Default: ignore the packet - .....................................................................*/ - default: - break; - - } /* end of switch */ - - return(true); -} - - -/*************************************************************************** - * SequencedConnClass::Get_Packet -- gets a packet from the receive queue * - * * - * INPUT: * - * buf location to store buffer * - * buflen filled in with length of 'buf' * - * * - * OUTPUT: * - * 1 = packet was read, 0 = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int SequencedConnClass::Get_Packet (void * buf, int *buflen) -{ - ReceiveQueueType *rec_entry; // ptr to receive entry header - int packetlen; // size of received packet - - /* - ------------------ Get ptr to the next available entry ------------------- - */ - rec_entry = Queue->Next_Receive(); - - /* - ------------------------ Read it if it's un-read ------------------------- - */ - if (rec_entry!=NULL && rec_entry->IsRead==0) { - /* - ........................... Mark as read .............................. - */ - rec_entry->IsRead = 1; - - /* - .......................... Copy data packet ........................... - */ - packetlen = rec_entry->BufLen - sizeof(CommHeaderType); - if (packetlen > 0) { - memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType), packetlen); - } - (*buflen) = packetlen; - return(true); - } - - return(false); -} - - -/*************************************************************************** - * SequencedConnClass::Service_Send_Queue -- services the send queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int SequencedConnClass::Service_Send_Queue (void) -{ - SendQueueType *send_entry; // ptr to send queue entry - CommHeaderType *packet_hdr; // packet header - unsigned long curtime; // current time - - /*------------------------------------------------------------------------ - - If the next packet is ACK'd remove it from the queue - - If the next packet isn't ACK'd, [re-]send it - ------------------------------------------------------------------------*/ - /* - ......................... Get ptr to data to send ........................ - */ - send_entry = Queue->Next_Send(); - if (send_entry==NULL) - return(true); - - /* - ------------------ If ACK has been received, unqueue it ------------------ - */ - if (send_entry->IsACK) { - - /* - .................. Update this queue's response time .................. - */ - packet_hdr = (CommHeaderType *)send_entry->Buffer; - if (packet_hdr->Code == PACKET_DATA_ACK) { - Queue->Add_Delay(Time() - send_entry->FirstTime); - } - - /* - ......................... unqueue the packet .......................... - */ -#ifdef DEBUG_SEQ -printf(">>>Unqueueing Receive packet #%d<<<\n",packet_hdr->PacketID); -#endif - Queue->UnQueue_Send(NULL,NULL); - } else { - - /* - ----------------- ACK not received yet, [re-]send packet ----------------- - */ - /*..................................................................... - Only send the message if time has elapsed. (The message's Time - fields are init'd to 0 when a message is queue'd or unqueue'd, so the - first time through, the delta time will appear large.) - .....................................................................*/ - curtime = Time(); - if (curtime - send_entry->LastTime > RetryDelta) { - /* - ......................... Send the message ......................... - */ - Send (send_entry->Buffer, send_entry->BufLen); - /* - ....................... Fill in Time fields ........................ - */ - send_entry->LastTime = curtime; - if (send_entry->SendCount==0) { - send_entry->FirstTime = curtime; - /*............................................................... - If this is the 1st time we're sending this packet, and it doesn't - require an ACK, mark it as ACK'd; then, the next time through, - it will just be removed from the queue. - ...............................................................*/ - packet_hdr = (CommHeaderType *)send_entry->Buffer; - if (packet_hdr->Code == PACKET_DATA_NOACK) - send_entry->IsACK = 1; - } - -#ifdef DEBUG_SEQ -packet_hdr = (CommHeaderType *)send_entry->Buffer; -if (packet_hdr->Code == PACKET_DATA_NOACK) { - printf("Sending PACKET_DATA_NOACK (%d)\n",packet_hdr->PacketID); -} else { - printf("Sending PACKET_DATA_ACK (%d)\n",packet_hdr->PacketID); -} -#endif - /* - ......................... Update SendCount ......................... - */ - send_entry->SendCount++; - /*.................................................................. - Perform error detection, based on either MaxRetries or Timeout - ..................................................................*/ - if (MaxRetries != -1 && send_entry->SendCount > MaxRetries) - return(false); - if (Timeout != -1 && send_entry->LastTime - - send_entry->FirstTime > Timeout) - return(false); - - } - } - - return(true); -} - - -/*************************************************************************** - * SequencedConnClass::Service_Receive_Queue -- services the recieve queue * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = OK, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/20/1994 BR : Created. * - *=========================================================================*/ -int SequencedConnClass::Service_Receive_Queue (void) -{ - CommHeaderType ackpacket; // ACK packet to send - ReceiveQueueType *rec_entry; // ptr to receive entry header - CommHeaderType *packet_hdr; // packet header - - /*------------------------------------------------------------------------ - Get a pointer to the next received entry - ------------------------------------------------------------------------*/ - rec_entry = Queue->Next_Receive(); - if (rec_entry==NULL) - return(true); - - /*------------------------------------------------------------------------ - If this packet doesn't require an ACK, mark it as ACK'd. - ------------------------------------------------------------------------*/ - packet_hdr = (CommHeaderType *)(rec_entry->Buffer); - if (packet_hdr->Code==PACKET_DATA_NOACK) - rec_entry->IsACK = 1; - - /*------------------------------------------------------------------------ - If this packet hasn't been ACK'd, send an ACK: - - Fill in the MagicNum & the Code - - Set the PacketID to the same ID that the sending system used, so the - sending system knows which packet the ACK is for - ------------------------------------------------------------------------*/ - if (rec_entry->IsACK==0) { -#ifdef DEBUG_SEQ -printf("Sending ACK (%d)\n",packet_hdr->PacketID); -#endif - ackpacket.MagicNumber = MagicNum; - ackpacket.Code = PACKET_ACK; - ackpacket.PacketID = packet_hdr->PacketID; - - Send((char *)&ackpacket, sizeof(CommHeaderType)); - - rec_entry->IsACK = 1; - } - - /*------------------------------------------------------------------------ - If this packet has been read by the application, and has been ACK'd, and - there is another packet in the queue behind this one, it means the other - system got the ACK we sent for this packet; remove this packet from the - queue. - ------------------------------------------------------------------------*/ - if (rec_entry!=NULL && rec_entry->IsRead && rec_entry->IsACK && - Queue->Num_Receive() > 1) { -#ifdef DEBUG_SEQ -printf(">>>Unqueueing Send packet #%d<<<\n",packet_hdr->PacketID); -#endif - Queue->UnQueue_Receive(NULL,NULL); - } - - return(true); -} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/SEQCONN.H b/code/TIBERIANDAWN/SEQCONN.H deleted file mode 100644 index a6884e4..0000000 --- a/code/TIBERIANDAWN/SEQCONN.H +++ /dev/null @@ -1,108 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\seqconn.h_v 1.12 16 Oct 1995 16:47:58 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SEQCONN.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 19, 1994 * - * * - * Last Update : April 9, 1995 [BR] * - * * - *-------------------------------------------------------------------------* - * * - * This class provides a "Sequenced" ACK/Retry approach to packet * - * transmission. It waits until the last packet has been ACK'd before * - * sending another packet. Thus, it guarantees order of delivery of * - * packets, but its performance will be slower than the Non-Sequenced * - * approach. * - * * - * A derived class must provide: * - * - Init: Initialization of any hardware-specific values. * - * - Send: a hardware-dependent send routine. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SEQCONN_H -#define SEQCONN_H - -#include "connect.h" -#include "comqueue.h" - - -/* -***************************** Class Declaration ***************************** -*/ -class SequencedConnClass : public ConnectionClass -{ - /* - ---------------------------- Public Interface ---------------------------- - */ - public: - /*..................................................................... - Constructor/destructor. - .....................................................................*/ - SequencedConnClass (int numsend, int numrecieve, int maxlen, - unsigned short magicnum, unsigned long retry_delta, - unsigned long max_retries, unsigned long timeout); - virtual ~SequencedConnClass (); - - /*..................................................................... - Initialization. - .....................................................................*/ - virtual void Init (void); - - /*..................................................................... - Send/Receive routines. - .....................................................................*/ - virtual int Send_Packet (void * buf, int buflen, int ack_req); - virtual int Receive_Packet (void * buf, int buflen); - virtual int Get_Packet (void * buf, int *buflen); - - /*..................................................................... - The packet queue. - .....................................................................*/ - CommQueueClass *Queue; - - /* - -------------------------- Protected Interface --------------------------- - */ - protected: - /*..................................................................... - Routines to service the Send & Receive queues. - .....................................................................*/ - virtual int Service_Send_Queue (void); - virtual int Service_Receive_Queue (void); - - /*..................................................................... - Running totals of # of packets we send & receive which require an ACK, - and those that don't. - .....................................................................*/ - unsigned long NumRecNoAck; - unsigned long NumRecAck; - unsigned long NumSendNoAck; - unsigned long NumSendAck; - -}; - -#endif -/*************************** end of seqconn.h ******************************/ diff --git a/code/TIBERIANDAWN/SESSION.H b/code/TIBERIANDAWN/SESSION.H deleted file mode 100644 index 7434282..0000000 --- a/code/TIBERIANDAWN/SESSION.H +++ /dev/null @@ -1,551 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SESSION.H * - * * - * Programmer : Bill R. Randolph * - * * - * Start Date : 11/30/95 * - * * - * Last Update : November 30, 1995 [BRR] * - * * - * The purpose of this class is to contain those variables & routines * - * specifically related to a multiplayer game. * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef SESSION_H -#define SESSION_H - -#include "ipxaddr.h" -#include "msglist.h" -#include "connect.h" - -//--------------------------------------------------------------------------- -// Forward declarations -//--------------------------------------------------------------------------- -class AircraftClass; -class AnimClass; -class BuildingClass; -class BulletClass; -class InfantryClass; -class UnitClass; -class PhoneEntryClass; -class CellClass; - -//--------------------------------------------------------------------------- -// Defines -//--------------------------------------------------------------------------- -//........................................................................... -// Various limiting values -//........................................................................... -#define MAX_PLAYERS 6 // max # of players we can have -#define MPLAYER_BUILD_LEVEL_MAX 7 // max build level in multiplay -#define MAX_MPLAYER_COLORS 6 // max # of colors - -//........................................................................... -// Max sizes of packets we want to send -// The IPX packet's size is IPX's max size (546), rounded down to accommodate -// the max number of events possible. -//........................................................................... -#define MAX_IPX_PACKET_SIZE (((546 - sizeof(CommHeaderType)) / \ - sizeof(EventClass) ) * sizeof(EventClass)) -#define MAX_SERIAL_PACKET_SIZE 200 - -//........................................................................... -// Max length of player names fields; attempt to use the constant for the -// HouseClass, if it's been defined; otherwise, define it myself. -//........................................................................... -#ifdef HOUSE_NAME_MAX -#define MPLAYER_NAME_MAX HOUSE_NAME_MAX -#else -#define MPLAYER_NAME_MAX 12 // max length of a player's name -#endif - -//........................................................................... -// Values to control the multiplayer score screen -//........................................................................... -#define MAX_MULTI_NAMES 8 // max # names (rows) on the score screen -#define MAX_MULTI_GAMES 4 // max # games (columns) on the score screen - -//........................................................................... -// Min value for MaxAhead, for both net & modem; only applies for -// COMM_PROTOCOL_MULTI_E_COMP. -//........................................................................... -#define MODEM_MIN_MAX_AHEAD 5 -#define NETWORK_MIN_MAX_AHEAD 2 - -//........................................................................... -// Send period (in frames) for COMM_PROTOCOL_MULTI_E_COMP and above -//........................................................................... -#define DEFAULT_FRAME_SEND_RATE 3 - -//........................................................................... -// Modem-specific constants -//........................................................................... -#define PORTBUF_MAX 5 // dialog field sizes -#define IRQBUF_MAX 3 -#define BAUDBUF_MAX 7 -#define INITSTRBUF_MAX 41 -#define CWAITSTRBUF_MAX 16 -#define CREDITSBUF_MAX 5 -#define PACKET_TIMING_TIMEOUT 40 // ticks b/w sending a timing packet - -//--------------------------------------------------------------------------- -// Enums -//--------------------------------------------------------------------------- -//........................................................................... -// Types of games; used to tell which protocol we're using -//........................................................................... -typedef enum GameEnum { - GAME_NORMAL, // not multiplayer - GAME_MODEM, // modem game - GAME_NULL_MODEM, // NULL-modem - GAME_IPX, // IPX Network game - GAME_INTERNET, // Winsock game - GAME_GLYPHX_MULTIPLAYER // Multiplayer game controlled by the GLYPHX engine. ST - 3/12/2019 10:04AM -} GameType; - -//........................................................................... -// Various Modem-specific enums -//........................................................................... -typedef enum DetectPortType { - PORT_VALID = 0, - PORT_INVALID, - PORT_IRQ_INUSE -} DetectPortType; - -typedef enum DialStatusType { - DIAL_CONNECTED = 0, - DIAL_NO_CARRIER, - DIAL_BUSY, - DIAL_ERROR, - DIAL_CANCELED -} DialStatusType; - -typedef enum DialMethodType { - DIAL_TOUCH_TONE = 0, - DIAL_PULSE, - DIAL_METHODS -} DialMethodType; - -typedef enum CallWaitStringType { - CALL_WAIT_TONE_1 = 0, - CALL_WAIT_TONE_2, - CALL_WAIT_PULSE, - CALL_WAIT_CUSTOM, - CALL_WAIT_STRINGS_NUM -} CallWaitStringType; - -typedef enum ModemGameType { - MODEM_NULL_HOST = 0, - MODEM_NULL_JOIN, - MODEM_DIALER, - MODEM_ANSWERER, - INTERNET_HOST = MODEM_NULL_HOST, - INTERNET_JOIN = MODEM_NULL_JOIN -} ModemGameType; - -//........................................................................... -// Commands sent over the serial Global Channel -//........................................................................... -typedef enum SerialCommandType { - SERIAL_CONNECT = 100, // Are you there? Hello? McFly? - SERIAL_GAME_OPTIONS = 101, // Hey, dudes, here's some new game options - SERIAL_SIGN_OFF = 102, // Bogus, dudes, my boss is coming; I'm outta here! - SERIAL_GO = 103, // OK, dudes, jump into the game loop! - SERIAL_MESSAGE = 104, // Here's a message - SERIAL_TIMING = 105, // timimg packet - SERIAL_SCORE_SCREEN = 106, // player at score screen - SERIAL_LOADGAME = 107, // Start the game, loading a saved game first - SERIAL_LAST_COMMAND // last command -} SerialCommandType; - -//........................................................................... -// Commands sent over the network Global Channel -//........................................................................... -typedef enum NetCommandType { - NET_QUERY_GAME, // Hey, what games are out there? - NET_ANSWER_GAME, // Yo, Here's my game's name! - NET_QUERY_PLAYER, // Hey, what players are in this game? - NET_ANSWER_PLAYER, // Yo, I'm in that game! - NET_CHAT_ANNOUNCE, // I'm at the chat screen - NET_CHAT_REQUEST, // Respond with a CHAT_ANNOUNCE, please. - NET_QUERY_JOIN, // Hey guys, can I play too? - NET_CONFIRM_JOIN, // Well, OK, if you really want to. - NET_REJECT_JOIN, // No, you can't join; sorry, dude. - NET_GAME_OPTIONS, // Hey, dudes, here's some new game options - NET_SIGN_OFF, // Bogus, dudes, my boss is coming; I'm outta here! - NET_GO, // OK, jump into the game loop! - NET_MESSAGE, // Here's a message - NET_PING, // I'm pinging you to take a time measurement - NET_LOADGAME, // start a game by loading a saved game -} NetCommandType; - -//--------------------------------------------------------------------------- -// Structures -//--------------------------------------------------------------------------- -//........................................................................... -// An entry on the score screen is defined by this structure -//........................................................................... -typedef struct { - char Name[MPLAYER_NAME_MAX]; - int Wins; - int Kills[MAX_MULTI_GAMES]; - int Color; -} MPlayerScoreType; - -//........................................................................... -// Settings for the serial port -//........................................................................... -typedef struct { - int Port; - int IRQ; - int Baud; - DialMethodType DialMethod; - int InitStringIndex; - int CallWaitStringIndex; - char CallWaitString[ CWAITSTRBUF_MAX ]; -} SerialSettingsType; - -//........................................................................... -// This is a "node", used for the lists of available games & players. The -// 'Game' structure is used for games; the 'Player' structure for players. -//........................................................................... -typedef struct NodeNameTag { - char Name[MPLAYER_NAME_MAX]; // player or game name - IPXAddressClass Address; - union { - struct { - unsigned char IsOpen; // is the game open? - unsigned long LastTime; // last time we heard from this guy - } Game; - struct { - HousesType House; // "ActLike" House of this player - unsigned char Color; // Color of this player - HousesType ID; // Actual House of this player - } Player; - struct { - unsigned long LastTime; // last time we heard from this guy - unsigned char LastChance; // we're about to remove him from the list - unsigned char Color; // chat player's color - } Chat; - }; -} NodeNameType; - -//........................................................................... -// Packet sent over the serial Global Channel -//........................................................................... -typedef struct { - SerialCommandType Command; // One of the enum's defined above - char Name[MPLAYER_NAME_MAX]; // Player or Game Name - unsigned long MinVersion; // min version this game supports - unsigned long MaxVersion; // max version this game supports - HousesType House; // player's House - unsigned char Color; // player's color or SIGNOFF ID - unsigned char Scenario; // Scenario # - unsigned int Credits; // player's credits - unsigned int IsBases : 1; // 1 = bases are allowed - unsigned int IsTiberium : 1; // 1 = tiberium is allowed - unsigned int IsGoodies : 1; // 1 = goodies are allowed - unsigned int IsGhosties : 1; // 1 = ghosts are allowed - unsigned char BuildLevel; // buildable level - unsigned char UnitCount; // max # units - int Seed; // random number seed - SpecialClass Special; // command-line options - unsigned int GameSpeed; // Game Speed - unsigned long ResponseTime; // packet response time - char Message[COMPAT_MESSAGE_LENGTH]; // inter-player message - unsigned char ID; // unique ID of sender of message -} SerialPacketType; - -//........................................................................... -// Packet sent over the network Global Channel -//........................................................................... -typedef struct { - NetCommandType Command; // One of the enum's defined above - char Name[MPLAYER_NAME_MAX]; // Player or Game Name - union { - struct { - unsigned int IsOpen : 1; // 1 = game is open for joining - } GameInfo; - struct { - HousesType House; // player's House - unsigned int Color; // player's color - unsigned long NameCRC; // CRC of player's game's name - unsigned long MinVersion; // game's min supported version - unsigned long MaxVersion; // game's max supported version - } PlayerInfo; - struct { - unsigned char Scenario; // Scenario # - unsigned int Credits; // player's credits - unsigned int IsBases : 1; // 1 = bases are allowed - unsigned int IsTiberium : 1; // 1 = tiberium is allowed - unsigned int IsGoodies : 1; // 1 = goodies are allowed - unsigned int IsGhosties : 1; // 1 = ghosts are allowed - unsigned char BuildLevel; // buildable level - unsigned char UnitCount; // max # units - int Seed; // random number seed - SpecialClass Special; // command-line options - unsigned int GameSpeed; // Game Speed - unsigned long Version; // version # common to all players - } ScenarioInfo; - struct { - char Buf[COMPAT_MESSAGE_LENGTH]; // inter-user message - unsigned char Color; // color of sender of message - unsigned long NameCRC; // CRC of sender's Game Name - } Message; - struct { - int OneWay; // one-way response time - } ResponseTime; - struct { - int Why; // why were we rejected from the game? - } Reject; - struct { - unsigned long ID; // unique ID for this chat node - unsigned char Color; // my color - } Chat; - }; -} GlobalPacketType; - -//........................................................................... -// For finding sync bugs; filled in by the engine when certain conditions -// are met; the pointers allow examination of objects in the debugger. -//........................................................................... -typedef struct { - union { - AircraftClass *Aircraft; - AnimClass *Anim; - BuildingClass *Building; - BulletClass *Bullet; - InfantryClass *Infantry; - UnitClass *Unit; - void *All; - } Ptr; -} TrapObjectType; - -typedef struct { - int ScenarioIndex; - int Bases; - int Credits; - int Tiberium; - int Goodies; - int Ghosts; - int UnitCount; -} GameOptionsType; - -//--------------------------------------------------------------------------- -// Class Definition -//--------------------------------------------------------------------------- -class SessionClass -{ - //------------------------------------------------------------------------ - // Public interface - //------------------------------------------------------------------------ - public: - //..................................................................... - // Constructor/Destructor - //..................................................................... - SessionClass(void); - ~SessionClass(void); - - //..................................................................... - // Initialization - //..................................................................... - void One_Time(void); - void Init(void); - - //..................................................................... - // Reads/writes to the INI file - //..................................................................... - void Read_MultiPlayer_Settings (void); - void Write_MultiPlayer_Settings (void); - void Read_Scenario_Descriptions (void); - void Free_Scenario_Descriptions(void); - - //..................................................................... - // Utility functions - //..................................................................... - int Create_Connections(void); - bool Am_I_Master(void); - unsigned long Compute_Unique_ID(void); - - //..................................................................... - // File I/O - //..................................................................... - int Save(FileClass &file); - int Load(FileClass &file); - - //..................................................................... - // Debugging / Sync Bugs - //..................................................................... - void Trap_Object(void); - - //--------------------------------------------------------------------- - // Public Data - //--------------------------------------------------------------------- - //..................................................................... - // The type of session being played - //..................................................................... - GameType Type; - - //..................................................................... - // The current communications protocol - //..................................................................... - CommProtocolType CommProtocol; - - //..................................................................... - // Game options - //..................................................................... - GameOptionsType Options; - - //..................................................................... - // Unique workstation ID, for detecting my own packets - //..................................................................... - unsigned long UniqueID; - - //..................................................................... - // Player's local options - //..................................................................... - char Handle[MPLAYER_NAME_MAX]; // player name - int PrefColor; // preferred color index - int ColorIdx; // actual color index - HousesType House; // GDI / NOD - int Blitz; // 1 = AI blitzes - int ObiWan; // 1 = player can see all - int Solo; // 1 = player can play alone - - //..................................................................... - // Max allowable # of players & actual # of (human) players - //..................................................................... - int MaxPlayers; - int NumPlayers; - - //..................................................................... - // Frame-sync'ing timing variables - // 'MaxAhead' is the number of frames ahead of this one to execute - // a given packet. It's set by the RESPONSE_TIME event. - // 'FrameSendRate' is the # frames between data packets - // 'FrameRateDelay' is the time ticks to wait between frames, for - // smoothing. - //..................................................................... - unsigned long MaxAhead; - unsigned long FrameSendRate; - unsigned long FrameRateDelay; - - //..................................................................... - // This flag is set when we've loaded a multiplayer game. - //..................................................................... - int LoadGame; - - //..................................................................... - // This flag is set when the modem game saves the game due to a lost - // connection. - //..................................................................... - int EmergencySave; - - //..................................................................... - // List of scenarios & their file numbers - //..................................................................... - DynamicVectorClass Scenarios; - DynamicVectorClass Filenum; - - //..................................................................... - // This is the multiplayer messaging system - //..................................................................... - MessageListClass Messages; - IPXAddressClass MessageAddress; - char LastMessage[MAX_MESSAGE_LENGTH]; - int WWChat : 1; // 1 = go into special WW Chat mode - - //..................................................................... - // This is the multiplayer scorekeeping system - //..................................................................... - MPlayerScoreType Score[MAX_MULTI_NAMES]; - int GamesPlayed; // # games played this run - int NumScores; // # active entries in MPlayerScore - int Winner; // index of winner of last game - int CurGame; // index of current game being played - - //..................................................................... - // Static arrays - //..................................................................... - static int GColors[]; - static int TColors[]; - static char Descriptions[100][40]; - static int CountMin[2]; - static int CountMax[2]; - static char * GlobalPacketNames[]; - static char * SerialPacketNames[]; - - //..................................................................... - // For Recording & Playing back a file - //..................................................................... - CCFileClass RecordFile; - int Record : 1; - int Play : 1; - int Attract : 1; - - //..................................................................... - // IPX-specific variables - //..................................................................... - int IsBridge; // 1 = we're crossing a bridge - IPXAddressClass BridgeNet; // address of bridge - bool NetStealth; // makes us invisible - bool NetProtect; // keeps others from messaging us - bool NetOpen; // 1 = game is open for joining - char GameName[MPLAYER_NAME_MAX]; // game's name - GlobalPacketType GPacket; // global packet - int GPacketlen; // global packet length - IPXAddressClass GAddress; // address of sender - unsigned short GProductID; // product ID of sender - char MetaPacket[MAX_IPX_PACKET_SIZE]; // packet building buffer - int MetaSize; // size of MetaPacket - DynamicVectorClass Games; // list of games - DynamicVectorClass Players; // list of players - DynamicVectorClass Chat; // list of chat nodes - - //..................................................................... - // Modem-specific variables - //..................................................................... - bool ModemService : 1; // 1 = service modem in Call_Back - int CurPhoneIdx; // phone listing index - SerialSettingsType SerialDefaults; // default serial settings - ModemGameType ModemType; // caller or answerer? - - DynamicVectorClass PhoneBook; - DynamicVectorClass InitStrings; - static char * DialMethodCheck[ DIAL_METHODS ]; - static char * CallWaitStrings[ CALL_WAIT_STRINGS_NUM ]; - - //..................................................................... - // For finding Sync Bugs - //..................................................................... - long TrapFrame; - RTTIType TrapObjType; - TrapObjectType TrapObject; - COORD TrapCoord; - void * TrapThis; - CellClass * TrapCell; - int TrapCheckHeap; - -}; - -#endif // SESSION_H - -/*************************** end of session.h ******************************/ \ No newline at end of file diff --git a/code/TIBERIANDAWN/SHAPEBTN.CPP b/code/TIBERIANDAWN/SHAPEBTN.CPP deleted file mode 100644 index 6d2290e..0000000 --- a/code/TIBERIANDAWN/SHAPEBTN.CPP +++ /dev/null @@ -1,163 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\shapebtn.cpv 2.17 16 Oct 1995 16:52:00 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SHAPEBTN.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ShapeButtonClass::ShapeButtonClass -- Constructor for a shape type button. * - * ShapeButtonClass::Draw_Me -- Renders the shape button's imagery. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "shapebtn.h" - - -/*********************************************************************************************** - * ShapeButtonClass::ShapeButtonClass -- Default Constructor for a shape type button. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: You must call Set_Shape() before using a button constructed with this function, * - * and you must set X & Y, and ID. * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -ShapeButtonClass::ShapeButtonClass(void) : - ToggleClass(0, 0, 0, 0, 0) -{ - ReflectButtonState = false; -} - - -/*********************************************************************************************** - * ShapeButtonClass::ShapeButtonClass -- Constructor for a shape type button. * - * * - * This is the normal constructor for a shape type button. Shape buttons are ones that * - * have their imagery controlled by a shape file. The various states of the button are * - * given a visual form as one of these shapes. Button dimensions are controlled by the * - * first shape. * - * * - * INPUT: id -- The button ID. * - * * - * shape -- Pointer to the shape file that controls the button's display. * - * * - * x,y -- The pixel coordinate of the upper left corner of the button. * - * * - * OUTPUT: none * - * * - * WARNINGS: The width and height of the shape is controlled by the first shape in the * - * shape file provided. This means that all the shapes in the shape file must be * - * the same size. * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -ShapeButtonClass::ShapeButtonClass(unsigned id, void const * shape, int x, int y) : - ToggleClass(id, x, y, 0, 0) -{ - Width = 0; - Height = 0; - ReflectButtonState = false; - Set_Shape(shape); -} - - -void ShapeButtonClass::Set_Shape(void const * data) -{ - ShapeData = data; - if (ShapeData) { - Width = Get_Build_Frame_Width(ShapeData); - Height = Get_Build_Frame_Height(ShapeData); - } -} - - -/*********************************************************************************************** - * ShapeButtonClass::Draw_Me -- Renders the shape button's imagery. * - * * - * This function is called when the button detects that it must be redrawn. The actual * - * shape to use is controled by the button's state and the shape file provided when then * - * button was constructed. * - * * - * INPUT: forced -- Should the button be redrawn regardless of the redraw flag? * - * * - * OUTPUT: bool; Was the shape redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int ShapeButtonClass::Draw_Me(int forced) -{ - if (ControlClass::Draw_Me(forced) && ShapeData) { - - /* - ** Hide the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Hide_Mouse(X, Y, X+Width-1, Y+Height-1); - } - - /* - ** Draw the body & set text color. - */ - int shapenum = 0; - if (IsDisabled) { - shapenum = DISABLED_SHAPE; - } else { - - if (!ReflectButtonState){ - if (IsPressed) { - shapenum = DOWN_SHAPE; - } else { - shapenum = UP_SHAPE; - } - }else{ - shapenum = IsOn; - } - } - CC_Draw_Shape(ShapeData, shapenum, X, Y, WINDOW_MAIN, SHAPE_NORMAL); - - /* - ** Display the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - return(true); - } - return(false); -} - - - diff --git a/code/TIBERIANDAWN/SHAPEBTN.H b/code/TIBERIANDAWN/SHAPEBTN.H deleted file mode 100644 index 1ded837..0000000 --- a/code/TIBERIANDAWN/SHAPEBTN.H +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\shapebtn.h_v 2.18 16 Oct 1995 16:46:30 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SHAPEBTN.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SHAPEBTN_H -#define SHAPEBTN_H - -#include "toggle.h" - -class ShapeButtonClass : public ToggleClass -{ - public: - ShapeButtonClass(void); - ShapeButtonClass(unsigned id, void const * shapes, int x, int y); - virtual int Draw_Me(int forced=false); - virtual void Set_Shape(void const * data); - - enum ShapeButtonClassEnums { - UP_SHAPE, // Shape to use when button is "up". - DOWN_SHAPE, // Shape to use when button is "down". - DISABLED_SHAPE, // Shape to use when button is disabled. - }; - - unsigned ReflectButtonState:1; - - protected: - - /* - ** This points to the shape data file. This file contains the appropriate shapes - ** for this button in the offsets specified above. - */ - void const * ShapeData; -}; -#endif diff --git a/code/TIBERIANDAWN/SIDEBAR.CPP b/code/TIBERIANDAWN/SIDEBAR.CPP deleted file mode 100644 index 9ec327d..0000000 --- a/code/TIBERIANDAWN/SIDEBAR.CPP +++ /dev/null @@ -1,2559 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\sidebar.cpv 2.13 02 Aug 1995 17:03:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SIDEBAR.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 20, 1994 * - * * - * Last Update : January 25, 1996 [] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * SidebarClass::Abandon_Production -- Stops production of the object specified. * - * SidebarClass::Activate -- Controls the sidebar activation. * - * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar. * - * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar. * - * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar. * - * SidebarClass::Add -- Adds a game object to the sidebar list. * - * SidebarClass::AI -- Handles player clicking on sidebar area. * - * SidebarClass::Draw_It -- Renders the sidebar display. * - * SidebarClass::Factory_Link -- Links a factory to a sidebar strip. * - * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state * - * SidebarClass::Init_IO -- Adds buttons to the button list * - * SidebarClass::Init_Theater -- Performs theater-specific initialization * - * SidebarClass::One_Time -- Handles the one time game initializations. * - * SidebarClass::One_Time -- Handles the one time game initializations. * - * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary. * - * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls. * - * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the s* - * SidebarClass::Scroll -- Handles scrolling the sidebar object strip. * - * SidebarClass::Set_Current -- Sets a specified object that controls the sidebar display. * - * SidebarClass::SidebarClass -- Default constructor for the sidebar. * - * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. * - * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system. * - * SidebarClass::StripClass::Add -- Add an object to the side strip. * - * SidebarClass::StripClass::AI -- Input and AI processing for the side strip. * - * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syst* - * SidebarClass::StripClass::Draw_It -- Render the sidebar display. * - * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button. * - * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn. * - * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape. * - * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state * - * SidebarClass::StripClass::Init_IO -- Adds buttons to the button list * - * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization * - * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side str* - * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. * - * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll. * - * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selecte* - * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select bu* - * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor. * - * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class. * - * SidebarClass::Which_Column -- Determines which column a given type should appear. * - * sortfunc -- Utility routine that handles 'qsort' the strip buttons. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** Define "_RETRIEVE" if the palette morphing tables are part of the loaded data. If this -** is undefined, then the files will be created. -*/ -#define _RETRIEVE - - -/*************************************************************************** -** This holds the translucent table for use with the construction clock -** animation. -*/ -char SidebarClass::StripClass::ClockTranslucentTable[(1+1)*256]; - - -/*************************************************************************** -** This points to the main sidebar shapes. These include the upgrade and -** repair buttons. -*/ -TheaterType SidebarClass::StripClass::LastTheater = THEATER_NONE; - -typedef enum ButtonNumberType { - BUTTON_RADAR = 100, - BUTTON_REPAIR, - BUTTON_DEMOLISH, - BUTTON_UPGRADE, - BUTTON_SELECT, - BUTTON_ZOOM -} ButtonNumberType; - -/* -** Sidebar buttons -*/ -SidebarClass::SBGadgetClass SidebarClass::Background; -ShapeButtonClass SidebarClass::Repair; -ShapeButtonClass SidebarClass::Upgrade; -ShapeButtonClass SidebarClass::Zoom; -ShapeButtonClass SidebarClass::StripClass::UpButton[COLUMNS]; -ShapeButtonClass SidebarClass::StripClass::DownButton[COLUMNS]; -SidebarClass::StripClass::SelectClass -SidebarClass::StripClass::SelectButton[COLUMNS][MAX_VISIBLE]; - -/* -** Shape data pointers -*/ -void const * SidebarClass::StripClass::LogoShapes; -void const * SidebarClass::StripClass::ClockShapes; -void const * SidebarClass::StripClass::SpecialShapes[3]; - -void const * SidebarClass::SidebarShape1; -void const * SidebarClass::SidebarShape2; - - -/*********************************************************************************************** - * SidebarClass::SidebarClass -- Default constructor for the sidebar. * - * * - * Constructor for the sidebar handler. It basically sets up the sidebar to the empty * - * condition. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/17/1994 JLB : Created. * - *=============================================================================================*/ -SidebarClass::SidebarClass(void) -{ - IsSidebarActive = false; - IsRepairActive = false; - IsUpgradeActive = false; - IsDemolishActive = false; - IsToRedraw = true; - -} - - -/*********************************************************************************************** - * SidebarClass::One_Time -- Handles the one time game initializations. * - * * - * This routine is used to load the graphic data that is needed by the sidebar display. It * - * should only be called ONCE. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Only call this routine once when the game first starts. * - * * - * HISTORY: * - * 10/28/94 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::One_Time(void) -{ - PowerClass::One_Time(); - /* - ** Set up the pixel offsets and widths and heights used to render the - ** sidebar. They are now variables because we need to change them for - ** variable resolutions. - */ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - SideBarWidth = SIDEBARWIDTH * factor; - SideX = SeenBuff.Get_Width() - SideBarWidth; - SideY = Map.RadY + Map.RadHeight + 1; - SideWidth = SeenBuff.Get_Width() - SideX; - SideHeight = SeenBuff.Get_Height() - SideY; - MaxVisible = 4; - ButtonHeight = 9 * factor; - TopHeight = ButtonHeight + (4 * factor); - - Background.X = SideX+8 * factor; - Background.Y = SideY, - Background.Width = SideWidth-1; - Background.Height = SideHeight-1; - /* - ** This sets up the clipping window. This window is used by the shape drawing - ** code so that as the sidebar buildable buttons scroll, they get properly - ** clipped at the top and bottom edges. - */ - WindowList[WINDOW_SIDEBAR][WINDOWX] = (SideX+PowWidth) >> 3; - WindowList[WINDOW_SIDEBAR][WINDOWY] = SideY + 1 + TopHeight; - WindowList[WINDOW_SIDEBAR][WINDOWWIDTH] = SideWidth>>3; - WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = (MaxVisible * (StripClass::OBJECT_HEIGHT * factor)) - 1; - - /* - ** Set up the coordinates for the sidebar strips. These coordinates are for - ** the upper left corner. - */ - int width = (SideWidth - PowWidth) - (((StripClass::STRIP_WIDTH ) * factor) << 1); - int spacing = width / 3; - - Column[0].X = SideX + PowWidth + spacing; - Column[0].Y = SideY + TopHeight + 1; - Column[1].X = Column[0].X + (StripClass::STRIP_WIDTH * factor) + spacing -1; - Column[1].Y = SideY + TopHeight + 1; - - Column[0].One_Time(0); - Column[1].One_Time(1); - - SidebarShape1 = Hires_Retrieve("SIDE1.SHP"); - SidebarShape2 = Hires_Retrieve("SIDE2.SHP"); - - -} - - -/*********************************************************************************************** - * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::Init_Clear(void) -{ - PowerClass::Init_Clear(); - - IsToRedraw = true; - IsRepairActive = false; - IsUpgradeActive = false; - IsDemolishActive = false; - - Column[0].Init_Clear(); - Column[1].Init_Clear(); - - Activate(false); -} - - -/*********************************************************************************************** - * SidebarClass::Init_IO -- Adds buttons to the button list * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::Init_IO(void) -{ - void *oldfont; - int oldx; - PowerClass::Init_IO(); - - /* - ** Add the sidebar's buttons only if we're not in editor mode. - */ - int buttonspacing = (SideBarWidth - (ButtonOneWidth + ButtonTwoWidth + ButtonThreeWidth)) / 4; - - - if (!Debug_Map) { - /* - ** Set the button widths based on the string that goes in them. - */ - oldfont = Set_Font(Font6Ptr); - oldx = FontXSpacing; - FontXSpacing = -1; - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6POINT | TPF_NOSHADOW); - - int maxwidth = String_Pixel_Width(Text_String(TXT_REPAIR_BUTTON)) + 8; - maxwidth = MAX((unsigned)maxwidth, String_Pixel_Width(Text_String(TXT_BUTTON_SELL)) + 8); - maxwidth = MAX((unsigned)maxwidth, String_Pixel_Width(Text_String(TXT_MAP)) + 8); - Repair.Width = maxwidth; - Upgrade.Width = maxwidth; - Zoom.Width = maxwidth; -// Repair.Width = String_Pixel_Width(Text_String(TXT_REPAIR_BUTTON)) + 8; -// Upgrade.Width = String_Pixel_Width(Text_String(TXT_BUTTON_SELL)) + 8; -// Zoom.Width = String_Pixel_Width(Text_String(TXT_MAP)) + 8; - /* - ** find the spacing between buttons by getting remaining width - ** and dividing it between the buttons. - */ - int buttonspacing = (SideBarWidth - (Repair.Width + Upgrade.Width + Zoom.Width)) / 4; - - Repair.IsSticky = true; - Repair.ID = BUTTON_REPAIR; - Repair.X = 484; - Repair.Y = 160; - Repair.IsPressed = false; - Repair.IsToggleType = true; - Repair.ReflectButtonState = true; -#if (FRENCH) - Repair.Set_Shape(Hires_Retrieve("REPAIRF.SHP")); -#else -#if (GERMAN) - Repair.Set_Shape(Hires_Retrieve("REPAIRG.SHP")); -#else - Repair.Set_Shape(Hires_Retrieve("REPAIR.SHP")); -#endif -#endif - - Upgrade.IsSticky = true; - Upgrade.ID = BUTTON_UPGRADE; - Upgrade.X = 480+57; - Upgrade.Y = 160; - Upgrade.IsPressed = false; - Upgrade.IsToggleType = true; - Upgrade.ReflectButtonState = true; -#if (FRENCH) - Upgrade.Set_Shape(Hires_Retrieve("SELLF.SHP")); -#else -#if (GERMAN) - Upgrade.Set_Shape(Hires_Retrieve("SELLG.SHP")); -#else - Upgrade.Set_Shape(Hires_Retrieve("SELL.SHP")); -#endif -#endif - - Zoom.IsSticky = true; - Zoom.ID = BUTTON_ZOOM; - Zoom.X = 480 + 110; - Zoom.Y = 160; - Zoom.IsPressed = false; -#if (FRENCH) - Zoom.Set_Shape(Hires_Retrieve("MAPF.SHP")); -#else -#if (GERMAN) - Zoom.Set_Shape(Hires_Retrieve("MAPG.SHP")); -#else - Zoom.Set_Shape(Hires_Retrieve("MAP.SHP")); -#endif -#endif - - if (IsRadarActive || GameToPlay!=GAME_NORMAL) { - Zoom.Enable(); - } else { - Zoom.Disable(); - } - - Set_Font(oldfont); - FontXSpacing = oldx; - FontXSpacing = -1; - - - Column[0].Init_IO(0); - Column[1].Init_IO(1); - - /* - ** If a game was loaded & the sidebar was enabled, pop it up now - */ - if (IsSidebarActive) { - IsSidebarActive = false; - Activate(1); -// Background.Zap(); -// Add_A_Button(Background); - } - } -} - - -/*********************************************************************************************** - * SidebarClass::Init_Theater -- Performs theater-specific initialization * - * * - * INPUT: theater -- The theater that is being initialized. Sometimes this has an effect on * - * the data that is loaded. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::Init_Theater(TheaterType theater) -{ - PowerClass::Init_Theater(theater); - - Column[0].Init_Theater(theater); - Column[1].Init_Theater(theater); -} - - -/*********************************************************************************************** - * SidebarClass::Which_Column -- Determines which column a given type should appear. * - * * - * Use this function to resolve what column the specified object type should be placed * - * into. * - * * - * INPUT: otype -- Pointer to the object type class of the object in question. * - * * - * OUTPUT: Returns with the column number that the object should be placed in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - *=============================================================================================*/ -int SidebarClass::Which_Column(RTTIType type) -{ - if (type == RTTI_BUILDINGTYPE || type == RTTI_BUILDING) { - return(0); - } - return(1); -} - - -/*********************************************************************************************** - * SidebarClass::Factory_Link -- Links a factory to a sidebar strip. * - * * - * This routine will link the specified factory to the sidebar strip. A factory must be * - * linked to the sidebar so that as the factory production progresses, the sidebar will * - * show the production progress. * - * * - * INPUT: factory -- The factory number to attach. * - * * - * type -- The object type number. * - * * - * id -- The object sub-type number. * - * * - * OUTPUT: Was the factory successfully attached to the sidebar strip? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/19/1995 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Factory_Link(int factory, RTTIType type, int id) -{ - return(Column[Which_Column(type)].Factory_Link(factory, type, id)); -} - - -/*********************************************************************************************** - * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls. * - * * - * This routine intercepts the Refresh_Cells call in order to see if the sidebar needs * - * to be refreshed as well. If the special code to refresh the sidebar was found, it * - * flags the sidebar to be redrawn and then removes the code from the list. * - * * - * INPUT: cell -- The cell to base the refresh list on. * - * * - * list -- Pointer to the cell offset list that elaborates all the cells that * - * need to be flagged for redraw. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::Refresh_Cells(CELL cell, short const *list) -{ - if (*list == REFRESH_SIDEBAR) { - IsToRedraw = true; - Column[0].IsToRedraw = true; - Column[1].IsToRedraw = true; - Flag_To_Redraw(false); - } - PowerClass::Refresh_Cells(cell, list); -} - - -/*********************************************************************************************** - * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar. * - * * - * Use this routine to turn the repair sidebar button on and off. Typically, the button * - * is enabled when the currently selected structure is friendly and damaged. * - * * - * INPUT: control -- The controls how the button is to be activated or deactivated; * - * 0 -- Turn button off. * - * 1 -- Turn button on. * - * -1 -- Toggle button state. * - * * - * OUTPUT: bool; Was the button previously activated? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Activate_Repair(int control) -{ - bool old = IsRepairActive; - - if (control == -1) { - control = IsRepairActive ? 0 : 1; - } - switch (control) { - case 1: - IsRepairActive = true; - break; - - default: - case 0: - IsRepairActive = false; - break; - } - if (old != IsRepairActive) { - Flag_To_Redraw(false); - IsToRedraw = true; - - if (!IsRepairActive) { - Help_Text(TXT_NONE); - Set_Default_Mouse(MOUSE_NORMAL, false); - } - } - return(old); -} - - -/*********************************************************************************************** - * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar. * - * * - * Use this routine to turn the upgrade sidebar button on and off. Typically, the button * - * is enabled when the currently selected structure can be upgraded and disabled otherwise. * - * * - * INPUT: control -- The controls how the button is to be activated or deactivated; * - * 0 -- Turn button off. * - * 1 -- Turn button on. * - * -1 -- Toggle button state. * - * * - * OUTPUT: bool; Was the button previously activated? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Activate_Upgrade(int control) -{ - bool old = IsUpgradeActive; - if (control == -1) { - control = IsUpgradeActive ? 0 : 1; - } - switch (control) { - case 1: - IsUpgradeActive = true; - break; - - default: - case 0: - IsUpgradeActive = false; - break; - } - if (old != IsUpgradeActive) { - Flag_To_Redraw(false); - IsToRedraw = true; - if (!IsUpgradeActive) { - Set_Default_Mouse(MOUSE_NORMAL, false); - } - } - return(old); -} - - -/*********************************************************************************************** - * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar. * - * * - * Use this routine to turn the demolish/dismantle sidebar button on and off. Typically, * - * the button is enabled when a friendly building is selected and disabled otherwise. * - * * - * INPUT: control -- The controls how the button is to be activated or deactivated; * - * 0 -- Turn button off. * - * 1 -- Turn button on. * - * -1 -- Toggle button state. * - * * - * OUTPUT: bool; Was the button previously activated? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Activate_Demolish(int control) -{ - bool old = IsDemolishActive; - - if (control == -1) { - control = IsDemolishActive ? 0 : 1; - } - switch (control) { - case 1: - IsDemolishActive = true; - break; - - default: - case 0: - IsDemolishActive = false; - break; - } - if (old != IsDemolishActive) { - Flag_To_Redraw(false); - IsToRedraw = true; - if (!IsDemolishActive) { - Set_Default_Mouse(MOUSE_NORMAL, false); - } - } - return(old); -} - - -/*********************************************************************************************** - * SidebarClass::Add -- Adds a game object to the sidebar list. * - * * - * This routine is used to add a game object to the sidebar. Call this routine when a * - * factory type building is created. It handles the case of adding an item that has already * - * been added -- it just ignores it. * - * * - * INPUT: object -- Pointer to the object that is being added. * - * * - * OUTPUT: bool; Was the object added to the sidebar? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/17/1994 JLB : Created. * - * 9/24/2019 3:17PM : Added via capture parameter for new sidebar functionality * - *=============================================================================================*/ -bool SidebarClass::Add(RTTIType type, int id, bool via_capture) -{ - int column; - - /* - ** Add the sidebar only if we're not in editor mode. - */ - if (!Debug_Map) { - column = Which_Column(type); - - if (Column[column].Add(type, id, via_capture)) { - Activate(1); - IsToRedraw = true; - Flag_To_Redraw(false); - return(true); - } - return(false); - } - - return(false); -} - - -/*********************************************************************************************** - * SidebarClass::Scroll -- Handles scrolling the sidebar object strip. * - * * - * This routine is used to scroll the sidebar strip of objects. The strip appears whenever * - * a building is selected that can produce units. If the number of units to produce is * - * greater than what the sidebar can hold, this routine is used to scroll the other object * - * into view so they can be selected. * - * * - * INPUT: up -- Should the scroll be upwards? Upward scrolling reveals object that are * - * later in the list of objects. * - * * - * OUTPUT: bool; Did scrolling occur? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/28/94 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Scroll(bool up, int column) -{ - if (Column[column].Scroll(up)) { - IsToRedraw = true; - Flag_To_Redraw(false); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * SidebarClass::Draw_It -- Renders the sidebar display. * - * * - * This routine performs the actual drawing of the sidebar display. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the sidebar imagery changed at all? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/28/94 JLB : Created. * - * 12/31/1994 JLB : Split rendering off into the sidebar strip class. * - *=============================================================================================*/ -void SidebarClass::Draw_It(bool complete) -{ - PowerClass::Draw_It(complete); - - if (IsSidebarActive && (IsToRedraw || complete) && !Debug_Map) { - IsToRedraw = false; - - if (LogicPage->Lock()){ - /* - ** Draw the outline box around the sidebar buttons. - */ - //CC_Draw_Shape(SidebarShape1, (int)complete, SideX, 158, WINDOW_MAIN, SHAPE_WIN_REL); - //CC_Draw_Shape(SidebarShape2, (int)complete, SideX, 158+118, WINDOW_MAIN, SHAPE_WIN_REL); - LogicPage->Draw_Line(SideX, 157, SeenBuff.Get_Width()-1, 157, 0); - CC_Draw_Shape(SidebarShape1, 0, SideX, 158, WINDOW_MAIN, SHAPE_WIN_REL); - CC_Draw_Shape(SidebarShape2, 0, SideX, 158+118, WINDOW_MAIN, SHAPE_WIN_REL); - - #if (0) - if ( complete ) { - LogicPage->Fill_Rect(SideX+Map.PowWidth, SideY, SideX+SideWidth-1, SideY+SideHeight-1, LTGREY); - } - LogicPage->Fill_Rect(SideX, SideY, SideX+SideWidth-1, SideY+TopHeight-1, LTGREY); - Draw_Box(SideX+Map.PowWidth, SideY+TopHeight, SideWidth-Map.PowWidth, SideHeight-TopHeight, BOXSTYLE_RAISED, false); - #endif //(0) - //Repair.Draw_Me(true); - //Upgrade.Draw_Me(true); - //Zoom.Draw_Me(true); - // } else { - // if (IsToRedraw || complete) { - // LogicPage->Fill_Rect(TacPixelX + Lepton_To_Pixel(TacLeptonWidth), SIDE_Y, 319, SIDE_Y+TOP_HEIGHT, BLACK); - // } - - LogicPage->Unlock(); - } - - } - /* - ** Draw the side strip elements by calling their respective draw functions. - */ - if (IsSidebarActive){ - Column[0].Draw_It(complete); - Column[1].Draw_It(complete); - Repair.Draw_Me(true); - Upgrade.Draw_Me(true); - Zoom.Draw_Me(true); - } - - IsToRedraw = false; -} - - -/*********************************************************************************************** - * SidebarClass::AI -- Handles player clicking on sidebar area. * - * * - * This routine handles the processing necessary when the player clicks on the sidebar. * - * Typically, this is selection of the item to build. * - * * - * INPUT: input -- Reference to the keyboard input value. * - * * - * x,y -- Mouse coordinates at time of input. * - * * - * OUTPUT: bool; Was the click handled? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/28/94 JLB : Created. * - * 11/11/1994 JLB : Processes input directly. * - * 12/26/1994 JLB : Uses factory manager class for construction handling. * - * 12/31/1994 JLB : Simplified to use the sidebar strip class handlers. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - * 06/27/1995 JLB : key toggles sidebar. * - *=============================================================================================*/ -void SidebarClass::AI(KeyNumType & input, int x, int y) -{ - bool redraw = false; - - // - // We need to process the sidebar differently in multiplayer. ST - 3/22/2019 1:27PM - // - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - PowerClass::AI(input, x, y); - return; - } - - /* - ** Toggle the sidebar in and out with the key. - */ - if (input == KN_TAB) { - Activate(-1); - } - - if (!Debug_Map) { - Column[0].AI(input, x, y); - Column[1].AI(input, x, y); - } - - if (IsSidebarActive && !Debug_Map) { - - if (input == KN_DOWN) { - redraw |= Column[0].Scroll(false); - redraw |= Column[1].Scroll(false); - input = KN_NONE; - } - if (input == KN_UP) { - redraw |= Column[0].Scroll(true); - redraw |= Column[1].Scroll(true); - input = KN_NONE; - } - } - - if (IsSidebarActive) { - - /* - ** If there are any buildings in the payer's inventory, then allow the repair - ** option. - */ - if (PlayerPtr->BScan) { - Activate_Repair(true); - } else { - Activate_Repair(false); - } - - if (input == (BUTTON_REPAIR|KN_BUTTON)) { - Repair_Mode_Control(-1); - } - - if (input == (BUTTON_ZOOM|KN_BUTTON)) { - /* - ** If radar is active, cycle as follows: - ** Zoomed => not zoomed - ** not zoomed => player status (multiplayer only) - ** player status => zoomed - */ - if (IsRadarActive) { - if (Is_Zoomed() || GameToPlay==GAME_NORMAL) { - Zoom_Mode(Coord_Cell(TacticalCoord)); - } else { - if (!Is_Player_Names()) { - Player_Names(1); - } else { - Player_Names(0); - Zoom_Mode(Coord_Cell(TacticalCoord)); - } - } - } else { - if (GameToPlay!=GAME_NORMAL) { - Player_Names(Is_Player_Names()==0); - } - } - } - - if (input == (BUTTON_UPGRADE|KN_BUTTON)) { - Sell_Mode_Control(-1); - } - -#ifdef NEVER -// int index = -1; - if (index != -1) { - /* - ** Display help text if the mouse is over a sidebar button. - */ - switch (index) { - default: - case 2: - Map.Help_Text(TXT_UPGRADE, -1, -1, PlayerPtr->Class->Color); - break; - - case 1: - Map.Help_Text(PlayerPtr->Class->House == HOUSE_GOOD ? TXT_SELL : TXT_DEMOLISH, x, y, PlayerPtr->Class->Color); - break; - - case 0: - Map.Help_Text(TXT_REPAIR, x, y, PlayerPtr->Class->Color); - break; - } - } -#endif - - if (redraw) { - //IsToRedraw = true; - Column[0].Flag_To_Redraw(); - Column[1].Flag_To_Redraw(); - - Flag_To_Redraw(false); - } - } - - if ((!IsRepairMode) && Repair.IsOn){ - Repair.Turn_Off(); - } - - if ((!IsSellMode) && Upgrade.IsOn){ - Upgrade.Turn_Off(); - } - - PowerClass::AI(input, x, y); -} - - -/*********************************************************************************************** - * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary. * - * * - * Occasionally a factory gets destroyed. This routine must be called in such a case * - * because it might be possible that sidebar object need to be removed. This routine will * - * examine all existing objects in the sidebar class and if no possible factory can * - * produce it, then it will be removed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine is exhaustive and thus time consuming. Only call it when really * - * necessary. Such as when a factory is destroyed rather than when a non-factory * - * is destroyed. * - * * - * HISTORY: * - * 11/30/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::Recalc(void) -{ - bool redraw = false; - - // Done elsewhere for new multiplayer. ST - 3/22/2019 2:06PM - if (GameToPlay == GAME_GLYPHX_MULTIPLAYER) { - return; - } - - redraw |= Column[0].Recalc(); - redraw |= Column[1].Recalc(); - - if (redraw) { - IsToRedraw = true; - Flag_To_Redraw(false); - } -} - - -/*********************************************************************************************** - * SidebarClass::Activate -- Controls the sidebar activation. * - * * - * Use this routine to turn the sidebar on or off. This routine handles updating the * - * necessary flags. * - * * - * INPUT: control -- Tells what to do with the sidebar according to the following: * - * 0 = Turn sidebar off. * - * 1 = Turn sidebar on. * - * -1= Toggle sidebar on or off. * - * * - * OUTPUT: bool; Was the sidebar already on? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Activate(int control) -{ - // - // We don't want the original sidebar to be visible. ST - 1/31/2019 11:28AM - // - if (control < 100) { - return IsSidebarActive; - } - - bool old = IsSidebarActive; - - int sidex = SeenBuff.Get_Width() - SideBarWidth; - int sidey = Map.RadY + Map.RadHeight; - int topheight = 13; - int sidewidth = SeenBuff.Get_Width() - sidex; - int sideheight = SeenBuff.Get_Height() - sidey; - - if (PlaybackGame) - return (old); - - /* - ** Determine the new state of the sidebar. - */ - switch (control) { - case -1: - IsSidebarActive = IsSidebarActive == false; - break; - - case 1: - IsSidebarActive = true; - break; - - default: - case 0: - IsSidebarActive = false; - break; - } - - /* - ** Only if there is a change in the state of the sidebar will anything - ** be done to change it. - */ - if (IsSidebarActive != old) { - - /* - ** If the sidebar is activated but was on the right side of the screen, then - ** activate it on the left side of the screen. - */ - if (IsSidebarActive /*&& X*/) { - Set_View_Dimensions(0, Map.Get_Tab_Height(), SeenBuff.Get_Width() - sidewidth); - IsToRedraw = true; - Help_Text(TXT_NONE); - Repair.Zap(); - Add_A_Button(Repair); - Upgrade.Zap(); - Add_A_Button(Upgrade); - Zoom.Zap(); - Add_A_Button(Zoom); - Column[0].Activate(); - Column[1].Activate(); - Background.Zap(); - Add_A_Button(Background); - Map.RadarButton.Zap(); - Add_A_Button(Map.RadarButton); - Map.PowerButton.Zap(); - Add_A_Button(Map.PowerButton); - } else { - Help_Text(TXT_NONE); - Set_View_Dimensions(0, Map.Get_Tab_Height()); - Remove_A_Button(Repair); - Remove_A_Button(Upgrade); - Remove_A_Button(Zoom); - Remove_A_Button(Background); - Column[0].Deactivate(); - Column[1].Deactivate(); - Remove_A_Button(Map.RadarButton); - Remove_A_Button(Map.PowerButton); - } - - /* - ** Since the sidebar status has changed, update the map so that the graphics - ** will be rendered correctly. - */ - Flag_To_Redraw(true); - } - - return(old); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class. * - * * - * This constructor is used to reset the side strip to default empty state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - *=============================================================================================*/ -SidebarClass::StripClass::StripClass(void) -{ - IsScrollingDown = false; - IsScrolling = false; - IsBuilding = false; TopIndex = 0; - Slid = 0; - BuildableCount = 0; - for (int index = 0; index < MAX_BUILDABLES; index++) { - Buildables[index].BuildableID = 0; - Buildables[index].BuildableType = RTTI_NONE; - Buildables[index].Factory = -1; - Buildables[index].BuildableViaCapture = false; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM - } -} - - - -/*********************************************************************************************** - * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side stri * - * * - * Call this routine ONCE at the beginning of the game. It handles retrieving pointers to * - * the shape files it needs for rendering. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::One_Time(int ) -{ - static char *_file[3] = { - "ION", - "ATOM", - "BOMB" - }; - int factor = Get_Resolution_Factor(); - - ObjectWidth = OBJECT_WIDTH << factor; - ObjectHeight = OBJECT_HEIGHT << factor; - StripWidth = STRIP_WIDTH << factor; - LeftEdgeOffset = (StripWidth - ObjectWidth) >> 1; - ButtonSpacingOffset = (StripWidth - ((BUTTON_WIDTH << factor) << 1)) / 3; - - LogoShapes = Hires_Retrieve("STRIP.SHP"); - ClockShapes = Hires_Retrieve("CLOCK.SHP"); - - char fullname[_MAX_FNAME+_MAX_EXT]; - char buffer[_MAX_FNAME]; - - for (int lp = 0; lp < 3; lp++) { - if ( Get_Resolution_Factor() ) { - sprintf(buffer, "%sICNH", _file[lp]); - } else { - sprintf(buffer, "%sICON", _file[lp]); - } - _makepath(fullname, NULL, NULL, buffer, ".SHP"); - SpecialShapes[lp] = MixFileClass::Retrieve(fullname); - } - - -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape. * - * * - * This routine will return with a pointer to the cameo data for the special objects that * - * can appear on the sidebar (e.g., nuclear bomb). * - * * - * INPUT: type -- The special type to fetch the cameo imagery for. * - * * - * OUTPUT: Returns with a pointer to the cameo imagery for the specified special object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/19/1995 JLB : commented * - *=============================================================================================*/ -void const * SidebarClass::StripClass::Get_Special_Cameo(int type) -{ - return(SpecialShapes[type]); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Init_Clear(void) -{ - IsScrollingDown = false; - IsScrolling = false; - IsBuilding = false; - Flasher = -1; - TopIndex = 0; - Slid = 0; - BuildableCount = 0; - - /* - ** Since we're resetting the strips, clear out all the buildables & factory pointers. - */ - for (int index = 0; index < MAX_BUILDABLES; index++) { - Buildables[index].BuildableID = 0; - Buildables[index].BuildableType = RTTI_NONE; - Buildables[index].Factory = -1; - Buildables[index].BuildableViaCapture = false; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM - } -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Init_IO -- Initializes the strip's buttons * - * * - * This routine doesn't actually add any buttons to the list; - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Init_IO(int id) -{ - ID = id; - - UpButton[ID].IsSticky = true; - UpButton[ID].ID = BUTTON_UP+id; - UpButton[ID].X = X+ButtonSpacingOffset+1; - UpButton[ID].Y = Y+MAX_VISIBLE*ObjectHeight-1; - - UpButton[ID].Set_Shape(Hires_Retrieve("STRIPUP.SHP")); - - DownButton[ID].IsSticky = true; - DownButton[ID].ID = BUTTON_DOWN+id; - DownButton[ID].X = UpButton[ID].X + UpButton[ID].Width + ButtonSpacingOffset-2; - DownButton[ID].Y = Y+MAX_VISIBLE*ObjectHeight-1; - - DownButton[ID].Set_Shape(Hires_Retrieve("STRIPDN.SHP")); - - for (int index = 0; index < MAX_VISIBLE; index++) { - SelectClass & g = SelectButton[ID][index]; - g.ID = BUTTON_SELECT; - g.X = X; - g.Y = Y + (ObjectHeight*index); - g.Width = ObjectWidth; - g.Height = ObjectHeight; - g.Set_Owner(*this, index); - } - -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization * - * * - * INPUT: theater * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Init_Theater(TheaterType theater) -{ - //if (theater != LastTheater) { - - - static char *_file[3] = { - "ION", - "ATOM", - "BOMB" - }; - int factor = Get_Resolution_Factor(); - char fullname[_MAX_FNAME+_MAX_EXT]; - char buffer[_MAX_FNAME]; - void const * cameo_ptr; - - for (int lp = 0; lp < 3; lp++) { - if ( Get_Resolution_Factor() ) { - sprintf(buffer, "%sICNH", _file[lp]); - } else { - sprintf(buffer, "%sICON", _file[lp]); - } - _makepath(fullname, NULL, NULL, buffer, Theaters[theater].Suffix); - cameo_ptr = MixFileClass::Retrieve(fullname); - if (cameo_ptr){ - SpecialShapes[lp] = cameo_ptr; - } - } - - -#ifndef _RETRIEVE - static TLucentType const ClockCols[1] = { -// {LTGREEN, BLACK, 0, 0}, - {GREEN, LTGREY, 180, 0} - }; - - /* - ** Make sure that remapping doesn't occur on the colors that cycle. - */ - Mem_Copy(GamePalette, OriginalPalette, 768); - memset(&GamePalette[CYCLE_COLOR_START*3], 0x3f, CYCLE_COLOR_COUNT*3); - - /* - ** Create the translucent table used for the sidebar. - */ - Build_Translucent_Table(GamePalette, &ClockCols[0], 1, (void*)ClockTranslucentTable); - CCFileClass(Fading_Table_Name("CLOCK", theater)).Write(ClockTranslucentTable, sizeof(ClockTranslucentTable)); - Mem_Copy(OriginalPalette, GamePalette, 768); -#else - CCFileClass(Fading_Table_Name("CLOCK", theater)).Read(ClockTranslucentTable, sizeof(ClockTranslucentTable)); -#endif - LastTheater = theater; - //} -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system. * - * * - * This routine will add the side strip buttons to the map's input system. This routine * - * should be called once when the sidebar activates. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Never call this routine a second time without first calling Deactivate(). * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Activate(void) -{ - UpButton[ID].Zap(); - Map.Add_A_Button(UpButton[ID]); - - DownButton[ID].Zap(); - Map.Add_A_Button(DownButton[ID]); - - for (int index = 0; index < MAX_VISIBLE; index++) { - SelectButton[ID][index].Zap(); - Map.Add_A_Button(SelectButton[ID][index]); - } -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syste * - * * - * Call this routine to remove all the buttons on the side strip from the map's input * - * system. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Never call this routine unless the Activate() function was prevously called. * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Deactivate(void) -{ - Map.Remove_A_Button(UpButton[ID]); - Map.Remove_A_Button(DownButton[ID]); - for (int index = 0; index < MAX_VISIBLE; index++) { - Map.Remove_A_Button(SelectButton[ID][index]); - } -} - - -#ifdef NEVER -/*********************************************************************************************** - * sortfunc -- Utility routine that handles 'qsort' the strip buttons. * - * * - * This routine is called by qsort() in order to sort the sidebar buttons. This sorting * - * forces the sidebar buttons to always occur in the order that they can be built in, * - * rather than the order that they were added to the sidebar list. * - * * - * INPUT: ptr1 -- Pointer to the first sidebar class object. * - * * - * ptr2 -- Pointer to the second sidebar class object. * - * * - * OUTPUT: Returns <0 if the first object can be produced before the second. It returns * - * >0 if the reverse is true. It returns exactly 0 if the production scneario for * - * both objects is the same. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -static int sortfunc(void const * ptr1, void const * ptr2) -{ - SidebarClass::StripClass::BuildType * b1 = (SidebarClass::StripClass::BuildType *)ptr1; - SidebarClass::StripClass::BuildType * b2 = (SidebarClass::StripClass::BuildType *)ptr2; - - TechnoTypeClass const * p1 = Fetch_Techno_Type(b1->BuildableType, b1->BuildableID); - TechnoTypeClass const * p2 = Fetch_Techno_Type(b2->BuildableType, b2->BuildableID); - - int i1 = 0; - int i2 = 0; - - if (p1) i1 = p1->What_Am_I()*2; - if (p2) i2 = p2->What_Am_I()*2; - - /* - ** Walls should be sorted after the regular buildings. - */ - if (p1 && p1->What_Am_I() == RTTI_BUILDINGTYPE && ((BuildingTypeClass * const)p1)->IsWall) { - i1++; - } - if (p2 && p2->What_Am_I() == RTTI_BUILDINGTYPE && ((BuildingTypeClass * const)p2)->IsWall) { - i2++; - } - - /* - ** If the object types are identical, then sort by scenario available. - */ - if (i1 == i2) { - - /* - ** In the case of walls (can tell if there is an odd value), then sort - ** by cost. - */ - if (i1 & 0x01) { - i1 = p1->Cost; - i2 = p2->Cost; - } else { - i1 = p1->Scenario; - i2 = p2->Scenario; - } - } - - return(i1 - i2); -} -#endif - - -/*********************************************************************************************** - * SidebarClass::StripClass::Add -- Add an object to the side strip. * - * * - * Use this routine to add a buildable object to the side strip. * - * * - * INPUT: object -- Pointer to the object type that can be built and is to be added to * - * the side strip. * - * * - * OUTPUT: bool; Was the object successfully added to the side strip? Failure could be the * - * result of running out of room in the side strip array or the object might * - * already be in the list. * - * * - * WARNINGS: none. * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - * 9/24/2019 3:17PM : Added via capture parameter for new sidebar functionality * - *=============================================================================================*/ -bool SidebarClass::StripClass::Add(RTTIType type, int id, bool via_capture) -{ - if (BuildableCount <= MAX_BUILDABLES) { - for (int index = 0; index < BuildableCount; index++) { - if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) { - return(false); - } - } - if (!ScenarioInit && type != RTTI_SPECIAL) { - Speak(VOX_NEW_CONSTRUCT); - } - Buildables[BuildableCount].BuildableType = type; - Buildables[BuildableCount].BuildableID = id; - Buildables[BuildableCount].BuildableViaCapture = via_capture; - BuildableCount++; - IsToRedraw = true; -#ifdef OBSOLETE - if (GameToPlay == GAME_NORMAL) { - qsort(&Buildables[0], BuildableCount, sizeof(Buildables[0]), sortfunc); - } -#endif - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll. * - * * - * Use this routine to flag the side strip to scroll. The direction scrolled is controlled * - * by the parameter. Scrolling is merely initiated by this routine. Subsequent calls to * - * the AI function and the Draw_It function are required to properly give the appearence * - * of scrolling. * - * * - * INPUT: bool; Should the side strip scroll UP? If it is to scroll down then pass false. * - * * - * OUTPUT: bool; Was the side strip started to scroll in the desired direction? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - * 07/29/1995 JLB : Simplified scrolling logic. * - *=============================================================================================*/ -bool SidebarClass::StripClass::Scroll(bool up) -{ - if (up) { - Scroller--; - } else { - Scroller++; - } -#ifdef NEVER - if (BuildableCount <= MAX_VISIBLE) return(false); - - /* - ** Top of list is moving toward lower ordered entries in the object list. It looks like - ** the "window" to the object list is moving up even though the actual object images are - ** scrolling downward. - */ - if (up) { - if (!TopIndex) return(false); - - TopIndex--; - Slid = 0; - } else { - if (TopIndex+MAX_VISIBLE >= BuildableCount) return(false); - - Slid = ObjectHeight; - } - IsScrollingDown = !up; - IsScrolling = true; -#endif - return(true); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn. * - * * - * This utility routine is called when something changes on the sidebar and it must be * - * reflected the next time drawing is performed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::Flag_To_Redraw(void) -{ - IsToRedraw = true; - //Map.SidebarClass::IsToRedraw = true; - Map.Flag_To_Redraw(false); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::AI -- Input and AI processing for the side strip. * - * * - * The side strip AI processing is performed by this function. This function not only * - * checks for player input, but also handles any graphic logic updating necessary as a * - * result of flashing or construction animation. * - * * - * INPUT: input -- The player input code. * - * * - * x,y -- Mouse coordinate to use. * - * * - * OUTPUT: bool; Did the AI detect that it will need a rendering change? If this routine * - * returns true, then the Draw_It function should be called at the * - * earliest opportunity. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - *=============================================================================================*/ -bool SidebarClass::StripClass::AI(KeyNumType & input, int , int ) -{ - bool redraw = false; - - /* - ** If this is scroll button for this side strip, then scroll the strip as - ** indicated. - */ - if (input == (UpButton[ID].ID|KN_BUTTON)) { // && !IsScrolling - UpButton[ID].IsPressed = false; - Scroll(true); - } - if (input == (DownButton[ID].ID|KN_BUTTON)) { // && !IsScrolling - DownButton[ID].IsPressed = false; - Scroll(false); - } - - /* - ** Reflect the scroll desired direction/value into the scroll - ** logic handler. This might result in up or down scrolling. - */ - if (!IsScrolling && Scroller) { - if (BuildableCount <= MAX_VISIBLE) { - Scroller = 0; - } else { - - /* - ** Top of list is moving toward lower ordered entries in the object list. It looks like - ** the "window" to the object list is moving up even though the actual object images are - ** scrolling downward. - */ - if (Scroller < 0) { - if (!TopIndex) { - Scroller = 0; - } else { - Scroller++; - IsScrollingDown = false; - IsScrolling = true; - TopIndex--; - Slid = 0; - } - - } else { - if (TopIndex+MAX_VISIBLE >= BuildableCount) { - Scroller = 0; - } else { - Scroller--; - Slid = ObjectHeight; - IsScrollingDown = true; - IsScrolling = true; - } - } - } - } - - /* - ** Scroll logic is handled here. - */ - if (IsScrolling) { - if (IsScrollingDown) { - Slid -= SCROLL_RATE; - if (Slid <= 0) { - IsScrolling = false; - Slid = 0; - TopIndex++; - } - } else { - Slid += SCROLL_RATE; - if (Slid >= ObjectHeight) { - IsScrolling = false; - Slid = 0; - } - } - redraw = true; - } - - /* - ** Handle any flashing logic. Flashing occurs when the player selects an object - ** and provides the visual feedback of a recognized and legal selection. - */ - if (Flasher != -1) { - if (Graphic_Logic()) { - redraw = true; - if (Fetch_Stage() >= 7) { - Set_Rate(0); - Set_Stage(0); - Flasher = -1; - } - } - } - - /* - ** Handle any building clock animation logic. - */ - if (IsBuilding) { - for (int index = 0; index < BuildableCount; index++) { - int factoryid = Buildables[index].Factory; - - if (factoryid != -1) { - FactoryClass * factory = Factories.Raw_Ptr(factoryid); - - if (factory && (factory->Has_Changed() || factory->Is_Blocked())) { - redraw = true; - if (factory->Has_Completed()) { - - /* - ** Construction has been completed. Announce this fact to the player and - ** try to get the object to automatically leave the factory. Buildings are - ** the main exception to the ability to leave the factory under their own - ** power. - */ - TechnoClass * pending = factory->Get_Object(); - if (pending) { - switch (pending->What_Am_I()) { - case RTTI_UNIT: - case RTTI_AIRCRAFT: - OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1)); - // Fall into next case. - - case RTTI_BUILDING: - if (!factory->Is_Blocked()) { - Speak(VOX_CONSTRUCTION); - } - break; - - case RTTI_INFANTRY: - OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1)); - if (!factory->Is_Blocked()) { - Speak(VOX_UNIT_READY); - } - break; - } - } - } - } - } - } - } - - /* - ** If any of the logic determined that this side strip needs to be redrawn, then - ** set the redraw flag for this side strip. - */ - if (redraw) { - Flag_To_Redraw(); - } - return(redraw); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Draw_It -- Render the sidebar display. * - * * - * Use this routine to render the sidebar display. It checks to see if it needs to be * - * redrawn and only redraw if necessary. If the "complete" parameter is true, then it * - * will force redraw the entire strip. * - * * - * INPUT: complete -- Should the redraw be forced? A force redraw will ignore the redraw * - * flag. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - * 08/06/1995 JLB : Handles multi factory tracking in same strip. * - *=============================================================================================*/ -void SidebarClass::StripClass::Draw_It(bool complete) -{ - if (IsToRedraw || complete) { - IsToRedraw = false; - - /* - ** Fills the background to the side strip. We shouldnt need to do this if the strip - ** has a full complement of icons. ST - 10/7/96 6:03PM - */ - if (BuildableCount < MAX_VISIBLE){ - CC_Draw_Shape(LogoShapes, ID, X+3, Y-1, WINDOW_MAIN, SHAPE_WIN_REL|SHAPE_NORMAL, 0); - } - - /* - ** Redraw the scroll buttons. - */ - UpButton[ID].Draw_Me(true); - DownButton[ID].Draw_Me(true); - - /* - ** Loop through all the buildable objects that are visible in the strip and render - ** them. Their Y offset may be adjusted if the strip is in the process of scrolling. - */ - for (int i = 0; i < MAX_VISIBLE + (IsScrolling ? 1 : 0); i++) { - bool production; - bool completed; - int stage; - bool darken = false; - void const * shapefile = 0; - int shapenum = 0; - void const * remapper = 0; - FactoryClass * factory = 0; - int index = i+TopIndex; - int x = X; - int y = Y + i*ObjectHeight; - y--; - - /* - ** If the strip is scrolling, then the offset is adjusted accordingly. - */ - if (IsScrolling) { - y -= ObjectHeight - Slid; - } - - /* - ** Fetch the shape number for the object type located at this current working - ** slot. This shape pointer is used to draw the underlying graphic there. - */ - if (index < BuildableCount) { - ObjectTypeClass const * obj = NULL; - int spc = 0; - - if (Buildables[index].BuildableType != RTTI_SPECIAL) { - - obj = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID); - if (obj) { - bool isbusy = false; - switch (Buildables[index].BuildableType) { - case RTTI_INFANTRYTYPE: - isbusy = (PlayerPtr->InfantryFactory != -1); - break; - - case RTTI_BUILDINGTYPE: - isbusy = (PlayerPtr->BuildingFactory != -1); - if (!BuildingTypeClass::As_Reference((StructType)Buildables[index].BuildableID).IsWall) { - remapper = PlayerPtr->Remap_Table(false, false); - } - break; - - case RTTI_UNITTYPE: - isbusy = (PlayerPtr->UnitFactory != -1); - switch (Buildables[index].BuildableID) { - case UNIT_MCV: - case UNIT_HARVESTER: - remapper = PlayerPtr->Remap_Table(false, false); - break; - - default: - remapper = PlayerPtr->Remap_Table(false, true); - break; - } - break; - - case RTTI_AIRCRAFTTYPE: - isbusy = (PlayerPtr->AircraftFactory != -1); - remapper = PlayerPtr->Remap_Table(false, true); - break; - } - shapefile = obj->Get_Cameo_Data(); - shapenum = 0; - if (Buildables[index].Factory != -1) { - factory = Factories.Raw_Ptr(Buildables[index].Factory); - production = true; - completed = factory->Has_Completed(); - stage = factory->Completion(); - darken = false; - } else { - production = false; -// darken = IsBuilding; - - /* - ** Darken the imagery if a factory of a matching type is - ** already busy. - */ - darken = isbusy; - } - } - - } else { - - spc = Buildables[index].BuildableID; - shapefile = Get_Special_Cameo(spc - 1); - shapenum = 0; - - switch (spc) { - case SPC_ION_CANNON: - production = true; - completed = PlayerPtr->IonCannon.Is_Ready(); - stage = PlayerPtr->IonCannon.Anim_Stage(); - darken = false; - break; - - case SPC_AIR_STRIKE: - production = true; - completed = PlayerPtr->AirStrike.Is_Ready(); - stage = PlayerPtr->AirStrike.Anim_Stage(); - darken = false; - break; - - case SPC_NUCLEAR_BOMB: - production = true; - completed = PlayerPtr->NukeStrike.Is_Ready(); - stage = PlayerPtr->NukeStrike.Anim_Stage(); - darken = false; - break; - } - } - - if (obj || spc) { - /* - ** If this item is flashing then take care of it. - ** - */ - if (Flasher == index && (Fetch_Stage() & 0x01)) { - remapper = Map.FadingLight; - } - - } else { - shapefile = LogoShapes; - shapenum = SB_BLANK; - } - } else { - shapefile = LogoShapes; - shapenum = SB_BLANK; - production = false; - } - - remapper = 0; - - /* - ** Now that the shape of the object at the current working slot has been found, - ** draw it and any graphic overlays as necessary. - ** - ** Dont draw blank shapes over the new 640x400 sidebar art - ST 5/1/96 6:01PM - */ - if (shapenum != SB_BLANK || shapefile != LogoShapes){ - IsTheaterShape = true; // This shape is theater specific - CC_Draw_Shape(shapefile, shapenum, - x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8)+LeftEdgeOffset, - y-WindowList[WINDOW_SIDEBAR][WINDOWY], - WINDOW_SIDEBAR, - SHAPE_NORMAL|SHAPE_WIN_REL| (remapper ? SHAPE_FADING : SHAPE_NORMAL), - remapper); - IsTheaterShape = false; - - - /* - ** Darken this object because it cannot be produced or is otherwise - ** unavailable. - */ - if (darken) { - CC_Draw_Shape(ClockShapes, 0, - x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8)+LeftEdgeOffset, - y-WindowList[WINDOW_SIDEBAR][WINDOWY], - WINDOW_SIDEBAR, - SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST, - NULL, ClockTranslucentTable); - } - } - - /* - ** Draw the overlapping clock shape if this is object is being constructed. - ** If the object is completed, then display "Ready" with no clock shape. - */ - if (production) { - if (completed) { - - /* - ** Display text showing that the object is ready to place. - */ - CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_READY, - (x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8))+LeftEdgeOffset+(ObjectWidth >> 1), - (y-WindowList[WINDOW_SIDEBAR][WINDOWY])+ObjectHeight-Get_Build_Frame_Height(ObjectTypeClass::PipShapes) -8, - WINDOW_SIDEBAR, SHAPE_CENTER); -// Fancy_Text_Print(TXT_READY, x+TEXT_X_OFFSET, y+TEXT_Y_OFFSET, TEXT_COLOR, TBLACK, TPF_6POINT|TPF_CENTER|TPF_NOSHADOW); - } else { - CC_Draw_Shape(ClockShapes, stage+1, - x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8)+LeftEdgeOffset, - y-WindowList[WINDOW_SIDEBAR][WINDOWY], - WINDOW_SIDEBAR, - SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST, - NULL, ClockTranslucentTable); - /* - ** Display text showing that the construction is temporarily on hold. - */ - if (factory && !factory->Is_Building()) { - CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_HOLDING, - (x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8))+LeftEdgeOffset+(ObjectWidth >> 1), - (y-WindowList[WINDOW_SIDEBAR][WINDOWY])+ObjectHeight-Get_Build_Frame_Height(ObjectTypeClass::PipShapes) - 8, // Moved up now that icons have names on them - WINDOW_SIDEBAR, SHAPE_CENTER); -// Fancy_Text_Print(TXT_HOLDING, x+TEXT_X_OFFSET, y+TEXT_Y_OFFSET, TEXT_COLOR, TBLACK, TPF_6POINT|TPF_CENTER|TPF_NOSHADOW); - } - } - } - } - } -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. * - * * - * This routine will revalidate all the buildable objects in the sidebar. This routine * - * comes in handy when a factory has been destroyed, and the sidebar needs to reflect any * - * change that this requires. It checks every object to see if there is a factory available * - * that could produce it. If none can be found, then the object is removed from the * - * sidebar. * - * * - * INPUT: none * - * * - * OUTPUT: bool; The sidebar has changed as a result of this call? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - * 06/26/1995 JLB : Doesn't collapse sidebar when buildables removed. * - *=============================================================================================*/ -bool SidebarClass::StripClass::Recalc(void) -{ - int ok; - - if (Debug_Map || !BuildableCount) { - return(false); - } - - /* - ** Sweep through all objects listed in the sidebar. If any of those object can - ** not be created -- even in theory -- then they must be removed form the sidebar and - ** any current production must be abandoned. - */ - bool redraw = false; - for (int index = 0; index < BuildableCount; index++) { - TechnoTypeClass const * tech = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID); - if (tech) { - ok = tech->Who_Can_Build_Me(true, false, PlayerPtr->Class->House) != NULL; - } else { - switch (Buildables[index].BuildableID) { - case SPC_ION_CANNON: - ok = PlayerPtr->IonCannon.Is_Present(); - break; - - case SPC_NUCLEAR_BOMB: - ok = PlayerPtr->NukeStrike.Is_Present(); - break; - - case SPC_AIR_STRIKE: - ok = PlayerPtr->AirStrike.Is_Present(); - break; - - default: - ok = false; - break; - } - -#ifdef OBSOLETE - } else { - switch (Buildables[index].BuildableID) { - case SPC_ION_CANNON: - ok = (PlayerPtr->BScan & STRUCTF_EYE) != 0 || PlayerPtr->IonOneTimeFlag; - if (!ok) { - PlayerPtr->Remove_Ion_Cannon(); - } - break; - - case SPC_NUCLEAR_BOMB: - ok = (PlayerPtr->BScan & STRUCTF_TEMPLE) != 0 && PlayerPtr->Has_Nuke_Device(); - ok = ok || PlayerPtr->NukeOneTimeFlag; - if (!ok) { - PlayerPtr->Remove_Nuke_Bomb(); - } - break; - - case SPC_AIR_STRIKE: -// ok = (PlayerPtr->BScan & STRUCTF_SAM) == 0; -// ok = !PlayerPtr->Does_Enemy_Building_Exist(STRUCT_SAM); - ok = (PlayerPtr->AirPresent /*&& !PlayerPtr->Does_Enemy_Building_Exist(STRUCT_SAM)*/) || PlayerPtr->AirOneTimeFlag; - if (!ok) { - PlayerPtr->Remove_Air_Strike(); - } - break; - - default: - ok = false; - break; - } -#endif - } - - if (!ok) { - - /* - ** If there was something in production, then abandon it before deleting the - ** factory manager. - */ - //if (Buildables[index].Factory != -1) { - //FactoryClass * factory = Factories.Raw_Ptr(Buildables[index].Factory); - //factory->Abandon(); - //delete factory; - //Buildables[index].Factory = -1; - //} -// Buildables[index].Factory = -1; - - /* - ** Removes this entry from the list. - */ - if (BuildableCount > 1 && index < BuildableCount-1) { - memcpy(&Buildables[index], &Buildables[index+1], sizeof(Buildables[0])*((BuildableCount-index)-1)); - } - TopIndex = 0; - IsToRedraw = true; - redraw = true; - BuildableCount--; - index--; - } - } - -#ifdef NEVER - /* - ** If there are no more buildable objects to display, make the sidebar go away. - */ - if (!BuildableCount) { - Map.SidebarClass::Activate(0); - } -#endif - return(redraw); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor. * - * * - * This is the default constructor for the button that controls the buildable cameos on * - * the sidebar strip. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: The coordinates are set to zero by this routine. They must be set to the * - * correct values before this button will function. * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -SidebarClass::StripClass::SelectClass::SelectClass(void) : - ControlClass(0, 0, 0, 0, 0, LEFTPRESS|RIGHTPRESS|LEFTUP) -{ - int factor = Get_Resolution_Factor(); - - Strip = 0; - Index = 0; - Width = StripClass::OBJECT_WIDTH << factor; - Height = StripClass::OBJECT_HEIGHT << factor; -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select but * - * * - * Use this routine to set custom buildable vars for this particular select button. It * - * uses this information to properly know what buildable object to start or stop production * - * on. * - * * - * INPUT: strip -- Reference to the strip that owns this buildable button. * - * * - * index -- The index (0 .. MAX_VISIBLE-1) of this button. This is used to let * - * the owning strip know what index this button refers to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void SidebarClass::StripClass::SelectClass::Set_Owner(StripClass & strip, int index) -{ - int factor = Get_Resolution_Factor(); - Strip = &strip; - Index = index; - X = strip.X; - Y = strip.Y + (index * (StripClass::OBJECT_HEIGHT << factor)); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selected * - * * - * This function is called when the buildable icon (cameo) is clicked on. It handles * - * starting and stopping production as indicated. * - * * - * INPUT: flags -- The input event that triggered the call. * - * * - * key -- The keyboard value at the time of the input. * - * * - * OUTPUT: Returns with whether the input list should be scanned further. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -int SidebarClass::StripClass::SelectClass::Action(unsigned flags, KeyNumType & key) -{ - int index = Strip->TopIndex + Index; - RTTIType otype = Strip->Buildables[index].BuildableType; - int oid = Strip->Buildables[index].BuildableID; - int fnumber = Strip->Buildables[index].Factory; - - FactoryClass * factory = NULL; - ObjectTypeClass const * choice = NULL; - int spc = 0; - - /* - ** Determine the factory number that would apply to objects of the type - ** the mouse is currently addressing. This doesn't mean that the factory number - ** fetched is actually producing the indicated object, merely that that particular - ** kind of factory is specified by the "genfactory" value. This can be used to see - ** if the factory type is currently busy or not. - */ - int genfactory = -1; - switch (otype) { - case RTTI_INFANTRYTYPE: - genfactory = PlayerPtr->InfantryFactory; - break; - - case RTTI_UNITTYPE: - genfactory = PlayerPtr->UnitFactory; - break; - - case RTTI_AIRCRAFTTYPE: - genfactory = PlayerPtr->AircraftFactory; - break; - - case RTTI_BUILDINGTYPE: - genfactory = PlayerPtr->BuildingFactory; - break; - - default: - genfactory = -1; - break; - } - - Map.Override_Mouse_Shape(MOUSE_NORMAL); - - if (index < Strip->BuildableCount) { - if (otype != RTTI_SPECIAL) { - choice = Fetch_Techno_Type(otype, oid); - } else { - spc = oid; - } - - if (fnumber != -1) { - factory = Factories.Raw_Ptr(fnumber); - } - - } else { - Map.Help_Text(TXT_NONE); - } - - if (spc) { - /* - ** Display the help text if the mouse is over the button. - */ - if (flags & LEFTUP) { - switch (spc) { - case SPC_ION_CANNON: - Map.Help_Text(TXT_ION_CANNON, X, Y, CC_GREEN, true); - break; - - case SPC_NUCLEAR_BOMB: - Map.Help_Text(TXT_NUKE_STRIKE, X, Y, CC_GREEN, true); - break; - - case SPC_AIR_STRIKE: - Map.Help_Text(TXT_AIR_STRIKE, X, Y, CC_GREEN, true); - break; - } - flags &= ~LEFTUP; - } - - /* - ** A right mouse button signals "cancel". If we are in targetting - ** mode then we don't want to be any more. - */ - if (flags & RIGHTPRESS) { - Map.IsTargettingMode = false; - } - /* - ** A left mouse press signal "activate". If our weapon type is - ** available then we should activate it. - */ - if (flags & LEFTPRESS) { - switch (spc) { - case SPC_ION_CANNON: - if (PlayerPtr->IonCannon.Is_Ready()) { - Map.IsTargettingMode = spc; - Unselect_All(); - Speak(VOX_SELECT_TARGET); - } else { - PlayerPtr->IonCannon.Impatient_Click(); - } - break; - - case SPC_AIR_STRIKE: - if (PlayerPtr->AirStrike.Is_Ready()) { - Map.IsTargettingMode = spc; - Unselect_All(); - Speak(VOX_SELECT_TARGET); - } else { - PlayerPtr->AirStrike.Impatient_Click(); - } - break; - - case SPC_NUCLEAR_BOMB: - if (PlayerPtr->NukeStrike.Is_Ready()) { - Map.IsTargettingMode = spc; - Unselect_All(); - Speak(VOX_SELECT_TARGET); - } else { - PlayerPtr->NukeStrike.Impatient_Click(); - } - break; - } - } - - } else { - - if (choice) { - - /* - ** Display the help text if the mouse is over the button. - */ - if (flags & LEFTUP) { - Map.Help_Text(choice->Full_Name(), X, Y, CC_GREEN, true, choice->Cost_Of() * PlayerPtr->CostBias); - flags &= ~LEFTUP; - } - - /* - ** A right mouse button signals "cancel". - */ - if (flags & RIGHTPRESS) { - - /* - ** If production is in progress, put it on hold. If production is already - ** on hold, then abandon it. Money will be refunded, the factory - ** manager deleted, and the object under construction is returned to - ** the free pool. - */ - if (factory) { - - /* - ** Cancels placement mode if the sidebar factory is abandoned or - ** suspended. - */ - if (Map.PendingObjectPtr && Map.PendingObjectPtr->Is_Techno()) { - Map.PendingObjectPtr = 0; - Map.PendingObject = 0; - Map.PendingHouse = HOUSE_NONE; - Map.Set_Cursor_Shape(0); - } - - if (!factory->Is_Building()) { - Speak(VOX_CANCELED); - OutList.Add(EventClass(EventClass::ABANDON, otype, oid)); - } else { - Speak(VOX_SUSPENDED); - OutList.Add(EventClass(EventClass::SUSPEND, otype, oid)); - } - } - } - - if (flags & LEFTPRESS) { - - /* - ** If there is already a factory attached to this strip but the player didn't click - ** on the icon that has the attached factory, then say that the factory is busy and - ** ignore the click. - */ - if (fnumber == -1 && genfactory != -1) { - Speak(VOX_NO_FACTORY); - ControlClass::Action(flags, key); - return(true); - } - - if (factory) { - - /* - ** If this object is currently being built, then give a scold sound and text and then - ** bail. - */ - if (factory->Is_Building()) { - Speak(VOX_NO_FACTORY); - } else { - - /* - ** If production has completed, then attempt to have the object exit - ** the factory or go into placement mode. - */ - if (factory->Has_Completed()) { - - TechnoClass * pending = factory->Get_Object(); - if (!pending && factory->Get_Special_Item()) { - Map.IsTargettingMode = true; - } else { - BuildingClass * builder = pending->Who_Can_Build_Me(false, false); - if (!builder) { - OutList.Add(EventClass(EventClass::ABANDON, otype, oid)); - Speak(VOX_NO_FACTORY); - } else { - - /* - ** If the completed object is a building, then change the - ** game state into building placement mode. This fact is - ** not transmitted to any linked computers until the moment - ** the building is actually placed down. - */ - if (pending->What_Am_I() == RTTI_BUILDING) { - PlayerPtr->Manual_Place(builder, (BuildingClass *)pending); - } else { - - /* - ** For objects that can leave the factory under their own - ** power, queue this event and process through normal house - ** production channels. - */ - OutList.Add(EventClass(EventClass::PLACE, otype, -1)); - } - } - } - } else { - - /* - ** The factory must have been in a suspended state. Resume construction - ** normally. - */ - Speak(VOX_BUILDING); - OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID)); - } - } - - } else { - - /* - ** If this side strip is already busy with production, then ignore the - ** input and announce this fact. - */ -// if (Strip->IsBuilding) { -// Speak(VOX_NO_FACTORY); -// } else { - Speak(VOX_BUILDING); - OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID)); -// } - } - } - } else { - flags = 0; - } - } - - ControlClass::Action(flags, key); - return(true); -} - - -/*********************************************************************************************** - * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the si * - * * - * This routine is called whenever the mouse is over the sidebar. It makes sure that the * - * mouse is always the normal shape while over the sidebar. * - * * - * INPUT: flags -- The event flags that resuled in this routine being called. * - * * - * key -- Reference the keyboard code that may be present. * - * * - * OUTPUT: Returns that no further keyboard processing is necessary. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/28/1995 JLB : Created. * - *=============================================================================================*/ -int SidebarClass::SBGadgetClass::Action(unsigned , KeyNumType & ) -{ - Map.Help_Text(TXT_NONE); - Map.Override_Mouse_Shape(MOUSE_NORMAL, false); - return(true); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button. * - * * - * This routine will link the specified factory to this sidebar strip. The exact button to * - * link to is determined from the object type and id specified. A linked button is one that * - * will show appropriate construction animation (clock shape) that matches the state of * - * the factory. * - * * - * INPUT: factory -- The factory number to link to the sidebar. * - * * - * type -- The object type that this factory refers to. * - * * - * id -- The object sub-type that this factory refers to. * - * * - * OUTPUT: Was the factory successfully attached? Failure would indicate that there is no * - * object of the specified type and sub-type in the sidebar list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::StripClass::Factory_Link(int factory, RTTIType type, int id) -{ - for (int index = 0; index < BuildableCount; index++) { - if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) { - Buildables[index].Factory = factory; - IsBuilding = true; - - /* - ** Flag that all the icons on this strip need to be redrawn - */ - Flag_To_Redraw(); - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * SidebarClass::Abandon_Production -- Stops production of the object specified. * - * * - * This routine is used to abandon production of the object specified. The factory will * - * be completely disabled by this call. * - * * - * INPUT: type -- The object type that is to be abandoned. The sub-type is not needed * - * since it is presumed there can be only one type in production at any * - * one time. * - * * - * factory -- The factory number that is doing the production. * - * * - * OUTPUT: Was the factory successfully abandoned? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -bool SidebarClass::Abandon_Production(RTTIType type, int factory) -{ - return(Column[Which_Column(type)].Abandon_Production(factory)); -} - - -/*********************************************************************************************** - * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. * - * * - * Production of the object associated with this sidebar is abandoned when this routine is * - * called. * - * * - * INPUT: factory -- The factory index that is to be suspended. * - * * - * OUTPUT: Was the production abandonment successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - * 08/06/1995 JLB : More intelligent abandon logic for multiple factories. * - *=============================================================================================*/ -bool SidebarClass::StripClass::Abandon_Production(int factory) -{ - bool noprod = true; - bool abandon = false; - for (int index = 0; index < BuildableCount; index++) { - if (Buildables[index].Factory == factory) { - Factories.Raw_Ptr(factory)->Abandon(); - Buildables[index].Factory = -1; - abandon = true; - } else { - if (Buildables[index].Factory != -1) { - noprod = false; - } - } - } - - /* - ** If there was a change to the strip, then flag the strip to be redrawn. - */ - if (abandon) { - Flag_To_Redraw(); - } - - /* - ** If there is no production whatsoever on this strip, then flag it so. - */ - if (noprod) { - IsBuilding = false; - } - return(abandon); -} diff --git a/code/TIBERIANDAWN/SIDEBAR.H b/code/TIBERIANDAWN/SIDEBAR.H deleted file mode 100644 index 7414d8f..0000000 --- a/code/TIBERIANDAWN/SIDEBAR.H +++ /dev/null @@ -1,395 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\sidebar.h_v 2.18 16 Oct 1995 16:45:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SIDEBAR.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 20, 1994 * - * * - * Last Update : October 20, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SIDEBAR_H -#define SIDEBAR_H - -#include "function.h" -#include "power.h" -#include "factory.h" - -class SidebarClass: public PowerClass -{ - public: - /* - ** These constants are used to control the sidebar rendering. They are instantiated - ** as enumerations since C++ cannot use "const" in this context. - */ - int SideX; // x position for side bar - int SideY; // y position for side bar - int SideBarWidth; // width of the sidebar - int SideWidth; // width of the sidebar - int SideHeight; // height of the sidebar - int TopHeight; // height of top of sidebar - int MaxVisible; // max production icons visible - int ButtonOneWidth; // Button width. - int ButtonTwoWidth; // Button width. - int ButtonThreeWidth; // Button width. - int ButtonHeight; // Button width. - - enum SideBarClassEnums { - BUTTON_ACTIVATOR=100, // Button ID for the activator. - SIDEBARWIDTH = 80, -#if 0 - SIDE_X=RADAR_X, // The X position of sidebar upper left corner. - SIDE_Y=RADAR_Y+RADAR_HEIGHT, // The Y position of sidebar upper left corner. - SIDE_WIDTH=320-SIDE_X, // Width of the entire sidebar (in pixels). - SIDE_HEIGHT=200-SIDE_Y, // Height of the entire sidebar (in pixels). - TOP_HEIGHT=13, // Height of top section (with repair/sell buttons). - COLUMN_ONE_X=SIDE_X+8, // Sidestrip upper left coordinates... - COLUMN_ONE_Y=SIDE_Y+TOP_HEIGHT, - COLUMN_TWO_X=COLUMN_ONE_X+((SIDE_WIDTH-16)/2)+3, - COLUMN_TWO_Y=SIDE_Y+TOP_HEIGHT, -#if (GERMAN | FRENCH) -//BGA: changes to all buttons - BUTTON_ONE_WIDTH=20, // Button width. - BUTTON_TWO_WIDTH=27, // Button width. - BUTTON_THREE_WIDTH=26, // Button width. - BUTTON_HEIGHT=9, // Button height. - BUTTON_ONE_X=SIDE_X+2, // Left button X coordinate. - BUTTON_ONE_Y=SIDE_Y+2, // Left button Y coordinate. - BUTTON_TWO_X=SIDE_X+24, // Right button X coordinate. - BUTTON_TWO_Y=SIDE_Y+2, // Right button Y coordinate. - BUTTON_THREE_X=SIDE_X+53, // Right button X coordinate. - BUTTON_THREE_Y=SIDE_Y+2, // Right button Y coordinate. -#else - BUTTON_ONE_WIDTH=32, // Button width. - BUTTON_TWO_WIDTH=20, // Button width. - BUTTON_THREE_WIDTH=20, // Button width. - BUTTON_HEIGHT=9, // Button height. - BUTTON_ONE_X=SIDE_X+2, // Left button X coordinate. - BUTTON_ONE_Y=SIDE_Y+2, // Left button Y coordinate. - BUTTON_TWO_X=SIDE_X+36, // Right button X coordinate. - BUTTON_TWO_Y=SIDE_Y+2, // Right button Y coordinate. - BUTTON_THREE_X=SIDE_X+58, // Right button X coordinate. - BUTTON_THREE_Y=SIDE_Y+2, // Right button Y coordinate. -#endif - BUTTON_ONE_WIDTH=32, // Button width. - BUTTON_TWO_WIDTH=20, // Button width. - BUTTON_THREE_WIDTH=20, // Button width. - BUTTON_HEIGHT=9, // Button height. -#endif - COLUMNS=2, // Number of side strips on sidebar. - }; - - SidebarClass(void); - - /* - ** Initialization - */ - virtual void One_Time(void); // One-time inits - virtual void Init_Clear(void); // Clears all to known state - virtual void Init_IO(void); // Inits button list - virtual void Init_Theater(TheaterType theater); // Theater-specific inits - - virtual void AI(KeyNumType & input, int x, int y); - virtual void Draw_It(bool complete); - virtual void Refresh_Cells(CELL cell, short const *list); - - bool Abandon_Production(RTTIType type, int factory); - bool Activate(int control); - bool Add(RTTIType type, int ID, bool via_capture = false); // Added via_capture for new sidebar functionality. ST - 9/24/2019 3:15PM - bool Sidebar_Click(KeyNumType & input, int x, int y); - void Recalc(void); - bool Factory_Link(int factory, RTTIType type, int id); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Each side strip is managed by this class. It handles all strip specific - ** actions. - */ - class StripClass : public StageClass - { - class SelectClass : public ControlClass - { - public: - SelectClass(void); - - void Set_Owner(StripClass & strip, int index); - StripClass * Strip; - int Index; - - protected: - virtual int Action(unsigned flags, KeyNumType & key); - }; - - public: - int ObjectWidth; - int ObjectHeight; - int StripWidth; - int LeftEdgeOffset; - int ButtonSpacingOffset; - - - StripClass(void); - bool Add(RTTIType type, int ID, bool via_capture); // Added via_capture for new sidebar functionality. ST - 9/24/2019 3:15PM - bool Abandon_Production(int factory); - bool Scroll(bool up); - bool AI(KeyNumType & input, int x, int y); - void Draw_It(bool complete); - void One_Time(int id); - void Init_Clear(void); - void Init_IO(int id); - void Init_Theater(TheaterType theater); - bool Recalc(void); - void Activate(void); - void Deactivate(void); - void Flag_To_Redraw(void); - bool Factory_Link(int factory, RTTIType type, int id); - void const * Get_Special_Cameo(int type); - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - /* - ** Working numbers used when rendering and processing the side strip. - */ - enum SideBarGeneralEnums { - BUTTON_UP=200, - BUTTON_DOWN=210, - BUTTON_SELECT=220, - MAX_BUILDABLES=30, // Maximum number of object types in sidebar. - OBJECT_HEIGHT=24, // Pixel height of each buildable object. - OBJECT_WIDTH=32, // Pixel width of each buildable object. - STRIP_WIDTH=35, // Width of strip (not counting border lines). - MAX_VISIBLE=4, // Number of object slots visible at any one time. - SCROLL_RATE=8, // The pixel jump while scrolling (larger is faster). - BUTTON_SPACING_OFFSET = 4, // spacing info for buttons - UP_X_OFFSET=2, // Scroll up arrow coordinates. - UP_Y_OFFSET=MAX_VISIBLE*OBJECT_HEIGHT+1, - DOWN_X_OFFSET=18, // Scroll down arrow coordinates. - DOWN_Y_OFFSET=MAX_VISIBLE*OBJECT_HEIGHT+1, - BUTTON_WIDTH=16, // Width of the mini-scroll button. - BUTTON_HEIGHT=12, // Height of the mini-scroll button. - //LEFT_EDGE_OFFSET=2, // Offset from left edge for building shapes. - TEXT_X_OFFSET=18, // X offset to print "ready" text. - TEXT_Y_OFFSET=15, // Y offset to print "ready" text. - TEXT_COLOR=255, // Color to use for the "Ready" text. - //BUTTON_SPACING_OFFSET = 4, // spacing info for buttons - //LEFT_EDGE_OFFSET=0, // Offset from left edge for building shapes. - //BUTTON_SPACING_OFFSET = 0, // spacing info for buttons - - }; - - /* - ** This is the coordinate of the upper left corner that this side strip - ** uses for rendering. - */ - int X,Y; - - /* - ** This is a unique identifier for the sidebar strip. Using this identifier, - ** it is possible to differentiate the button messages that arrive from the - ** common input button list. It >MUST< be equal to the strip's index into - ** the Column[] array, because the strip uses it to access the stripclass - ** buttons. - */ - int ID; - - /* - ** Shape numbers for the shapes in the STRIP.SHP file. - */ - enum SideBarStipShapeEnums { - SB_BLANK, // The blank rectangle to use if there are no objects present. - SB_FRAME - }; - - /* - ** If this particular side strip needs to be redrawn, then this flag - ** will be true. - */ - unsigned IsToRedraw:1; - - /* - ** If construction is in progress (no other objects in this strip can - ** be started), then this flag will be true. It will be cleared when - ** the strip is free to start production again. - */ - unsigned IsBuilding:1; - - /* - ** This controls the sidebar slide direction. If this is true, then the sidebar - ** will scroll downward -- revealing previous objects. - */ - unsigned IsScrollingDown:1; - - /* - ** If the sidebar is scrolling, then this flag is true. Otherwise it is false. - */ - unsigned IsScrolling:1; - - /* - ** This is the object (sidebar slot) that is flashing. Only one slot can be flashing - ** at any one instant. This is usually the result of a click on the slot and construction - ** has commenced. - */ - int Flasher; - - /* - ** As the sidebar scrolls up and down, this variable holds the index for the topmost - ** visible sidebar slot. - */ - int TopIndex; - - /* - ** This is the queued scroll direction and amount. The sidebar - ** will scroll the number of slots indicated by this value. This - ** value is set according to the scroll buttons. - */ - int Scroller; - - /* - ** The sidebar has smooth scrolling. This is the number of pixels the sidebar - ** has slide down. Thus, if this value were 5, then there would be 5 pixels of - ** the TopIndex-1 sidebar object visible. When the Slid value reaches 24, then - ** the value resets to zero and the TopIndex is decremented. For sliding in the - ** opposite direction, change the IsScrollingDown flag. - */ - int Slid; - - /* - ** This is the count of the number of sidebar slots that are active. - */ - int BuildableCount; - - /* - ** This is the array of buildable object types. This array is sorted in the order - ** that it is to be displayed. This array keeps track of which objects are building - ** and ready to be placed. The very nature of this method precludes simultaneous - ** construction of the same object type. - */ - typedef struct BuildType { - int BuildableID; - RTTIType BuildableType; - int Factory; // Production manager. - bool BuildableViaCapture; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM - } BuildType; - BuildType Buildables[MAX_BUILDABLES]; - - /* - ** Pointer to the shape data for small versions of the logos. These are used as - ** placeholder pieces on the side bar. - */ - static void const * LogoShapes; - - /* - ** This points to the animation sequence of frames used to mark the passage of time - ** as an object is undergoing construction. - */ - static void const * ClockShapes; - - /* - ** This points to the animation sequence which deals with special - ** shapes which handle non-production based icons. - */ - static void const * SpecialShapes[3]; - - /* - ** This is the last theater that the special palette remap table was loaded - ** for. If the current theater differs from this recorded value, then the - ** remap tables are reloaded. - */ - static TheaterType LastTheater; - - static ShapeButtonClass UpButton[COLUMNS]; - static ShapeButtonClass DownButton[COLUMNS]; - static SelectClass SelectButton[COLUMNS][MAX_VISIBLE]; - - /* - ** This points to the shapes that are used for the clock overlay. This displays - ** progress of construction. - */ - static char ClockTranslucentTable[(1+1)*256]; - - } Column[COLUMNS]; - - - /* - ** If the sidebar is active then this flag is true. - */ - unsigned IsSidebarActive:1; - - /* - ** This flag tells the rendering system that the sidebar needs to be redrawn. - */ - unsigned IsToRedraw:1; - - class SBGadgetClass: public GadgetClass { - public: -// SBGadgetClass(void) : GadgetClass(SIDE_X+8, SIDE_Y, SIDE_WIDTH-1, SIDE_HEIGHT-1, LEFTUP) {}; - SBGadgetClass(void) : GadgetClass(0,0,0,0,LEFTUP) {}; - - protected: - virtual int Action(unsigned flags, KeyNumType & key); - }; - - /* - ** This is the button that is used to collapse and expand the sidebar. - ** These buttons must be available to derived classes, for Save/Load. - */ - static ShapeButtonClass Repair; - static ShapeButtonClass Upgrade; - static ShapeButtonClass Zoom; - static SBGadgetClass Background; - - /* - ** Pointer to the shape data for the sidebar - */ - static void const * SidebarShape1; - static void const * SidebarShape2; - - - private: - bool Activate_Repair(int control); - bool Activate_Upgrade(int control); - bool Activate_Demolish(int control); - bool Scroll(bool up, int column); - int Which_Column(RTTIType type); - - unsigned IsRepairActive:1; - unsigned IsUpgradeActive:1; - unsigned IsDemolishActive:1; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/SIDEBARGlyphx.CPP b/code/TIBERIANDAWN/SIDEBARGlyphx.CPP deleted file mode 100644 index 826731b..0000000 --- a/code/TIBERIANDAWN/SIDEBARGlyphx.CPP +++ /dev/null @@ -1,833 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\sidebar.cpv 2.13 02 Aug 1995 17:03:22 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SIDEBARGlyphx.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : March 14th, 2019 * - * * - * Last Update : March 14th, 2019 * - * * - *---------------------------------------------------------------------------------------------* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "SidebarGlyphx.h" - - -/* -** ST - 3/14/2019 10:49AM -** -** We are going to need one sidebar per player for multiplayer with GlyphX. We can't have different maps / cell arrays per -** player though, so SidebarClass being in the middle of the map/display class hierarchy is a problem. -** -** All the class static data will have to be made non-static so we can have multiple instances. -** -** So, this is a stub sidebar class with the functionality we need just to support the exporting of production data to the -** GlyphX client. -** -** -*/ - - - -/*********************************************************************************************** - * SidebarGlyphxClass::SidebarGlyphxClass -- Default constructor for the sidebar. * - * * - * Constructor for the sidebar handler. It basically sets up the sidebar to the empty * - * condition. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/17/1994 JLB : Created. * - *=============================================================================================*/ -SidebarGlyphxClass::SidebarGlyphxClass(void) : - SidebarPlayerPtr(NULL) -{ - //IsRepairActive = false; - //IsUpgradeActive = false; - //IsDemolishActive = false; -} - - - - -/*********************************************************************************************** - * SidebarGlyphxClass::Init_Clear -- Sets sidebar to a known (and deactivated) state * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarGlyphxClass::Init_Clear(HouseClass *player_ptr) -{ - SidebarPlayerPtr = player_ptr; - - //IsRepairActive = false; - //IsUpgradeActive = false; - //IsDemolishActive = false; - - Column[0].Set_Parent_Sidebar(this); - Column[1].Set_Parent_Sidebar(this); - - Column[0].Init_Clear(); - Column[1].Init_Clear(); - - - //Activate(false); -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Init_IO -- Adds buttons to the button list * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarGlyphxClass::Init_IO(void) -{ - /* - ** If a game was loaded & the sidebar was enabled, pop it up now - */ - //if (IsSidebarActive) { - // IsSidebarActive = false; - // Activate(1); - //} -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::Which_Column -- Determines which column a given type should appear. * - * * - * Use this function to resolve what column the specified object type should be placed * - * into. * - * * - * INPUT: otype -- Pointer to the object type class of the object in question. * - * * - * OUTPUT: Returns with the column number that the object should be placed in. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/01/1995 JLB : Created. * - *=============================================================================================*/ -int SidebarGlyphxClass::Which_Column(RTTIType type) -{ - if (type == RTTI_BUILDINGTYPE || type == RTTI_BUILDING) { - return(0); - } - return(1); -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Factory_Link -- Links a factory to a sidebar strip. * - * * - * This routine will link the specified factory to the sidebar strip. A factory must be * - * linked to the sidebar so that as the factory production progresses, the sidebar will * - * show the production progress. * - * * - * INPUT: factory -- The factory number to attach. * - * * - * type -- The object type number. * - * * - * id -- The object sub-type number. * - * * - * OUTPUT: Was the factory successfully attached to the sidebar strip? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/19/1995 JLB : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::Factory_Link(int factory, RTTIType type, int id) -{ - return(Column[Which_Column(type)].Factory_Link(factory, type, id)); -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::Add -- Adds a game object to the sidebar list. * - * * - * This routine is used to add a game object to the sidebar. Call this routine when a * - * factory type building is created. It handles the case of adding an item that has already * - * been added -- it just ignores it. * - * * - * INPUT: object -- Pointer to the object that is being added. * - * * - * OUTPUT: bool; Was the object added to the sidebar? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/17/1994 JLB : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::Add(RTTIType type, int id, bool via_capture) -{ - int column; - - /* - ** Add the sidebar only if we're not in editor mode. - */ - if (!Debug_Map) { - column = Which_Column(type); - - if (Column[column].Add(type, id, via_capture)) { - //Activate(1); - return(true); - } - return(false); - } - - return(false); -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::AI -- Handles player clicking on sidebar area. * - * * - * This routine handles the processing necessary when the player clicks on the sidebar. * - * Typically, this is selection of the item to build. * - * * - * INPUT: input -- Reference to the keyboard input value. * - * * - * x,y -- Mouse coordinates at time of input. * - * * - * OUTPUT: bool; Was the click handled? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/28/94 JLB : Created. * - * 11/11/1994 JLB : Processes input directly. * - * 12/26/1994 JLB : Uses factory manager class for construction handling. * - * 12/31/1994 JLB : Simplified to use the sidebar strip class handlers. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - * 06/27/1995 JLB : key toggles sidebar. * - *=============================================================================================*/ -void SidebarGlyphxClass::AI(KeyNumType & input, int x, int y) -{ - if (!Debug_Map) { - Column[0].AI(input, x, y); - Column[1].AI(input, x, y); - } -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Recalc -- Examines the sidebar data and updates it as necessary. * - * * - * Occasionally a factory gets destroyed. This routine must be called in such a case * - * because it might be possible that sidebar object need to be removed. This routine will * - * examine all existing objects in the sidebar class and if no possible factory can * - * produce it, then it will be removed. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine is exhaustive and thus time consuming. Only call it when really * - * necessary. Such as when a factory is destroyed rather than when a non-factory * - * is destroyed. * - * * - * HISTORY: * - * 11/30/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarGlyphxClass::Recalc(void) -{ - Column[0].Recalc(); - Column[1].Recalc(); -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::StripClass -- Default constructor for the side strip class. * - * * - * This constructor is used to reset the side strip to default empty state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - *=============================================================================================*/ -SidebarGlyphxClass::StripClass::StripClass(void) -{ - IsBuilding = false; - BuildableCount = 0; - for (int index = 0; index < MAX_BUILDABLES; index++) { - Buildables[index].BuildableID = 0; - Buildables[index].BuildableType = RTTI_NONE; - Buildables[index].Factory = -1; - Buildables[index].BuildableViaCapture = false; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM - } - ParentSidebar = NULL; -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state* - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/24/1994 JLB : Created. * - *=============================================================================================*/ -void SidebarGlyphxClass::StripClass::Init_Clear(void) -{ - IsBuilding = false; - BuildableCount = 0; - - /* - ** Since we're resetting the strips, clear out all the buildables & factory pointers. - */ - for (int index = 0; index < MAX_BUILDABLES; index++) { - Buildables[index].BuildableID = 0; - Buildables[index].BuildableType = RTTI_NONE; - Buildables[index].Factory = -1; - Buildables[index].BuildableViaCapture = false; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM - } -} - - - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::Add -- Add an object to the side strip. * - * * - * Use this routine to add a buildable object to the side strip. * - * * - * INPUT: object -- Pointer to the object type that can be built and is to be added to * - * the side strip. * - * * - * OUTPUT: bool; Was the object successfully added to the side strip? Failure could be the * - * result of running out of room in the side strip array or the object might * - * already be in the list. * - * * - * WARNINGS: none. * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::StripClass::Add(RTTIType type, int id, bool via_capture) -{ - if (BuildableCount <= MAX_BUILDABLES) { - for (int index = 0; index < BuildableCount; index++) { - if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) { - return(false); - } - } - if (!ScenarioInit && type != RTTI_SPECIAL) { - Speak(VOX_NEW_CONSTRUCT); - } - Buildables[BuildableCount].BuildableType = type; - Buildables[BuildableCount].BuildableID = id; - Buildables[BuildableCount].Factory = -1; - Buildables[BuildableCount].BuildableViaCapture = via_capture; - BuildableCount++; - return(true); - } - return(false); -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::AI -- Input and AI processing for the side strip. * - * * - * The side strip AI processing is performed by this function. This function not only * - * checks for player input, but also handles any graphic logic updating necessary as a * - * result of flashing or construction animation. * - * * - * INPUT: input -- The player input code. * - * * - * x,y -- Mouse coordinate to use. * - * * - * OUTPUT: bool; Did the AI detect that it will need a rendering change? If this routine * - * returns true, then the Draw_It function should be called at the * - * earliest opportunity. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/31/1994 JLB : Created. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - *=============================================================================================*/ -bool SidebarGlyphxClass::StripClass::AI(KeyNumType & input, int , int ) -{ - /* - ** This is needed as it's where units get queued for structure exit. ST -3/14/2019 12:03PM - */ - - - if (IsBuilding) { - for (int index = 0; index < BuildableCount; index++) { - int factoryid = Buildables[index].Factory; - - if (factoryid != -1) { - FactoryClass * factory = Factories.Raw_Ptr(factoryid); - - if (factory && (factory->Has_Changed() || factory->Is_Blocked())) { - - if (factory->Has_Completed()) { - - /* - ** Construction has been completed. Announce this fact to the player and - ** try to get the object to automatically leave the factory. Buildings are - ** the main exception to the ability to leave the factory under their own - ** power. - */ - TechnoClass * pending = factory->Get_Object(); - if (pending) { - switch (pending->What_Am_I()) { - case RTTI_UNIT: - case RTTI_AIRCRAFT: - OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1)); - if (!factory->Is_Blocked()) { - Speak(VOX_UNIT_READY); - } - break; - - case RTTI_BUILDING: - if (!factory->Is_Blocked()) { - Speak(VOX_CONSTRUCTION); - } - break; - - case RTTI_INFANTRY: - OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1)); - if (!factory->Is_Blocked()) { - Speak(VOX_UNIT_READY); - } - break; - } - } - } - } - } - } - } - - return(false); -} - - - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. * - * * - * This routine will revalidate all the buildable objects in the sidebar. This routine * - * comes in handy when a factory has been destroyed, and the sidebar needs to reflect any * - * change that this requires. It checks every object to see if there is a factory available * - * that could produce it. If none can be found, then the object is removed from the * - * sidebar. * - * * - * INPUT: none * - * * - * OUTPUT: bool; The sidebar has changed as a result of this call? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - * 06/26/1995 JLB : Doesn't collapse sidebar when buildables removed. * - *=============================================================================================*/ -bool SidebarGlyphxClass::StripClass::Recalc(void) -{ - int ok; - - if (Debug_Map || !BuildableCount) { - return(false); - } - - /* - ** Sweep through all objects listed in the sidebar. If any of those object can - ** not be created -- even in theory -- then they must be removed form the sidebar and - ** any current production must be abandoned. - */ - for (int index = 0; index < BuildableCount; index++) { - TechnoTypeClass const * tech = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID); - if (tech) { - ok = tech->Who_Can_Build_Me(true, false, ParentSidebar->SidebarPlayerPtr->Class->House) != NULL; - } else { - switch (Buildables[index].BuildableID) { - case SPC_ION_CANNON: - ok = ParentSidebar->SidebarPlayerPtr->IonCannon.Is_Present(); - break; - - case SPC_NUCLEAR_BOMB: - ok = ParentSidebar->SidebarPlayerPtr->NukeStrike.Is_Present(); - break; - - case SPC_AIR_STRIKE: - ok = ParentSidebar->SidebarPlayerPtr->AirStrike.Is_Present(); - break; - - default: - ok = false; - break; - } - } - - if (!ok) { - - /* - ** Removes this entry from the list. - */ - if (BuildableCount > 1 && index < BuildableCount-1) { - memcpy(&Buildables[index], &Buildables[index+1], sizeof(Buildables[0])*((BuildableCount-index)-1)); - } - BuildableCount--; - index--; - - Buildables[BuildableCount].BuildableID = 0; - Buildables[BuildableCount].BuildableType = RTTI_NONE; - Buildables[BuildableCount].Factory = -1; - Buildables[BuildableCount].BuildableViaCapture = false; - } - } - - return(false); -} - - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::Factory_Link -- Links a factory to a sidebar button. * - * * - * This routine will link the specified factory to this sidebar strip. The exact button to * - * link to is determined from the object type and id specified. A linked button is one that * - * will show appropriate construction animation (clock shape) that matches the state of * - * the factory. * - * * - * INPUT: factory -- The factory number to link to the sidebar. * - * * - * type -- The object type that this factory refers to. * - * * - * id -- The object sub-type that this factory refers to. * - * * - * OUTPUT: Was the factory successfully attached? Failure would indicate that there is no * - * object of the specified type and sub-type in the sidebar list. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::StripClass::Factory_Link(int factory, RTTIType type, int id) -{ - for (int index = 0; index < BuildableCount; index++) { - if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) { - Buildables[index].Factory = factory; - IsBuilding = true; - - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Abandon_Production -- Stops production of the object specified. * - * * - * This routine is used to abandon production of the object specified. The factory will * - * be completely disabled by this call. * - * * - * INPUT: type -- The object type that is to be abandoned. The sub-type is not needed * - * since it is presumed there can be only one type in production at any * - * one time. * - * * - * factory -- The factory number that is doing the production. * - * * - * OUTPUT: Was the factory successfully abandoned? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::Abandon_Production(RTTIType type, int factory) -{ - return(Column[Which_Column(type)].Abandon_Production(factory)); -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. * - * * - * Production of the object associated with this sidebar is abandoned when this routine is * - * called. * - * * - * INPUT: factory -- The factory index that is to be suspended. * - * * - * OUTPUT: Was the production abandonment successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/18/1995 JLB : Created. * - * 08/06/1995 JLB : More intelligent abandon logic for multiple factories. * - *=============================================================================================*/ -bool SidebarGlyphxClass::StripClass::Abandon_Production(int factory) -{ - bool noprod = true; - bool abandon = false; - for (int index = 0; index < BuildableCount; index++) { - if (Buildables[index].Factory == factory) { - Factories.Raw_Ptr(factory)->Abandon(); - Buildables[index].Factory = -1; - abandon = true; - } else { - if (Buildables[index].Factory != -1) { - noprod = false; - } - } - } - - /* - ** If there is no production whatsoever on this strip, then flag it so. - */ - if (noprod) { - IsBuilding = false; - } - return(abandon); -} - - - - - - -/*********************************************************************************************** - * SidebarGlyphxClass::Code_Pointers -- Converts classes pointers to savable representation * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 9/25/2019 5:36PM ST : Created. * - *=============================================================================================*/ -void SidebarGlyphxClass::Code_Pointers(void) -{ - if (SidebarPlayerPtr) { - ((HouseClass *&)SidebarPlayerPtr) = (HouseClass *)SidebarPlayerPtr->Class->House; - } else { - ((HouseClass *&)SidebarPlayerPtr) = (HouseClass *)HOUSE_NONE; - } -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Decode_Pointers -- Converts classes savable representation to run-time * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 9/25/2019 5:36PM ST : Created. * - *=============================================================================================*/ -void SidebarGlyphxClass::Decode_Pointers(void) -{ - - if (*((HousesType*)&SidebarPlayerPtr) == HOUSE_NONE) { - SidebarPlayerPtr = NULL; - } else { - ((HouseClass *&)SidebarPlayerPtr) = HouseClass::As_Pointer(*((HousesType*)&SidebarPlayerPtr)); - } -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Load -- Loads from a save game file. * - * * - * INPUT: file -- The file to read the data from. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 9/26/2019 10:57AM ST : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::Load(FileClass & file) -{ - ::new (this) SidebarGlyphxClass(); - - bool ok = Read_Object(this, sizeof(*this), file, false); - - Column[0].Set_Parent_Sidebar(this); - Column[1].Set_Parent_Sidebar(this); - - return ok; -} - - -/*********************************************************************************************** - * SidebarGlyphxClass::Save -- Write to a save game file. * - * * - * INPUT: file -- The file to write the data to. * - * * - * OUTPUT: true = success, false = failure * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 9/26/2019 10:57AM ST : Created. * - *=============================================================================================*/ -bool SidebarGlyphxClass::Save(FileClass & file) -{ - return(Write_Object(this, sizeof(*this), file)); -} - - -extern SidebarGlyphxClass *Get_Current_Context_Sidebar(HouseClass *player_ptr); - - -void Sidebar_Glyphx_Init_Clear(HouseClass *player_ptr) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - sidebar->Init_Clear(player_ptr); - } -} - -void Sidebar_Glyphx_Init_IO(HouseClass *player_ptr) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - sidebar->Init_IO(); - } -} - -bool Sidebar_Glyphx_Abandon_Production(RTTIType type, int factory, HouseClass *player_ptr) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - return sidebar->Abandon_Production(type, factory); - } - - return false; -} - -bool Sidebar_Glyphx_Add(RTTIType type, int id, HouseClass *player_ptr, bool via_capture) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - return sidebar->Add(type, id, via_capture); - } - - return false; -} - -void Sidebar_Glyphx_Recalc(HouseClass *player_ptr) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - sidebar->Recalc(); - } -} - -void Sidebar_Glyphx_AI(HouseClass *player_ptr, KeyNumType & input) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - sidebar->AI(input, 0, 0); - } -} - -bool Sidebar_Glyphx_Factory_Link(int factory, RTTIType type, int id, HouseClass *player_ptr) -{ - SidebarGlyphxClass *sidebar = Get_Current_Context_Sidebar(player_ptr); - if (sidebar) { - return sidebar->Factory_Link(factory, type, id); - } - - return false; -} - -bool Sidebar_Glyphx_Save(FileClass &file, SidebarGlyphxClass *sidebar) -{ - if (sidebar) { - return sidebar->Save(file); - } - return false; -} - -bool Sidebar_Glyphx_Load(FileClass &file, SidebarGlyphxClass *sidebar) -{ - if (sidebar) { - return sidebar->Load(file); - } - return false; -} - -void Sidebar_Glyphx_Code_Pointers(SidebarGlyphxClass *sidebar) -{ - if (sidebar) { - sidebar->Code_Pointers(); - } -} - -void Sidebar_Glyphx_Decode_Pointers(SidebarGlyphxClass *sidebar) -{ - if (sidebar) { - sidebar->Decode_Pointers(); - } -} - \ No newline at end of file diff --git a/code/TIBERIANDAWN/SIDEBARGlyphx.H b/code/TIBERIANDAWN/SIDEBARGlyphx.H deleted file mode 100644 index fbce978..0000000 --- a/code/TIBERIANDAWN/SIDEBARGlyphx.H +++ /dev/null @@ -1,206 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\sidebar.h_v 2.18 16 Oct 1995 16:45:24 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SIDEBAR.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 20, 1994 * - * * - * Last Update : October 20, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SIDEBAR_GLYPHX_H -#define SIDEBAR_GLYPHX_H - -#pragma once - -#include "function.h" -#include "power.h" -#include "factory.h" - - -/* -** ST - 3/14/2019 10:49AM -** -** We are going to need one sidebar per player for multiplayer with GlyphX. We can't have different maps / cell arrays per -** player though, so SidebarClass being in the middle of the map/display class hierarchy is a problem. -** -** All the class static data will have to be made non-static so we can have multiple instances. -** -** So, this is a stub sidebar class with the functionality we need just to support the exporting of production data to the -** GlyphX client. -** -** -*/ - - - - -class SidebarGlyphxClass -{ - public: - - enum SideBarClassEnums { - COLUMNS=2 // Number of side strips on sidebar. - }; - - SidebarGlyphxClass(void); - - /* - ** Initialization - */ - void Init_Clear(HouseClass *player_ptr); // Clears all to known state - void Init_IO(void); // Inits button list - - void AI(KeyNumType & input, int x, int y); - - bool Abandon_Production(RTTIType type, int factory); - bool Add(RTTIType type, int ID, bool via_capture = false); - void Recalc(void); - bool Factory_Link(int factory, RTTIType type, int id); - - /* - ** File I/O. - */ - void Code_Pointers(void); - void Decode_Pointers(void); - bool Load(FileClass & file); - bool Save(FileClass & file); - - /* - ** Each side strip is managed by this class. It handles all strip specific - ** actions. - */ - class StripClass : public StageClass - { - class SelectClass : public ControlClass - { - public: - SelectClass(void); - - void Set_Owner(StripClass & strip, int index); - StripClass * Strip; - int Index; - - protected: - virtual int Action(unsigned flags, KeyNumType & key); - }; - - public: - - StripClass(void); - bool Add(RTTIType type, int ID, bool via_capture); - bool Abandon_Production(int factory); - bool AI(KeyNumType & input, int x, int y); - void One_Time(int id); - void Init_Clear(void); - void Init_IO(int id); - void Init_Theater(TheaterType theater); - bool Recalc(void); - bool Factory_Link(int factory, RTTIType type, int id); - void const * Get_Special_Cameo(int type); - - void Set_Parent_Sidebar(SidebarGlyphxClass *parent) {ParentSidebar = parent;} - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - //void Code_Pointers(void); - //void Decode_Pointers(void); - - - /* - ** Working numbers used when rendering and processing the side strip. - */ - enum SideBarGeneralEnums { - MAX_BUILDABLES = 30 // Maximum number of object types in sidebar. - }; - - SidebarGlyphxClass *ParentSidebar; - - - /* - ** This is a unique identifier for the sidebar strip. Using this identifier, - ** it is possible to differentiate the button messages that arrive from the - ** common input button list. It >MUST< be equal to the strip's index into - ** the Column[] array, because the strip uses it to access the stripclass - ** buttons. - */ - int ID; - - /* - ** If construction is in progress (no other objects in this strip can - ** be started), then this flag will be true. It will be cleared when - ** the strip is free to start production again. - */ - unsigned IsBuilding:1; - - /* - ** This is the count of the number of sidebar slots that are active. - */ - int BuildableCount; - - /* - ** This is the array of buildable object types. This array is sorted in the order - ** that it is to be displayed. This array keeps track of which objects are building - ** and ready to be placed. The very nature of this method precludes simultaneous - ** construction of the same object type. - */ - typedef struct BuildType { - int BuildableID; - RTTIType BuildableType; - int Factory; // Production manager. - bool BuildableViaCapture; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM - } BuildType; - BuildType Buildables[MAX_BUILDABLES]; - - } Column[COLUMNS]; - - - private: - int Which_Column(RTTIType type); - - HouseClass *SidebarPlayerPtr; -}; - - - -void Sidebar_Glyphx_Init_Clear(HouseClass *player_ptr = NULL); -void Sidebar_Glyphx_Init_IO(HouseClass *player_ptr = NULL); // Inits button list -bool Sidebar_Glyphx_Abandon_Production(RTTIType type, int factory, HouseClass *player_ptr = NULL); -bool Sidebar_Glyphx_Add(RTTIType type, int ID, HouseClass *player_ptr = NULL, bool via_capture = false); -void Sidebar_Glyphx_Recalc(HouseClass *player_ptr = NULL); -bool Sidebar_Glyphx_Factory_Link(int factory, RTTIType type, int id, HouseClass *player_ptr = NULL); -void Sidebar_Glyphx_AI(HouseClass *player_ptr, KeyNumType & input); -bool Sidebar_Glyphx_Save(FileClass &file, SidebarGlyphxClass *sidebar); -bool Sidebar_Glyphx_Load(FileClass &file, SidebarGlyphxClass *sidebar); -void Sidebar_Glyphx_Code_Pointers(SidebarGlyphxClass *sidebar); -void Sidebar_Glyphx_Decode_Pointers(SidebarGlyphxClass *sidebar); - - -#endif //SIDEBAR_GLYPHX_H \ No newline at end of file diff --git a/code/TIBERIANDAWN/SLIDER.CPP b/code/TIBERIANDAWN/SLIDER.CPP deleted file mode 100644 index ceef5da..0000000 --- a/code/TIBERIANDAWN/SLIDER.CPP +++ /dev/null @@ -1,405 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\slider.cpv 2.17 16 Oct 1995 16:51:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SLIDER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 16, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * SliderClass::Action -- Handles input processing for the slider. * - * SliderClass::Bump -- Bumps the slider one "thumb size" up or down. * - * SliderClass::Recalc_Thumb -- Recalculates the thumb pixel size and starting offset. * - * SliderClass::Set_Maximum -- Sets the maximum value for this slider. * - * SliderClass::Set_Thumb_Size -- Sets the size fo the thumb in "slider units". * - * SliderClass::Set_Value -- Sets the current thumb position for the slider. * - * SliderClass::SliderClass -- Normal constructor for a slider (with thumb) gadget. * - * SliderClass::Step -- Steps the slider one value up or down. * - * SliderClass::Draw_Thumb -- Draws the "thumb" for this slider. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "slider.h" - - -/*********************************************************************************************** - * SliderClass::SliderClass -- Normal constructor for a slider (with thumb) gadget. * - * * - * This is the normal constructor for the slider gadget. * - * * - * INPUT: id -- The ID number to assign to this gadget. * - * x,y -- The pixel coordinate of the upper left corner for this gadget. * - * w,h -- The width and height of the slider gadget. The slider automatically * - * adapts for horizontal or vertical operation depending on which of these * - * dimensions is greater. * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -SliderClass::SliderClass(unsigned id, int x, int y, int w, int h, int belong_to_list) - : GaugeClass(id, x, y, w, h) -{ - BelongToList = belong_to_list ? true : false; - - PlusGadget = 0; - MinusGadget = 0; - if (!BelongToList) { - PlusGadget = new ShapeButtonClass(id, MixFileClass::Retrieve("BTN-PLUS.SHP"), X+Width+2, Y); - MinusGadget = new ShapeButtonClass(id, MixFileClass::Retrieve("BTN-MINS.SHP"), X-6, Y); - - if (PlusGadget) { - PlusGadget->Make_Peer(*this); - PlusGadget->Add(*this); - PlusGadget->Flag_To_Redraw(); - } - if (MinusGadget) { - MinusGadget->Make_Peer(*this); - MinusGadget->Add(*this); - MinusGadget->Flag_To_Redraw(); - } - } - Set_Thumb_Size(1); - Recalc_Thumb(); - - /* - ** Gauges have at least 2 colors, but sliders should only have one. - */ - IsColorized = 0; -} - - -SliderClass::~SliderClass(void) -{ - if (PlusGadget) { - delete PlusGadget; - PlusGadget = 0; - } - if (MinusGadget) { - delete MinusGadget; - MinusGadget = 0; - } -} - - -/*********************************************************************************************** - * SliderClass::Set_Maximum -- Sets the maximum value for this slider. * - * * - * This sets the maximum value that the slider can be set at. The maximum value controls * - * the size of the thumb and the resolution of the thumb's movement. * - * * - * INPUT: value -- The value to set for the slider's maximum. * - * OUTPUT: bool; Was the maximum value changed? A false indicates a set to the value it * - * is currently set to already. * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int SliderClass::Set_Maximum(int value) -{ - if (GaugeClass::Set_Maximum(value)) { - Recalc_Thumb(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * SliderClass::Set_Thumb_Size -- Sets the size fo the thumb in "slider units". * - * * - * This routine will set the size of the thumb as it relates to the maximum value the * - * slider can achieve. This serves to display a proportionally sized thumb as well as * - * control how the slider "bumps" up or down. * - * * - * INPUT: value -- The new value of the thumb. It should never be larger than the slider * - * maximum. * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void SliderClass::Set_Thumb_Size(int value) -{ - Thumb = MIN(value, MaxValue); - Thumb = MAX(Thumb, 1); - Flag_To_Redraw(); - Recalc_Thumb(); -} - - -/*********************************************************************************************** - * SliderClass::Set_Value -- Sets the current thumb position for the slider. * - * * - * This routine will set the thumb position for the slider. * - * * - * INPUT: value -- The position to set the slider. This position is relative to the maximum * - * value for the slider. * - * * - * OUTPUT: bool; Was the slider thumb position changed at all? * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int SliderClass::Set_Value(int value) -{ - value = MIN(value, MaxValue-Thumb); - - if (GaugeClass::Set_Value(value)) { - Recalc_Thumb(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * SliderClass::Recalc_Thumb -- Recalculates the thumb pixel size and starting offset. * - * * - * This takes the current thumb logical size and starting value and calculates the pixel * - * size and starting offset accordingly. This function should be called whenever one of * - * these elements has changed. * - * * - * INPUT: none * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void SliderClass::Recalc_Thumb(void) -{ - int length = IsHorizontal ? Width : Height; - int size = Fixed_To_Cardinal(length, Cardinal_To_Fixed(MaxValue, Thumb)); - ThumbSize = MAX(size, 4); - int start = Fixed_To_Cardinal(length, Cardinal_To_Fixed(MaxValue, CurValue)); - ThumbStart = MIN(start, length-ThumbSize); -} - - -/*********************************************************************************************** - * SliderClass::Action -- Handles input processing for the slider. * - * * - * This routine is called when a qualifying input event has occured. This routine will * - * process that event and make any adjustments to the slider as necessary. * - * * - * INPUT: flags -- Flag bits that tell the input event that caused this function to * - * be called. * - * key -- Reference to the key that caused the input event. * - * OUTPUT: bool; Was the event consumed and further processing of the gadget list should be * - * aborted? * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int SliderClass::Action(unsigned flags, KeyNumType &key) -{ - /* - ** Handle the mouse click in a special way. If the click was not on the thumb, then - ** jump the thumb position one "step" in the appropriate direction. Otherwise, let normal - ** processing take place -- the slider then "sticks" and the thumb moves according to - ** mouse position. - */ - if (flags & LEFTPRESS) { - int mouse; // Mouse pixel position. - int edge; // Edge of slider. - - if (IsHorizontal) { - mouse = Get_Mouse_X(); - edge = X; - } else { - mouse = Get_Mouse_Y(); - edge = Y; - } - edge += 1; - - /* - ** Clicking outside the thumb: invoke parent's Action to process flags etc, - ** but turn off the event & return true so processing stops at this button. - */ - if (mouse < edge+ThumbStart) { - Bump(true); - GaugeClass::Action(0, key); - key = KN_NONE; - return(true); - } else { - if (mouse > edge+ThumbStart+ThumbSize) { - Bump(false); - GaugeClass::Action(0, key); - key = KN_NONE; - return(true); - } else { - GaugeClass::Action(flags, key); - key = KN_NONE; - return(true); - } - } - } - - /* - ** CHANGE GAUGECLASS::ACTION -- REMOVE (LEFTRELEASE) FROM IF STMT - */ - return(GaugeClass::Action(flags, key)); -} - - -/*********************************************************************************************** - * SliderClass::Bump -- Bumps the slider one "thumb size" up or down. * - * * - * This support function will bump the slider one "step" or the size of the thumb up or * - * down as specified. It is typically called when the slider is clicked outside of the * - * thumb region but still inside of the slider. * - * * - * INPUT: up -- Should the bump be to increase the current position? * - * OUTPUT: bool; Was the slider changed at all? A false indicates that the slider is already * - * at one end or the other. * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int SliderClass::Bump(int up) -{ - if (up) { - return(Set_Value(CurValue - Thumb)); - } - return(Set_Value(CurValue + Thumb)); -} - - -/*********************************************************************************************** - * SliderClass::Step -- Steps the slider one value up or down. * - * * - * This routine will move the slider thumb one step in the direction specified. * - * * - * INPUT: up -- Should the step be up (i.e., forward)? * - * OUTPUT: bool; Was the slider changed at all? A false indicates that the slider is already * - * at one end or the other. * - * WARNINGS: none * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -int SliderClass::Step(int up) -{ - if (up) { - return(Set_Value(CurValue - 1)); - } - return(Set_Value(CurValue + 1)); -} - - -/*********************************************************************************************** - * SliderClass::Draw_Thumb -- Draws the "thumb" for this slider. * - * * - * This will draw the thumb graphic for this slider. Sometimes the thumb requires special * - * drawing, thus the need for this function separate from the normal Draw_Me function. * - * * - * INPUT: none * - * OUTPUT: none * - * WARNINGS: The mouse is guaranteed to be hidden when this routine is called. * - * HISTORY: 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void SliderClass::Draw_Thumb(void) -{ - if (IsHorizontal) { - Draw_Box(X+ThumbStart, Y, ThumbSize, Height, BOXSTYLE_GREEN_RAISED, true); - } else { - Draw_Box(X, Y+ThumbStart, Width, ThumbSize, BOXSTYLE_GREEN_RAISED, true); - } -} - - -/*********************************************************************************************** - * SliderClass::Draw_Me -- Draws the body of the gauge. * - * * - * This routine will draw the body of the gauge if necessary. * - * * - * INPUT: forced -- Should the gauge be redrawn regardless of the current redraw flag? * - * OUTPUT: bool; Was the gauge redrawn? * - * WARNINGS: none * - * HISTORY: 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int SliderClass::Draw_Me(int forced) -{ - if (BelongToList) { - if (ControlClass::Draw_Me(forced)) { - - /* - ===================== Hide the mouse ===================== - */ - if (LogicPage == &SeenBuff) { - Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); - } - - /* - =========== Draw the body & set text color =============== - */ - Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_DOWN, true); -// if (IsHorizontal) { -// LogicPage->Fill_Rect(X, Y+1, X+Width-1, Y+Height-2, 141); -// LogicPage->Draw_Line(X, Y, X+Width-1, Y, 140); // top -// LogicPage->Draw_Line(X, Y+Height, X+Width, Y+Height, 159); // bottom -// } else { -// LogicPage->Fill_Rect(X+1, Y, X+Width-2, Y+Height-1, 141); -// LogicPage->Draw_Line(X, Y, X, Y+Height, 140); // left -// LogicPage->Draw_Line(X+Width-1, Y, X+Width-1, Y+Height, 159); // right -// } - Draw_Thumb(); - - /* - =================== Display the mouse =================== - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - return(true); - } - } - - /* - ** If it does not belong to a listbox... - */ - return(GaugeClass::Draw_Me(forced)); -} - - -/*********************************************************************************************** - * SliderClass::Peer_To_Peer -- A peer gadget was touched -- make adjustments. * - * * - * This routine is called when one of the peer gadgets (the scroll arrows or the slider) * - * was touched in some fashion. This routine will sort out whom and why and then make * - * any necessary adjustments to the list box. * - * * - * INPUT: flags -- The event flags that affected the peer gadget. * - * key -- The key value at the time of the event. * - * whom -- Which gadget is being touched. * - * OUTPUT: none * - * WARNINGS: none * - * HISTORY: 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void SliderClass::Peer_To_Peer(unsigned flags, KeyNumType & , ControlClass & whom) -{ - if (flags & LEFTRELEASE) { - if (&whom == PlusGadget) { - Step(false); - } - if (&whom == MinusGadget) { - Step(true); - } - } -} - - diff --git a/code/TIBERIANDAWN/SLIDER.H b/code/TIBERIANDAWN/SLIDER.H deleted file mode 100644 index 6e81b40..0000000 --- a/code/TIBERIANDAWN/SLIDER.H +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\slider.h_v 2.16 16 Oct 1995 16:45:38 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SLIDER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SLIDER_H -#define SLIDER_H - -#include "gauge.h" -#include "shapebtn.h" - -/*************************************************************************** - * SliderClass -- Like a Windows ListBox structure * - * * - * INPUT: int id-- id of gadget * - * int x -- x position of gadget * - * int y -- y position of gadget * - * int w -- width of gadget * - * int h -- height of gadget * - * int belong_to_list -- does this slider go with a listclass? * - * * - * OUTPUT: none. * - * WARNINGS: * - * HISTORY: 01/03/1995 MML : Created. * - *=========================================================================*/ -class SliderClass : public GaugeClass -{ - public: - SliderClass(unsigned id, int x, int y, int w, int h, int belong_to_list=false); - virtual ~SliderClass(void); -// static SliderClass * Create_One_Of(unsigned id, int x, int y, int w, int h, int belong_to_list=false); - - virtual void Set_Thumb_Size(int value); - virtual int Set_Maximum(int value); - virtual int Set_Value(int); - virtual int Bump(int up); - virtual int Step(int up); - virtual int Draw_Me(int forced); - virtual void Peer_To_Peer(unsigned flags, KeyNumType & key, ControlClass & whom); - - virtual int Thumb_Pixels(void) { return (ThumbSize);} - - protected: - - /* - ** If the slider bar has been created, these point to the respective gadgets - ** that it is composed of. - */ - ShapeButtonClass * PlusGadget; - ShapeButtonClass * MinusGadget; - - /* - ** If I belong to a listbox, I have to draw myself differently... - **/ - unsigned BelongToList:1; - - /* - ** This is the logical size of the thumb. This value is used when drawing - ** the thumb imagery. It is also the amount that is bumped when the - ** Bump() function is called. (This value is in application units.) - */ - int Thumb; - - /* - ** This is the current thumb pixel size and starting offset from beginning - ** of slider region. (These values are in pixels.) - */ - int ThumbSize; - int ThumbStart; // x or y position for the thumb - - virtual int Action(unsigned flags, KeyNumType &key); - virtual void Draw_Thumb(void); - - private: - void Recalc_Thumb(void); -}; - -#endif diff --git a/code/TIBERIANDAWN/SMUDGE.CPP b/code/TIBERIANDAWN/SMUDGE.CPP deleted file mode 100644 index 08d3463..0000000 --- a/code/TIBERIANDAWN/SMUDGE.CPP +++ /dev/null @@ -1,405 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\smudge.cpv 2.18 16 Oct 1995 16:52:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SMUDGE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 9, 1994 * - * * - * Last Update : July 24, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * SmudgeClass::Init -- Initialize the smudge tracking system. * - * SmudgeClass::SmudgeClass -- Constructor for smudge objects. * - * SmudgeClass::operator delete -- Deletes the smudge from the tracking system. * - * SmudgeClass::operator new -- Creator of smudge objects. * - * SmudgeClass::Mark -- Marks a smudge down on the map. * - * SmudgeClass::Read_INI -- Reads smudge data from an INI file. * - * SmudgeClass::Write_INI -- Writes the smudge data to an INI file. * - * SmudgeClass::Disown -- Disowns (removes) a building bib piece. * - * SmudgeClass::Validate -- validates smudge pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "smudge.h" - - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * SmudgeClass::VTable; - -HousesType SmudgeClass::ToOwn = HOUSE_NONE; - - -/*********************************************************************************************** - * SmudgeClass::Validate -- validates smudge pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int SmudgeClass::Validate(void) const -{ - int num; - - num = Smudges.ID(this); - if (num < 0 || num >= SMUDGE_MAX) { - Validate_Error("SMUDGE"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * SmudgeClass::operator new -- Creator of smudge objects. * - * * - * This routine will allocate a smudge object from the smudge tracking pool. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to a newly allocated smudge object. If one couldn't be * - * found, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void * SmudgeClass::operator new(size_t ) -{ - void * ptr = Smudges.Allocate(); - if (ptr) { - ((SmudgeClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * SmudgeClass::operator delete -- Deletes the smudge from the tracking system. * - * * - * This routine is used to remove the smudge from the tracking system. * - * * - * INPUT: ptr -- Pointer to the smudge to delete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void SmudgeClass::operator delete(void *ptr) -{ - if (ptr) { - ((SmudgeClass *)ptr)->IsActive = false; - } - Smudges.Free((SmudgeClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * SmudgeClass::SmudgeClass -- Constructor for smudge objects. * - * * - * This is the typical constructor for smudge objects. If the position to place the * - * smudge is not given, then the smudge will be initialized in a limbo state. If the * - * smudge is placed on the map, then this operation causes the smudge object itself to be * - * deleted and special map values updated to reflect the presence of a smudge. * - * * - * INPUT: type -- The type of smudge to construct. * - * * - * pos -- The position to place the smudge. If -1, then the smudge is initialized * - * into a limbo state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -SmudgeClass::SmudgeClass(SmudgeType type, COORDINATE pos, HousesType house) : - Class(&SmudgeTypeClass::As_Reference(type)) -{ - if (pos != -1) { - ToOwn = house; - if (!Unlimbo(pos)) { - Delete_This(); - } - ToOwn = HOUSE_NONE; - } -} - - -/*********************************************************************************************** - * SmudgeClass::Init -- Initialize the smudge tracking system. * - * * - * This routine is used during the scenario clearing process to initialize the smudge * - * object tracking system to a null state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - *=============================================================================================*/ -void SmudgeClass::Init(void) -{ - SmudgeClass *ptr; - - Smudges.Free_All(); - - ptr = new SmudgeClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * SmudgeClass::Mark -- Marks a smudge down on the map. * - * * - * This routine will place the smudge on the map. If the map cell allows. * - * * - * INPUT: mark -- The type of marking to perform. Only MARK_DOWN is supported. * - * * - * OUTPUT: bool; Was the smudge marked successfully? Failure occurs if the smudge isn't * - * marked DOWN. * - * * - * WARNINGS: The smudge object is DELETED by this routine. * - * * - * HISTORY: * - * 09/22/1994 JLB : Created. * - * 12/23/1994 JLB : Checks low level legality before proceeding. * - *=============================================================================================*/ -bool SmudgeClass::Mark(MarkType mark) -{ - Validate(); - if (ObjectClass::Mark(mark)) { - if (mark == MARK_DOWN) { - CELL origin = Coord_Cell(Coord); - - for (int w = 0; w < Class->Width; w++) { - for (int h = 0; h < Class->Height; h++) { - CELL newcell = origin + w + (h*MAP_CELL_W); - if (Map.In_Radar(newcell)) { - CellClass * cell = &Map[newcell]; - - if (Class->IsBib) { - cell->Smudge = Class->Type; - cell->SmudgeData = w + (h*Class->Width); - cell->Owner = ToOwn; - } else { - if (cell->Is_Generally_Clear()) { - if (Class->IsCrater && cell->Smudge != SMUDGE_NONE && SmudgeTypeClass::As_Reference(cell->Smudge).IsCrater) { - cell->SmudgeData++; - cell->SmudgeData = (int)MIN((int)cell->SmudgeData, (int)4); - } - - if (cell->Smudge == SMUDGE_NONE) { - - /* - ** Special selection of a crater that starts as close to the - ** specified coordinate as possible. - */ - if (Class->IsCrater) { - cell->Smudge = (SmudgeType)(SMUDGE_CRATER1 + CellClass::Spot_Index(Coord)); - } else { - cell->Smudge = Class->Type; - } - cell->SmudgeData = 0; - } - } - } - - /* - ** Flag everything that might be overlapping this cell to redraw itself. - */ - cell->Redraw_Objects(); - } - } - } - - /* - ** Whether it was successful in placing, or not, delete the smudge object. It isn't - ** needed once the map has been updated with the proper smudge data. - */ - Delete_This(); - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * SmudgeClass::Read_INI -- Reads smudge data from an INI file. * - * * - * This routine is used by the scenario loader to read the smudge data in an INI file and * - * create the appropriate smudge objects on the map. * - * * - * INPUT: buffer -- Pointer to the INI file staging buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - * 07/24/1995 JLB : Sets the smudge data value as well. * - *=============================================================================================*/ -void SmudgeClass::Read_INI(char *buffer) -{ - char buf[128]; // Working string staging buffer. - - int len = strlen(buffer) + 2; - char * tbuffer = buffer + len; - - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - while (*tbuffer != '\0') { - SmudgeType smudge; // Smudge type. - - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - smudge = SmudgeTypeClass::From_Name(strtok(buf, ",")); - if (smudge != SMUDGE_NONE) { - char * ptr = strtok(NULL, ","); - if (ptr) { - int data = 0; - CELL cell = atoi(ptr); - ptr = strtok(NULL, ","); - if (ptr) data = atoi(ptr); - new SmudgeClass(smudge, Cell_Coord(cell)); - if (Map[cell].Smudge == smudge && data) { - Map[cell].SmudgeData = data; - } - } - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * SmudgeClass::Write_INI -- Writes the smudge data to an INI file. * - * * - * This routine is used by the scenario editor to write the smudge data to an INI file. * - * * - * INPUT: buffer -- Pointer to the INI file staging buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/01/1994 JLB : Created. * - * 07/24/1995 JLB : Records the smudge data as well. * - *=============================================================================================*/ -void SmudgeClass::Write_INI(char *buffer) -{ - char uname[10]; - char buf[127]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing template data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Find all templates and write them to the file. - */ - for (CELL index = 0; index < MAP_CELL_TOTAL; index++) { - CellClass * ptr; - - ptr = &Map[index]; - if (ptr->Smudge != SMUDGE_NONE) { - SmudgeTypeClass const * stype = &SmudgeTypeClass::As_Reference(ptr->Smudge); - if (!stype->IsBib) { - sprintf(uname, "%03d", index); - sprintf(buf, "%s,%d,%d", stype->IniName, index, ptr->SmudgeData); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } - } -} - - -/*********************************************************************************************** - * SmudgeClass::Disown -- Disowns (removes) a building bib piece. * - * * - * This routine is used when a building is removed from the game. If there was any bib * - * attached, this routine will be called to disown the cells and remove the bib artwork. * - * * - * INPUT: cell -- The origin cell for this bib removal. * - * * - * OUTPUT: none * - * * - * WARNINGS: This is actually working on a temporary bib object. It is created for the sole * - * purpose of calling this routine. It will be deleted immediately afterward. * - * * - * HISTORY: * - * 07/04/1995 JLB : Created. * - *=============================================================================================*/ -void SmudgeClass::Disown(CELL cell) -{ - Validate(); - if (Class->IsBib) { - for (int w = 0; w < Class->Width; w++) { - for (int h = 0; h < Class->Height; h++) { - CellClass & cellptr = Map[cell + w + (h*MAP_CELL_W)]; - - if (cellptr.Overlay == OVERLAY_NONE || !OverlayTypeClass::As_Reference(cellptr.Overlay).IsWall) { - cellptr.Smudge = SMUDGE_NONE; - cellptr.SmudgeData = 0; - cellptr.Owner = HOUSE_NONE; - cellptr.Redraw_Objects(); - } - } - } - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/SMUDGE.H b/code/TIBERIANDAWN/SMUDGE.H deleted file mode 100644 index eefdde4..0000000 --- a/code/TIBERIANDAWN/SMUDGE.H +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\smudge.h_v 2.16 16 Oct 1995 16:47:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SMUDGE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 9, 1994 * - * * - * Last Update : August 9, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SMUDGE_H -#define SMUDGE_H - -#include "object.h" -#include "type.h" - -/****************************************************************************** -** This is the transitory form for smudges. They exist as independent objects -** only in the transition stage from creation to placement upon the map. Once -** they are placed on the map, they merely become 'smudges' in the cell data. This -** object is then destroyed. -*/ -class SmudgeClass : public ObjectClass -{ - public: - /*------------------------------------------------------------------- - ** Constructors and destructors. - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - SmudgeClass(SmudgeType type, COORDINATE pos=-1, HousesType house = HOUSE_NONE); - SmudgeClass(void) : Class(0) {}; - operator SmudgeType(void) const {return Class->Type;}; - virtual ~SmudgeClass(void) {if (GameActive) SmudgeClass::Limbo();}; - virtual RTTIType What_Am_I(void) const {return RTTI_SMUDGE;}; - - static void Init(void); - - /* - ** File I/O. - */ - static void Read_INI(char *); - static void Write_INI(char *); - static char *INI_Name(void) {return "SMUDGE";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - virtual bool Mark(MarkType); - virtual void Draw_It(int , int , WindowNumberType ) {}; - - void Disown(CELL cell); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - private: - - static HousesType ToOwn; - - /* - ** This is a pointer to the template object's class. - */ - SmudgeTypeClass const * const Class; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[8]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif diff --git a/code/TIBERIANDAWN/SOUNDDLG.CPP b/code/TIBERIANDAWN/SOUNDDLG.CPP deleted file mode 100644 index 838f0ca..0000000 --- a/code/TIBERIANDAWN/SOUNDDLG.CPP +++ /dev/null @@ -1,431 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\sounddlg.cpv 2.17 16 Oct 1995 16:51:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SOUNDDLG.CPP * - * * - * Programmer : Maria del Mar McCready-Legg, Joe L. Bostic * - * * - * Start Date : Jan 8, 1995 * - * * - * Last Update : Jan 18, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * SoundControlsClass::Process -- Handles all the options graphic interface. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "sounddlg.h" - -class MusicListClass : public ListClass -{ - public: - MusicListClass(int id, int x, int y, int w, int h) : - ListClass(id, x, y, w, h, TPF_6PT_GRAD|TPF_NOSHADOW, Hires_Retrieve("BTN-UP.SHP"), Hires_Retrieve("BTN-DN.SHP")) - {}; - virtual ~MusicListClass(void) {}; - - protected: - virtual void Draw_Entry(int index, int x, int y, int width, int selected); -}; -int SoundControlsClass::Init(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - Option_Width =292 * factor; - Option_Height =146 * factor; - - Option_X =((SeenBuff.Get_Width() - Option_Width) / 2); - Option_Y =(SeenBuff.Get_Height() - Option_Height) / 2; - - Listbox_X =1 * factor; - Listbox_Y =54 * factor; - Listbox_W =290 * factor; - Listbox_H =73 * factor; - - Button_Width =85 * factor; - Button_X =Option_Width-(Button_Width + (7 * factor)); - Button_Y =130 * factor; - - Stop_X =5 * factor; - Stop_Y =129 * factor; - - Play_X =23 * factor; - Play_Y =129 * factor; - - OnOff_Width =25 * factor; - #ifdef GERMAN - Shuffle_X =79 * factor; - #else - Shuffle_X =91 * factor; - #endif - - Shuffle_Y =130 * factor; - - Repeat_X =166 * factor; - Repeat_Y =130 * factor; - - MSlider_X =147 * factor; - MSlider_Y =28 * factor; - MSlider_W =108 * factor; - MSlider_Height =5 * factor; - - FXSlider_X =147 * factor; - FXSlider_Y =40 * factor; - FXSlider_W =108 * factor; - FXSlider_Height=5 * factor; - return(factor); -} - -/*********************************************************************************************** - * OptionsClass::Process -- Handles all the options graphic interface. * - * * - * This routine is the main control for the visual representation of the options * - * screen. It handles the visual overlay and the player input. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: 12/31/1994 MML : Created. * - *=============================================================================================*/ -void SoundControlsClass::Process(void) -{ -// ThemeType theme; - - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - - Init(); - /* - ** List box that holds the score text strings. - */ - MusicListClass listbox(0, Option_X+Listbox_X, Option_Y+Listbox_Y, Listbox_W, Listbox_H); - - /* - ** Return to options menu button. - */ - TextButtonClass returnto(BUTTON_OPTIONS, TXT_OPTIONS_MENU, TPF_6PT_GRAD|TPF_NOSHADOW, -#ifdef FRENCH - Option_X+Button_X-8*2, Option_Y+Button_Y, Button_Width+11*2); -#else - Option_X+Button_X, Option_Y+Button_Y, Button_Width); -#endif - - /* - ** Stop playing button. - */ - char filename[30]; - if (factor == 1) - strcpy(filename,"BTN-ST.SHP"); - else - strcpy(filename,"BTN-STH.SHP"); - ShapeButtonClass stopbtn(BUTTON_STOP, MixFileClass::Retrieve(filename), - Option_X+Stop_X, Option_Y+Stop_Y); - - /* - ** Start playing button. - */ - if (factor == 1) - strcpy(filename,"BTN-PL.SHP"); - else - strcpy(filename,"BTN-PLH.SHP"); - - ShapeButtonClass playbtn(BUTTON_PLAY, MixFileClass::Retrieve(filename), - Option_X+Play_X, Option_Y+Play_Y); - - /* - ** Shuffle control. - */ - TextButtonClass shufflebtn(BUTTON_SHUFFLE, TXT_OFF, TPF_6PT_GRAD|TPF_NOSHADOW, - Option_X+Shuffle_X, Option_Y+Shuffle_Y, OnOff_Width); - - /* - ** Repeat control. - */ - TextButtonClass repeatbtn(BUTTON_REPEAT, TXT_OFF, TPF_6PT_GRAD|TPF_NOSHADOW, Option_X+Repeat_X, Option_Y+Repeat_Y, OnOff_Width); - - /* - ** Music volume slider. - */ - SliderClass music(SLIDER_MUSIC, Option_X+MSlider_X, Option_Y+MSlider_Y, MSlider_W, MSlider_Height); - - /* - ** Sound volume slider. - */ - SliderClass sound(SLIDER_SOUND, Option_X+FXSlider_X, Option_Y+FXSlider_Y, FXSlider_W, FXSlider_Height); - - /* - ** Causes left mouse clicks inside the dialog area, but not on any - ** particular button, to be ignored. - */ - GadgetClass area(Option_X, Option_Y, Option_Width, Option_Height, GadgetClass::LEFTPRESS); - - /* - ** Causes right clicks anywhere or left clicks outside of the dialog - ** box area to be the same a clicking the return to game options button. - */ - ControlClass ctrl(BUTTON_OPTIONS, 0, 0, SeenBuff.Get_Width(), SeenBuff.Get_Height(), GadgetClass::RIGHTPRESS|GadgetClass::LEFTPRESS); - - /* - ** The repeat and shuffle buttons are of the toggle type. They toggle - ** between saying "on" and "off". - */ - shufflebtn.IsToggleType = true; - if (Options.IsScoreShuffle) { - shufflebtn.Turn_On(); - } else { - shufflebtn.Turn_Off(); - } - shufflebtn.Set_Text(shufflebtn.IsOn ? TXT_ON : TXT_OFF); - - repeatbtn.IsToggleType = true; - if (Options.IsScoreRepeat) { - repeatbtn.Turn_On(); - } else { - repeatbtn.Turn_Off(); - } - repeatbtn.Set_Text(repeatbtn.IsOn ? TXT_ON : TXT_OFF); - - /* - ** Set the initial values of the sliders. - */ - music.Set_Maximum(255); - music.Set_Thumb_Size(16); - music.Set_Value(Options.ScoreVolume); - sound.Set_Maximum(255); - sound.Set_Thumb_Size(16); - sound.Set_Value(Options.Volume); - - /* - ** Set up the window. Window x-coords are in bytes not pixels. - */ - Set_Logic_Page(SeenBuff); - - /* - ** Create Buttons. - */ - GadgetClass * optionsbtn = &returnto; - listbox.Add_Tail(*optionsbtn); - stopbtn.Add_Tail(*optionsbtn); - playbtn.Add_Tail(*optionsbtn); - shufflebtn.Add_Tail(*optionsbtn); - repeatbtn.Add_Tail(*optionsbtn); - music.Add_Tail(*optionsbtn); - sound.Add_Tail(*optionsbtn); - area.Add_Tail(*optionsbtn); - ctrl.Add_Tail(*optionsbtn); - - /* - ** Add all the themes to the list box. The list box entries are constructed - ** and then stored into allocated EMS memory blocks. - */ -// char buffer[100]; - for (ThemeType index = THEME_FIRST; index < Theme.Max_Themes(); index++) { - if (Theme.Is_Allowed(index)) { - int length = Theme.Track_Length(index); - char const * fullname = Theme.Full_Name(index); - - void * ptr = new char [sizeof(100)]; - if (ptr) { - sprintf((char *)ptr, "%cTrack %d\t%d:%02d\t%s", index, listbox.Count()+1, length / 60, length % 60, fullname); - listbox.Add_Item((char const *)ptr); - } - - if (Theme.What_Is_Playing() == index) { - listbox.Set_Selected_Index(listbox.Count()-1); - } - } - } - static int _tabs[] = { - 55*factor, 72*factor, 90*factor - }; - listbox.Set_Tabs(_tabs); - - /* - ** Main Processing Loop. - */ - bool display = true; - bool process = true; - - while (process) { - - /* - ** Invoke game callback. - */ - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - } - } - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Refresh display if needed. - */ - if (display) { - - Hide_Mouse(); - - /* - ** Draw the background. - */ - Dialog_Box(Option_X, Option_Y, Option_Width, Option_Height); - - Draw_Caption(TXT_SOUND_CONTROLS, Option_X, Option_Y, Option_Width); - - /* - ** Draw the Music, Speech & Sound titles. - */ - Fancy_Text_Print(TXT_MUSIC_VOLUME, Option_X+MSlider_X-5, Option_Y+MSlider_Y-2, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT); - Fancy_Text_Print(TXT_SOUND_VOLUME, Option_X+FXSlider_X-5, Option_Y+FXSlider_Y-2, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT); - - Fancy_Text_Print(TXT_SHUFFLE, Option_X+Shuffle_X-5, Option_Y+Shuffle_Y+1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT); - Fancy_Text_Print(TXT_REPEAT, Option_X+Repeat_X-5, Option_Y+Repeat_Y+1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT); - - optionsbtn->Draw_All(); - Show_Mouse(); - display = false; - } - - /* - ** Get user input. - */ - KeyNumType input = optionsbtn->Input(); - - /* - ** Process Input. - */ - switch (input) { - - case KN_ESC: - case BUTTON_OPTIONS|KN_BUTTON: - process = false; - break; - - /* - ** Control music volume. - */ - case SLIDER_MUSIC|KN_BUTTON: - Options.Set_Score_Volume(music.Get_Value()); - break; - - /* - ** Control sound volume. - */ - case SLIDER_SOUND|KN_BUTTON: - Options.Set_Sound_Volume(sound.Get_Value(), true); - break; - - case BUTTON_LISTBOX|KN_BUTTON: -// Mono_Printf ("%d %s Listbox was pressed.\r",__LINE__, __FILE__); - break; - - /* - ** Stop all themes from playing. - */ - case BUTTON_STOP|KN_BUTTON: - Theme.Queue_Song(THEME_NONE); - break; - - /* - ** Start the currently selected theme to play. - */ - case KN_SPACE: - case BUTTON_PLAY|KN_BUTTON: - if (listbox.Count()) { - Theme.Queue_Song( (ThemeType)*((unsigned char *)listbox.Current_Item()) ); - } - break; - - /* - ** Toggle the shuffle button. - */ - case BUTTON_SHUFFLE|KN_BUTTON: - shufflebtn.Set_Text(shufflebtn.IsOn ? TXT_ON : TXT_OFF); - Options.Set_Shuffle(shufflebtn.IsOn); - break; - - /* - ** Toggle the repeat button. - */ - case BUTTON_REPEAT|KN_BUTTON: - repeatbtn.Set_Text(repeatbtn.IsOn ? TXT_ON : TXT_OFF); - Options.Set_Repeat(repeatbtn.IsOn); - break; - } - } - - /* - ** If the score volume was turned all the way down, then actually - ** stop the scores from being played. - */ - if (!Options.ScoreVolume) { - Theme.Stop(); - } - - /* - ** Save them settings - you know it makes sense - */ - Options.Save_Settings(); // save new value - - /* - ** Free the items from the list box. - */ - while (listbox.Count()) { - char const * ptr = listbox.Get_Item(0); - listbox.Remove_Item(ptr); - delete [] (void*)ptr; - } -} - - -void MusicListClass::Draw_Entry(int index, int x, int y, int width, int selected) -{ - if (TextFlags & TPF_6PT_GRAD) { - TextPrintType flags = TextFlags; - - if (selected) { - flags = flags | TPF_BRIGHT_COLOR; - LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, CC_GREEN_SHADOW); - } else { - if (!(flags & TPF_USE_GRAD_PAL)) { - flags = flags | TPF_MEDIUM_COLOR; - } - } - - Conquer_Clip_Text_Print((char *)Add_Long_To_Pointer(List[index], 1), x, y, CC_GREEN, TBLACK, flags, width, Tabs); - - } else { - Conquer_Clip_Text_Print((char *)Add_Long_To_Pointer(List[index], 1), x, y, (selected ? BLUE : WHITE), TBLACK, TextFlags, width, Tabs); - } -} diff --git a/code/TIBERIANDAWN/SOUNDDLG.H b/code/TIBERIANDAWN/SOUNDDLG.H deleted file mode 100644 index 3fc5cde..0000000 --- a/code/TIBERIANDAWN/SOUNDDLG.H +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\sounddlg.h_v 2.18 16 Oct 1995 16:46:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : OPTIONS.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 8, 1994 * - * * - * Last Update : June 8, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SOUNDDLG_H -#define SOUNDDLG_H - -#include "gadget.h" - -class SoundControlsClass -{ - enum SoundControlsClassEnums { -#ifdef FRENCH - OPTION_WIDTH=308, -#else - OPTION_WIDTH=292, -#endif - OPTION_HEIGHT=146, - - OPTION_X=((320 - OPTION_WIDTH) / 2), - OPTION_Y=(200 - OPTION_HEIGHT) / 2, - - LISTBOX_X=1, - LISTBOX_Y=54, - LISTBOX_W=290, - LISTBOX_H=72, - - BUTTON_WIDTH=85, - BUTTON_X=OPTION_WIDTH-(BUTTON_WIDTH+7), // Options button x pos - BUTTON_Y=130, // Options button y pos - - STOP_X=5, // Stop button X. - STOP_Y=129, // Stop button Y. - - PLAY_X=23, - PLAY_Y=129, - - ONOFF_WIDTH=25, -#ifdef GERMAN - SHUFFLE_X=79,//BGA:91, -#else -#ifdef FRENCH - SHUFFLE_X=99, -#else - SHUFFLE_X=91, -#endif -#endif - SHUFFLE_Y=130, - -#ifdef FRENCH - REPEAT_X=174, -#else - REPEAT_X=166, -#endif - REPEAT_Y=130, - - MSLIDER_X=147, - MSLIDER_Y=28, - MSLIDER_W=108, - MSLIDER_HEIGHT=5, - - FXSLIDER_X=147, - FXSLIDER_Y=40, - FXSLIDER_W=108, - FXSLIDER_HEIGHT=5, - - BUTTON_STOP = 605, - BUTTON_PLAY, - BUTTON_SHUFFLE, - BUTTON_REPEAT, - BUTTON_OPTIONS, - SLIDER_MUSIC, -// SLIDER_SPEECH, - SLIDER_SOUND, - BUTTON_LISTBOX, - }; - - public: - SoundControlsClass(void) {} - void Process(void); - int Init(void); - - private: - - int Option_Width; - int Option_Height; - - int Option_X; - int Option_Y; - - int Listbox_X; - int Listbox_Y; - int Listbox_W; - int Listbox_H; - - int Button_Width; - int Button_X; - int Button_Y; - - int Stop_X; - int Stop_Y; - - int Play_X; - int Play_Y; - - int OnOff_Width; - - int Shuffle_X; - int Shuffle_Y; - - int Repeat_X; - int Repeat_Y; - - int MSlider_X; - int MSlider_Y; - int MSlider_W; - int MSlider_Height; - - int FXSlider_X; - int FXSlider_Y; - int FXSlider_W; - int FXSlider_Height; - -}; - -#endif diff --git a/code/TIBERIANDAWN/SPECIAL.CPP b/code/TIBERIANDAWN/SPECIAL.CPP deleted file mode 100644 index 1b0b1c6..0000000 --- a/code/TIBERIANDAWN/SPECIAL.CPP +++ /dev/null @@ -1,271 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\special.cpv 1.4 16 Oct 1995 16:50:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SPECIAL.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 05/27/95 * - * * - * Last Update : May 27, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#define OPTION_WIDTH 236 -#define OPTION_HEIGHT 162 -#define OPTION_X ((320 - OPTION_WIDTH) / 2) -#define OPTION_Y (200 - OPTION_HEIGHT) / 2 - -void Special_Dialog(void) -{ - SpecialClass oldspecial = Special; - GadgetClass * buttons = NULL; - static struct { - int Description; - int Setting; - CheckBoxClass * Button; - } _options[] = { -// {TXT_DEFENDER_ADVANTAGE, 0, 0}, - {TXT_SEPARATE_HELIPAD, 0, 0}, - {TXT_VISIBLE_TARGET, 0, 0}, - {TXT_TREE_TARGET, 0, 0}, - {TXT_MCV_DEPLOY, 0, 0}, - {TXT_SMART_DEFENCE, 0, 0}, - {TXT_THREE_POINT, 0, 0}, -// {TXT_TIBERIUM_GROWTH, 0, 0}, -// {TXT_TIBERIUM_SPREAD, 0, 0}, - {TXT_TIBERIUM_FAST, 0, 0}, - {TXT_ROAD_PIECES, 0, 0}, - {TXT_SCATTER, 0, 0}, - {TXT_SHOW_NAMES, 0, 0}, - }; - - TextButtonClass ok(200, TXT_OK, TPF_6PT_GRAD|TPF_NOSHADOW, OPTION_X+5, OPTION_Y+OPTION_HEIGHT-15); - TextButtonClass cancel(201, TXT_CANCEL, TPF_6PT_GRAD|TPF_NOSHADOW, OPTION_X+OPTION_WIDTH-50, OPTION_Y+OPTION_HEIGHT-15); - buttons = &ok; - cancel.Add(*buttons); - int index; - for (index = 0; index < sizeof(_options)/sizeof(_options[0]); index++) { - _options[index].Button = new CheckBoxClass(100+index, OPTION_X+7, OPTION_Y+20+(index*10)); - if (_options[index].Button) { - _options[index].Button->Add(*buttons); - - bool value = false; - switch (_options[index].Description) { - case TXT_SEPARATE_HELIPAD: - value = Special.IsSeparate; - break; - - case TXT_SHOW_NAMES: - value = Special.IsNamed; - break; - - case TXT_DEFENDER_ADVANTAGE: - value = Special.IsDefenderAdvantage; - break; - - case TXT_VISIBLE_TARGET: - value = Special.IsVisibleTarget; - break; - - case TXT_TREE_TARGET: - value = Special.IsTreeTarget; - break; - - case TXT_MCV_DEPLOY: - value = Special.IsMCVDeploy; - break; - - case TXT_SMART_DEFENCE: - value = Special.IsSmartDefense; - break; - - case TXT_THREE_POINT: - value = Special.IsThreePoint; - break; - - case TXT_TIBERIUM_GROWTH: - value = Special.IsTGrowth; - break; - - case TXT_TIBERIUM_SPREAD: - value = Special.IsTSpread; - break; - - case TXT_TIBERIUM_FAST: - value = Special.IsTFast; - break; - - case TXT_ROAD_PIECES: - value = Special.IsRoad; - break; - - case TXT_SCATTER: - value = Special.IsScatter; - break; - } - - _options[index].Setting = value; - if (value) { - _options[index].Button->Turn_On(); - } else { - _options[index].Button->Turn_Off(); - } - } - } - - Map.Override_Mouse_Shape(MOUSE_NORMAL); - Set_Logic_Page(SeenBuff); - bool recalc = true; - bool display = true; - bool process = true; - while (process) { - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - } - } - - if (display) { - display = false; - - Hide_Mouse(); - Dialog_Box(OPTION_X, OPTION_Y, OPTION_WIDTH, OPTION_HEIGHT); - Draw_Caption(TXT_SPECIAL_OPTIONS, OPTION_X, OPTION_Y, OPTION_WIDTH); - - for (index = 0; index < sizeof(_options)/sizeof(_options[0]); index++) { - Fancy_Text_Print(_options[index].Description, _options[index].Button->X+10, _options[index].Button->Y, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); - } - buttons->Draw_All(); - Show_Mouse(); - } - - KeyNumType input = buttons->Input(); - switch (input) { - case KN_ESC: - case 200|KN_BUTTON: - process = false; - for (index = 0; index < sizeof(_options)/sizeof(_options[0]); index++) { - switch (_options[index].Description) { - case TXT_SEPARATE_HELIPAD: - oldspecial.IsSeparate = _options[index].Setting; - break; - - case TXT_SHOW_NAMES: - oldspecial.IsNamed = _options[index].Setting; - break; - - case TXT_DEFENDER_ADVANTAGE: - oldspecial.IsDefenderAdvantage = _options[index].Setting; - break; - - case TXT_VISIBLE_TARGET: - oldspecial.IsVisibleTarget = _options[index].Setting; - break; - - case TXT_TREE_TARGET: - oldspecial.IsTreeTarget = _options[index].Setting; - break; - - case TXT_MCV_DEPLOY: - oldspecial.IsMCVDeploy = _options[index].Setting; - break; - - case TXT_SMART_DEFENCE: - oldspecial.IsSmartDefense = _options[index].Setting; - break; - - case TXT_THREE_POINT: - oldspecial.IsThreePoint = _options[index].Setting; - break; - - case TXT_TIBERIUM_GROWTH: - oldspecial.IsTGrowth = _options[index].Setting; - break; - - case TXT_TIBERIUM_SPREAD: - oldspecial.IsTSpread = _options[index].Setting; - break; - - case TXT_TIBERIUM_FAST: - oldspecial.IsTFast = _options[index].Setting; - break; - - case TXT_ROAD_PIECES: - oldspecial.IsRoad = _options[index].Setting; - break; - - case TXT_SCATTER: - oldspecial.IsScatter = _options[index].Setting; - break; - } - } - OutList.Add(EventClass(oldspecial)); - break; - - case 201|KN_BUTTON: - process = false; - break; - - case KN_NONE: - break; - - default: - index = (input & ~KN_BUTTON) - 100; - if ((unsigned)index < sizeof(_options)/sizeof(_options[0])) { - _options[index].Setting = (_options[index].Setting == false); - if (_options[index].Setting) { - _options[index].Button->Turn_On(); - } else { - _options[index].Button->Turn_Off(); - } - } - break; - } - } - - Map.Revert_Mouse_Shape(); - HiddenPage.Clear(); - Map.Flag_To_Redraw(true); - Map.Render(); -} - - - - - diff --git a/code/TIBERIANDAWN/SPECIAL.H b/code/TIBERIANDAWN/SPECIAL.H deleted file mode 100644 index 80db3cd..0000000 --- a/code/TIBERIANDAWN/SPECIAL.H +++ /dev/null @@ -1,265 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\special.h_v 2.15 16 Oct 1995 16:47:36 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SPECIAL.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 02/27/95 * - * * - * Last Update : February 27, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SPECIAL_H -#define SPECIAL_H - -class SpecialClass -{ - public: - void Init(void) { - IsScrollMod = false; - IsGross = false; - IsEasy = false; - IsDifficult = false; - IsSpeedBuild = false; - IsDefenderAdvantage = true; - IsVisibleTarget = false; - IsVariation = false; - IsJurassic = false; - IsJuvenile = false; - IsSmartDefense = false; - IsTreeTarget = false; - IsMCVDeploy = false; - IsVisceroids = false; - IsMonoEnabled = false; - IsInert = false; - IsShowPath = false; - IsThreePoint = false; - IsTGrowth = true; - IsTSpread = true; - IsTFast = true; - IsRoad = false; - IsScatter = false; - IsCaptureTheFlag = false; - IsNamed = false; - IsFromInstall = false; - IsSeparate = false; - IsFromWChat = false; - IsEarlyWin = false; - HealthBarDisplayMode = HB_SELECTED; - ResourceBarDisplayMode = RB_SELECTED; - } - - /* - ** Is the game flagged for easy mode? - */ - unsigned IsEasy:1; - - /* - ** Is the game flagged for difficult? - */ - unsigned IsDifficult:1; - - /* - ** Controls the speedy build option -- used for testing. - */ - unsigned IsSpeedBuild:1; - - /* - ** If the player can build the helipad separate from the helipad and - ** helicopter combo, then this flag will be true. - */ - unsigned IsSeparate:1; - - /* - ** If the defender has the advantage then this will be true. This flag - ** allows the defender to have a better advantage in combat than the - ** attacker. Moving units will not be able to dish out or take as much - ** damage when this flag is true. - */ - unsigned IsDefenderAdvantage:1; - - /* - ** If civilian structures are to have a name, then this flag will be - ** set to true. The default case is to just use generic names for - ** civilians. - */ - unsigned IsNamed:1; - - /* - ** If from install, then play the special installation movie and - ** skip asking them what type of game they want to play. - */ - unsigned IsFromInstall:1; - - /* - ** If capture the flag mode is on, this flag will be true. With this - ** flag enabled, then the flag is initially placed at the start of - ** the scenario. - */ - unsigned IsCaptureTheFlag:1; - - /* - ** Is target selecting by other human opponents visible to the player? - */ - unsigned IsVisibleTarget:1; - - /* - ** If human generated sound effects are to be used, then this - ** flag will be true. - */ - unsigned IsJuvenile:1; - - /* - ** If friendly units should return fire when fired upon, set this - ** flag to true. The default is only for the enemy units to do this. - */ - unsigned IsSmartDefense:1; - - /* - ** If targeting of trees is allowed, then this flag will be true. - */ - unsigned IsTreeTarget:1; - - /* - ** If this flag is true, then the construction yard can undeploy back into an MCV. - */ - unsigned IsMCVDeploy:1; - - /* - ** Controls whether or not visceroids spawn - */ - unsigned IsVisceroids:1; - - /* - ** If the monochrome debugging output is enabled, then this flag will be true. - */ - unsigned IsMonoEnabled:1; - - /* - ** This flags controls whether weapons are inert. An inert weapon doesn't do any - ** damage. Effectively, if this is true, then the units never die. - */ - unsigned IsInert:1; - - /* - ** When this flag is true, the computer findpath algorithm reveals the route being - ** examined. This is used to trace findpath bugs. - */ - unsigned IsShowPath:1; - - /* - ** If wheeled vehicles should do a 3-point turn when rotating in place, then - ** this flag is true. - */ - unsigned IsThreePoint:1; - - /* - ** If Tiberium is allowed to grow, then this flag will be true. - */ - unsigned IsTGrowth:1; - - /* - ** If Tiberium is allowed to spread, then this flag will be true. - */ - unsigned IsTSpread:1; - - /* - ** This controls whether Tiberium grows&spreads quickly or not. - */ - unsigned IsTFast:1; - - /* - ** This flag controls whether the road additional pieces are added to - ** the bottom of buildings. If true, then the roads are NOT added. - */ - unsigned IsRoad:1; - - /* - ** Controls whether units (especially infantry) will scatter when there - ** is an immediate threat. This gives infantry a "mind of their own" when - ** it comes to self preservation. If set to false, then units will not - ** scatter. - */ - unsigned IsScatter:1; - - /* - ** Special bonus scenario enabled. - */ - unsigned IsJurassic:1; - - /* - ** Are score variations allowed? - */ - unsigned IsVariation:1; - - /* - ** If the gross human splatter marks should be present. - */ - unsigned IsGross:1; - - /* - ** Disables scrolling over the "options" and "sidebar" tabs. - */ - unsigned IsScrollMod:1; - - /* - ** Flag that we were spawned from WChat. - */ - unsigned IsFromWChat:1; - - /* - ** New anti-griefing early win mode. ST - 1/31/2020 3:42PM - */ - unsigned IsEarlyWin:1; - - /* - ** Health bar display mode - */ - enum eHealthBarDisplayMode - { - HB_DAMAGED = 0, - HB_ALWAYS, - HB_SELECTED - } HealthBarDisplayMode; - - /* - ** Resource bar display mode - */ - enum eResourceBarDisplayMode - { - RB_SELECTED = 0, - RB_ALWAYS, - } ResourceBarDisplayMode; - - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[128]; -}; - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/STAGE.H b/code/TIBERIANDAWN/STAGE.H deleted file mode 100644 index 2c39fb5..0000000 --- a/code/TIBERIANDAWN/STAGE.H +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\stage.h_v 2.15 16 Oct 1995 16:45:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : STAGE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 17, 1994 * - * * - * Last Update : June 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef STAGE_H -#define STAGE_H - -class StageClass { - - /* - ** This handles the animation stage of the object. This includes smoke, walking, - ** flapping, and rocket flames. - */ - unsigned short Stage; - - /* - ** This is the countdown timer for stage animation. When this counts down - ** to zero, then the stage increments by one and the time cycle starts - ** over again. - */ - unsigned char StageTimer; - - /* - ** This is the value to assign the StageTimer whenever it needs to be reset. Thus, - ** this value is the control of how fast the stage value increments. - */ - unsigned char Rate; - - public: - StageClass(void) { - StageTimer = 0; - Stage = 0; - Rate = 0; - }; - - int Fetch_Stage(void) const {return Stage;}; - int Fetch_Rate(void) const {return Rate;}; - void Set_Stage(int stage) {Stage = stage;}; - void Set_Rate(unsigned char rate) {Rate = StageTimer = rate;}; - void AI(void) {}; - bool Graphic_Logic(void) { - if (Rate) { - StageTimer--; - if (!StageTimer) { - Stage++; - StageTimer = Rate; - return true; - } - } - return false; - }; - #ifdef CHEAT_KEYS - void Debug_Dump(MonoClass *mono) const { - mono->Set_Cursor(56, 7); - mono->Printf("%3d[%d]", Stage, Rate); - }; - #endif - - /* - ** File I/O. - */ - void Code_Pointers(void) { return; } - void Decode_Pointers(void) { return; } -}; - - -#endif diff --git a/code/TIBERIANDAWN/STARTUP.CPP b/code/TIBERIANDAWN/STARTUP.CPP deleted file mode 100644 index bc7df7e..0000000 --- a/code/TIBERIANDAWN/STARTUP.CPP +++ /dev/null @@ -1,872 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\startup.cpv 2.17 16 Oct 1995 16:48:12 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : STARTUP.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : October 3, 1994 * - * * - * Last Update : August 27, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Delete_Swap_Files -- Deletes previously existing swap files. * - * Prog_End -- Cleans up library systems in prep for game exit. * - * main -- Initial startup routine (preps library systems). * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include -#include -#include "ccdde.h" - -bool Read_Private_Config_Struct(char *profile, NewConfigType *config); -void Delete_Swap_Files(void); -void Print_Error_End_Exit(char *string); -void Print_Error_Exit(char *string); -WinTimerClass *WinTimer; -extern void Create_Main_Window ( HANDLE instance , int command_show , int width , int height); - -extern bool ReadyToQuit; -void Read_Setup_Options(RawFileClass *config_file); - -bool VideoBackBufferAllowed = true; -void Check_From_WChat(char *wchat_name); -bool SpawnedFromWChat = false; -bool ProgEndCalled = false; - - -extern "C"{ - bool __cdecl Detect_MMX_Availability(void); - void __cdecl Init_MMX(void); -} - - - -#if (0) -char WibbleBuffer[1024*1024]; - -void CD_Test(void) -{ - HANDLE handle; - DWORD size; - - handle= CreateFile("e:\\scores.mix", GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (handle== INVALID_HANDLE_VALUE){ - return; - } - - unsigned bytes_read; - - do{ - bytes_read = ReadFile (handle , WibbleBuffer , 1024*1024, &size, NULL); - - }while(size == 1024*1024); - - - CloseHandle (handle); -} -#endif //(0) - - - -/*********************************************************************************************** - * main -- Initial startup routine (preps library systems). * - * * - * This is the routine that is first called when the program starts up. It basically * - * handles the command line parsing and setting up library systems. * - * * - * INPUT: argc -- Number of command line arguments. * - * * - * argv -- Pointer to array of comman line argument strings. * - * * - * OUTPUT: Returns with execution failure code (if any). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/20/1995 JLB : Created. * - *=============================================================================================*/ - -HINSTANCE ProgramInstance; -extern BOOL CC95AlreadyRunning; -void Move_Point(short &x, short &y, register DirType dir, unsigned short distance); - -void Check_Use_Compressed_Shapes (void); -extern void DLL_Shutdown(void); - - -BOOL WINAPI DllMain(HINSTANCE instance, unsigned int fdwReason, void *lpvReserved) -{ - lpvReserved; - - switch (fdwReason) { - - case DLL_PROCESS_ATTACH: - ProgramInstance = instance; - break; - - case DLL_PROCESS_DETACH: - if (WindowsTimer) { - delete WindowsTimer; - WindowsTimer = NULL; - } - DLL_Shutdown(); - - MixFileClass::Free_All(); - - Uninit_Game(); - - break; - - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - } - - - - return true; -} - - -//int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show ) -//{ -// Heap_Dump_Check( "first thing in main" ); -// malloc(1); - -int DLL_Startup(const char * command_line_in) -{ - RunningAsDLL = true; - int command_show = SW_HIDE; - HINSTANCE instance = ProgramInstance; - char command_line[1024]; - strcpy(command_line, command_line_in); - - CCDebugString ("C&C95 - Starting up.\n"); - - - //WindowsTimer = new WinTimerClass(60,FALSE); - //CD_Test(); - - - - /* - ** These values return 0x47 if code is working correctly - */ -// int temp = Desired_Facing256 (1070, 5419, 1408, 5504); - - - - /* - ** If we are already running then switch to the existing process and exit - */ - SpawnedFromWChat = false; - - if (CC95AlreadyRunning) { //Set in the DDEServer constructor - //MessageBox (NULL, "Error - attempt to restart C&C95 when already running.", "Command & Conquer", MB_ICONEXCLAMATION|MB_OK); - - HWND ccwindow; - ccwindow = FindWindow ("Command & Conquer", "Command & Conquer"); - if (ccwindow){ - SetForegroundWindow ( ccwindow ); - ShowWindow ( ccwindow, SW_RESTORE ); - } - - return (EXIT_SUCCESS); - } - - // ST - 3/6/2019 1:36PM - //DDSCAPS surface_capabilities; - - if (Ram_Free(MEM_NORMAL) < 5000000) { -#ifdef GERMAN - printf("Zuwenig Hauptspeicher verfgbar.\n"); -#else -#ifdef FRENCH - printf("M‚moire vive (RAM) insuffisante.\n"); -#else - printf("Insufficient RAM available.\n"); -#endif -#endif - return(EXIT_FAILURE); - } - - - //void *test_buffer = Alloc(20,MEM_NORMAL); - - //memset ((char*)test_buffer, 0, 21); - - //Free(test_buffer); - - - int argc; //Command line argument count - unsigned command_scan; - char command_char; - char * argv[20]; //Pointers to command line arguments - char path_to_exe[280]; - - ProgramInstance = instance; - - /* - ** Get the full path to the .EXE - */ - GetModuleFileName (instance, &path_to_exe[0], 280); - - /* - ** First argument is supposed to be a pointer to the .EXE that is running - ** - */ - argc=1; //Set argument count to 1 - argv[0]=&path_to_exe[0]; //Set 1st command line argument to point to full path - - /* - ** Get pointers to command line arguments just like if we were in DOS - ** - ** The command line we get is cr/zero? terminated. - ** - */ - - command_scan=0; - - do { - /* - ** Scan for non-space character on command line - */ - do { - command_char = *( command_line+command_scan++ ); - } while ( command_char==' ' ); - - if ( command_char!=0 && command_char != 13 ){ - argv[argc++]=command_line+command_scan-1; - - /* - ** Scan for space character on command line - */ - bool in_quotes = false; - do { - command_char = *( command_line+command_scan++ ); - if (command_char == '"') { - in_quotes = !in_quotes; - } - } while ( (in_quotes || command_char!=' ') && command_char != 0 && command_char!=13 ); - - *( command_line+command_scan-1 ) = 0; - } - - } while ( command_char != 0 && command_char != 13 && argc<20 ); - - - - /* - ** Remember the current working directory and drive. - */ -#if (0) //PG_TO_FIX - unsigned olddrive; - char oldpath[MAX_PATH]; - getcwd(oldpath, sizeof(oldpath)); - _dos_getdrive(&olddrive); - - - /* - ** Change directory to the where the executable is located. Handle the - ** case where there is no path attached to argv[0]. - */ - char drive[_MAX_DRIVE]; - char path[_MAX_PATH]; - unsigned drivecount; - _splitpath(argv[0], drive, path, NULL, NULL); - if (!drive[0]) { - drive[0] = ('A' + olddrive)-1; - } - if (!path[0]) { - strcpy(path, "."); - } - _dos_setdrive(toupper((drive[0])-'A')+1, &drivecount); - if (path[strlen(path)-1] == '\\') { - path[strlen(path)-1] = '\0'; - } - chdir(path); -#endif - -#ifdef JAPANESE - ForceEnglish = false; -#endif - if (Parse_Command_Line(argc, argv)) { - - WindowsTimer = new WinTimerClass(60,FALSE); - - int time_test = WindowsTimer->Get_System_Tick_Count(); - Sleep (1000); - if (WindowsTimer->Get_System_Tick_Count() == time_test){ -#ifdef FRENCH - MessageBox(0, "Error - L'horloge systŠme n'a pas pu s'initialiser en raison de l'instabilit‚ du sytŠme. Vous devez red‚marrer Windows.", "Command & Conquer" , MB_OK|MB_ICONSTOP); -#else -#ifdef GERMAN - MessageBox(0, "Fehler - das Timer-System konnte aufgrund einer Instabilit„t des Systems nicht initialisiert werden. Bitte starten Sie Windows neu.", "Command & Conquer", MB_OK|MB_ICONSTOP); -#else - MessageBox(0, "Error - Timer system failed to start due to system instability. You need to restart Windows.", "Command & Conquer", MB_OK|MB_ICONSTOP); -#endif //GERMAN -#endif //FRENCH - return(EXIT_FAILURE); - } - - RawFileClass cfile("CONQUER.INI"); - -#ifdef JAPANESE - //////////////////////////////////////if(!ForceEnglish) KBLanguage = 1; -#endif - - - /* - ** Check for existance of MMX support on the processor - */ - if (Detect_MMX_Availability()){ - //MessageBox(NULL, "MMX extensions detected - enabling MMX support.", "Command & Conquer",MB_ICONEXCLAMATION|MB_OK); - MMXAvailable = true; - } - - /* - ** If there is loads of memory then use uncompressed shapes - */ - Check_Use_Compressed_Shapes(); - - /* - ** If there is not enough disk space free, dont allow the product to run. - */ - if (Disk_Space_Available() < INIT_FREE_DISK_SPACE) { -#ifdef GERMAN - char disk_space_message [512]; - sprintf (disk_space_message, "Nicht genug Festplattenplatz fr Command & Conquer.\nSie brauchen %d MByte freien Platz auf der Festplatte.", (INIT_FREE_DISK_SPACE) / (1024 * 1024)); - MessageBox(NULL, disk_space_message, "Command & Conquer", MB_ICONEXCLAMATION|MB_OK); - if ( WindowsTimer ) - delete WindowsTimer; - return (EXIT_FAILURE); -#endif -#ifdef FRENCH - char disk_space_message [512]; - sprintf (disk_space_message, "Espace disque insuffisant pour lancer Command & Conquer.\nVous devez disposer de %d Mo d'espace disponsible sur disque dur.", (INIT_FREE_DISK_SPACE) / (1024 * 1024)); - MessageBox(NULL, disk_space_message, "Command & Conquer", MB_ICONEXCLAMATION|MB_OK); - if ( WindowsTimer ) - delete WindowsTimer; - return (EXIT_FAILURE); -#endif -#if !(FRENCH | GERMAN) - int reply = MessageBox(NULL, "Warning - you are critically low on free disk space for virtual memory and save games. Do you want to play C&C anyway?", "Command & Conquer", MB_ICONQUESTION|MB_YESNO); - if (reply == IDNO){ - - if ( WindowsTimer ) - delete WindowsTimer; - return (EXIT_FAILURE); - } - -#endif - } - -#if (0) // ST - 1/2/2019 5:50PM - CDFileClass::Set_CD_Drive (CDList.Get_First_CD_Drive()); -#endif - if (cfile.Is_Available()) { - -#ifndef NOMEMCHECK - char * cdata = (char *)Load_Alloc_Data(cfile); - Read_Private_Config_Struct(cdata, &NewConfig); - delete [] cdata; -#else - Read_Private_Config_Struct((char *)Load_Alloc_Data(cfile), &NewConfig); -#endif - Read_Setup_Options( &cfile ); - - CCDebugString ("C&C95 - Creating main window.\n"); - - Create_Main_Window( instance , command_show , ScreenWidth , ScreenHeight ); - - CCDebugString ("C&C95 - Initialising audio.\n"); - - SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 ); - - Palette = new(MEM_CLEAR) unsigned char[768]; - - BOOL video_success = FALSE; - CCDebugString ("C&C95 - Setting video mode.\n"); - /* - ** Set 640x400 video mode. If its not available then try for 640x480 - */ - if (ScreenHeight == 400){ - if (Set_Video_Mode (MainWindow, ScreenWidth, ScreenHeight, 8)){ - video_success = TRUE; - }else{ - if (Set_Video_Mode (MainWindow, ScreenWidth, 480, 8)){ - video_success = TRUE; - ScreenHeight = 480; - } - } - }else{ - if (Set_Video_Mode (MainWindow, ScreenWidth, ScreenHeight, 8)){ - video_success = TRUE; - } - } - - if (!video_success){ - CCDebugString ("C&C95 - Failed to set video mode.\n"); - MessageBox(MainWindow, Text_String(TXT_UNABLE_TO_SET_VIDEO_MODE), "Command & Conquer", MB_ICONEXCLAMATION|MB_OK); - if (WindowsTimer) delete WindowsTimer; - if (Palette) delete [] Palette; - return (EXIT_FAILURE); - } - - CCDebugString ("C&C95 - Initialising video surfaces.\n"); - - if (ScreenWidth==320){ - VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0); - ModeXBuff.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM)); - } else { - -#if (1) //ST - 1/3/2019 2:11PM - - VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0); - HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0); - - -#else - VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM)); - - /* - ** Check that we really got a video memory page. Failure is fatal. - */ - memset (&surface_capabilities, 0, sizeof(surface_capabilities)); - VisiblePage.Get_DD_Surface()->GetCaps(&surface_capabilities); - if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY){ - /* - ** Aaaarrgghh! - */ - CCDebugString ("C&C95 - Unable to allocate primary surface.\n"); - MessageBox(MainWindow, Text_String(TXT_UNABLE_TO_ALLOCATE_PRIMARY_VIDEO_BUFFER), "Command & Conquer", MB_ICONEXCLAMATION|MB_OK); - if (WindowsTimer) delete WindowsTimer; - if (Palette) delete [] Palette; - return (EXIT_FAILURE); - } - - /* - ** If we have enough left then put the hidpage in video memory unless... - ** - ** If there is no blitter then we will get better performance with a system - ** memory hidpage - ** - ** Use a system memory page if the user has specified it via the ccsetup program. - */ - CCDebugString ("C&C95 - Allocating back buffer "); - long video_memory = Get_Free_Video_Memory(); - unsigned video_capabilities = Get_Video_Hardware_Capabilities(); - if (video_memory < ScreenWidth*ScreenHeight || - (! (video_capabilities & VIDEO_BLITTER)) || - (video_capabilities & VIDEO_NO_HARDWARE_ASSIST) || - !VideoBackBufferAllowed){ - CCDebugString ("in system memory.\n"); - HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0); - } else { - //HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0); - CCDebugString ("in video memory.\n"); - HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)GBC_VIDEOMEM); - - /* - ** Make sure we really got a video memory hid page. If we didnt then things - ** will run very slowly. - */ - memset (&surface_capabilities, 0, sizeof(surface_capabilities)); - HiddenPage.Get_DD_Surface()->GetCaps(&surface_capabilities); - if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY){ - /* - ** Oh dear, big trub. This must be an IBM Aptiva or something similarly cruddy. - ** We must redo the Hidden Page as system memory. - */ - AllSurfaces.Remove_DD_Surface(HiddenPage.Get_DD_Surface()); // Remove the old surface from the AllSurfaces list - HiddenPage.Get_DD_Surface()->Release(); - HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0); - }else{ - VisiblePage.Attach_DD_Surface(&HiddenPage); - } - } -#endif - } - ScreenHeight = 1536; - - if (VisiblePage.Get_Height() == 480){ - SeenBuff.Attach(&VisiblePage,0, 40, 1536, 1536); - HidPage.Attach(&HiddenPage, 0, 40, 1536, 1536); - }else{ - SeenBuff.Attach(&VisiblePage,0, 0, 1536, 1536); - HidPage.Attach(&HiddenPage, 0, 0, 1536, 1536); - } - CCDebugString ("C&C95 - Adjusting variables for resolution.\n"); - Options.Adjust_Variables_For_Resolution(); - - CCDebugString ("C&C95 - Setting palette.\n"); - /////////Set_Palette(Palette); - - WindowList[0][WINDOWWIDTH] = SeenBuff.Get_Width() >> 3; - WindowList[0][WINDOWHEIGHT] = SeenBuff.Get_Height(); - - /* - ** Install the memory error handler - */ - Memory_Error = &Memory_Error_Handler; - - /* - ** Initialise MMX support if its available - */ - CCDebugString ("C&C95 - Entering MMX detection.\n"); - if (MMXAvailable){ - Init_MMX(); - } - - CCDebugString ("C&C95 - Creating mouse class.\n"); - WWMouse = new WWMouseClass(&SeenBuff, 32, 32); -// MouseInstalled = Install_Mouse(32,24,320,200); - MouseInstalled = TRUE; - - /* - ** See if we should run the intro - */ - CCDebugString ("C&C95 - Reading CONQUER.INI.\n"); - char *buffer = (char*)Alloc(64000 , MEM_NORMAL); //(char *)HidPage.Get_Buffer(); - cfile.Read(buffer, cfile.Size()); - buffer[cfile.Size()] = '\0'; - - /* - ** Check for forced intro movie run disabling. If the conquer - ** configuration file says "no", then don't run the intro. - */ - char tempbuff[5]; - WWGetPrivateProfileString("Intro", "PlayIntro", "Yes", tempbuff, 4, buffer); - if ((stricmp(tempbuff, "No") == 0) || SpawnedFromWChat) { - Special.IsFromInstall = false; - }else{ - Special.IsFromInstall = true; - } - SlowPalette = WWGetPrivateProfileInt("Options", "SlowPalette", 1, buffer); - -#ifdef DEMO - /* - ** Check for override directory path for CD searches. - */ - WWGetPrivateProfileString("CD", "Path", ".", OverridePath, sizeof(OverridePath), buffer); -#endif - - /* - ** Regardless of whether we should run it or not, here we're - ** gonna change it to say "no" in the future. - */ - WWWritePrivateProfileString("Intro", "PlayIntro", "No", buffer); - cfile.Write(buffer, strlen(buffer)); - - Free(buffer); - - CCDebugString ("C&C95 - Checking availability of C&CSPAWN.INI packet from WChat.\n"); - if (DDEServer.Get_MPlayer_Game_Info()){ - CCDebugString ("C&C95 - C&CSPAWN.INI packet available.\n"); - Check_From_WChat(NULL); - }else{ - CCDebugString ("C&C95 - C&CSPAWN.INI packet not arrived yet.\n"); - //Check_From_WChat("C&CSPAWN.INI"); - //if (Special.IsFromWChat){ - // DDEServer.Disable(); - //} - } - - /* - ** If the intro is being run for the first time, then don't - ** allow breaking out of it with the key. - */ - if (Special.IsFromInstall) { - BreakoutAllowed = false; - } - - Memory_Error_Exit = Print_Error_End_Exit; - - CCDebugString ("C&C95 - Entering main game.\n"); - Main_Game(argc, argv); - - if (RunningAsDLL) { - return (EXIT_SUCCESS); - } - - VisiblePage.Clear(); - HiddenPage.Clear(); -// Set_Video_Mode(RESET_MODE); - - Memory_Error_Exit = Print_Error_Exit; - - CCDebugString ("C&C95 - About to exit.\n"); - ReadyToQuit = 1; - - PostMessage(MainWindow, WM_DESTROY, 0, 0); - do - { - Keyboard::Check(); - }while (ReadyToQuit == 1); - - CCDebugString ("C&C95 - Returned from final message loop.\n"); - //Prog_End(); - //Invalidate_Cached_Icons(); - //VisiblePage.Un_Init(); - //HiddenPage.Un_Init(); - //AllSurfaces.Release(); - //Reset_Video_Mode(); - //Stop_Profiler(); - return (EXIT_SUCCESS); - - } else { -#ifdef GERMAN - puts("Bitte erst das SETUP-Programm starten.\n"); -#else -#ifdef FRENCH - puts("Lancez d'abord le programme de configuration SETUP.\n"); -#else - puts("Run SETUP program first."); - puts("\n"); -#endif - Kbd.Get(); -#endif - } - -// Remove_Keyboard_Interrupt(); - if (WindowsTimer){ - delete WindowsTimer; - WindowsTimer = NULL; - } - - if (Palette){ - delete [] Palette; - Palette = NULL; - } - } - - /* - ** Restore the current drive and directory. - */ -#ifdef NOT_FOR_WIN95 - _dos_setdrive(olddrive, &drivecount); - chdir(oldpath); -#endif //NOT_FOR_WIN95 - - return(EXIT_SUCCESS); -} - - -/*********************************************************************************************** - * Prog_End -- Cleans up library systems in prep for game exit. * - * * - * This routine should be called before the game terminates. It handles cleaning up * - * library systems so that a graceful return to the host operating system is achieved. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/20/1995 JLB : Created. * - *=============================================================================================*/ -void __cdecl Prog_End(const char *why, bool fatal) // Added why and fatal parameters. ST - 6/27/2019 10:10PM -{ - GlyphX_Debug_Print("Prog_End()"); - - if (why) { - GlyphX_Debug_Print(why); - } - if (fatal) { - *((int*)0) = 0; - } - -#ifndef DEMO - if (GameToPlay == GAME_MODEM || GameToPlay == GAME_NULL_MODEM) { -// NullModem.Change_IRQ_Priority(0); - } -#endif - CCDebugString ("C&C95 - About to call Sound_End.\n"); - Sound_End(); - CCDebugString ("C&C95 - Returned from Sound_End.\n"); - if (WWMouse){ - CCDebugString ("C&C95 - Deleting mouse object.\n"); - delete WWMouse; - WWMouse = NULL; - } - if (WindowsTimer){ - CCDebugString ("C&C95 - Deleting windows timer.\n"); - delete WindowsTimer; - WindowsTimer = NULL; - } - - if (Palette){ - CCDebugString ("C&C95 - Deleting palette object.\n"); - delete [] Palette; - Palette = NULL; - } - - ProgEndCalled = true; -} - - -/*********************************************************************************************** - * Delete_Swap_Files -- Deletes previously existing swap files. * - * * - * This routine will scan through the current directory and delete any swap files it may * - * find. This is used to clear out any left over swap files from previous runs (crashes) * - * of the game. This routine presumes that it cannot delete the swap file that is created * - * by the current run of the game. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -void Delete_Swap_Files(void) -{ -#if (0) - struct find_t ff; // for _dos_findfirst - - if (!_dos_findfirst("*.SWP", _A_NORMAL, &ff)) { - do { - unlink(ff.name); - } while(!_dos_findnext(&ff)); - } -#endif -} - - -void Print_Error_End_Exit(char *string) -{ - printf( "%s\n", string ); - Get_Key(); - Prog_End(); - printf( "%s\n", string ); - if (!RunningAsDLL) { - exit(1); - } -} - - -void Print_Error_Exit(char *string) -{ - printf( "%s\n", string ); - if (!RunningAsDLL) { - exit(1); - } -} - - - - - - - - -/*********************************************************************************************** - * Read_Setup_Options -- Read stuff in from the INI file that we need to know sooner * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 4:09PM ST : Created * - *=============================================================================================*/ -void Read_Setup_Options( RawFileClass *config_file ) -{ - char *buffer = new char [config_file->Size()]; - - if (config_file->Is_Available()){ - - config_file->Read (buffer, config_file->Size()); - - VideoBackBufferAllowed = WWGetPrivateProfileInt ("Options", "VideoBackBuffer", 1, buffer); - AllowHardwareBlitFills = WWGetPrivateProfileInt ("Options", "HardwareFills", 1, buffer); - ScreenHeight = WWGetPrivateProfileInt ("Options", "Resolution", 0, buffer) ? 1536 : 1536; - IsV107 = WWGetPrivateProfileInt ("Options", "Compatibility", 0, buffer); - - /* - ** See if an alternative socket number has been specified - */ - int socket = WWGetPrivateProfileInt ("Options", "Socket", 0, buffer); - if (socket >0 ){ - socket += 0x4000; - if (socket >= 0x4000 && socket < 0x8000) { - Ipx.Set_Socket (socket); - } - } - - /* - ** See if a destination network has been specified - */ - char netbuf [512]; - memset (netbuf, 0, sizeof (netbuf) ); - char *netptr = WWGetPrivateProfileString ("Options", "DestNet", NULL, netbuf, sizeof (netbuf), buffer); - - if (netptr && strlen (netbuf)){ - NetNumType net; - NetNodeType node; - - /* - ** Scan the string, pulling off each address piece - */ - int i = 0; - char * p = strtok(netbuf,"."); - int x; - while (p) { - sscanf(p,"%x",&x); // convert from hex string to int - if (i < 4) { - net[i] = (char)x; // fill NetNum - } else { - node[i-4] = (char)x; // fill NetNode - } - i++; - p = strtok(NULL,"."); - } - - /* - ** If all the address components were successfully read, fill in the - ** BridgeNet with a broadcast address to the network across the bridge. - */ - if (i >= 4) { - IsBridge = 1; - memset(node, 0xff, 6); - BridgeNet = IPXAddressClass(net, node); - } - } - - } - - delete [] buffer; -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/STATS.CPP b/code/TIBERIANDAWN/STATS.CPP deleted file mode 100644 index 44f2c11..0000000 --- a/code/TIBERIANDAWN/STATS.CPP +++ /dev/null @@ -1,676 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : WINSTUB.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : 05/29/1996 * - * * - * Last Update : May 29th 1996 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * Internet game statistics to collect and upload to the server * - * * - * * - *---------------------------------------------------------------------------------------------* - * * - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "tcpip.h" -#include "packet.h" -#include "ccdde.h" - -#define FIELD_PACKET_TYPE "TYPE" -#define FIELD_GAME_ID "IDNO" -#define FIELD_START_CREDITS "CRED" -#define FIELD_BASES "BASE" -#define FIELD_TIBERIUM "TIBR" -#define FIELD_CRATES "CRAT" -#define FIELD_AI_PLAYERS "AIPL" -#define FIELD_CAPTURE_THE_FLAG "FLAG" -#define FIELD_START_UNIT_COUNT "UNIT" -#define FIELD_TECH_LEVEL "TECH" -#define FIELD_SCENARIO "SCEN" -#define FIELD_COMPLETION "CMPL" -#define FIELD_START_TIME "TIME" -#define FIELD_GAME_DURATION "DURA" -#define FIELD_FRAME_RATE "AFPS" -#define FIELD_SPEED_SETTING "SPED" -#define FIELD_GAME_VERSION "VERS" -#define FIELD_GAME_BUILD_DATE "DATE" -#define FIELD_COVERT_PRESENT "COVT" -#define FIELD_CPU_TYPE "PROC" -#define FIELD_MEMORY "MEMO" -#define FIELD_VIDEO_MEMORY "VIDM" -#define FIELD_PLAYER1_HANDLE "NAM1" -#define FIELD_PLAYER2_HANDLE "NAM2" -#define FIELD_PLAYER1_TEAM "SID1" -#define FIELD_PLAYER2_TEAM "SID2" -#define FIELD_PLAYER1_COLOR "COL1" -#define FIELD_PLAYER2_COLOR "COL2" -#define FIELD_PLAYER1_CREDITS "CRD1" -#define FIELD_PLAYER2_CREDITS "CRD2" - -#define FIELD_PLAYER1_UNITS_LEFT "UNL1" -#define FIELD_PLAYER2_UNITS_LEFT "UNL2" -#define FIELD_PLAYER1_INFANTRY_LEFT "INL1" -#define FIELD_PLAYER2_INFANTRY_LEFT "INL2" -#define FIELD_PLAYER1_PLANES_LEFT "PLL1" -#define FIELD_PLAYER2_PLANES_LEFT "PLL2" -#define FIELD_PLAYER1_BUILDINGS_LEFT "BLL1" -#define FIELD_PLAYER2_BUILDINGS_LEFT "BLL2" - -#define FIELD_PLAYER1_UNITS_BOUGHT "UNB1" -#define FIELD_PLAYER2_UNITS_BOUGHT "UNB2" -#define FIELD_PLAYER1_INFANTRY_BOUGHT "INB1" -#define FIELD_PLAYER2_INFANTRY_BOUGHT "INB2" -#define FIELD_PLAYER1_PLANES_BOUGHT "PLB1" -#define FIELD_PLAYER2_PLANES_BOUGHT "PLB2" -#define FIELD_PLAYER1_BUILDINGS_BOUGHT "BLB1" -#define FIELD_PLAYER2_BUILDINGS_BOUGHT "BLB2" - -#define FIELD_PLAYER1_UNITS_KILLED "UNK1" -#define FIELD_PLAYER2_UNITS_KILLED "UNK2" -#define FIELD_PLAYER1_INFANTRY_KILLED "INK1" -#define FIELD_PLAYER2_INFANTRY_KILLED "INK2" -#define FIELD_PLAYER1_PLANES_KILLED "PLK1" -#define FIELD_PLAYER2_PLANES_KILLED "PLK2" -#define FIELD_PLAYER1_BUILDINGS_KILLED "BLK1" -#define FIELD_PLAYER2_BUILDINGS_KILLED "BLK2" - -#define FIELD_PLAYER1_BUILDINGS_CAPTURED "BLC1" -#define FIELD_PLAYER2_BUILDINGS_CAPTURED "BLC2" - -#define FIELD_PLAYER1_CRATES_FOUND "CRA1" -#define FIELD_PLAYER2_CRATES_FOUND "CRA2" -#define FIELD_PLAYER1_HARVESTED "HRV1" -#define FIELD_PLAYER2_HARVESTED "HRV2" - - -#define PACKET_TYPE_HOST_GAME_INFO (unsigned char) 50 -#define PACKET_TYPE_GUEST_GAME_INFO (unsigned char) 51 - -enum { - COMPLETION_CONNECTION_LOST, - COMPLETION_PLAYER_1_WON, - COMPLETION_PLAYER_1_WON_BY_RESIGNATION, - COMPLETION_PLAYER_1_WON_BY_DISCONNECTION, - COMPLETION_PLAYER_2_WON, - COMPLETION_PLAYER_2_WON_BY_RESIGNATION, - COMPLETION_PLAYER_2_WON_BY_DISCONNECTION -}; - - -extern unsigned long PlanetWestwoodGameID; -extern HINSTANCE ProgramInstance; -extern unsigned long PlanetWestwoodStartTime; - -extern "C" char CPUType; - - -bool GameTimerInUse = false; -TimerClass GameTimer; -long GameEndTime; -void *PacketLater = NULL; - -/*********************************************************************************************** - * Send_Statistics_To_Server -- sends internet game statistics to the Westeood server * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/29/96 12:38PM ST : Created * - *=============================================================================================*/ - -void Send_Statistics_Packet(void) -{ -//PG_TO_FIX -#if (0) -#ifndef DEMO - - PacketClass stats; - HouseClass *player; - static int packet_size; - int index; - bool packet_later = false; // Should the packet be sent later - void *packet; - - static char field_player_handle[5] = { "NAM?" }; - static char field_player_team[5] = { "SID?" }; - static char field_player_color[5] = { "COL?" }; - static char field_player_credits[5] = { "CRD?" }; - static char field_player_units_left[5] = { "UNL?" }; - static char field_player_infantry_left[5] = { "INL?" }; - static char field_player_planes_left[5] = { "PLL?" }; - static char field_player_buildings_left[5] = { "BLL?" }; - static char field_player_units_bought[5] = { "UNB?" }; - static char field_player_infantry_bought[5] = { "INB?" }; - static char field_player_planes_bought[5] = { "PLB?" }; - static char field_player_buildings_bought[5] = { "BLB?" }; - static char field_player_units_killed[5] = { "UNK?" }; - static char field_player_infantry_killed[5] = { "INK?" }; - static char field_player_planes_killed[5] = { "PLK?" }; - static char field_player_buildings_killed[5] = { "BLK?" }; - static char field_player_buildings_captured[5] = { "BLC?" }; - static char field_player_crates_found[5] = { "CRA?" }; - static char field_player_harvested[5] = { "HRV?" }; - - static char *houses[] = { - "GDI", - "NOD", - "NUT", - "JUR", - "M01", - "M02", - "M03", - "M04", - "M05", - "M06" - }; - - CCDebugString ("C&C95 - In Send_Statistics_Packet.\n"); - - - if (!PacketLater){ - - CCDebugString ("C&C95 - PacketLater is false.\n"); - - - /* - ** Field to identify this as C&C 95 internet game statistics packet - */ - if (Server){ - stats.Add_Field(FIELD_PACKET_TYPE, PACKET_TYPE_HOST_GAME_INFO); - }else{ - stats.Add_Field(FIELD_PACKET_TYPE, PACKET_TYPE_GUEST_GAME_INFO); - } - - /* - ** Game ID. A unique game identifier assigned by WChat. - */ - stats.Add_Field(FIELD_GAME_ID, PlanetWestwoodGameID); - - /* - ** Start credits. - */ - stats.Add_Field(FIELD_START_CREDITS, (unsigned long)MPlayerCredits); - - /* - ** Bases (On/Off) - */ - stats.Add_Field(FIELD_BASES, MPlayerBases ? "ON" : "OFF"); - - /* - ** Tiberium (On/Off) - */ - stats.Add_Field(FIELD_TIBERIUM, MPlayerTiberium ? "ON" : "OFF"); - - /* - ** Crates (On/Off) - */ - stats.Add_Field(FIELD_CRATES, MPlayerGoodies ? "ON" : "OFF"); - - /* - ** AI Players (On/Off/Capture the flag) - */ - stats.Add_Field(FIELD_AI_PLAYERS, MPlayerGhosts ? "ON" : "OFF"); - stats.Add_Field(FIELD_CAPTURE_THE_FLAG, Special.IsCaptureTheFlag ? "ON" : "OFF"); - - /* - ** Start unit count - */ - stats.Add_Field(FIELD_START_UNIT_COUNT, (unsigned long)MPlayerUnitCount); - - /* - ** Tech level. - */ - stats.Add_Field(FIELD_TECH_LEVEL, (unsigned long)BuildLevel); - - CCDebugString ("C&C95 - Adding stats field for scenario.\n"); - /* - ** Scenario - */ - char fname[128]; - char namebuffer[40]; - char *abuffer = (char *)_ShapeBuffer; - memset(abuffer, '\0', _ShapeBufferSize); - sprintf(fname,"%s.INI",ScenarioName); - CCFileClass fileo; - fileo.Set_Name (fname); - fileo.Read(abuffer, _ShapeBufferSize-1); - fileo.Close(); - WWGetPrivateProfileString("Basic", "Name", "Nulls-Ville", namebuffer, 40, abuffer); - stats.Add_Field(FIELD_SCENARIO, namebuffer); - //stats.Add_Field(FIELD_SCENARIO, MPlayerScenarios[ScenarioIdx]); - - - /* - ** Game completion status. - ** - ** Connection lost. - ** Player 1 won - ** Player 2 won - ** Player 1 won by resignation - ** Player 2 won by resignation - ** Player 1 aborted - ** Player 2 aborted - ** - */ - CCDebugString ("C&C95 - Adding stats field for completion status.\n"); - HouseClass *player1 = HouseClass::As_Pointer(MPlayerHouses[0]); - HouseClass *player2 = HouseClass::As_Pointer(MPlayerHouses[1]); - - int completion = -1; - - if (ConnectionLost){ - completion = COMPLETION_CONNECTION_LOST; - CCDebugString ("C&C95 - Completion status is connection lost.\n"); - }else{ - - if (player1 && player2){ - if (player1->IGaveUp){ - completion = COMPLETION_PLAYER_2_WON_BY_DISCONNECTION; - CCDebugString ("C&C95 - Completion status is player 1 disconnected.\n"); - } - - if (player2->IGaveUp){ - completion = COMPLETION_PLAYER_1_WON_BY_DISCONNECTION; - CCDebugString ("C&C95 - Completion status is player 2 disconnected.\n"); - } - - - if (player2->IsDefeated){ - /* - ** Player 1 won. Find out how. - */ - completion = COMPLETION_PLAYER_1_WON; - if (player2->Resigned){ - completion = COMPLETION_PLAYER_1_WON_BY_RESIGNATION; - CCDebugString ("C&C95 - Completion status is player 2 resigned.\n"); - }else{ - if (player2->IGaveUp){ - completion = COMPLETION_PLAYER_1_WON_BY_DISCONNECTION; - CCDebugString ("C&C95 - Completion status is player 2 disconnected.\n"); - } - } - - - }else{ - - if (player1->IsDefeated){ - /* - ** Player 2 won. Find out how. - */ - completion = COMPLETION_PLAYER_2_WON; - if (player1->Resigned){ - completion = COMPLETION_PLAYER_2_WON_BY_RESIGNATION; - CCDebugString ("C&C95 - Completion status is player 1 resigned.\n"); - }else{ - if (player1->IGaveUp){ - completion = COMPLETION_PLAYER_2_WON_BY_DISCONNECTION; - CCDebugString ("C&C95 - Completion status is player 1 disconnected.\n"); - } - } - } - } - } - } - - stats.Add_Field (FIELD_COMPLETION, (char) completion); - - - - - - - /* - ** Game start time (GMT or Pacific?) - ** - ** Passed from WChat - */ - stats.Add_Field (FIELD_START_TIME, (long) PlanetWestwoodStartTime); - - /* - ** Game duration (seconds). - */ - stats.Add_Field (FIELD_GAME_DURATION, (long) GameEndTime/60); - - /* - ** Avg. frame rate. - */ - if (GameEndTime/60 == 0){ - stats.Add_Field (FIELD_FRAME_RATE, 0L ); - }else{ - stats.Add_Field (FIELD_FRAME_RATE, (long) Frame / (GameEndTime/60) ); - } - - - CCDebugString ("C&C95 - Adding hardware info stats.\n"); - /* - ** CPU type - */ - stats.Add_Field (FIELD_CPU_TYPE, (char)CPUType); - - /* - ** Memory - */ - MEMORYSTATUS mem_info; - mem_info.dwLength=sizeof(mem_info); - GlobalMemoryStatus(&mem_info); - stats.Add_Field (FIELD_MEMORY, (long)mem_info.dwTotalPhys); - - /* - ** Video memory - */ - DDCAPS video_capabilities; - long video_memory; - - if (DirectDrawObject){ - video_capabilities.dwSize = sizeof (video_capabilities); - if (DD_OK == DirectDrawObject->GetCaps (&video_capabilities , NULL)){ - video_memory = video_capabilities.dwVidMemTotal; - video_memory += 1024*1024 -1; - video_memory &= 0xfff00000; - stats.Add_Field (FIELD_VIDEO_MEMORY, (long) video_memory); - } - } - - CCDebugString ("C&C95 - Adding game info stats.\n"); - /* - ** Game speed setting. - */ - stats.Add_Field (FIELD_SPEED_SETTING, (char)Options.GameSpeed); - - /* - ** C&C 95 version/build date - */ - char version[128]; - sprintf (version, "%d%s", Version_Number(), VersionText); - stats.Add_Field (FIELD_GAME_VERSION, version); - - char path_to_exe[280]; - FILETIME write_time; //File time is 64 bits - - GetModuleFileName (ProgramInstance, path_to_exe, 280); - RawFileClass file; - file.Set_Name(path_to_exe); - file.Open(); - HANDLE handle = file.Get_File_Handle(); - - if (handle != INVALID_HANDLE_VALUE){ - if (GetFileTime (handle, NULL, NULL, &write_time)){ - write_time.dwLowDateTime = htonl (write_time.dwLowDateTime); - write_time.dwHighDateTime = htonl (write_time.dwHighDateTime); - stats.Add_Field (FIELD_GAME_BUILD_DATE, (void*)&write_time, sizeof (write_time)); - } - } - - /* - ** Covert installed? (Yes/No) - */ - stats.Add_Field(FIELD_COVERT_PRESENT, (char) Expansion_Present()); - - CCDebugString ("C&C95 - Adding house specific stats.\n"); - /* - ** Build the player specific statistics - ** - */ - for (int house = 0 ; house < 2 ; house++){ - - player = HouseClass::As_Pointer(MPlayerHouses[house]); - - if (player){ - /* - ** Player handle. - */ - field_player_handle[3] = '1' + (char)house; - stats.Add_Field (field_player_handle, (char*) MPlayerNames[house]); - - /* - ** Player team. (NOD or GDI) - */ - field_player_team[3] = '1' + (char)house; - stats.Add_Field (field_player_team, houses[player->ActLike]); - - /* - ** Player color - */ - field_player_color[3] = '1' + (char)house; - stats.Add_Field (field_player_color, (unsigned char) (player->Class->House - HOUSE_MULTI1)); - - /* - ** Player end credits. - */ - field_player_credits[3] = '1' + (char)house; - stats.Add_Field (field_player_credits, player->Credits + player->Tiberium); - - /* - ** Number of each unit/building type built - */ - field_player_infantry_bought[3] = '1' + (char)house; - field_player_units_bought[3] = '1' + (char)house; - field_player_planes_bought[3] = '1' + (char)house; - field_player_buildings_bought[3] = '1' + (char)house; - - player->InfantryTotals->To_Network_Format(); - player->UnitTotals->To_Network_Format(); - player->AircraftTotals->To_Network_Format(); - player->BuildingTotals->To_Network_Format(); - - stats.Add_Field (field_player_infantry_bought, (void*) player->InfantryTotals->Get_All_Totals(), player->InfantryTotals->Get_Unit_Count()*4); - stats.Add_Field (field_player_units_bought, (void*) player->UnitTotals->Get_All_Totals(), player->UnitTotals->Get_Unit_Count()*4); - stats.Add_Field (field_player_planes_bought, (void*) player->AircraftTotals->Get_All_Totals(), player->AircraftTotals->Get_Unit_Count()*4); - stats.Add_Field (field_player_buildings_bought, (void*) player->BuildingTotals->Get_All_Totals(), player->BuildingTotals->Get_Unit_Count()*4); - - player->InfantryTotals->To_PC_Format(); - player->UnitTotals->To_PC_Format(); - player->AircraftTotals->To_PC_Format(); - player->BuildingTotals->To_PC_Format(); - - /* - ** Clear out the counts and use the space to count up the current number of units/buildings - */ - player->InfantryTotals->Clear_Unit_Total(); - player->AircraftTotals->Clear_Unit_Total(); - player->UnitTotals->Clear_Unit_Total(); - player->BuildingTotals->Clear_Unit_Total(); - - /* - ** Number of units remaining to player - */ - for (index = 0; index < Units.Count(); index++) { - UnitClass const * unit = Units.Ptr(index); - if (unit->House == player){ - player->UnitTotals->Increment_Unit_Total (unit->Class->Type); - } - } - - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass const * infantry = Infantry.Ptr(index); - if (infantry->House == player && !infantry->Class->IsCivilian){ - player->InfantryTotals->Increment_Unit_Total (infantry->Class->Type); - } - } - - for (index = 0; index < Aircraft.Count(); index++) { - AircraftClass const * aircraft = Aircraft.Ptr(index); - if (aircraft->House == player && aircraft->Class->Type != AIRCRAFT_CARGO){ - player->AircraftTotals->Increment_Unit_Total (aircraft->Class->Type); - } - } - - for (index = 0; index < Buildings.Count(); index++) { - BuildingClass const * building = Buildings.Ptr(index); - if (building->House == player){ - player->BuildingTotals->Increment_Unit_Total (building->Class->Type); - } - } - - player->InfantryTotals->To_Network_Format(); - player->UnitTotals->To_Network_Format(); - player->AircraftTotals->To_Network_Format(); - player->BuildingTotals->To_Network_Format(); - - field_player_infantry_left[3] = '1' + (char)house; - field_player_units_left[3] = '1' + (char)house; - field_player_planes_left[3] = '1' + (char)house; - field_player_buildings_left[3] = '1' + (char)house; - stats.Add_Field (field_player_infantry_left, (void*) player->InfantryTotals->Get_All_Totals(), player->InfantryTotals->Get_Unit_Count()*4); - stats.Add_Field (field_player_units_left, (void*) player->UnitTotals->Get_All_Totals(), player->UnitTotals->Get_Unit_Count()*4); - stats.Add_Field (field_player_planes_left, (void*) player->AircraftTotals->Get_All_Totals(), player->AircraftTotals->Get_Unit_Count()*4); - stats.Add_Field (field_player_buildings_left, (void*) player->BuildingTotals->Get_All_Totals(), player->BuildingTotals->Get_Unit_Count()*4); - - - /* - ** Number of enemy units/buildings of each type destroyed. - */ - - player->DestroyedInfantry->To_Network_Format(); - player->DestroyedUnits->To_Network_Format(); - player->DestroyedAircraft->To_Network_Format(); - player->DestroyedBuildings->To_Network_Format(); - - field_player_infantry_killed[3] = '1' + (char)house; - field_player_units_killed[3] = '1' + (char)house; - field_player_planes_killed[3] = '1' + (char)house; - field_player_buildings_killed[3] = '1' + (char)house; - stats.Add_Field (field_player_infantry_killed, (void*) player->DestroyedInfantry->Get_All_Totals(), player->DestroyedInfantry->Get_Unit_Count()*4); - stats.Add_Field (field_player_units_killed, (void*) player->DestroyedUnits->Get_All_Totals(), player->DestroyedUnits->Get_Unit_Count()*4); - stats.Add_Field (field_player_planes_killed, (void*) player->DestroyedAircraft->Get_All_Totals(), player->DestroyedAircraft->Get_Unit_Count()*4); - stats.Add_Field (field_player_buildings_killed, (void*) player->DestroyedBuildings->Get_All_Totals(), player->DestroyedBuildings->Get_Unit_Count()*4); - - - /* - ** Number and type of enemy buildings captured - */ - field_player_buildings_captured[3] = '1' + (char)house; - player->CapturedBuildings->To_Network_Format(); - stats.Add_Field (field_player_buildings_captured, (void*) player->CapturedBuildings->Get_All_Totals(), player->CapturedBuildings->Get_Unit_Count()*4); - - /* - ** Number of crates discovered and their contents - */ - field_player_crates_found[3] = '1' + (char)house; - player->TotalCrates->To_Network_Format(); - stats.Add_Field (field_player_crates_found, (void*) player->TotalCrates->Get_All_Totals(), player->TotalCrates->Get_Unit_Count()*4); - - /* - ** Amount of tiberium turned into credits - */ - field_player_harvested[3] = '1' + (char)house; - stats.Add_Field (field_player_harvested, (unsigned long) player->HarvestedCredits); - } - } - - CCDebugString ("C&C95 - Calling Create_Comms_Packet.\n"); - /* - ** Create the comms packet to be sent - */ - packet = stats.Create_Comms_Packet(packet_size); - CCDebugString ("C&C95 - Returned from Create_Comms_Packet.\n"); - - /* - ** If a player disconnected then dont send the packet at this time - save it for later - */ - if (completion == COMPLETION_PLAYER_1_WON_BY_DISCONNECTION - || completion == COMPLETION_PLAYER_2_WON_BY_DISCONNECTION){ - PacketLater = packet; - CCDebugString ("C&C95 - Flagging to send the packet later.\n"); - return; - } - - }else{ //else for if (!PacketLater) - - CCDebugString ("C&C95 - PacketLater is true.\n"); - - /* - ** Send the packet we calculated earlier when the disconnect occurred - */ - packet = PacketLater; - PacketLater = NULL; - } - - /* - ** Send it..... - */ - int times = 100; //100 times max - CountDownTimerClass send_timer; - - CCDebugString ("C&C95 - About to send stats packet to DDE server.\n"); - while ( ! Send_Data_To_DDE_Server ((char*)packet, packet_size, DDEServerClass::DDE_PACKET_GAME_RESULTS)){ - CCDebugString ("C&C95 - Stats packet send failed.\n"); - send_timer.Set (60, true); - while (send_timer.Time()){}; - } - - - /* - ** Save it to disk as well so I can see it - */ -#if (0) - RawFileClass anotherfile ("packet.net"); - anotherfile.Write(packet, packet_size); -#endif //(0) - /* - ** Tidy up - */ - CCDebugString ("C&C95 - About to delete packet memory.\n"); - delete [] packet; - - GameStatisticsPacketSent = true; - CCDebugString ("C&C95 - Returning from Send_Statistics_Packet.\n"); -#endif //DEMO -#endif -} - - - - - - - - - -void Register_Game_Start_Time(void) -{ - - GameTimer.Set (0, true); - GameTimerInUse = true; -} - - -extern void Register_Game_End_Time(void) -{ - GameEndTime = GameTimer.Time(); - GameTimerInUse = false; -} - diff --git a/code/TIBERIANDAWN/SUPER.CPP b/code/TIBERIANDAWN/SUPER.CPP deleted file mode 100644 index df0eb58..0000000 --- a/code/TIBERIANDAWN/SUPER.CPP +++ /dev/null @@ -1,383 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\super.cpv 1.5 16 Oct 1995 16:49:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SUPER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 07/28/95 * - * * - * Last Update : July 29, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * SuperClass::AI -- Process the super weapon AI. * - * SuperClass::Anim_Stage -- Fetches the animation stage for this super weapon. * - * SuperClass::Discharged -- Handles discharged action for special super weapon. * - * SuperClass::Enable -- Enable this super special weapon. * - * SuperClass::Forced_Charge -- Force the super weapon to full charge state. * - * SuperClass::Impatient_Click -- Called when player clicks on unfinished super weapon. * - * SuperClass::Recharge -- Starts the special super weapon recharging. * - * SuperClass::Remove -- Removes super weapon availability. * - * SuperClass::SuperClass -- Constructor for special super weapon objects. * - * SuperClass::Suspend -- Suspend the charging of the super weapon. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * SuperClass::SuperClass -- Constructor for special super weapon objects. * - * * - * This is the constructor for the super weapons. * - * * - * INPUT: recharge -- The recharge delay time (in game frames). * - * * - * charging -- Voice to announce that the weapon is charging. * - * * - * ready -- Voice to announce that the weapon is fully charged. * - * * - * impatient -- Voice to announce current charging state. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -SuperClass::SuperClass(int recharge, VoxType ready, VoxType charging, VoxType impatient, VoxType suspend) -{ - IsPresent = false; - IsOneTime = false; - IsReady = false; - IsSuspended = false; - OldStage = -1; - Control = 0; - RechargeTime = recharge; - SuspendTime = 0; - VoxRecharge = ready; - VoxCharging = charging; - VoxImpatient = impatient; - VoxSuspend = suspend; -} - - -/*********************************************************************************************** - * SuperClass::Suspend -- Suspend the charging of the super weapon. * - * * - * This will temporarily put on hold the charging of the special weapon. This might be the * - * result of insufficient power. * - * * - * INPUT: on -- Should the weapon charging be suspended? Else, it will unsuspend. * - * * - * OUTPUT: Was the weapon suspend state changed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -bool SuperClass::Suspend(bool on) -{ - if (IsPresent && !IsReady && !IsOneTime) { - if (on != IsSuspended) { - if (on) { - SuspendTime = Control; - } else { - Control = SuspendTime; - } - IsSuspended = on; - return(true); - } - } - return(false); -} - - -/*********************************************************************************************** - * SuperClass::Enable -- Enable this super special weapon. * - * * - * This routine is called when the special weapon needs to be activated. This is used for * - * both the normal super weapons and the speicial one-time super weapons (from crates). * - * * - * INPUT: onetime -- Is this a special one time super weapon? * - * * - * player -- Is this weapon for the player? If true, then there might be a voice * - * announcement of this weapon's availability. * - * * - * quiet -- Request that the weapon start in suspended state (quiet mode). * - * * - * OUTPUT: Was the special super weapon enabled? Failure might indicate that the weapon was * - * already available. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -bool SuperClass::Enable(bool onetime, bool player, bool quiet) -{ - if (!IsPresent) { - IsPresent = true; - IsOneTime = onetime; - bool retval = Recharge(player && !quiet); - if (quiet) Suspend(true); - return(retval); - } - return(false); -} - - -/*********************************************************************************************** - * SuperClass::Remove -- Removes super weapon availability. * - * * - * Call this routine when the super weapon should be removed because of some outside * - * force. For one time special super weapons, they can never be removed except as the * - * result of discharging them. * - * * - * INPUT: none * - * * - * OUTPUT: Was the special weapon removed and disabled? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -bool SuperClass::Remove(bool forced) -{ - if (IsPresent && (!IsOneTime || forced)) { - IsReady = false; - IsPresent = false; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * SuperClass::Recharge -- Starts the special super weapon recharging. * - * * - * This routine is called when the special weapon is allowed to recharge. Suspension will * - * be disabled and the animation process will begin. * - * * - * INPUT: player -- Is this for a player owned super weapon? If so, then a voice * - * announcement might be in order. * - * * - * OUTPUT: Was the super weapon begun charging up? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -bool SuperClass::Recharge(bool player) -{ - if (IsPresent && !IsReady) { - IsSuspended = false; - OldStage = -1; -#ifdef CHEAT_KEYS - if (Special.IsSpeedBuild) { - Control = 1; - } else { - Control = RechargeTime; - } -#else - Control = RechargeTime; -#endif - if (player && VoxCharging != VOX_NONE) { - Speak(VoxCharging); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * Superclass::Discharged -- Handles discharged action for special super weapon. * - * * - * This routine should be called when the special super weapon has been discharged. The * - * weapon will either begin charging anew or will be removed entirely -- depends on the * - * one time flag for the weapon. * - * * - * INPUT: player -- Is this special weapon for the player? If so, then there might be a * - * voice announcement. * - * * - * OUTPUT: Should the sidebar be reprocessed because the special weapon has been eliminated? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -bool SuperClass::Discharged(bool player) -{ - if (!IsSuspended && IsPresent && IsReady) { - IsReady = false; - if (IsOneTime) { - IsOneTime = false; - return(Remove()); - } else { - Recharge(player); - } - } - return(false); -} - - -/*********************************************************************************************** - * SuperClass::AI -- Process the super weapon AI. * - * * - * This routine will process the charge up AI for this super weapon object. If the weapon * - * has advanced far enough to change any sidebar graphic that might represent it, then * - * "true" will be returned. Use this return value to intelligenly update the sidebar. * - * * - * INPUT: player -- Is this for the player? If it is and the weapon is now fully charged, * - * then this fully charged state will be announced to the player. * - * * - * OUTPUT: Was the weapon's state changed such that a sidebar graphic update will be * - * necessary? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -bool SuperClass::AI(bool player) -{ - if (IsPresent && !IsReady) { - if (IsSuspended) { - if (OldStage != -1) { - OldStage = -1; - return(true); - } - } else { - if (Control.Expired()) { - IsReady = true; - if (player && VoxRecharge != VOX_NONE) { - Speak(VoxRecharge); - } - return(true); - } else { - if (Anim_Stage() != OldStage) { - OldStage = Anim_Stage(); - return(true); - } - } - } - } - return(false); -} - - -/*********************************************************************************************** - * SuperClass::Anim_Stage -- Fetches the animation stage for this super weapon. * - * * - * This will return the current animation stage for this super weapon. The value will be * - * between zero (uncharged) to ANIMATION_STAGES (fully charged). Use this value to render * - * the appropriate graphic on the sidebar. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current animation stage for this special super weapon powerup. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -int SuperClass::Anim_Stage(void) const -{ - if (IsPresent) { - if (IsReady) { - return(ANIMATION_STAGES); - } - int time = Control.Time(); - if (IsSuspended) { - time = SuspendTime; - } - - return(Fixed_To_Cardinal(ANIMATION_STAGES, Cardinal_To_Fixed(RechargeTime, RechargeTime-time))); - } - return(0); -} - - -/*********************************************************************************************** - * SuperClass::Impatient_Click -- Called when player clicks on unfinished super weapon. * - * * - * This routine is called when the player clicks on the super weapon icon on the sidebar * - * when the super weapon is not ready yet. This results in a voice message feedback to the * - * player. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/28/1995 JLB : Created. * - *=============================================================================================*/ -void SuperClass::Impatient_Click(void) const -{ - if (IsSuspended) { - if (VoxSuspend != VOX_NONE) { - Speak(VoxSuspend); - } - } else { - if (VoxImpatient != VOX_NONE) { - Speak(VoxImpatient); - } - } -} - - -/*********************************************************************************************** - * SuperClass::Forced_Charge -- Force the super weapon to full charge state. * - * * - * This routine will force the special weapon to full charge state. Call it when the weapon * - * needs to be instantly charged. The airstrike (when it first becomes available) is a * - * good example. * - * * - * INPUT: player -- Is this for the player? If true, then the full charge state will be * - * announced. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void SuperClass::Forced_Charge(bool player) -{ - if (IsPresent) { - IsReady = true; - IsSuspended = false; - if (player && VoxRecharge != VOX_NONE) { - Speak(VoxRecharge); - } - } -} diff --git a/code/TIBERIANDAWN/SUPER.H b/code/TIBERIANDAWN/SUPER.H deleted file mode 100644 index 2500222..0000000 --- a/code/TIBERIANDAWN/SUPER.H +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\super.h_v 1.5 16 Oct 1995 16:47:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : SUPER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 07/28/95 * - * * - * Last Update : July 28, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SUPER_H -#define SUPER_H - -#include "ftimer.h" - -class SuperClass { - public: - SuperClass(int recharge=0, VoxType charging=VOX_NONE, VoxType ready=VOX_NONE, VoxType impatient=VOX_NONE, VoxType suspend=VOX_NONE); - - bool Suspend(bool on); - bool Enable(bool onetime = false, bool player=false, bool quiet=false); - void Forced_Charge(bool player=false); - bool AI(bool player=false); - bool Remove(bool forced=false); - void Impatient_Click(void) const; - int Anim_Stage(void) const; - bool Discharged(bool player); - bool Is_Ready(void) const {return(IsReady);}; - bool Is_Present(void) const {return(IsPresent);}; - bool Is_One_Time(void) const {return(IsOneTime && IsPresent);}; - - //Needed access to recharge times for tooltips - 2019/08/14 Jason Scott - int Get_Recharge_Time() const { return(RechargeTime); }; - - private: - bool Recharge(bool player=false); - - unsigned IsPresent:1; - unsigned IsOneTime:1; - unsigned IsReady:1; - unsigned IsSuspended:1; - - TCountDownTimerClass Control; - int OldStage; - int SuspendTime; - - VoxType VoxRecharge; - VoxType VoxCharging; - VoxType VoxImpatient; - VoxType VoxSuspend; - int RechargeTime; - - //Needed to make ANIMATION_STAGES public so the animation frame numbers could be turned into progress - //percentages - 2019/08/07 Jason Scott -public: - enum { - ANIMATION_STAGES=102 - }; -}; - - - -#endif diff --git a/code/TIBERIANDAWN/SUPPORT.ASM b/code/TIBERIANDAWN/SUPPORT.ASM deleted file mode 100644 index fb131c4..0000000 --- a/code/TIBERIANDAWN/SUPPORT.ASM +++ /dev/null @@ -1,456 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -; $Header: F:\projects\c&c\vcs\code\support.asv 2.13 16 Oct 1995 16:52:36 JOE_BOSTIC $ -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : Command & Conquer * -;* * -;* File Name : SUPPORT.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : September 23, 1993 * -;* * -;* Last Update : May 10, 1994 [JLB] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* strtrim -- Remove the trailing white space from a string. * -;* Fat_Put_Pixel -- Draws a fat pixel. * -;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.* -;* Remove_From_List -- Removes a pointer from a list of pointers. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -INCLUDE "gbuffer.inc" - DISPLAY "Command & Conquer assembly support routines." - - CODESEG - - -;*************************************************************************** -;* strtrim -- Remove the trailing white space from a string. * -;* * -;* Use this routine to remove white space characters from the beginning * -;* and end of the string. The string is modified in place by * -;* this routine. * -;* * -;* INPUT: buffer -- Pointer to the string to modify. * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 10/07/1992 JLB : Created. * -;*=========================================================================* -; VOID cdecl strtrim(BYTE *buffer); - global C strtrim :NEAR - PROC strtrim C near - USES ax, edi, esi - - ARG buffer:DWORD ; Pointer to string to modify. - - cmp [buffer],0 - je short ??fini - - ; Prepare for string scanning by loading pointers. - cld - mov esi,[buffer] - mov edi,esi - - ; Strip white space from the start of the string. -??looper: - lodsb - cmp al,20h ; Space - je short ??looper - cmp al,9 ; TAB - je short ??looper - stosb - - ; Copy the rest of the string. -??gruntloop: - lodsb - stosb - or al,al - jnz short ??gruntloop - dec edi - ; Strip the white space from the end of the string. -??looper2: - mov [edi],al - dec edi - mov ah,[edi] - cmp ah,20h - je short ??looper2 - cmp ah,9 - je short ??looper2 - -??fini: - ret - - ENDP strtrim - - -;*************************************************************************** -;* Fat_Put_Pixel -- Draws a fat pixel. * -;* * -;* Use this routine to draw a "pixel" that is bigger than 1 pixel * -;* across. This routine is faster than drawing a similar small shape * -;* and faster than calling Fill_Rect. * -;* * -;* INPUT: x,y -- Screen coordinates to draw the pixel's upper * -;* left corner. * -;* * -;* color -- The color to render the pixel in. * -;* * -;* size -- The number of pixels width of the big "pixel". * -;* * -;* page -- The pointer to a GraphicBuffer class or something * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 03/17/1994 JLB : Created. * -;*=========================================================================* -; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page) - global C Fat_Put_Pixel:NEAR - PROC Fat_Put_Pixel C near - USES eax, ebx, ecx, edx, edi, esi - - ARG x:DWORD ; X coordinate of upper left pixel corner. - ARG y:DWORD ; Y coordinate of upper left pixel corner. - ARG color:DWORD ; Color to use for the "pixel". - ARG siz:DWORD ; Size of "pixel" to plot (square). - ARG gpage:DWORD ; graphic page address to plot onto - - cmp [siz],0 - je short ??exit - - ; Set EDI to point to start of logical page memory. - ;*=================================================================== - ; Get the viewport information and put bytes per row in ecx - ;*=================================================================== - mov ebx,[gpage] ; get a pointer to viewport - mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset - - ; Verify the the Y pixel offset is legal. - mov eax,[y] - cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX - jae short ??exit - mov ecx,[(GraphicViewPort ebx).GVPWidth] - add ecx,[(GraphicViewPort ebx).GVPXAdd] - add ecx,[(GraphicViewPort ebx).GVPPitch] - mul ecx - add edi,eax - - ; Verify the the X pixel offset is legal. - - mov edx,[(GraphicViewPort ebx).GVPWidth] - cmp edx,[x] - mov edx,ecx - jbe short ??exit - add edi,[x] - - ; Write the pixel to the screen. - mov ebx,[siz] ; Copy of pixel size. - sub edx,ebx ; Modulo to reach start of next row. - mov eax,[color] -??again: - mov ecx,ebx - rep stosb - add edi,edx ; EDI points to start of next row. - dec [siz] - jnz short ??again - -??exit: - ret - - ENDP Fat_Put_Pixel - - -;*************************************************************************** -;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. * -;* * -;* This routine is used to build a special fading table for C&C. There * -;* are certain colors that get faded to and cannot be faded again. * -;* With this rule, it is possible to draw a shadow multiple times and * -;* not have it get any lighter or darker. * -;* * -;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. * -;* * -;* dest -- Pointer to the 256 byte remap table. * -;* * -;* color -- Color index of the color to "fade to". * -;* * -;* frac -- The fraction to fade to the specified color * -;* * -;* OUTPUT: Returns with pointer to the remap table. * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 10/07/1992 JLB : Created. * -;*=========================================================================*/ -;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac); - global C Conquer_Build_Fading_Table : NEAR - PROC Conquer_Build_Fading_Table C near - USES ebx, ecx, edi, esi - - ARG palette:DWORD - ARG dest:DWORD - ARG color:DWORD - ARG frac:DWORD - - LOCAL matchvalue:DWORD ; Last recorded match value. - LOCAL targetred:BYTE ; Target gun red. - LOCAL targetgreen:BYTE ; Target gun green. - LOCAL targetblue:BYTE ; Target gun blue. - LOCAL idealred:BYTE - LOCAL idealgreen:BYTE - LOCAL idealblue:BYTE - LOCAL matchcolor:BYTE ; Tentative match color. - -ALLOWED_COUNT EQU 16 -ALLOWED_START EQU 256-ALLOWED_COUNT - - cld - - ; If the source palette is NULL, then just return with current fading table pointer. - cmp [palette],0 - je ??fini1 - cmp [dest],0 - je ??fini1 - - ; Fractions above 255 become 255. - mov eax,[frac] - cmp eax,0100h - jb short ??ok - mov [frac],0FFh -??ok: - - ; Record the target gun values. - mov esi,[palette] - mov ebx,[color] - add esi,ebx - add esi,ebx - add esi,ebx - lodsb - mov [targetred],al - lodsb - mov [targetgreen],al - lodsb - mov [targetblue],al - - ; Main loop. - xor ebx,ebx ; Remap table index. - - ; Transparent black never gets remapped. - mov edi,[dest] - mov [edi],bl - inc edi - - ; EBX = source palette logical number (1..255). - ; EDI = running pointer into dest remap table. -??mainloop: - inc ebx - mov esi,[palette] - add esi,ebx - add esi,ebx - add esi,ebx - - mov edx,[frac] - shr edx,1 - ; new = orig - ((orig-target) * fraction); - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetred] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl eax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealred],dh ; preserve ideal color gun value. - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetgreen] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl eax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealgreen],dh ; preserve ideal color gun value. - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetblue] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl eax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealblue],dh ; preserve ideal color gun value. - - ; Sweep through a limited set of existing colors to find the closest - ; matching color. - - mov eax,[color] - mov [matchcolor],al ; Default color (self). - mov [matchvalue],-1 ; Ridiculous match value init. - mov ecx,ALLOWED_COUNT - - mov esi,[palette] ; Pointer to original palette. - add esi,(ALLOWED_START)*3 - - ; BH = color index. - mov bh,ALLOWED_START -??innerloop: - - xor edx,edx ; Comparison value starts null. - - ; Build the comparison value based on the sum of the differences of the color - ; guns squared. - lodsb - sub al,[idealred] - mov ah,al - imul ah - add edx,eax - - lodsb - sub al,[idealgreen] - mov ah,al - imul ah - add edx,eax - - lodsb - sub al,[idealblue] - mov ah,al - imul ah - add edx,eax - jz short ??perfect ; If perfect match found then quit early. - - cmp edx,[matchvalue] - jae short ??notclose - mov [matchvalue],edx ; Record new possible color. - mov [matchcolor],bh -??notclose: - inc bh ; Checking color index. - loop ??innerloop - mov bh,[matchcolor] -??perfect: - mov [matchcolor],bh - xor bh,bh ; Make BX valid main index again. - - ; When the loop exits, we have found the closest match. - mov al,[matchcolor] - stosb - cmp ebx,ALLOWED_START-1 - jne ??mainloop - - ; Fill the remainder of the remap table with values - ; that will remap the color to itself. - mov ecx,ALLOWED_COUNT -??fillerloop: - inc bl - mov al,bl - stosb - loop ??fillerloop - -??fini1: - mov esi,[dest] - mov eax,esi - ret - - ENDP Conquer_Build_Fading_Table - - -;*************************************************************************** -;* Remove_From_List -- Removes a pointer from a list of pointers. * -;* * -;* This low level routine is used to remove a pointer from a list of * -;* pointers. The trailing pointers are moved downward to fill the * -;* hole. * -;* * -;* INPUT: list -- Pointer to list of pointer. * -;* * -;* index -- Pointer to length of pointer list. * -;* * -;* ptr -- The pointer value to search for and remove. * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 04/11/1994 JLB : Created. * -;* 04/22/1994 JLB : Convert to assembly language. * -;* 05/10/1994 JLB : Short pointers now. * -;*=========================================================================*/ -;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr); - global C Remove_From_List:NEAR - PROC Remove_From_List C near - USES edi, esi, ecx, eax - ARG list:DWORD ; Pointer to list. - ARG index:DWORD ; Pointer to count. - ARG element:DWORD ; Element to remove. - - ; Fetch the number of elements in the list. If there are no - ; elements, then just exit quickly. - mov edi,[index] - mov ecx,[edi] - jcxz short ??fini2 - - ; Fetch pointer to list. - cmp [list],0 - je short ??fini2 - mov edi,[list] - - ; Loop through all elements searching for a match. - mov eax,[element] - repne scasd - jne short ??fini2 ; No match found. - - ; Copy all remaining elements down. If this is the - ; last element in the list then nothing needs to be - ; copied -- just decrement the list size. - jcxz short ??nocopy ; No copy necessary. - mov esi,edi - sub edi,4 - rep movsd - - ; Reduce the list count by one. -??nocopy: - mov edi,[index] - dec [DWORD PTR edi] - -??fini2: - ret - - ENDP Remove_From_List - - -; long cdecl Get_EAX(); - global C Get_EAX :NEAR - PROC Get_EAX C near - ret - - ENDP Get_EAX - -;---------------------------------------------------------------------------- - - END diff --git a/code/TIBERIANDAWN/Shape.cpp b/code/TIBERIANDAWN/Shape.cpp deleted file mode 100644 index cca1b42..0000000 --- a/code/TIBERIANDAWN/Shape.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/* -** -** Replacement for Shape asm files -** -** ST - 12/19/2018 10:15AM -** -** -** -*/ - - -extern "C" unsigned char *_ShapeBuffer = 0; -extern "C" long _ShapeBufferSize = 0; - - - -/* -;*************************************************************************** -;* SET_SHAPE_BUFFER -- Sets the shape buffer to the given pointer * -;* * -;* This routine will set the shape buffer to the given value and make sure * -;* that the system does not try to compress any shapes that will be larger * -;* than the shape buffer. * -;* * -;* INPUT: void * - pointer to the shape buffer * -;* int - size of the buffer which has been passed in * -;* * -;* OUTPUT: none * -;* * -;* PROTO: VOID *Set_Shape_Bufer(void *buffer, int size); * -;* * -;* HISTORY: * -;* 10/26/1994 PWG : Created. * -;*=========================================================================* -*/ -extern "C" void __cdecl Set_Shape_Buffer(void const *buffer, int size) -{ - _ShapeBuffer = (unsigned char *)buffer; - _ShapeBufferSize = size; -} - - - -#if (0) -global C ShapeBuffer :dword -global C ShapeBufferSize :dword -global C _ShapeBuffer :dword -global C _ShapeBufferSize :dword -global C Set_Shape_Buffer :near - -DATASEG -label ShapeBuffer dword -_ShapeBuffer dd 0 - -label ShapeBufferSize dword -_ShapeBufferSize dd 0 - -CODESEG - -;*************************************************************************** -;* SET_SHAPE_BUFFER -- Sets the shape buffer to the given pointer * -;* * -;* This routine will set the shape buffer to the given value and make sure * -;* that the system does not try to compress any shapes that will be larger * -;* than the shape buffer. * -;* * -;* INPUT: void * - pointer to the shape buffer * -;* int - size of the buffer which has been passed in * -;* * -;* OUTPUT: none * -;* * -;* PROTO: VOID *Set_Shape_Bufer(void *buffer, int size); * -;* * -;* HISTORY: * -;* 10/26/1994 PWG : Created. * -;*=========================================================================* -GLOBAL C Set_Shape_Buffer:NEAR - -PROC Set_Shape_Buffer C near - USES eax - - ARG buff:DWORD - ARG size:DWORD - - mov eax,[size] - mov [_ShapeBufferSize],eax - - mov eax,[buff] - mov [_ShapeBuffer],eax - ret - - ENDP Set_Shape_Buffer -END - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TAB.CPP b/code/TIBERIANDAWN/TAB.CPP deleted file mode 100644 index 7a0faf9..0000000 --- a/code/TIBERIANDAWN/TAB.CPP +++ /dev/null @@ -1,261 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\tab.cpv 2.18 16 Oct 1995 16:52:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TAB.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : August 25, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TabClass::AI -- Handles player I/O with the tab buttons. * - * TabClass::Draw_It -- Displays the tab buttons as necessary. * - * TabClass::Set_Active -- Activates a "filefolder tab" button. * - * TabClass::TabClass -- Default construct for the tab button class. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -void const * TabClass::TabShape = NULL; - - -/*********************************************************************************************** - * TabClass::TabClass -- Default construct for the tab button class. * - * * - * The default constructor merely sets the tab buttons to default non-selected state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ -TabClass::TabClass(void) -{ - IsToRedraw = false; -// Select = -1; -} - - -/*********************************************************************************************** - * TabClass::Draw_It -- Displays the tab buttons as necessary. * - * * - * This routine is called whenever the display is being redrawn (in some fashion). The * - * parameter can be used to force the tab buttons to redraw completely. The default action * - * is to only redraw if the tab buttons have been explicitly flagged to be redraw. The * - * result of this is the elimination of unnecessary redraws. * - * * - * INPUT: complete -- bool; Force redraw of the entire tab button graphics? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - * 05/19/1995 JLB : New EVA style. * - *=============================================================================================*/ -void TabClass::Draw_It(bool complete) -{ - - SidebarClass::Draw_It(complete); - - if (Debug_Map){ - //HidPage.Unlock(); - return; - } - -// Disable tab drawing. ST - 3/1/2019 11:35AM -#if 0 - /* - ** Redraw the top bar imagery if flagged to do so or if the entire display needs - ** to be redrawn. - */ - int width = SeenBuff.Get_Width(); - int rightx = width - 1; - - if (complete || IsToRedraw) { - - if (Tab_Height != 0) { - - - if (LogicPage->Lock()){ - - LogicPage->Fill_Rect(0, 0, rightx, Tab_Height-2, BLACK); - CC_Draw_Shape(TabShape, 0, 0, 0, WINDOW_MAIN, SHAPE_NORMAL); - CC_Draw_Shape(TabShape, 0, width-Eva_Width, 0, WINDOW_MAIN, SHAPE_NORMAL); - Draw_Credits_Tab(); - LogicPage->Draw_Line(0, Tab_Height-1, rightx, Tab_Height-1, BLACK); - - Fancy_Text_Print(TXT_TAB_BUTTON_CONTROLS, Eva_Width/2, 0, 11, TBLACK, TPF_GREEN12_GRAD|TPF_CENTER | TPF_USE_GRAD_PAL); - Fancy_Text_Print(TXT_TAB_SIDEBAR, width-(Eva_Width/2), 0, 11, TBLACK, TPF_GREEN12_GRAD|TPF_CENTER | TPF_USE_GRAD_PAL); - } - LogicPage->Unlock(); - - - } - - } - - Credits.Graphic_Logic(complete || IsToRedraw); -#endif - IsToRedraw = false; -} - - -void TabClass::Draw_Credits_Tab(void) -{ - CC_Draw_Shape(TabShape, 0, 320, 0, WINDOW_MAIN, SHAPE_NORMAL); -} - - -/*********************************************************************************************** - * TC::Hilite_Tab -- Draw a tab in its depressed state * - * * - * * - * * - * INPUT: Tab to draw (not used) * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/21/96 10:47AM ST : Created * - *=============================================================================================*/ - -void TabClass::Hilite_Tab(int tab) -{ - int xpos = 0; - int text = TXT_TAB_BUTTON_CONTROLS; - tab = tab; - - CC_Draw_Shape(TabShape, 1 , xpos, 0, WINDOW_MAIN, SHAPE_NORMAL); - Fancy_Text_Print(TXT_TAB_BUTTON_CONTROLS, 80, 0, 11, TBLACK, TPF_GREEN12|TPF_CENTER | TPF_USE_GRAD_PAL); -} - - -/*********************************************************************************************** - * TabClass::AI -- Handles player I/O with the tab buttons. * - * * - * This routine is called every game tick and passed whatever key the player has supplied. * - * If the input selects a tab button, then the graphic gets updated accordingly. * - * * - * INPUT: input -- The player's input character (might be mouse click). * - * * - * x,y -- Mouse coordinates at time of input. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - * 12/31/1994 JLB : Uses mouse coordinate parameters. * - * 05/31/1995 JLB : Fixed to handle mouse shape properly. * - * 08/25/1995 JLB : Handles new scrolling option. * - *=============================================================================================*/ -void TabClass::AI(KeyNumType &input, int x, int y) -{ - if (y >= 0 && y < Tab_Height && x < (SeenBuff.Get_Width() - 1) && x > 0) { - - bool ok = false; - int width = SeenBuff.Get_Width(); - - /* - ** If the mouse is at the top of the screen, then the tab bars only work - ** in certain areas. If the special scroll modification is not active, then - ** the tabs never work when the mouse is at the top of the screen. - */ - if (y > 0 || (Special.IsScrollMod && ((x > 3 && x < Eva_Width) || (x < width-3 && x > width-Eva_Width)))) { - ok = true; - } - - if (ok) { - if (input == KN_LMOUSE) { - int sel = -1; - if (x < Eva_Width) sel = 0; - if (x > width-Eva_Width) sel = 1; - if (sel >= 0) { - Set_Active(sel); - input = KN_NONE; - } - } - - Override_Mouse_Shape(MOUSE_NORMAL, false); - } - } - - Credits.AI(); - - SidebarClass::AI(input, x, y); -} - - -/*********************************************************************************************** - * TabClass::Set_Active -- Activates a "filefolder tab" button. * - * * - * This function is used to activate one of the file folder tab buttons that appear at the * - * top edge of the screen. * - * * - * INPUT: select -- The button to activate. 0 = left button, 1=next button, etc. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/15/1994 JLB : Created. * - *=============================================================================================*/ - void TabClass::Set_Active(int select) -{ - switch (select) { - case 0: - Queue_Options(); - break; - - case 1: - Map.SidebarClass::Activate(-1); - break; - - default: - break; - } -} - -void TabClass::One_Time(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - Eva_Width = 80 * factor; - //Tab_Height = 8 * factor; - Tab_Height = 0; // Disable tab drawing. ST - 3/1/2019 11:35AM - - SidebarClass::One_Time(); - TabShape = Hires_Retrieve("TABS.SHP"); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/TAB.H b/code/TIBERIANDAWN/TAB.H deleted file mode 100644 index d18461f..0000000 --- a/code/TIBERIANDAWN/TAB.H +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\tab.h_v 2.18 16 Oct 1995 16:45:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TAB.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/15/94 * - * * - * Last Update : December 15, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TAB_H -#define TAB_H - -#include "sidebar.h" -#include "credits.h" - -class TabClass: public SidebarClass -{ - public: - TabClass(void); - - virtual void AI(KeyNumType &input, int x, int y); - virtual void Draw_It(bool complete=false); - - virtual void One_Time(void); // One-time inits - static void Draw_Credits_Tab(void); - static void Hilite_Tab(int tab); - void Redraw_Tab(void) {IsToRedraw = true;Flag_To_Redraw(false);}; - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - inline int Get_Tab_Height(void) { return(Tab_Height); }; - - CreditClass Credits; - - protected: - - /* - ** If the tab graphic is to be redrawn, then this flag is true. - */ - unsigned IsToRedraw:1; - int Eva_Width; - int Tab_Height; - - private: - void Set_Active(int select); - - static void const * TabShape; -}; - - -#endif diff --git a/code/TIBERIANDAWN/TARCOM.CPP b/code/TIBERIANDAWN/TARCOM.CPP deleted file mode 100644 index 1897605..0000000 --- a/code/TIBERIANDAWN/TARCOM.CPP +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\tarcom.cpv 2.17 16 Oct 1995 16:52:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TARCOM.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 16, 1994 * - * * - * Last Update : July 19, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TarComClass::Debug_Dump -- Displays the status of the tarcom class to the mono screen. * - * TarComClass::AI -- Handles the logical AI for the tarcom class. * - * TarComClass::~TarComClass -- Destructor for turret object. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * TarComClass::~TarComClass -- Destructor for turret object. * - * * - * This is the destructor for turret objects. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1995 JLB : Created. * - *=============================================================================================*/ -TarComClass::~TarComClass(void) -{ -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * TarComClass::Debug_Dump -- Displays the status of the tarcom class to the mono screen. * - * * - * This routine is used to display the tarcom class status to the monochrome monitor. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void TarComClass::Debug_Dump(MonoClass *mono) const -{ - TurretClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * TarComClass::AI -- Handles the logical AI for the tarcom class. * - * * - * This handles the AI logic for the targeting computer. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void TarComClass::AI(void) -{ - TurretClass::AI(); - - if (Class->Primary != WEAPON_NONE) { - - /* - ** Determine which weapon can fire. First check for the primary weapon. If that weapon - ** cannot fire, then check any secondary weapon. If neither weapon can fire, then the - ** failure code returned is that from the primary weapon. - */ - WeaponTypeClass const * weapon = &Weapons[Class->Primary]; - int primary = 0; - FireErrorType ok = Can_Fire(TarCom, 0); - if (ok != FIRE_OK) { - if (Can_Fire(TarCom, 1) == FIRE_OK) { - ok = FIRE_OK; - primary = 1; - weapon = &Weapons[Class->Secondary]; - } - } - - switch (ok) { - case FIRE_OK: - if (What_Am_I() != RTTI_UNIT) { - IsFiring = false; - } else { - if (!((UnitClass *)this)->Class->IsFireAnim) { - IsFiring = false; - } - } - - if (TurretClass::Fire_At(TarCom, primary)) { - Sound_Effect(weapon->Sound, Coord); - } - break; - - case FIRE_FACING: - if (Class->IsLockTurret) { - if (!Target_Legal(NavCom) && !IsDriving) { - PrimaryFacing.Set_Desired(Direction(TarCom)); - SecondaryFacing.Set_Desired(PrimaryFacing.Desired()); - } - } else { - if (*this == UNIT_FTANK) { - SecondaryFacing.Set_Desired(Facing_Dir(Dir_Facing(Direction(TarCom)))); - } else { - SecondaryFacing.Set_Desired(Direction(TarCom)); - } -// SecondaryFacing.Set_Desired(Direction256(Center_Coord(), As_Coord(TarCom))); - } - break; - - case FIRE_CLOAKED: - IsFiring = false; - Do_Uncloak(); - break; - } - } - - if (Target_Legal(TarCom) && !IsRotating) { - DirType dir = Direction(TarCom); - - if (Class->IsTurretEquipped) { - SecondaryFacing.Set_Desired(dir); - } else { - - /* - ** Non turret equipped vehicles will rotate their body to face the target only - ** if the vehicle isn't currently moving or facing the correct direction. This - ** applies only to tracked vehicles. Wheeled vehicles never rotate to face the - ** target, since they aren't maneuverable enough. - */ - if ((Class->Speed == SPEED_TRACK || *this == UNIT_BIKE) && !Target_Legal(NavCom) && !IsDriving && PrimaryFacing.Difference(dir)) { - if (*this == UNIT_FTANK) { - PrimaryFacing.Set_Desired(Facing_Dir(Dir_Facing(dir))); - } else { - PrimaryFacing.Set_Desired(dir); - } - } - } - } -} - - diff --git a/code/TIBERIANDAWN/TARCOM.H b/code/TIBERIANDAWN/TARCOM.H deleted file mode 100644 index 6906a31..0000000 --- a/code/TIBERIANDAWN/TARCOM.H +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\tarcom.h_v 2.16 16 Oct 1995 16:45:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TARCOM.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 23, 1994 * - * * - * Last Update : April 23, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TARCOM_H -#define TARCOM_H - -#include "turret.h" -#include "bullet.h" - -/**************************************************************************** -** Units that can perform combat are handled by this class. It performs -** such operations as determining threat value down to actually launching the -** projectile. -*/ -class TarComClass : public TurretClass -{ - public: - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - TarComClass(void) {}; - TarComClass(UnitType classid, HousesType house) : TurretClass(classid, house) {}; - virtual ~TarComClass(void); - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - virtual void AI(void); -// virtual bool Target_Something_Nearby(ThreatType rangmatters=THREAT_NORMAL); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - -}; - -#endif - - diff --git a/code/TIBERIANDAWN/TARGET.CPP b/code/TIBERIANDAWN/TARGET.CPP deleted file mode 100644 index 0e8170c..0000000 --- a/code/TIBERIANDAWN/TARGET.CPP +++ /dev/null @@ -1,529 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\target.cpv 2.17 16 Oct 1995 16:51:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TARGET.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : August 27, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * As_Aircraft -- Converts the target value into an aircraft pointer. * - * As_Animation -- Converts target value into animation pointer. * - * As_Building -- Converts a target value into a building object pointer. * - * As_Bullet -- Converts the target into a bullet pointer. * - * As_Cell -- Converts a target value into a cell number. * - * As_Coord -- Converts a target value into a coordinate value. * - * As_Infantry -- If the target is infantry, return a pointer to it. * - * As_Movement_Coord -- Fetches coordinate if trying to move to this target. * - * As_Object -- Converts a target value into an object pointer. * - * As_Team -- Converts a target number into a team pointer. * - * As_TeamType -- Converts a target into a team type pointer. * - * As_Techno -- Converts a target value into a TechnoClass pointer. * - * As_Trigger -- Converts specified target into a trigger pointer. * - * As_Unit -- Converts a target value into a unit pointer. * - * Target_Legal -- Determines if the specified target is legal. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "target.h" - - -/*********************************************************************************************** - * As_Trigger -- Converts specified target into a trigger pointer. * - * * - * This routine will convert the specified target number into a trigger pointer. * - * * - * INPUT: target -- The target number to convert. * - * * - * OUTPUT: Returns with the trigger pointer that the specified target number represents. If * - * it doesn't represent a legal trigger object, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -TriggerClass * As_Trigger(TARGET target, bool check_active) -{ - TriggerClass* trigger = Is_Target_Trigger(target) ? Triggers.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && trigger != NULL && !trigger->IsActive) { - trigger = NULL; - } - return(trigger); -} - - -/*********************************************************************************************** - * As_Team -- Converts a target number into a team pointer. * - * * - * This routine will convert the specified target number into a team pointer. * - * * - * INPUT: target -- The target number to convert. * - * * - * OUTPUT: Returns with the team object that the specified target number represents. If it * - * doesn't represent a legal team then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -TeamClass * As_Team(TARGET target, bool check_active) -{ - TeamClass* team = Is_Target_Team(target) ? Teams.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && team != NULL && !team->IsActive) { - team = NULL; - } - return(team); -} - - -/*********************************************************************************************** - * As_TeamType -- Converts a target into a team type pointer. * - * * - * This routine will convert the specified target number into a team type pointer. * - * * - * INPUT: target -- The target number to convert. * - * * - * OUTPUT: Returns with a pointer to the team type represented by the target number. If the * - * target number doesn't represent a legal team type, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -TeamTypeClass * As_TeamType(TARGET target) -{ - return(Is_Target_TeamType(target) ? TeamTypes.Raw_Ptr(Target_Value(target)) : NULL); -} - - -/*********************************************************************************************** - * As_Animation -- Converts target value into animation pointer. * - * * - * This routine will convert the specified target number into an animation pointer. * - * * - * INPUT: target -- The target number to convert into an animation pointer. * - * * - * OUTPUT: Returns with a pointer to the legal animation that this target represents. If it * - * doesn't represent a legal animation, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -AnimClass * As_Animation(TARGET target, bool check_active) -{ - AnimClass* anim = Is_Target_Animation(target) ? Anims.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && anim != NULL && !anim->IsActive) { - anim = NULL; - } - return(anim); -} - - -/*********************************************************************************************** - * As_Bullet -- Converts the target into a bullet pointer. * - * * - * This routine will convert the specified target number into a bullet pointer. * - * * - * INPUT: target -- The target number to convert. * - * * - * OUTPUT: Returns with a pointer to the bullet it specifies. If the target doesn't refer to * - * a legal bullet, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -BulletClass * As_Bullet(TARGET target, bool check_active) -{ - BulletClass* bullet = Is_Target_Bullet(target) ? Bullets.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && bullet != NULL && !bullet->IsActive) { - bullet = NULL; - } - return(bullet); -} - - -/*********************************************************************************************** - * As_Aircraft -- Converts the target value into an aircraft pointer. * - * * - * This routine will convert the specified target value into an aircraft object pointer. * - * * - * INPUT: target -- The target value to convert. * - * * - * OUTPUT: Returns with a pointer to the aircraft that this target value represents. If the * - * specified target value doesn't represent an aircraft, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -AircraftClass * As_Aircraft(TARGET target, bool check_active) -{ - AircraftClass* aircraft = Is_Target_Aircraft(target) ? Aircraft.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && aircraft != NULL && !aircraft->IsActive) { - aircraft = NULL; - } - return(aircraft); -} - - -/*********************************************************************************************** - * As_Techno -- Converts a target value into a TechnoClass pointer. * - * * - * This routine will take the target value specified and convert it into a TechnoClass * - * pointer if the target represents an object that has a TechnoClass. * - * * - * INPUT: target -- The target value to convert into a TechnoClass pointer. * - * * - * OUTPUT: Returns with a pointer to the associated object's TechnoClass. If the target * - * cannot be converted into a TechnoClass pointer, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -TechnoClass * As_Techno(TARGET target, bool check_active) -{ - ObjectClass * obj = As_Object(target, check_active); - - if (obj && obj->Is_Techno()) { - return(TechnoClass *)obj; - } - return(NULL); -} - - -/*********************************************************************************************** - * As_Object -- Converts a target value into an object pointer. * - * * - * This routine is used to convert the target value specified into an object pointer. If * - * the target doesn't represent an object or the target value is illegal, then NULL is * - * returned. * - * * - * INPUT: target -- The target value to convert from. * - * check_active -- Check if the target is active, return NULL if not. * - * * - * OUTPUT: Returns with a pointer to the object it represent, or NULL if not an object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * As_Object(TARGET target, bool check_active) -{ - int val = Target_Value(target); - ObjectClass * object = NULL; - - switch (Target_Kind(target)) { - case KIND_INFANTRY: - object = Infantry.Raw_Ptr(val); - break; - - case KIND_UNIT: - object = Units.Raw_Ptr(val); - break; - - case KIND_BUILDING: - object = Buildings.Raw_Ptr(val); - break; - - case KIND_AIRCRAFT: - object = Aircraft.Raw_Ptr(val); - break; - - case KIND_TERRAIN: - object = Terrains.Raw_Ptr(val); - break; - - case KIND_BULLET: - object = Bullets.Raw_Ptr(val); - break; - - case KIND_ANIMATION: - object = Anims.Raw_Ptr(val); - break; - - default: - break; - } - - /* - ** Special check to ensure that a target value that references an - ** invalid object will not be converted back into an object pointer. - ** This condition is rare, but could occur in a network game if the - ** object it refers to is destroyed between the time an event message - ** is sent and when it is received. - */ - if (check_active && object != NULL && !object->IsActive) { - object = NULL; - } - - return(object); -} - - -/*********************************************************************************************** - * As_Unit -- Converts a target value into a unit pointer. * - * * - * This routine is used to convert the target value specified into a pointer to a unit * - * object. * - * * - * INPUT: target -- The target value to convert into a unit pointer. * - * * - * OUTPUT: Returns with a pointer to the unit the target value represents or NULL if not * - * a unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -UnitClass * As_Unit(TARGET target, bool check_active) -{ - UnitClass* unit = Is_Target_Unit(target) ? Units.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && unit != NULL && !unit->IsActive) { - unit = NULL; - } - return(unit); -} - - -/*********************************************************************************************** - * As_Infantry -- If the target is infantry, return a pointer to it. * - * * - * This routine will translate the specified target value into an infantry pointer if the * - * target actually represents an infantry object. * - * * - * INPUT: target -- The target to convert to a pointer. * - * * - * OUTPUT: Returns a pointer to the infantry object that this target value represents. If * - * the target doesn't represent an infantry object, then return NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -InfantryClass * As_Infantry(TARGET target, bool check_active) -{ - InfantryClass* infantry = Is_Target_Infantry(target) ? Infantry.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && infantry != NULL && !infantry->IsActive) { - infantry = NULL; - } - return(infantry); -} - - -#ifdef NEVER -TerrainClass * As_Terrain(TARGET target) -{ - return(Is_Target_Terrain(target) ? &Terrains[Target_Value(target)] : NULL); -} -#endif - - -/*********************************************************************************************** - * As_Building -- Converts a target value into a building object pointer. * - * * - * This routine is used to convert the target value specified into a building pointer. * - * * - * INPUT: target -- The target value to convert from. * - * * - * OUTPUT: Returns with a pointer to the building object that the target value represents. * - * If it doesn't represent a building, then return NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -BuildingClass * As_Building(TARGET target, bool check_active) -{ - BuildingClass* building = Is_Target_Building(target) ? Buildings.Raw_Ptr(Target_Value(target)) : NULL; - if (check_active && building != NULL && !building->IsActive) { - building = NULL; - } - return(building); -} - - -/*********************************************************************************************** - * Target_Legal -- Determines if the specified target is legal. * - * * - * This routine is used to check for the legality of the target value specified. It is * - * necessary to call this routine if there is doubt about the the legality of the target. * - * It is possible for the unit that a target value represents to be eliminated and thus * - * rendering the target value invalid. * - * * - * INPUT: target -- The target value to check. * - * * - * OUTPUT: bool; Is the target value legal? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -bool Target_Legal(TARGET target) -{ - if (target == TARGET_NONE) return(false); - - ObjectClass * obj = As_Object(target, false); - if (obj) { - return(obj->IsActive); - } - return(true); -} - - -/*********************************************************************************************** - * As_Cell -- Converts a target value into a cell number. * - * * - * This routine is used to convert the target value specified, into a cell value. This is * - * necessary for find path and other procedures that need a cell value. * - * * - * INPUT: target -- The target value to convert to a cell value. * - * * - * OUTPUT: Returns with the target value expressed as a cell location. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - *=============================================================================================*/ -CELL As_Cell(TARGET target) -{ - return(Coord_Cell(As_Coord(target))); -} - - -/*********************************************************************************************** - * As_Coord -- Converts a target value into a coordinate value. * - * * - * This routine is used to convert the target value specified into a coordinate value. It * - * is necessary for those procedures that require a coordinate value. * - * * - * INPUT: target -- The target value to convert. * - * * - * OUTPUT: Returns with the target expressed as a COORD value. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/27/1994 JLB : Created. * - * 11/16/1994 JLB : Simplified. * - *=============================================================================================*/ -COORDINATE As_Coord(TARGET target) -{ - if (Target_Legal(target)) { - /* - ** Cell target values are handled as a special case. The value of the target number is - ** actually the cell index number. - */ - if (Is_Target_Cell(target)) { - return(Cell_Coord((CELL)Target_Value(target))); - } - - /* - ** Normal targets correspond to game objects. Fetch the object pointer and then ask it - ** for the center coordinate. Return the center coordinate as the target's coordinate. - */ - ObjectClass * obj = As_Object(target); - if (obj) { - - /* - ** If this is invalid memory or the object is dead then return 0 - ** This is a kludge to fix the problem of team target objects being assigned after - ** the object is already destroyed - 1/15/97 3:13PM - */ - if (IsBadReadPtr ((void*)obj, sizeof (ObjectClass) ) || !obj->IsActive){ -//OutputDebugString ("C&C95 - As_Coord called for invalid target object\m"); - return(0x00000000L); - } - - return(obj->Target_Coord()); - } - } - - /* - ** An unrecognized target value results in a null coordinate value. - */ - return(0x00000000L); -} - - -/*********************************************************************************************** - * As_Movement_Coord -- Fetches coordinate if trying to move to this target. * - * * - * This routine will convert the specified target into a coordinate location. This location * - * is used when moving to the target specified. For cells, this is the center of the cell. * - * For special buildings that allow docking, it is the center location of the docking * - * bay. * - * * - * INPUT: target -- The target to convert into a coordinate value. * - * * - * OUTPUT: Returns with the docking coordinate of the target value specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE As_Movement_Coord(TARGET target) -{ - if (Target_Legal(target)) { - /* - ** Cell target values are handled as a special case. The value of the target number is - ** actually the cell index number. - */ - if (Is_Target_Cell(target)) { - return(Cell_Coord((CELL)Target_Value(target))); - } - - /* - ** Normal targets correspond to game objects. Fetch the object pointer and then ask it - ** for the center coordinate. Return the center coordinate as the target's coordinate. - */ - ObjectClass * obj = As_Object(target); - if (obj) { - return(obj->Docking_Coord()); - } - } - - /* - ** An unrecognized target value results in a null coordinate value. - */ - return(0x00000000L); -} diff --git a/code/TIBERIANDAWN/TARGET.H b/code/TIBERIANDAWN/TARGET.H deleted file mode 100644 index 3449943..0000000 --- a/code/TIBERIANDAWN/TARGET.H +++ /dev/null @@ -1,154 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\target.h_v 2.16 16 Oct 1995 16:45:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TARGET.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 25, 1994 * - * * - * Last Update : April 25, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TARGET_H -#define TARGET_H - -/************************************************************************** -** When a unit proceeds with carrying out its mission, it can have several -** intermediate goals. Each goal (or target if you will) can be one of the -** following kinds. -*/ -typedef enum KindType : unsigned char { - KIND_NONE, - KIND_CELL, - KIND_UNIT, - KIND_INFANTRY, - KIND_BUILDING, - KIND_TERRAIN, - KIND_AIRCRAFT, - KIND_TEMPLATE, - KIND_BULLET, - KIND_ANIMATION, - KIND_TRIGGER, - KIND_TEAM, - KIND_TEAMTYPE -} KindType; - - -#define TARGET_MANTISSA 12 // Bits of value precision. -#define TARGET_MANTISSA_MASK (~((~0)<>TARGET_EXPONENT)) - -inline KindType Target_Kind(TARGET a){return (KindType)(((unsigned)a)>>TARGET_MANTISSA);} -inline unsigned Target_Value(TARGET a){return (((unsigned)a) & TARGET_MANTISSA_MASK);} - -inline bool Is_Target_Team(TARGET a) {return (Target_Kind(a) == KIND_TEAM);} -inline bool Is_Target_TeamType(TARGET a) {return (Target_Kind(a) == KIND_TEAMTYPE);} -inline bool Is_Target_Trigger(TARGET a) {return (Target_Kind(a) == KIND_TRIGGER);} -inline bool Is_Target_Infantry(TARGET a) {return (Target_Kind(a) == KIND_INFANTRY);} -inline bool Is_Target_Bullet(TARGET a){return (Target_Kind(a) == KIND_BULLET);} -inline bool Is_Target_Terrain(TARGET a){return (Target_Kind(a) == KIND_TERRAIN);} -inline bool Is_Target_Cell(TARGET a){return (Target_Kind(a) == KIND_CELL);} -inline bool Is_Target_Unit(TARGET a){return (Target_Kind(a) == KIND_UNIT);} -inline bool Is_Target_Building(TARGET a){return (Target_Kind(a) == KIND_BUILDING);} -inline bool Is_Target_Template(TARGET a){return (Target_Kind(a) == KIND_TEMPLATE);} -inline bool Is_Target_Aircraft(TARGET a){return (Target_Kind(a) == KIND_AIRCRAFT);} -inline bool Is_Target_Animation(TARGET a) {return (Target_Kind(a) == KIND_ANIMATION);} - -inline TARGET Build_Target(KindType kind, int value) {return (TARGET)((((unsigned)kind) << TARGET_MANTISSA) | (unsigned)value);} -inline TARGET As_Target(CELL cell){return (TARGET)(((unsigned)KIND_CELL << TARGET_MANTISSA) | cell);} - -class UnitClass; -class BuildingClass; -class TechnoClass; -class TerrainClass; -class ObjectClass; -class InfantryClass; -class BulletClass; -class TriggerClass; -class TeamClass; -class TeamTypeClass; -class AnimClass; -class AircraftClass; - -#ifdef NEVER -class TargetClass -{ - public: - TargetClass(void) {Target.Raw = 0;}; - - /* - ** This handles assignment from an integer and conversion - ** to an integer. - */ - inline TargetClass(int val, KindType kind) {Target.Component.Value=val; Target.Component.Kind=kind;}; - inline TargetClass(int val) {Target.Raw = val;}; - inline operator int () {return Target.Raw;}; - //inline TargetClass & operator = (const int &val) {*((int*)this)=val; return *this;}; - - inline bool Is_Filled(void) {return Target.Component.Kind != KIND_NONE;}; - inline void Invalidate(void) {Target.Component.Kind = 0;}; - inline bool Is_Cell(void) {return Target.Component.Kind == KIND_CELL;}; - inline bool Is_Unit(void) {return Target.Component.Kind == KIND_UNIT;}; - inline bool Is_Building(void) {return Target.Component.Kind == KIND_BUILDING;}; - inline bool Is_Aircraft(void) {return Target.Component.Kind == KIND_AIRCRAFT;}; - inline int As_Value(void) {return Target.Component.Value;}; - inline KindType As_Kind(void) {return Target.Component.Kind;}; - - // Allows comparing one target to another (for equality). - inline bool operator == (TargetClass t1) { - return (Target.Raw == t1.Target.Raw); - }; - - UnitClass * As_Unit(void); - BuildingClass * As_Building(void); - bool Legal(void); - CELL As_Cell(void); - COORDINATE As_Coord(void); - int Distance(TechnoClass *base); - static int As_Target(UnitClass *unit); - static int As_Target(BuildingClass *building); - static int As_Target(CELL cell); - - private: - - /* - ** This is the special encoded target value. - */ - union { - struct { - unsigned Value:TARGET_MANTISSA; - KindType Kind:TARGET_EXPONENT; - } Component; - int Raw; - } Target; - - - static int Build(int value, KindType kind); -}; -#endif - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TCPIP.CPP b/code/TIBERIANDAWN/TCPIP.CPP deleted file mode 100644 index 0f97cfc..0000000 --- a/code/TIBERIANDAWN/TCPIP.CPP +++ /dev/null @@ -1,1002 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TCPIP.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : March 11th, 1996 * - * * - * Last Update : March 20th, 1996 [ST] * - * * - *-------------------------------------------------------------------------* - * Overview: * - * * - * Member functions of the TcpipManagerClass which provides the Winsock * - * interface for C&C * - * * - * * - *-------------------------------------------------------------------------* - * Functions: * - * * - * TMC::TcpipManagerClass -- constructor for the TcpipManagerClass * - * TMC::~TcpipManagerClass -- destructor for the TcpipManagerClass * - * TMC::Close -- restores any currently in use Winsock resources * - * TMC::Init -- Initialised Winsock for use. * - * TMC::Start_Server -- Initialise connection and start listening. * - * TMC::Read -- read any pending input from the stream socket * - * TMC::Write -- Send data via the Winsock streaming socket * - * TMC::Add_Client -- A client has requested to connect. * - * TMC::Message_Handler -- Message handler for Winsock. * - * TMC::Set_Host_Address -- Set the address of the host * - * TMC::Start_Client -- Start trying to connect to a game host * - * TMC::Close_Socket -- Close an opened Winsock socket. * - * TMC::Copy_To_In_Buffer -- copy data from our winsock buffer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "function.h" -#include "tcpip.h" - -#ifdef FORCE_WINSOCK - - -/* -** Nasty globals -*/ -bool Server; //Is this player acting as client or server -TcpipManagerClass Winsock; //The object for interfacing with Winsock - - - -/*********************************************************************************************** - * TMC::TcpipManagerClass -- constructor for the TcpipManagerClass * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 2:51PM ST : Created * - *=============================================================================================*/ -TcpipManagerClass::TcpipManagerClass(void) -{ - WinsockInitialised = FALSE; - Connected = FALSE; - UseUDP = TRUE; - SocketReceiveBuffer = 4096; - SocketSendBuffer = 4096; - -} - - -/*********************************************************************************************** - * TMC::~TcpipManagerClass -- destructor for the TcpipManagerClass * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 2:52PM ST : Created * - *=============================================================================================*/ - -TcpipManagerClass::~TcpipManagerClass(void) -{ - Close(); -} - - -/*********************************************************************************************** - * TMC::Close -- restores any currently in use Winsock resources * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 2:52PM ST : Created * - *=============================================================================================*/ - -void TcpipManagerClass::Close(void) -{ - /* - ** If we never initialised the class in the first place then just return - */ - if (!WinsockInitialised) return; - - /* - ** Cancel any outstaning asyncronous events - */ - if (Async){ - WSACancelAsyncRequest(Async); - } - - /* - ** Close any open sockets - */ - if (ConnectSocket != INVALID_SOCKET){ - Close_Socket(ConnectSocket); - ConnectSocket = INVALID_SOCKET; - } - - if (ListenSocket != INVALID_SOCKET){ - Close_Socket(ListenSocket); - ListenSocket = INVALID_SOCKET; - } - - if (UDPSocket != INVALID_SOCKET){ - Close_Socket(ListenSocket); - UDPSocket = INVALID_SOCKET; - } - - /* - ** Call the Winsock cleanup function to say we are finished using Winsock - */ - WSACleanup(); - - WinsockInitialised = FALSE; - Connected = FALSE; -} - - - -/*********************************************************************************************** - * TMC::Init -- Initialised Winsock for use. * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: TRUE if Winsock is available and was initialised * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 2:54PM ST : Created * - *=============================================================================================*/ - -BOOL TcpipManagerClass::Init(void) -{ - short version; - int rc; - - /* - ** Just return true if we are already set up - */ - if (WinsockInitialised) return (TRUE); - - /* - ** Initialise sockets to null - */ - ListenSocket = INVALID_SOCKET; - ConnectSocket =INVALID_SOCKET; - UDPSocket = INVALID_SOCKET; - - /* - ** Start WinSock, and fill in our WinSockData - */ - version = (WINSOCK_MINOR_VER << 8) | WINSOCK_MAJOR_VER; - rc = WSAStartup(version, &WinsockInfo); - if (rc != 0) { - return (FALSE); - } - - /* - ** Check the Winsock version number - */ - if ((WinsockInfo.wVersion & 0x00ff) != (version & 0x00ff) || - (WinsockInfo.wVersion >> 8) != (version >> 8)) { - return (FALSE); - } - - /* - ** Everything is OK so return success - */ - WinsockInitialised = TRUE; - return (TRUE); - -} - - - - -/*********************************************************************************************** - * TMC::Start_Server -- initialise out connection as the server. Start listening for clients. * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 2:56PM ST : Created * - *=============================================================================================*/ - -void TcpipManagerClass::Start_Server(void) -{ - int i; - //struct sockaddr_in addr; - - Start_Client(); - - /* - ** Set up the incoming and outgoing data buffers head and tail pointers - */ - //InBufferHead = 0; - //InBufferTail = 0; - //OutBufferHead= 0; - //OutBufferTail= 0; - - TXBufferHead = 0; - TXBufferTail = 0; - RXBufferHead = 0; - RXBufferTail = 0; - - for (i=0 ; ih_name); - } - Async = 0; - return; - - }else{ - /* - ** We are the client - */ - ConnectStatus = CONTACTING_SERVER; - if (WSAGETASYNCERROR(lParam)==0) { - hentry = (struct hostent *)&HostBuff[0]; - strcpy (Server.Name, hentry->h_name); - } - else { - Server.Name[0] = 0; - } - Async = 0; - return; - } - - - /* - ** Retrieve host by name: Start connecting now that we have the - ** address. - */ - case WM_HOSTBYNAME: - if (WSAGETASYNCERROR(lParam)==0) { - hentry = (struct hostent *)&HostBuff[0]; - memcpy (&(Server.Addr.s_addr), hentry->h_addr, 4); - memcpy(&UDPIPAddress, hentry->h_addr, 4); - strcpy (Server.DotAddr, inet_ntoa(Server.Addr)); - ConnectStatus = CONNECTED_OK; - Connected = TRUE; - } - else { - Server.Name[0] = 0; - strcpy (Server.DotAddr, "????"); - ConnectStatus = SERVER_ADDRESS_LOOKUP_FAILED; - } - Async = 0; - return; - - - /* - ** Connection is ready - accept the client - */ - case WM_ACCEPT: - rc = WSAGETSELECTERROR(lParam); - if (rc != 0) { - ConnectStatus = UNABLE_TO_ACCEPT_CLIENT; - return; - } - if (Add_Client()) { - ConnectStatus = CONNECTED_OK; - Connected = TRUE; - } - else { - ConnectStatus = UNABLE_TO_ACCEPT_CLIENT; - } - return; - - - - /* - ** Handle UDP packet events - */ - case WM_UDPASYNCEVENT: - event = WSAGETSELECTEVENT(lParam); - switch (event) { - - case FD_READ: - rc = WSAGETSELECTERROR(lParam); - if (rc != 0) { - Clear_Socket_Error(UDPSocket); - return; - } - addr_len = sizeof(addr); - rc = recvfrom(UDPSocket, ReceiveBuffer, WS_RECEIVE_BUFFER_LEN, 0, - (LPSOCKADDR)&addr, &addr_len); - if (rc == SOCKET_ERROR) { - Clear_Socket_Error(UDPSocket); - return; - } - memcpy(&UDPIPAddress, &addr.sin_addr.s_addr, 4); - Copy_To_In_Buffer(rc); - return; - - - case FD_WRITE: - if (UseUDP){ - rc = WSAGETSELECTERROR(lParam); - if (rc != 0) { - Clear_Socket_Error(UDPSocket); - return; - } - - addr.sin_family = AF_INET; - addr.sin_port = htons(PlanetWestwoodPortNumber); - memcpy (&addr.sin_addr.s_addr, &UDPIPAddress, 4); - - /* - ** Send as many bytes as there are in the buffer; if there's - ** an error, just bail out. If we get a WOULDBLOCK error, - ** WinSock will send us another message when the socket is - ** available for another write. - */ - while (TransmitBuffers[TXBufferTail].InUse){ - rc = sendto(UDPSocket, - TransmitBuffers[TXBufferTail].Buffer, - TransmitBuffers[TXBufferTail].DataLength, - 0, - (LPSOCKADDR)&addr, - sizeof (addr)); - - if (rc == SOCKET_ERROR){ - if (WSAGetLastError() != WSAEWOULDBLOCK) { - Clear_Socket_Error(UDPSocket); - } - break; - } - TransmitBuffers[TXBufferTail++].InUse = false; - TXBufferTail &= WS_NUM_TX_BUFFERS-1; - } - return; - } - } - - - - /* - ** Handle the asynchronous event callbacks - */ - case WM_ASYNCEVENT: - event = WSAGETSELECTEVENT(lParam); - switch (event) { - /* - ** FD_CLOSE: the client has gone away. Remove the client from our system. - */ - case FD_CLOSE: - rc = WSAGETSELECTERROR(lParam); - if (rc != 0 && rc != WSAECONNRESET) { - ConnectStatus = CONNECTION_LOST; - return; - } - if (Async != 0) { - WSACancelAsyncRequest(Async); - } - WSAAsyncSelect (ConnectSocket, MainWindow, WM_ASYNCEVENT, 0); - Close_Socket (ConnectSocket); - ConnectSocket = INVALID_SOCKET; - //Connected = FALSE; - ConnectStatus = CONNECTION_LOST; - break; -#if (0) - /* - ** FD_READ: Data is available on our socket. This message is sent every time - ** data becomes available so we only have to do one read - */ - case FD_READ: - if (!UseUDP){ - rc = WSAGETSELECTERROR(lParam); - if (rc != 0) { - return; - } - rc = recv(ConnectSocket, ReceiveBuffer, WS_RECEIVE_BUFFER_LEN, 0); - if (rc == SOCKET_ERROR) { - Clear_Socket_Error(ConnectSocket); - return; - } - Copy_To_In_Buffer(rc); - return; - } - - /* - ** FD_WRITE: The socket is available for writing. We may actually have sent this - ** message from elewhere in the class. - */ - case FD_WRITE: - rc = WSAGETSELECTERROR(lParam); - if (rc != 0) { - return; - } - /* - ** Send as many bytes as there are in the buffer; if there's - ** an error, just bail out. If we get a WOULDBLOCK error, - ** WinSock will send us another message when the socket is - ** available for another write. - */ - while (OutBufferHead > OutBufferTail){ - rc = send(ConnectSocket, OutBuffer + OutBufferTail, - OutBufferHead - OutBufferTail, 0); - if (rc == SOCKET_ERROR){ - if (WSAGetLastError() != WSAEWOULDBLOCK) { - Clear_Socket_Error(ConnectSocket); - } - break; - } - OutBufferTail+=rc; - } - if (OutBufferHead == OutBufferTail){ - OutBufferHead = OutBufferTail = 0; - } - return; -#endif //(0) - /* - ** FD_CONNECT: A connection was made, or an error occurred. - */ - case FD_CONNECT: - rc = WSAGETSELECTERROR(lParam); - if (rc != 0) { - ConnectStatus = UNABLE_TO_CONNECT; - return; - } - - ConnectStatus = CONNECTED_OK; - Connected = TRUE; - return; - - } - } -} - - - -/*********************************************************************************************** - * TMC::Copy_To_In_Buffer -- copy data from our winsock buffer to our internal buffer * - * * - * * - * * - * INPUT: bytes to copy * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 3:17PM ST : Created * - *=============================================================================================*/ -void TcpipManagerClass::Copy_To_In_Buffer(int bytes) -{ - if (!ReceiveBuffers[RXBufferHead].InUse){ - memcpy (ReceiveBuffers[RXBufferHead].Buffer, ReceiveBuffer, MIN(bytes, WS_INTERNET_BUFFER_LEN)); - ReceiveBuffers[RXBufferHead].InUse = true; - ReceiveBuffers[RXBufferHead++].DataLength = MIN(bytes, WS_INTERNET_BUFFER_LEN); - RXBufferHead &= WS_NUM_RX_BUFFERS-1; - } -} - - - -/*********************************************************************************************** - * TMC::Set_Host_Address -- Set the address of the host game we want to connect to * - * * - * * - * * - * INPUT: ptr to address string * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 3:19PM ST : Created * - *=============================================================================================*/ -void TcpipManagerClass::Set_Host_Address(char *address) -{ - strcpy(HostAddress, address); -} - - - -/*********************************************************************************************** - * TMC::Start_Client -- Start trying to connect to a game host * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 3/20/96 3:19PM ST : Created * - *=============================================================================================*/ - -void TcpipManagerClass::Start_Client(void) -{ - struct sockaddr_in addr; - bool delay = true; - int i; - - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - /* - ** Set up the incoming and outgoing data buffers head and tail pointers - */ -// InBufferHead = 0; -// InBufferTail = 0; -// OutBufferHead= 0; -// OutBufferTail= 0; - - TXBufferHead = 0; - TXBufferTail = 0; - RXBufferHead = 0; - RXBufferTail = 0; - - for (i=0 ; iIniName) == 0) { - return(index); - } - } - } - return(TERRAIN_NONE); -} - - -#ifdef SCENARIO_EDITOR -/*********************************************************************************************** - * TerrainTypeClass::Display -- Display a generic terrain object. * - * * - * This routine is used to display a generic terrain object. Typical * - * use is during scenario editing. * - * * - * INPUT: x,y -- Pixel coordinates to display object at (centered). * - * * - * window-- The window to display the object within. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/16/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainTypeClass::Display(int x, int y, WindowNumberType window, HousesType) const -{ - CC_Draw_Shape(Get_Image_Data(), 0, x, y, window, SHAPE_NORMAL|SHAPE_CENTER|SHAPE_WIN_REL); -} - - -/*********************************************************************************************** - * TerrainTypeClass::Prep_For_Add -- Prepares to add terrain object. * - * * - * Submits all of the valid terrain objects to the scenario editor for possible selection * - * and subsequent placement on the map. All terrain objects, that have a valid shape * - * file available, are added. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainTypeClass::Prep_For_Add(void) -{ - for (TerrainType index = TERRAIN_FIRST; index < TERRAIN_COUNT; index++) { - if (As_Reference(index).Get_Image_Data()) { - Map.Add_To_List(&As_Reference(index)); - } - } -} -#endif - - -/*********************************************************************************************** - * TerrainTypeClass::Create_And_Place -- Creates and places terrain object on map. * - * * - * This support routine is used by the scenario editor to add a terrain object to the map. * - * * - * INPUT: cell -- The cell to place the terrain object in. * - * * - * OUTPUT: bool; Was the placement successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -bool TerrainTypeClass::Create_And_Place(CELL cell, HousesType ) const -{ - if (new TerrainClass(Type, cell)) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TerrainTypeClass::Create_On_Of -- Creates a terrain object from type. * - * * - * This is used to create a terrain object by using the terrain type as a guide. This * - * routine is typically used by the scenario editor in order to place a terrain object * - * onto the map. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the created terrain object or NULL if one couldn't be * - * created. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/19/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * TerrainTypeClass::Create_One_Of(HouseClass *) const -{ - return(new TerrainClass(Type, -1)); -} - - -short const * TerrainTypeClass::Occupy_List(bool ) const -{ - if (Occupy) return(Occupy); - - static short const _simple[1] = { - REFRESH_EOL - }; - return(&_simple[0]); -} - - -short const * TerrainTypeClass::Overlap_List(void) const -{ - if (Overlap) return(Overlap); - - static short const _simple[1] = { - REFRESH_EOL - }; - return(&_simple[0]); -} diff --git a/code/TIBERIANDAWN/TEAM.CPP b/code/TIBERIANDAWN/TEAM.CPP deleted file mode 100644 index f14214f..0000000 --- a/code/TIBERIANDAWN/TEAM.CPP +++ /dev/null @@ -1,1509 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\team.cpv 2.18 16 Oct 1995 16:48:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEAM.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/11/94 * - * * - * Last Update : August 6, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Assign_Mission_Target -- Sets teams mission target and clears old target * - * TeamClass::Add -- Adds specified object to team. * - * TeamClass::AI -- Process team logic. * - * TeamClass::As_Target -- Converts this team object into a target number. * - * TeamClass::Calc_Center -- Determines average location of team members. * - * TeamClass::Control -- Updates control on a member unit. * - * TeamClass::Coordinate_Attack -- Handles coordinating a team attack. * - * TeamClass::Coordinate_Conscript -- Gives orders to new recruit. * - * TeamClass::Coordinate_Move -- Handles team movement coordination. * - * TeamClass::Coordinate_Regroup -- Handles team idling (regrouping). * - * TeamClass::Coordinate_Unload -- Tells the team to unload passengers now. * - * TeamClass::Detach -- Removes specified target from team tracking. * - * TeamClass::Init -- Initializes the team objects for scenario preparation. * - * TeamClass::Is_A_Member -- Tests if a unit is a member of a team * - * TeamClass::Recruit -- Attempts to recruit members to the team for the given index ID. * - * TeamClass::Remove -- Removes the specified object from the team. * - * TeamClass::Suspend_Teams -- Suspends activity for low priority teams * - * TeamClass::Took_Damage -- Informs the team when the team member takes damage. * - * TeamClass::Validate -- validates team pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "mission.h" - -/* -** This array records the number of teams in existance of each type. -*/ -unsigned char TeamClass::Number[TEAMTYPE_MAX]; - -/* -** This array records the success rating of each of the team types. -*/ -unsigned char TeamClass::Success[TEAMTYPE_MAX]; - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * TeamClass::VTable; - - -/*********************************************************************************************** - * TeamClass::Validate -- validates team pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int TeamClass::Validate(void) const -{ - int num; - - num = Teams.ID(this); - if (num < 0 || num >= TEAM_MAX) { - Validate_Error("TEAM"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * TeamClass::Init -- Initializes the team objects for scenario preparation. * - * * - * This routine clears out the team object array in preparation for starting a new * - * scenario. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Init(void) -{ - TeamClass *ptr; - - Teams.Free_All(); - memset(Number, 0, sizeof(Number)); - memset(Success, 0, sizeof(Success)); - - ptr = new TeamClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -void * TeamClass::operator new (size_t) -{ - void * ptr = Teams.Allocate(); - if (ptr) { - ((TeamClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -void TeamClass::operator delete(void * ptr) -{ - if (ptr) { - ((TeamClass *)ptr)->IsActive = false; - } - Teams.Free((TeamClass *)ptr); -} - - -TeamClass::~TeamClass(void) -{ - if (GameActive && Class) { - Number[TeamTypes.ID(Class)]--; - while (Member) { - Remove(Member); - } - - if (Class->IsTransient && !Number[TeamTypes.ID(Class)]) { - delete (TeamTypeClass *)Class; - } - } -} - - -TeamClass::TeamClass(TeamTypeClass const * type, HouseClass * owner) : - Class(type), - House(owner) -{ - memset(Quantity, 0, sizeof(Quantity)); - IsAltered = true; - IsForcedActive = false; - IsFullStrength = false; - IsUnderStrength = true; - IsReforming = false; - IsLagging = false; - IsMoving = false; - IsHasBeen = false; - Center = 0; - Target = TARGET_NONE; - ObjectiveCenter = 0; - MissionTarget = TARGET_NONE; - Member = 0; - Total = 0; - Risk = 0; - CurrentMission = -1; - IsNextMission = true; - TimeOut = 0; - SuspendTimer.Clear(); - Suspended = false; - Number[TeamTypes.ID(Class)]++; -} - - -/*************************************************************************** - * TeamClass::Assign_Mission_Target -- Sets mission target and clears old * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/16/1995 PWG : Created. * - *=========================================================================*/ -void TeamClass::Assign_Mission_Target(TARGET new_target) -{ - Validate(); - /* - ** First go through and find anyone who is currently targetting - ** the old mission target and clear their Tarcom. - */ - FootClass * unit = Member; - while (unit) { - bool tar = (unit->TarCom == MissionTarget); - bool nav = (unit->NavCom == MissionTarget); - if (tar || nav) { - - /* - ** If the unit was doing something related to the team mission - ** then we kick him into guard mode so that he is easy to change - ** missions for. - */ - unit->Assign_Mission(MISSION_GUARD); - - /* - ** If the unit's tarcom is set to the old mission target, then - ** clear it, so that it will be reset by whatever happens next. - */ - if (nav) { - unit->Assign_Destination(TARGET_NONE); - } - - /* - ** If the unit's navcom is set to the old mission target, then - ** clear it, so that it will be reset by whatever happens next. - */ - if (tar) { - unit->Assign_Target(TARGET_NONE); - } - } - unit = (FootClass *)unit->Member; - } - - /* - ** If there is not currently an override on the current mission target - ** then assign both MissionTarget and Target to the new target. If - ** there is an overide, allow the team to keep fighting the overide but - ** make sure they pick up on the new mission when they are ready. - */ - if (Target == MissionTarget || !Target_Legal(Target)) { - MissionTarget = Target = new_target; - } else { - MissionTarget = new_target; - } -} - - -/*********************************************************************************************** - * TeamClass::AI -- Process team logic. * - * * - * General purpose team logic is handled by this routine. It should be called once per * - * active team per game tick. This routine handles recruitment and assigning orders to * - * member units. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - * 01/06/1995 JLB : Choreographed gesture. * - *=============================================================================================*/ -void TeamClass::AI(void) -{ - Validate(); - int desired = 0; - int old_under = IsUnderStrength; - int old_full = IsFullStrength; - - /* - ** If the team has been suspended then we need to check if its time for - ** us to reactivate the team. If not, no team logic will be processed - ** for this team. - */ - if (Suspended) { - if (!SuspendTimer.Expired()) { - return; - } - Suspended = false; - } - - /* - ** If this team senses that its composition has been altered, then it should - ** recalculate the under strength and full strength flags. - */ - if (IsAltered) { - - for (int index = 0; index < Class->ClassCount; index++) { - desired += Class->DesiredNum[index]; - } - - if (Total) { - IsFullStrength = (Total == desired); - - /* - ** Human controlled teams are always considered full strength. This ensures - ** that no new team members will be recruited and the team won't go into - ** regroup logic. - */ - if (House->IsHuman) { - IsUnderStrength = false; - } else { - - /* - ** Reinforcable teams will revert (or snap out of) the under strength - ** mode when the members transition the magic 1/3 strength threshhold. - */ - if (Class->IsReinforcable) { - IsUnderStrength = (Total <= desired / 3); - } else { - - /* - ** Teams that are not flagged as reinforcable are never considered under - ** strength if the team has already started its main mission. This - ** ensures that once the team has started, it won't dally to pick up - ** new members. - */ - IsUnderStrength = !IsHasBeen; - } - } - IsAltered = false; - } else { - IsUnderStrength = true; - IsFullStrength = false; - Center = 0; - - /* - ** A team that exists on the player's side is automatically destroyed - ** when there are no team members left. This team was created as a - ** result of reinforcement logic and no longer needs to exist when there - ** are no more team members. - */ - if (House->IsHuman || IsHasBeen) { - Delete_This(); - return; - } - } - - /* - ** If the team has gone from under strength to no longer under - ** strength than the team needs to reform. - */ - if (old_under != IsUnderStrength) { - IsReforming = true; - } - } - - /* - ** If the team is under strength, then flag it to regroup. - */ - if (IsMoving && IsUnderStrength) { - IsMoving = false; - CurrentMission = -1; - if (Total) { - Calc_Center(Center, ObjectiveCenter); - - /* - ** When a team is badly damaged and needs to regroup it should - ** pick a friendly building to go and regroup at. Its first preference - ** should be somewhere near repair factory. If it cannot find a repair - ** factory then it should pick another structure that is friendly to - ** its side. - */ - CELL dest = Center; - int max = 0x7FFFFFFF; - - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * b = Buildings.Ptr(index); - - if (b && !b->IsInLimbo && b->House == House && b->Class->Primary == WEAPON_NONE) { - CELL cell = Coord_Cell(b->Center_Coord()); - int dist = Map.Cell_Distance(cell, Center) * (Map.Cell_Threat(cell, House->Class->House) + 1); - - if (*b == STRUCT_REPAIR) { - dist >>= 1; - } - if (dist < max) { - cell = Member->Safety_Point(Center, cell, 2, 4); - if (cell != -1) { - max = dist; - dest = cell; - } - } - } - } - - // Should calculate a regroup location. - Target = ::As_Target(dest); - Coordinate_Move(); - return; - } else { - Center = 0; - } - } - - /* - ** Flag this team into action when it gets to full strength. Human owned teams are only - ** used for reinforcement purposes -- always consider them at full strength. - */ - if (!IsMoving && (IsFullStrength || IsForcedActive)) { - IsMoving = true; - IsHasBeen = true; - IsUnderStrength = false; - - /* - ** Infantry can do a gesture when they start their mission. Pick - ** a gesture at random. - */ - FootClass * techno = Member; - DoType doaction = (Random_Pick(1, 2) == 1) ? DO_GESTURE1 : DO_GESTURE2; - while (techno) { - if (!techno->IsInLimbo && techno->What_Am_I() == RTTI_INFANTRY) { - ((InfantryClass *)techno)->Do_Action(doaction); - } - - if (IsReforming || IsForcedActive) { - techno->IsInitiated = true; - } - - techno = techno->Member; - } - CurrentMission = -1; - IsNextMission = true; - IsForcedActive = false; - } - - /* - ** If the team is moving or if there is no center position for - ** the team, then the center position must be recalculated. - */ - if (IsReforming || IsMoving || Center == 0) { - Calc_Center(Center, ObjectiveCenter); - } - - /* - ** Try to recruit members if there is room to do so for this team. - ** Only try to recruit members for a non player controlled team. - */ - if (!IsMoving || (!IsFullStrength && Class->IsReinforcable) && !House->IsHuman) { - for (int index = 0; index < Class->ClassCount; index++) { - if (Quantity[index] < Class->DesiredNum[index]) { - Recruit(index); - } - } - } - - /* - ** If there are no members of the team and the team has reached - ** full strength at one time, then delete the team. - */ - if (!Member && IsHasBeen) { - Delete_This(); - return; - } - - /* - ** If the mission should be advanced to the next entry, then do so at - ** this time. Various events may cause the mission to advance, but it - ** all boils down to the following change-mission code. - */ - if (IsMoving && !IsReforming && IsNextMission) { - IsNextMission = false; - CurrentMission++; - if (CurrentMission < Class->MissionCount) { - TeamMissionStruct const * mission = &Class->MissionList[CurrentMission]; - - TimeOut = mission->Argument * (TICKS_PER_MINUTE/10); - Target = TARGET_NONE; - switch (mission->Mission) { - case TMISSION_MOVECELL: - Assign_Mission_Target(::As_Target((CELL)mission->Argument)); - break; - - case TMISSION_MOVE: - case TMISSION_UNLOAD: - /* - ** Argument can be a waypoint index or a direct target. - */ - if (mission->Argument < WAYPT_COUNT) { - Assign_Mission_Target(::As_Target((CELL)Waypoint[mission->Argument])); - } else { - Assign_Mission_Target((TARGET)mission->Argument); - } - break; - - case TMISSION_ATTACKTARCOM: - Assign_Mission_Target(mission->Argument); - break; - - default: - Assign_Mission_Target(TARGET_NONE); - break; - } - } else { - Delete_This(); - return; - } - } - - /* - ** Perform mission of the team. This depends on the mission list. - */ - if (Member && IsMoving && !IsReforming && !IsUnderStrength) { - /* - ** If the current Target has been dealt with but the mission target - ** has not, then the current target needs to be reset to the mission - ** target. - */ - if (!Target_Legal(Target)) { - Target = MissionTarget; - } - - /* - ** If the current mission is one that times out, then check for - ** this case. If it has timed out then advance to the next - ** mission in the list or disband the team. - */ - TeamMissionStruct const * mission = &Class->MissionList[CurrentMission]; - switch (mission->Mission) { - case TMISSION_ATTACKBASE: - if (!Target_Legal(MissionTarget)) { - Assign_Mission_Target(Member->Greatest_Threat(THREAT_BUILDINGS)); - if (!Target_Legal(MissionTarget)) IsNextMission = true; - } - Coordinate_Attack(); - break; - - case TMISSION_ATTACKUNITS: - if (!Target_Legal(MissionTarget)) { - Assign_Mission_Target(Member->Greatest_Threat(THREAT_VEHICLES|THREAT_INFANTRY)); - if (!Target_Legal(MissionTarget)) IsNextMission = true; - } - Coordinate_Attack(); - break; - - case TMISSION_ATTACKCIVILIANS: - if (!Target_Legal(MissionTarget)) { - Assign_Mission_Target(Member->Greatest_Threat(THREAT_CIVILIANS)); - if (!Target_Legal(MissionTarget)) IsNextMission = true; - } - Coordinate_Attack(); - break; - - case TMISSION_ATTACKTARCOM: - case TMISSION_RAMPAGE: - if (!Target_Legal(MissionTarget)) { - Assign_Mission_Target(Member->Greatest_Threat(THREAT_NORMAL)); - if (!Target_Legal(MissionTarget)) IsNextMission = true; - } - Coordinate_Attack(); - break; - - case TMISSION_DEFENDBASE: - Coordinate_Move(); - break; - -// case TMISSION_HARVEST: -// Coordinate_Move(); -// break; - - case TMISSION_UNLOAD: - Coordinate_Unload(); - break; - - case TMISSION_MOVE: - Coordinate_Move(); - break; - - case TMISSION_RETREAT: - Coordinate_Move(); - break; - - case TMISSION_GUARD: - Coordinate_Regroup(); - break; - - case TMISSION_LOOP: - CurrentMission = mission->Argument-1; - IsNextMission = true; - break; - } - - /* - ** Check for mission time out condition. If the mission does in fact time out, then - ** flag it so that the team mission list will advance. - */ - switch (mission->Mission) { - case TMISSION_ATTACKBASE: - case TMISSION_ATTACKUNITS: - case TMISSION_ATTACKCIVILIANS: - case TMISSION_RAMPAGE: - case TMISSION_DEFENDBASE: - case TMISSION_UNLOAD: - case TMISSION_RETREAT: - case TMISSION_GUARD: - if (TimeOut.Expired()) { - IsNextMission = true; - } - break; - } - - } else { - if (IsMoving) { - IsReforming = !Coordinate_Regroup(); - } else { - Coordinate_Move(); - } - } -} - - -/*********************************************************************************************** - * TeamClass::Add -- Adds specified object to team. * - * * - * Use this routine to add the specified object to the team. The object is checked to make * - * sure that it can be assigned to the team. If it can't, then the object will be left * - * alone and false will be returned. * - * * - * INPUT: obj -- Pointer to the object that is to be assigned to this team. * - * * - * typeindex-- Optional value that specifies the index in the team type class array * - * that this object belongs. * - * * - * OUTPUT: bool; Was the unit added to the team? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - * 01/02/1995 JLB : Initiation flag setup. * - * 08/06/1995 JLB : Allows member stealing from lesser priority teams. * - *=============================================================================================*/ -bool TeamClass::Add(FootClass * obj, int typeindex) -{ - Validate(); - /* - ** If this team doesn't accept new members, then don't accept this one either. - */ -// if (!Class->IsReinforcable && IsMoving) { -// return(false); -// } - - if (!obj || !obj->Strength || (obj->IsInLimbo && !ScenarioInit) || obj->In_Radio_Contact() || obj->House != House) { - return(false); - } - - TeamClass * team = obj->Team; - - /* - ** Trying to add the team member to itself is an error condition. Just return - ** with success, since the end result is the same. - */ - if (team == this) { - return(true); - } - - /* - ** If the object is doing some mission that precludes it from joining - ** a team then don't add it. - */ - if (obj->Mission == MISSION_STICKY || obj->Mission == MISSION_SLEEP || obj->Mission == MISSION_GUARD_AREA || obj->Mission == MISSION_HUNT || obj->Mission == MISSION_HARVEST) { - return(false); - } - - /* - ** If this object is part of another team, then check to make sure that it - ** is permitted to leave the other team in order to join this one. If not, - ** then no further processing is allowed -- bail. - */ - if (team && - (/*team->Total >= Total || team->IsMoving ||*/ - team->Class->RecruitPriority >= Class->RecruitPriority)) { - return(false); - } - - /* - ** If the proper team index was not provided, then find it in the type type class. - ** On the chance that a match could not be found, then it is illegal to add this - ** object to this team -- return with failure flag. - */ - if (typeindex == -1) { - for (typeindex = 0; typeindex < Class->ClassCount; typeindex++) { - if (Class->Class[typeindex] == &obj->Class_Of()) { - break; - } - } - } - - /* - ** If the team is already full of this type, then adding the object is not allowed. - ** Return with a failure flag in this case. - */ - if (Quantity[typeindex] >= Class->DesiredNum[typeindex]) { - return(false); - } - - /* - ** All is ok to add the object to the team, but if the object is already part of - ** another team, then it must be removed from that team first. - */ - if (team) { - team->Remove(obj); - } - - /* - ** Actually add the object to the team. - */ - Quantity[typeindex]++; - obj->IsInitiated = (Member == NULL); - obj->Member = Member; - Member = obj; - obj->Team = this; - Total++; - Risk += obj->Risk(); - if (!Center) { - Calc_Center(Center, ObjectiveCenter); - } - - /* - ** Return with success, since the object was added to the team. - */ - IsAltered = true; - return(true); -} - - -/*********************************************************************************************** - * TeamClass::Remove -- Removes the specified object from the team. * - * * - * Use this routine to remove an object from a team. Objects removed from the team are * - * then available to be recruited by other teams, or even by the same team at a later time. * - * * - * INPUT: obj -- Pointer to the object that is to be removed from this team. * - * * - * typeindex-- Optional index of where this object type is specified in the type * - * type class. This parameter can be omitted. It only serves to make * - * the removal process faster. * - * * - * OUTPUT: bool; Was the object removed from this team? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - * 01/02/1995 JLB : Initiation tracking and team captain selection. * - *=============================================================================================*/ -bool TeamClass::Remove(FootClass * obj, int typeindex) -{ - Validate(); - /* - ** Make sure that the object is in fact a member of this team. If not, then it can't - ** be removed. Return success because the end result is the same. - */ - if (obj->Team != this) { - return(true); - } - - /* - ** If the proper team index was not provided, then find it in the type type class. The - ** team type class will not be set if the appropriate type could not be found - ** for this object. This indicates that the object was illegally added. Continue to - ** process however, since removing this object from the team is a good idea. - */ - if (typeindex == -1) { - for (typeindex = 0; typeindex < Class->ClassCount; typeindex++) { - if (Class->Class[typeindex] == &obj->Class_Of()) { - break; - } - } - } - - /* - ** Decrement the counter for the team class. There is now one less of this object type. - */ - if ((unsigned)typeindex < Class->ClassCount) { - Quantity[typeindex]--; - } - - /* - ** Actually remove the object from the team. Scan through the team members - ** looking for the one that matches the one specified. If it is found, it - ** is unlinked from the member chain. During this scan, a check is made to - ** ensure that at least one remaining member is still initiated. If not, then - ** a new team captain must be chosen. - */ - bool initiated = false; - FootClass * prev = 0; - FootClass * curr = Member; - bool found = false; - while (curr && (!found || !initiated)) { - if (curr == obj) { - if (prev) { - prev->Member = curr->Member; - } else { - Member = curr->Member; - } - FootClass * temp = curr->Member; - curr->Member = 0; - curr->Team = 0; - curr = temp; - Total--; - found = true; - Risk -= obj->Risk(); - continue; - } - - /* - ** If this (remaining) member is initiated, then keep a record of this. - */ - initiated |= curr->IsInitiated; - - prev = curr; - curr = curr->Member; - } - - /* - ** If, after removing the team member, there are no initiated members left - ** in the team, then just make the first remaining member of the team the - ** team captain. Mark the center location of the team as invalid so that - ** it will be centered around the captain. - */ - if (!initiated && Member) { - Member->IsInitiated = true; - Center = 0; - } - - /* - ** Must record that the team composition has changed. At the next opportunity, - ** the team members will be counted and appropriate AI adjustments made. - */ - IsAltered = true; - return(true); -} - - -/*********************************************************************************************** - * TeamClass::Recruit -- Attempts to recruit members to the team for the given index ID. * - * * - * This routine will take the given index ID and scan for available objects of that type * - * to recruit to the team. Recruiting will continue until that object type has either * - * been exhausted or if the team's requirment for that type has been filled. * - * * - * INPUT: typeindex -- The index for the object type to recruit. The index is used to * - * look into the type type's array of object types that make up this * - * team. * - * * - * OUTPUT: Returns with the number of objects added to this team. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - * 04/10/1995 JLB : Scans for units too. * - *=============================================================================================*/ -int TeamClass::Recruit(int typeindex) -{ - Validate(); - int added = 0; // Total number added to team. - - /* - ** Quick check to see if recruiting is really allowed for this index or not. - */ - if (Class->DesiredNum[typeindex] > Quantity[typeindex]) { - - /* - ** For infantry objects, sweep through the infantry in the game looking for - ** ones owned by the house that owns the team. When found, try to add. - */ - if (Class->Class[typeindex]->What_Am_I() == RTTI_INFANTRYTYPE) { - - for (int index = 0; index < Infantry.Count(); index++) { - InfantryClass * infantry = Infantry.Ptr(index); - - if (infantry->House == House && infantry->Class == Class->Class[typeindex]) { - if (Add(infantry, typeindex)) { - added++; - } - } - - /* - ** If there is sufficient quantity of this type of object recruited to the - ** team, then abort further scanning for members. - */ - if (Quantity[typeindex] >= Class->DesiredNum[typeindex]) { - break; - } - } - } - - if (Class->Class[typeindex]->What_Am_I() == RTTI_UNITTYPE) { - - for (int index = 0; index < Units.Count(); index++) { - UnitClass * unit = Units.Ptr(index); - - if (unit->House == House && unit->Class == Class->Class[typeindex]) { - if (Add(unit, typeindex)) { - added++; - - /* - ** If a transport is added to the team, the occupants - ** are added by default. - */ - FootClass * f = unit->Attached_Object(); - while (f) { - Add(f); - f = (FootClass *)f->Next; - } - } - } - - /* - ** If there is sufficient quantity of this type of object recruited to the - ** team, then abort further scanning for members. - */ - if (Quantity[typeindex] >= Class->DesiredNum[typeindex]) { - break; - } - } - } - } - - return(added); -} - - -/*********************************************************************************************** - * TeamClass::Detach -- Removes specified target from team tracking. * - * * - * When a target object is about to be removed from the game (e.g., it was killed), then * - * any team that is looking at that target must abort from that target. * - * * - * INPUT: target -- The target object that is going to be removed from the game. * - * * - * all -- Is the target going away for good as opposed to just cloaking/hiding? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Detach(TARGET target, bool ) -{ - Validate(); - - /* - ** If the target to detatch matches the target of this team, then remove - ** the target from this team's Tar/Nav com and let the chips fall - ** where they may. - */ - if (Target == target) { - Target = TARGET_NONE; - } - if (MissionTarget == target) { - MissionTarget = TARGET_NONE; - } - -} - - -/*********************************************************************************************** - * TeamClass::As_Target -- Converts this team object into a target number. * - * * - * This routine is used by the save/load code to produce a persistant identifier for this * - * team object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the team represented as a target number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/14/1995 JLB : Created. * - *=============================================================================================*/ -TARGET TeamClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_TEAM, Teams.ID(this))); -} - - -/*********************************************************************************************** - * TeamClass::Calc_Center -- Determines average location of team members. * - * * - * Use this routine to calculate the "center" location of the team. This is the average * - * position of all members of the team. Using this center value it is possible to tell * - * if a team member is too far away and where to head to in order to group up. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the cell number of the team's center point. If the team contains * - * no members, then the return value will be zero. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Calc_Center(CELL ¢er, CELL &obj_center) const -{ - Validate(); - long x = 0; - long y = 0; - int dist = 0x7FFFFFFF; - int quantity = 0; - FootClass * unit; - - obj_center = 0; - center = 0; - - unit = Member; - while (unit) { - if (unit->IsInitiated && !unit->IsInLimbo) { - CELL c = Coord_Cell(unit->Center_Coord()); - if (unit->Distance(Target) < dist) { - dist = unit->Distance(Target); - obj_center = c; - } - x += Cell_X(c); - y += Cell_Y(c); - quantity++; - } - unit = unit->Member; - } - if (quantity) { - x /= quantity; - y /= quantity; - CELL cell = XY_Cell((int)x, (int)y); - center = cell; - } -} - - -/*********************************************************************************************** - * TeamClass::Took_Damage -- Informs the team when the team member takes damage. * - * * - * This routine is used when a team member takes damage. Usually the team will react in * - * some fashion to the attack. This reaction can range from running away to assigning this * - * new target as the team's target. * - * * - * INPUT: obj -- The team member that was damaged. * - * * - * result -- The severity of the damage taken. * - * * - * source -- The purpetrator of the damage. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/29/1994 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Took_Damage(FootClass * , ResultType result, TechnoClass * source) -{ - Validate(); - if ((result != RESULT_NONE) && (!Class->IsSuicide)) { - if (!IsMoving) { - // Should run to a better hiding place or disband into a group of hunting units. - } else { - - if (source && !Is_A_Member(source) && Member && Member->What_Am_I() != RTTI_AIRCRAFT) { - if (Target != source->As_Target()) { - - /* - ** Don't change target if the team's target is one that can fire as well. There is - ** no point in endlessly shuffling between targets that have firepower. - */ - if (Target_Legal(Target)) { - TechnoClass * techno = As_Techno(Target); - - if (techno && ((TechnoTypeClass const &)techno->Class_Of()).Primary != WEAPON_NONE) { - if (techno->In_Range(Cell_Coord(Center), 0)) { - return; - } - } - } - Target = source->As_Target(); - } - } - } - } -} - - -/*********************************************************************************************** - * TeamClass::Coordinate_Attack -- Handles coordinating a team attack. * - * * - * This function is called when the team knows what it should attack. This routine will * - * give the necessary orders to the members of the team. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/06/1995 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Coordinate_Attack(void) -{ - Validate(); - if (!Target_Legal(Target)) { - Target = MissionTarget; - } - - if (!Target_Legal(Target)) { - IsNextMission = true; - - } else { - - FootClass * unit = Member; - while (unit) { - - Coordinate_Conscript(unit); - - if (unit->IsInitiated && !unit->IsInLimbo) { - - if (unit->Mission != MISSION_ATTACK && unit->Mission != MISSION_ENTER && unit->Mission != MISSION_CAPTURE) { - unit->Assign_Mission(MISSION_ATTACK); - unit->Assign_Target(TARGET_NONE); - unit->Assign_Destination(TARGET_NONE); - } - - if (unit->TarCom != Target) { - unit->Assign_Target(Target); - } - } - - unit = unit->Member; - } - } -} - - -/*********************************************************************************************** - * TeamClass::Coordinate_Regroup -- Handles team idling (regrouping). * - * * - * This routine is called when the team must delay at its current location. Team members * - * are grouped together by this function. It is called when the team needs to sit and * - * wait. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/06/1995 JLB : Created. * - *=============================================================================================*/ -bool TeamClass::Coordinate_Regroup(void) -{ - Validate(); - FootClass * unit = Member; - bool retval = true; - - /* - ** Regroup default logic. - */ - while (unit) { - - Coordinate_Conscript(unit); - - if (unit->IsInitiated && !unit->IsInLimbo) { - - if (unit->Distance(Center) > STRAY_DISTANCE && (unit->Mission != MISSION_GUARD_AREA || !Target_Legal(unit->TarCom))) { - if (unit->Mission != MISSION_MOVE || !Target_Legal(unit->NavCom) || ::Distance(As_Cell(unit->NavCom), Center) > STRAY_DISTANCE) { - unit->Assign_Mission(MISSION_MOVE); - unit->Assign_Destination(::As_Target(Center)); - } - retval = false; - } else { - - /* - ** This unit has gotten close enough to the team center so that it is - ** now considered intiated. An initiated unit is considered when calculating - ** the center of the team. - */ - unit->IsInitiated = true; - - /* - ** The team is regrouping, so just sit here and wait. - */ - if (unit->Mission != MISSION_GUARD_AREA) { - unit->Assign_Mission(MISSION_GUARD); - unit->Assign_Destination(TARGET_NONE); - } - } - - } - - unit = unit->Member; - } - return(retval); -} - - -/*********************************************************************************************** - * TeamClass::Coordinate_Move -- Handles team movement coordination. * - * * - * This routine is called when the team must move to a new location. Movement and grouping * - * commands associated with this task are initiated here. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/06/1995 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Coordinate_Move(void) -{ - Validate(); - FootClass * unit = Member; - bool finished = true; - - if (!Target_Legal(Target)) { - Target = MissionTarget; - } - - if (Target_Legal(Target)) { - - if (!Lagging_Units()) { - - - while (unit) { - - Coordinate_Conscript(unit); - - if (unit->IsInitiated && !unit->IsInLimbo) { - - if (unit->What_Am_I() != RTTI_AIRCRAFT && unit->Distance(Center) > STRAY_DISTANCE) { - IsLagging = true; - finished = false; - } else { - - if ((unit->Distance(Target)/ICON_LEPTON_W) > STRAY_DISTANCE || - (unit->What_Am_I() == RTTI_AIRCRAFT && - ((AircraftClass *)unit)->Altitude > 0 && - Class->MissionList[CurrentMission+1].Mission != TMISSION_MOVE)) { - - if (unit->Mission != MISSION_MOVE) { - unit->Assign_Mission(MISSION_MOVE); - } - if (unit->NavCom != Target) { - unit->Assign_Destination(Target); - } - finished = false; - } else { - if (unit->Mission == MISSION_MOVE && !Target_Legal(unit->NavCom)) { - unit->Enter_Idle_Mode(); - } - } - } - } - - unit = unit->Member; - } - } else { - finished = false; - } - } - - /* - ** If all the team members are close enough to the desired destination, then - ** move to the next mission. - */ - if (finished && IsMoving) { - IsNextMission = true; - } -} - - -/*************************************************************************** - * Lagging_Units -- processes units that cant keep up with the pack * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 08/01/1995 PWG : Created. * - *=========================================================================*/ -bool TeamClass::Lagging_Units(void) -{ - Validate(); - FootClass * unit = Member; - bool lag = false; - - /* - ** If the IsLagging bit is not set, then obviously there are no lagging - ** units. - */ - if (!IsLagging) return(false); - - /* - ** Scan through all of the units, searching for units who are having - ** trouble keeping up with the pack. - */ - while (unit) { - - if (!unit->IsInLimbo) { - /* - ** If we find a unit who has fallen to far away from the center of - ** the pack, then we need to order that unit to catch up with the - ** first unit. - */ - if (unit->Distance(ObjectiveCenter) > STRAY_DISTANCE) { - if (unit->Mission != MISSION_MOVE || !Target_Legal(unit->NavCom) || ::Distance(As_Cell(unit->NavCom), ObjectiveCenter) > STRAY_DISTANCE) { - unit->Assign_Mission(MISSION_MOVE); - unit->Assign_Destination(::As_Target(ObjectiveCenter)); - } - lag = true; - } else { - /* - ** We need to order all of the other units to hold there - ** position until all lagging units catch up. - */ - unit->Assign_Mission(MISSION_GUARD); - unit->Assign_Destination(TARGET_NONE); - } - } - unit = unit->Member; - } - - /* - ** Once we have handled the loop we know whether there are any lagging - ** units or not. - */ - IsLagging = lag; - return(lag); -} - - -/*********************************************************************************************** - * TeamClass::Coordinate_Unload -- Tells the team to unload passengers now. * - * * - * This routine tells all transport vehicles to unload passengers now. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/14/1995 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Coordinate_Unload(void) -{ - Validate(); - FootClass * unit = Member; - bool finished = true; - - while (unit) { - - Coordinate_Conscript(unit); - - if (unit->IsInitiated && !unit->IsInLimbo) { - if (unit->Is_Something_Attached()) { - - /* - ** Loaner transports will break off of the team at this time. The normal - ** unload logic for the transport will proceed normally. The rest of the team - ** members will be in a dormant state until they are unloaded. - */ - if (unit->IsALoaner) { - Remove(unit); - unit->Commence(); - unit->Assign_Mission(MISSION_UNLOAD); - unit->Assign_Destination(Target); - } else { - if (unit->Mission != MISSION_UNLOAD) { - unit->Assign_Mission(MISSION_UNLOAD); - unit->Assign_Destination(Target); - } - } - finished = false; - } - } - - unit = unit->Member; - } - - if (finished) { - IsNextMission = true; - } -} - - -/*********************************************************************************************** - * TeamClass::Coordinate_Conscript -- Gives orders to new recruit. * - * * - * This routine will give the movement orders to the conscript so that it will group * - * with the other members of the team. * - * * - * INPUT: unit -- Pointer to the conscript unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/06/1995 JLB : Created. * - *=============================================================================================*/ -void TeamClass::Coordinate_Conscript(FootClass * unit) -{ - Validate(); - if (unit && !unit->IsInitiated && !unit->IsInLimbo) { - if (unit->Distance(Center) > STRAY_DISTANCE) { - if (!Target_Legal(unit->NavCom)) { - unit->Assign_Mission(MISSION_MOVE); - unit->Assign_Target(TARGET_NONE); - unit->Assign_Destination(::As_Target(Center)); - } - } else { - - /* - ** This unit has gotten close enough to the team center so that it is - ** now considered intiated. An initiated unit is considered when calculating - ** the center of the team. - */ - unit->IsInitiated = true; - } - } -} - - -/*************************************************************************** - * TeamClass::Is_A_Member -- Tests if a unit is a member of a team * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/16/1995 PWG : Created. * - *=========================================================================*/ -bool TeamClass::Is_A_Member(void const * who) const -{ - Validate(); - FootClass * unit = Member; - while (unit) { - if (unit == who) { - return(true); - } - unit = unit->Member; - } - return(false); -} - - -/*************************************************************************** - * TeamClass::Suspend_Teams -- Suspends activity for low priority teams * - * * - * INPUT: int priority - determines what is considered low priority. * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/19/1995 PWG : Created. * - *=========================================================================*/ -void TeamClass::Suspend_Teams(int priority) -{ - for (int index = 0; index < Teams.Count(); index++) { - TeamClass *team = Teams.Ptr(index); - - /* - ** If a team is below the "survival priority level", then it gets - ** destroyed. The team members are then free to be reassigned. - */ - if (team && team->Class->RecruitPriority < priority) { - FootClass * unit = team->Member; - while (team->Member) { - team->Remove(team->Member); - } - team->IsAltered = true; - team->SuspendTimer = TICKS_PER_MINUTE*2; - team->Suspended = true; - } - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/TEAM.H b/code/TIBERIANDAWN/TEAM.H deleted file mode 100644 index 2d41072..0000000 --- a/code/TIBERIANDAWN/TEAM.H +++ /dev/null @@ -1,255 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\team.h_v 2.16 16 Oct 1995 16:48:04 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEAM.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 12/11/94 * - * * - * Last Update : December 11, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TEAM_H -#define TEAM_H - -#include -#include "teamtype.h" -#include "abstract.h" - -/* -** Units are only allowed to stray a certain distance away from their -** team. When they exceed this distance, some sort of fixup must be -** done. -*/ -#define STRAY_DISTANCE 2 - -class TeamClass : public AbstractClass -{ -#ifdef USE_RA_AI - friend class HouseClass; // Needed for RA AI moved into C&C. ST - 7/24/2019 2:44PM -#endif // USE_RA_AI - - public: - /* - ** This specifies the type of team this is. - */ - TeamTypeClass const * const Class; - - /* - ** This specifies the owner of this team. - */ - HouseClass * const House; - - /* - ** This flag forces the team into active state regardless of whether it - ** is understrength or not. - */ - unsigned IsForcedActive:1; - - /* - ** This flag is set to true when the team initiates into active mode. The - ** flag is never cleared. By examining this flag, it is possible to determine - ** if the team has ever launched into active mode. - */ - unsigned IsHasBeen:1; - - /* - ** If the team is full strength, then this flag is true. A full strength - ** team will not try to recruit members. - */ - unsigned IsFullStrength:1; - - /* - ** A team that is below half strength has this flag true. It means that the - ** the team should hide back at the owner's base and try to recruit - ** members. - */ - unsigned IsUnderStrength:1; - - /* - ** If a team is not understrength but is not yet full strength, then - ** the team is regrouping. If this flag is set and the team becomes - ** full strength, the all members of the team will become initiated - ** and this flag will be reset. - */ - unsigned IsReforming:1; - - /* - ** This bit should be set if a team is determined to have lagging - ** units in its formation. - */ - unsigned IsLagging:1; - - private: - /* - ** If a team member was removed or added, then this flag will be set to true. The - ** team system uses this flag to tell whether it should recalculate the team - ** under strength or full strength flags. This process does not need to occur - ** EVERY time a unit added or deleted from a team, just every so often if the - ** team has been changed. - */ - unsigned IsAltered:1; - - /* - ** If the team is working on it's primary mission (it is past the build up stage) - ** then this flag will be true. The transition between "moving" and "stationary" - ** stages usually requires some action on the team's part. - */ - unsigned IsMoving:1; - - /* - ** When the team determines that the next mission should be advanced to, it will - ** set this flag to true. Mission advance will either change the behavior of the - ** team or cause it to disband. - */ - unsigned IsNextMission:1; - /* - ** Records whether the team is suspended from production. - */ - unsigned Suspended:1; - - public: - /* - ** A team will have a center point. This is the point used to determine if - ** any member of the team is "too far" from the team and must return. This - ** center point is usually calculated as the average position of all the - ** team members. - */ - CELL Center; - CELL ObjectiveCenter; - - /* - ** This is the target of the team. Typically, it is a unit or structure, but - ** for the case of teams with a movement mission, it might represent a - ** destination cell. - */ - TARGET MissionTarget; - TARGET Target; - - /* - ** This is the total number of members in this team. - */ - int Total; - - /* - ** This is the teams combined risk value - */ - int Risk; - /* - ** This is the amount of time the team is suspended for. - */ - TCountDownTimerClass SuspendTimer; - - //------------------------------------------------------------ - TeamClass(void) : Class(0), House(0) {IsActive=false;Member=0;IsAltered=true;}; - TeamClass(TeamTypeClass const * team, HouseClass * owner); - virtual ~TeamClass(void); - virtual RTTIType What_Am_I(void) const {return RTTI_TEAM;}; - static void operator delete(void *ptr); - static void * operator new(size_t size); - static void Init(void); - static void Suspend_Teams(int priority); - - TARGET As_Target(void) const; - - /* - ** File I/O. - */ - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - void Force_Active(void) {IsForcedActive = true;IsUnderStrength=false;}; - bool Remove(FootClass *, int typeindex=-1); - void Detach(TARGET target, bool all); - void AI(void); - void Took_Damage(FootClass * obj, ResultType result, TechnoClass * source); - bool Add(FootClass *, int typeindex=-1); - void Assign_Mission_Target(TARGET new_target); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** This is a record of the current number of active teams of each - ** type. It can range from zero to MaxAllowed. - */ - static unsigned char Number[TEAMTYPE_MAX]; - - private: - - /* - ** The current mission index into the mission list is recorded here. - */ - int CurrentMission; - - /* - ** Some missions will time out. This is the timer that keeps track of the - ** time to transition between missions. - */ - TCountDownTimerClass TimeOut; - - void Coordinate_Unload(void); - bool Coordinate_Regroup(void); - void Coordinate_Attack(void); - void Coordinate_Move(void); - void Coordinate_Conscript(FootClass * unit); -// void Control(FootClass *, bool initial=false); - void Calc_Center(CELL ¢er, CELL &obj_center) const; - int Recruit(int typeindex); - bool Is_A_Member(void const * who) const; - bool Lagging_Units(void); - - /* - ** Points to the first member in the list of members for this team. - */ - FootClass * Member; - - unsigned char Quantity[TeamTypeClass::MAX_TEAM_CLASSCOUNT]; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - - /* - ** This records the success of each team type. As the team carries out its - ** mission, it increments this counter if it considers the mission - ** to have been successfully completed. Teams with greater success - ** will be created more than the others. - */ - static unsigned char Success[TEAMTYPE_MAX]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TEAMTYPE.CPP b/code/TIBERIANDAWN/TEAMTYPE.CPP deleted file mode 100644 index 1430b79..0000000 --- a/code/TIBERIANDAWN/TEAMTYPE.CPP +++ /dev/null @@ -1,977 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\teamtype.cpv 2.17 16 Oct 1995 16:48:52 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEAMTYPE.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 7, 1994 * - * * - * Last Update : July 21, 1995 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * TeamTypeClass::TeamTypeClass -- class constructor * - * TeamTypeClass::~TeamTypeClass -- class destructor * - * TeamTypeClass::Init -- pre-scenario initialization * - * TeamTypeClass::Read_INI -- reads INI data * - * TeamTypeClass::Write_INI -- writes INI data * - * TeamTypeClass::Read_Old_INI -- reads old INI format * - * TeamTypeClass::As_Pointer -- gets ptr for team type with given name * - * TeamTypeClass::Remove -- removes this team from the system * - * TeamTypeClass::Mission_From_Name -- returns mission for given name * - * TeamTypeClass::Name_From_Mission -- returns name for given mission * - * TeamTypeClass::operator new -- 'new' operator * - * TeamTypeClass::operator delete -- 'delete' operator * - * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. * - * TeamTypeClass::Validate -- validates teamtype pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/* -********************************** Globals ********************************** -*/ -char const * TeamTypeClass::TMissions[TMISSION_COUNT] = { - "Attack Base", - "Attack Units", - "Attack Civil.", - "Rampage", - "Defend Base", -// "Harvest", - "Move", - "Move to Cell", - "Retreat", - "Guard", - "Loop", - "Attack Tarcom", - "Unload", -}; - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * TeamTypeClass::VTable; - - -/*********************************************************************************************** - * TeamTypeClass::Validate -- validates teamtype pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int TeamTypeClass::Validate(void) const -{ - int num; - - num = TeamTypes.ID(this); - if (num < 0 || num >= TEAMTYPE_MAX) { - Validate_Error("TEAMTYPE"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*************************************************************************** - * TeamTypeClass::TeamTypeClass -- class constructor * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - *=========================================================================*/ -TeamTypeClass::TeamTypeClass(void) -{ - IsPrebuilt = true; - IsReinforcable = true; - IsRoundAbout = false; - IsLearning = false; - IsSuicide = false; - IsAutocreate = false; - IsTransient = false; - IsMercenary = false; - RecruitPriority = 7; - MaxAllowed = 0; - Fear = 0; - InitNum = 0; - House = HOUSE_NONE; - MissionCount = 0; - IniName[0] = '\0'; - ClassCount = 0; - for (int i = 0; i < MAX_TEAM_CLASSCOUNT; i++) { - Class[i] = NULL; - DesiredNum[i] = 0; - } -} - - -/*************************************************************************** - * TeamTypeClass::Init -- pre-scenario initialization * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - *=========================================================================*/ -void TeamTypeClass::Init(void) -{ - TeamTypeClass *ptr; - - TeamTypes.Free_All(); - - ptr = new TeamTypeClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractTypeClass) - 4))[0]; - delete ptr; -} - - -/*************************************************************************** - * TeamTypeClass::Read_INI -- reads INI data * - * * - * INI entry format: * - * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * - * RecruitPriority,MaxAllowed,InitNum,Fear, * - * ClassCount,Class:Num,Class:Num,..., * - * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... * - * * - * INPUT: * - * buffer buffer to hold the INI data * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) * - *=========================================================================*/ -void TeamTypeClass::Read_INI(char *buffer) -{ - TeamTypeClass * team; // Working team pointer. - char *tbuffer; // Accumulation buffer of team names. - int len; // Length of data in buffer. - char buf[500]; // INI entry buffer - - /*------------------------------------------------------------------------ - Set 'tbuffer' to point just past the INI buffer - ------------------------------------------------------------------------*/ - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - /*------------------------------------------------------------------------ - Read all TeamType entry names into 'tbuffer' - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - - /* - ----------------------- Loop for all team entries ------------------------ - */ - while (*tbuffer != '\0') { - /* - ....................... Create a new team type ........................ - */ - team = new TeamTypeClass(); - - /* - ......................... Get the team entry .......................... - */ - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - - /* - .......................... Fill the team in ........................... - */ - team->Fill_In(tbuffer, buf); - - /* - ...................... Go to the next INI entry ....................... - */ - tbuffer += strlen(tbuffer)+1; - } - - /* - ** If no teams were read in, try reading the old INI format. - */ - if (TeamTypes.Count()==0) { - Read_Old_INI(buffer); - } -} - - -/*********************************************************************************************** - * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry * - * * - * This routine fills in the given teamtype with the given name, and values from * - * the given INI entry. * - * * - * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) * - * * - * INI entry format: * - * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * - * RecruitPriority,MaxAllowed,InitNum,Fear, * - * ClassCount,Class:Num,Class:Num,..., * - * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... * - * * - * INPUT: * - * name mnemonic for the desired trigger * - * entry INI entry to parse * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -void TeamTypeClass::Fill_In(char * name, char *entry) -{ - Validate(); - int num_classes; - char *p1; // parsing pointer - char *p2; // parsing pointer - int i; // loop counter - TechnoTypeClass const *otype; // ptr to type of object - InfantryType i_id; // infantry ID - UnitType u_id; // unit ID - AircraftType a_id; // aircraft ID - TeamMissionStruct mission; - - /* - ------------------------------ Set its name ------------------------------ - */ - Set_Name(name); - - /* - ---------------------------- 1st token: House ---------------------------- - */ - House = HouseTypeClass::From_Name(strtok(entry,",")); - - /* - -------------------------- 2nd token: RoundAbout ------------------------- - */ - IsRoundAbout = atoi(strtok(NULL,",")); - - /* - --------------------------- 3rd token: Learning -------------------------- - */ - IsLearning = atoi(strtok(NULL,",")); - - /* - --------------------------- 4th token: Suicide --------------------------- - */ - IsSuicide = atoi(strtok(NULL,",")); - - /* - ----------------------------- 5th token: Spy ----------------------------- - */ - IsAutocreate = atoi(strtok(NULL,",")); - - /* - -------------------------- 6th token: Mercenary -------------------------- - */ - IsMercenary = atoi(strtok(NULL,",")); - - /* - ----------------------- 7th token: RecruitPriority ----------------------- - */ - RecruitPriority = atoi(strtok(NULL,",")); - - /* - -------------------------- 8th token: MaxAllowed ------------------------- - */ - MaxAllowed = atoi(strtok(NULL,",")); - - /* - --------------------------- 9th token: InitNum --------------------------- - */ - InitNum = atoi(strtok(NULL,",")); - - /* - ------------------------- 10th token: Fear level ------------------------- - */ - Fear = atoi(strtok(NULL,",")); - - /* - ------------------------ 11th token: Class count ------------------------- - */ - num_classes = atoi(strtok(NULL,",")); - - /* - -------------- Loop through entries, setting class ptr & num ------------- - */ - ClassCount = 0; - for (i = 0; i < num_classes; i++) { - p1 = strtok(NULL,",:"); - p2 = strtok(NULL,",:"); - otype = NULL; - - /* - ------------------- See if this is an infantry name ------------------- - */ - i_id = InfantryTypeClass::From_Name(p1); - if (i_id != INFANTRY_NONE) { - otype = &InfantryTypeClass::As_Reference(i_id); - } - - /* - ---------------------- See if this is a unit name --------------------- - */ - u_id = UnitTypeClass::From_Name(p1); - if (u_id != UNIT_NONE) { - otype = &UnitTypeClass::As_Reference(u_id); - } - - /* - ------------------- See if this is an aircraft name ------------------- - */ - a_id = AircraftTypeClass::From_Name(p1); - if (a_id != AIRCRAFT_NONE) { - otype = &AircraftTypeClass::As_Reference(a_id); - } - - /* - --------------- If the name was resolved, add this class -------------- - */ - if (otype) { - if (ClassCount < MAX_TEAM_CLASSCOUNT) { - Class[ClassCount] = otype; - DesiredNum[ClassCount] = atoi(p2); - ClassCount++; - } - } - } - - /* - ----------------------- next token: Mission count ------------------------ - */ - MissionCount = atoi(strtok(NULL,",")); - - for (i = 0; i < MissionCount; i++) { - p1 = strtok(NULL,",:"); - p2 = strtok(NULL,",:"); - mission.Mission = Mission_From_Name(p1); - mission.Argument = atoi(p2); - MissionList[i] = mission; - } - - char * ptr = strtok(NULL, ","); - if (ptr) { - IsReinforcable = atoi(ptr); - } - ptr = strtok(NULL, ","); - if (ptr) { - IsPrebuilt = atoi(ptr); - } -} - - -/*************************************************************************** - * TeamTypeClass::Write_INI -- writes INI data * - * * - * INI entry format: * - * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * - * RecruitPriority,MaxAllowed,InitNum,Fear, * - * ClassCount,Class:Num,Class:Num,..., * - * MissionCount,Mission,Arg,Mission,Arg,Mission,Arg,... * - * * - * INPUT: * - * buffer buffer to store INI data in * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - *=========================================================================*/ -void TeamTypeClass::Write_INI(char *buffer, bool refresh) -{ - int index; - int i; - char buf[500]; - TeamTypeClass * team; - char const *hname; - - /*------------------------------------------------------------------------ - First, clear out all existing teamtypes in the old-style format. - ------------------------------------------------------------------------*/ - WWWritePrivateProfileString("Teams", NULL, NULL, buffer); - - /*------------------------------------------------------------------------ - Clear out all existing teamtype data from the INI file. - ------------------------------------------------------------------------*/ - if (refresh) { - WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer); - } - - /*------------------------------------------------------------------------ - Now write all the team data out - ------------------------------------------------------------------------*/ - buf[0] = 0; - for (index = 0; index < TeamTypes.Count(); index++) { - /* - .................. Get ptr to next active teamtype .................... - */ - team = TeamTypes.Ptr(index); - - /* - .......................... Find house's name .......................... - */ - if (team->House==HOUSE_NONE) { - hname = "None"; - } else { - hname = HouseClass::As_Pointer(team->House)->Class->IniName; - } - - /* - ......................... Generate INI entry .......................... - */ - sprintf(buf,"%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", - hname, - team->IsRoundAbout, - team->IsLearning, - team->IsSuicide, - team->IsAutocreate, - team->IsMercenary, - team->RecruitPriority, - team->MaxAllowed, - team->InitNum, - team->Fear, - team->ClassCount); - - /*..................................................................... - For every class in the team, record the class's name & desired count - .....................................................................*/ - for (i = 0; i < team->ClassCount; i++) { - sprintf (buf + strlen(buf), ",%s:%d", - team->Class[i]->IniName, - team->DesiredNum[i]); - } - - /*..................................................................... - Record the # of missions, and each mission name & argument value. - .....................................................................*/ - sprintf(buf + strlen(buf),",%d",team->MissionCount); - for (i = 0; i < team->MissionCount; i++) { - sprintf (buf + strlen(buf), ",%s:%d", - Name_From_Mission(team->MissionList[i].Mission), - team->MissionList[i].Argument); - } - - if (team->IsReinforcable) { - strcat(buf, ",1"); - } else { - strcat(buf, ",0"); - } - if (team->IsPrebuilt) { - strcat(buf, ",1"); - } else { - strcat(buf, ",0"); - } - - WWWritePrivateProfileString(INI_Name(), team->IniName, buf, buffer); - } -} - - -/*************************************************************************** - * TeamTypeClass::Read_Old_INI -- reads old INI format * - * * - * INI entry format: * - * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * - * RecruitPriority,MaxAllowed,InitNum,Class:Num,Class:Num,...,Fear * - * * - * INPUT: * - * buffer buffer to hold the INI data * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) * - *=========================================================================*/ -void TeamTypeClass::Read_Old_INI(char *buffer) -{ - TeamTypeClass * team; // Working team pointer. - char *tbuffer; // Accumulation buffer of team names. - int len; // Length of data in buffer. - char buf[256]; // INI entry buffer - char *p1; // parsing pointer - char *p2; // parsing pointer - int index; - TechnoTypeClass const *otype; // ptr to type of object - InfantryType i_id; // infantry ID - UnitType u_id; // unit ID - AircraftType a_id; // infantry ID - - /*------------------------------------------------------------------------ - Set 'tbuffer' to point just past the INI buffer - ------------------------------------------------------------------------*/ - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - /*------------------------------------------------------------------------ - Read all TeamType entry names into 'tbuffer' - ------------------------------------------------------------------------*/ - WWGetPrivateProfileString("Teams", NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - - /* - ----------------------- Loop for all team entries ------------------------ - */ - while (*tbuffer != '\0') { - /* - ........................ Create a new trigger ......................... - */ - team = new TeamTypeClass(); - - /* - ............................ Set its name ............................. - */ - team->Set_Name(tbuffer); - - /* - ......................... Get the team entry .......................... - */ - WWGetPrivateProfileString("Teams", tbuffer, NULL, buf, sizeof(buf)-1, buffer); - - /* - .......................... 1st token: House ........................... - */ - team->House = HouseTypeClass::From_Name(strtok(buf,",")); - - /* - ........................ 2nd token: RoundAbout ........................ - */ - team->IsRoundAbout = atoi(strtok(NULL,",")); - - /* - ......................... 3rd token: Learning ......................... - */ - team->IsLearning = atoi(strtok(NULL,",")); - - /* - ......................... 4th token: Suicide .......................... - */ - team->IsSuicide = atoi(strtok(NULL,",")); - - /* - ........................... 5th token: Spy ............................ - */ - team->IsAutocreate = atoi(strtok(NULL,",")); - - /* - ........................ 6th token: Mercenary ......................... - */ - team->IsMercenary = atoi(strtok(NULL,",")); - - /* - ..................... 7th token: RecruitPriority ...................... - */ - team->RecruitPriority = atoi(strtok(NULL,",")); - - /* - ........................ 8th token: MaxAllowed ........................ - */ - team->MaxAllowed = atoi(strtok(NULL,",")); - - /* - ......................... 9th token: InitNum .......................... - */ - team->InitNum = atoi(strtok(NULL,",")); - - /* - ....................... 10th token: Mission name ...................... - */ - strtok(NULL,","); // just throw it away - - /* - ............ Loop through entries, setting class ptr & num ............ - */ - index = 0; - p1 = strtok(NULL,",:"); - p2 = strtok(NULL,",:"); - while (p1 && p2) { - otype = NULL; - - /* - ................. See if this is an infantry name .................. - */ - i_id = InfantryTypeClass::From_Name(p1); - if (i_id!=INFANTRY_NONE) { - otype = &InfantryTypeClass::As_Reference(i_id); - } - - /* - .................... See if this is a unit name .................... - */ - u_id = UnitTypeClass::From_Name(p1); - if (u_id != UNIT_NONE) { - otype = &UnitTypeClass::As_Reference(u_id); - } - - /* - ................. See if this is an aircraft name .................. - */ - a_id = AircraftTypeClass::From_Name(p1); - if (a_id != AIRCRAFT_NONE) { - otype = &AircraftTypeClass::As_Reference(a_id); - } - - /* - ............. If the name was resolved, add this class ............. - */ - if (otype) { - team->Class[index] = otype; - team->DesiredNum[index] = atoi(p2); - index++; - team->ClassCount = index; - } - - /* - ................. Go to the next entry on the line ................. - */ - p1 = strtok(NULL,",:"); - p2 = strtok(NULL,",:"); - } - - team->Fear = 0; - - /* - ...................... Go to the next INI entry ....................... - */ - tbuffer += strlen(tbuffer)+1; - } -} - - -/*************************************************************************** - * TeamTypeClass::As_Pointer -- gets ptr for team type with given name * - * * - * INPUT: * - * name name of teamtype * - * * - * OUTPUT: * - * ptr to TeamType with that name * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/07/1994 BR : Created. * - *=========================================================================*/ -TeamTypeClass * TeamTypeClass::As_Pointer(char *name) -{ - int i; - - if (name == NULL) { - return(NULL); - } - - for (i = 0; i < TeamTypes.Count(); i++) { - if (!stricmp(name, TeamTypes.Ptr(i)->IniName)) { - return(TeamTypes.Ptr(i)); - } - } - - return(NULL); -} - - -/*************************************************************************** - * TeamTypeClass::Remove -- removes this team from the system * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/09/1994 BR : Created. * - *=========================================================================*/ -void TeamTypeClass::Remove(void) -{ - Validate(); - int i; - TriggerClass * trigger; - - /* - ** Remove all trigger references to this team. - */ - for (i = 0; i < Triggers.Count(); i++) { - trigger = Triggers.Ptr(i); - if (trigger->Team == this) { - trigger->Team = NULL; - } - } - - /* - ** Delete myself. - */ - delete this; -} - - -/*************************************************************************** - * TeamTypeClass::Mission_From_Name -- returns team mission for given name * - * * - * INPUT: * - * name name to compare * - * * - * OUTPUT: * - * mission for that name * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/13/1994 BR : Created. * - *=========================================================================*/ -TeamMissionType TeamTypeClass::Mission_From_Name(char const *name) -{ - int order; - - if (name) { - for (order = TMISSION_FIRST; order < TMISSION_COUNT; order++) { - if (stricmp(TMissions[order], name) == 0) { - return((TeamMissionType) order); - } - } - } - - return(TMISSION_NONE); -} - - -/*************************************************************************** - * TeamTypeClass::Name_From_Mission -- returns name for given mission * - * * - * INPUT: * - * order mission to get name for * - * * - * OUTPUT: * - * name of mission * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/13/1994 BR : Created. * - *=========================================================================*/ -char const * TeamTypeClass::Name_From_Mission(TeamMissionType order) -{ - if (order <= TMISSION_NONE || order >= TMISSION_COUNT) { - return("None"); - } else { - return(TMissions[order]); - } -} - - -/*************************************************************************** - * TeamTypeClass::operator new -- 'new' operator * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * pointer to new TeamType * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=========================================================================*/ -void * TeamTypeClass::operator new(size_t ) -{ - void * ptr = TeamTypes.Allocate(); - if (ptr) { - ((TeamTypeClass *)ptr)->IsActive = true; - } - return(ptr); -} - - -/*************************************************************************** - * TeamTypeClass::operator delete -- 'delete' operator * - * * - * INPUT: * - * ptr pointer to delete * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=========================================================================*/ -void TeamTypeClass::operator delete(void *ptr) -{ - if (ptr) { - ((TeamTypeClass *)ptr)->IsActive = false; - } - TeamTypes.Free((TeamTypeClass *)ptr); -} - - - -TeamClass * TeamTypeClass::Create_One_Of(void) const -{ - if (ScenarioInit || TeamClass::Number[TeamTypes.ID(this)] < MaxAllowed) { - return(new TeamClass(this, HouseClass::As_Pointer(House))); - } - return(NULL); -} - - -TARGET TeamTypeClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_TEAMTYPE, TeamTypes.ID(this))); -} - - -void TeamTypeClass::Destroy_All_Of(void) const -{ - for (int index = 0; index < Teams.Count(); index++) { - TeamClass * team = Teams.Ptr(index); - - if (team->Class == this) { - delete team; - index--; - } - } -} - - -/*********************************************************************************************** - * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. * - * * - * This routine will scan through the team types available and create teams of the * - * type that can best utilize the existing unit mix. * - * * - * INPUT: house -- Pointer to the house that this team is to be created for. * - * * - * utype -- A bit mask of the unit types available for this house. * - * * - * itypes -- A bit mask of the infantry types available for this house. * - * * - * alerted -- Is this house alerted? If true, then the Autocreate teams will be * - * considered in the selection process. * - * * - * OUTPUT: Returns with a pointer to the team type that should be created. If no team should * - * be created, then it returns NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/13/1995 JLB : Created. * - * 07/21/1995 JLB : Will autocreate team even if no members in field. * - *=============================================================================================*/ -TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long utypes, long itypes, bool alerted) -{ - TeamTypeClass const * best = NULL; - int bestvalue = 0; - - for (int index = 0; index < TeamTypes.Count(); index++) { - TeamTypeClass const * ttype = TeamTypes.Ptr(index); - - if (ttype && - ttype->House == house->Class->House && - TeamClass::Number[index] < ((alerted || !ttype->IsAutocreate) ? ttype->MaxAllowed : 0)) { - - /* - ** Determine what kind of units this team requires. - */ - long uneeded = 0; - long ineeded = 0; - for (int ctype = 0; ctype < ttype->ClassCount; ctype++) { - switch (ttype->Class[ctype]->What_Am_I()) { - case RTTI_INFANTRYTYPE: - ineeded |= (1 << ((InfantryTypeClass *)ttype->Class[ctype])->Type); - break; - - case RTTI_UNITTYPE: - uneeded |= (1 << ((UnitTypeClass *)ttype->Class[ctype])->Type); - break; - } - } - - /* - ** If this team can use the types required, then consider it a possible - ** team type to create. - */ - int value = 0; - if ((ineeded & itypes) || (uneeded & utypes)) { - value = ttype->RecruitPriority; - } else { - value = ttype->RecruitPriority/2; - } - - if (!best || bestvalue < value) { - bestvalue = value; - best = ttype; - } - } - } - - return(best); -} diff --git a/code/TIBERIANDAWN/TEAMTYPE.H b/code/TIBERIANDAWN/TEAMTYPE.H deleted file mode 100644 index e9bc114..0000000 --- a/code/TIBERIANDAWN/TEAMTYPE.H +++ /dev/null @@ -1,261 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\teamtype.h_v 2.18 16 Oct 1995 16:45:40 JOE_BOSTIC $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEAMTYPE.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : December 7, 1994 * - * * - * Last Update : December 7, 1994 [BR] * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TEAMTYPE_H -#define TEAMTYPE_H - -/* -********************************** Defines ********************************** -*/ -//#define TEAMTYPE_MAX 20 // max # of different team types - -/* -** TeamMissionType: the various missions that a team can have. -*/ -typedef enum TeamMissionType : char { - TMISSION_NONE=-1, - TMISSION_ATTACKBASE, // Attack nearest enemy base. - TMISSION_ATTACKUNITS, // Attack all enemy units. - TMISSION_ATTACKCIVILIANS, // Attack all civilians - TMISSION_RAMPAGE, // attack & destroy anything that's not mine - TMISSION_DEFENDBASE, // Protect my base. -// TMISSION_HARVEST, // stake out a Tiberium claim, defend & harvest it - TMISSION_MOVE, // moves to waypoint specified. - TMISSION_MOVECELL, // moves to cell # specified. - TMISSION_RETREAT, // order given by superior team, for coordinating - TMISSION_GUARD, // works like an infantry's guard mission - TMISSION_LOOP, // loop back to start of mission list - TMISSION_ATTACKTARCOM, // attack tarcom - TMISSION_UNLOAD, // Unload at current location. - TMISSION_COUNT, - TMISSION_FIRST=0 -} TeamMissionType; - -/* -** Forward declarations. -*/ -class TechnoTypeClass; - - -/* -** This structure contains one team mission value & its argument. -*/ -typedef struct TeamMissionTag -{ - TeamMissionType Mission; - int Argument; -} TeamMissionStruct; - -/* -** TeamTypeClass declaration -*/ -class TeamTypeClass : public AbstractTypeClass -{ - public: - enum TeamTypeClassEnums { - MAX_TEAM_CLASSCOUNT=5, - MAX_TEAM_MISSIONS=20 - }; - - /* - ** Constructor/Destructor - */ - TeamTypeClass(void); - virtual ~TeamTypeClass(void) {}; - - /* - ** Initialization: clears all team types in preparation for new scenario - */ - static void Init(void); - - /* - ** File I/O routines - */ - static void Read_INI(char *buffer); - void Fill_In(char *name, char *entry); - static void Write_INI(char *buffer, bool refresh); - static void Read_Old_INI(char *buffer); - static char * INI_Name(void) {return "TeamTypes";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - /* - ** As_Pointer gets a pointer to the trigger object give its name - */ - static TeamTypeClass *As_Pointer(char *name); - - /* - ** Processing routines - */ - void Remove(void); - TeamClass * Create_One_Of(void) const; - void Destroy_All_Of(void) const; - - /* - ** Utility routines - */ - static char const * Name_From_Mission(TeamMissionType order); - static TeamMissionType Mission_From_Name(char const *name); - static TeamTypeClass const * Suggested_New_Team(HouseClass * house, long utypes, long itypes, bool alerted); - - TARGET As_Target(void) const; - - /* - ** Overloaded operators - */ - void * operator new(size_t ); - void operator delete(void *ptr); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** If this teamtype object is active, then this flag will be true. - ** TeamType objects that are not active are either not yet created or have - ** been deleted after fulfilling their action. - */ - unsigned IsActive:1; - - /* - ** If RoundAbout, the team avoids high-threat areas - */ - unsigned IsRoundAbout:1; - - /* - ** If Learning, the team learns from mistakes - */ - unsigned IsLearning:1; - - /* - ** If Suicide, the team won't stop until it achieves its mission or it's - ** dead - */ - unsigned IsSuicide:1; - - /* - ** Is this team type allowed to be created automatically by the computer - ** when the appropriate trigger indicates? - */ - unsigned IsAutocreate:1; - - /* - ** Mercenaries will change sides if they start to lose. - */ - unsigned IsMercenary:1; - - /* - ** This flag tells the computer that it should build members to fill - ** a team of this type regardless of whether there actually is a team - ** of this type active. - */ - unsigned IsPrebuilt:1; - - /* - ** If this team should allow recruitment of new members, then this flag - ** will be true. A false value results in a team that fights until it - ** is dead. This is similar to IsSuicide, but they will defend themselves. - */ - unsigned IsReinforcable:1; - - /* - ** A transient team type was created exclusively to bring on reinforcements - ** as a result of some special event. As soon as there are no teams - ** existing of this type, then this team type should be deleted. - */ - unsigned IsTransient:1; - - /* - ** Priority given the team for recruiting purposes; higher priority means - ** it can steal members from other teams (scale: 0 - 15) - */ - int RecruitPriority; - - /* - ** Initial # of this type of team - */ - unsigned char InitNum; - - /* - ** Max # of this type of team allowed at one time - */ - unsigned char MaxAllowed; - - /* - ** Fear level of this team - */ - unsigned char Fear; - - /* - ** House the team belongs to - */ - HousesType House; - - /* - ** The mission list for this team - */ - int MissionCount; - TeamMissionStruct MissionList[MAX_TEAM_MISSIONS]; - - /* - ** Number of different classes in the team - */ - unsigned char ClassCount; - - /* - ** Array of object types comprising the team - */ - TechnoTypeClass const * Class[MAX_TEAM_CLASSCOUNT]; - - /* - ** Desired # of each type of object comprising the team - */ - unsigned char DesiredNum[MAX_TEAM_CLASSCOUNT]; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - - private: - static char const * TMissions[TMISSION_COUNT]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TECHNO.CPP b/code/TIBERIANDAWN/TECHNO.CPP deleted file mode 100644 index 87bf3cc..0000000 --- a/code/TIBERIANDAWN/TECHNO.CPP +++ /dev/null @@ -1,4809 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\techno.cpv 2.13 02 Aug 1995 17:01:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : BASE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 8, 1994 * - * * - * Last Update : August 23, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TechnoClass::AI -- Handles AI processing for techno object. * - * TechnoClass::Assign_Destination -- Assigns movement destination to the object. * - * TechnoClass::Assign_Target -- Assigns the targeting computer with specified target. * - * TechnoClass::Base_Is_Attacked -- Handle panic response to base being attacked. * - * TechnoClass::Can_Fire -- Determines if this techno object can fire. * - * TechnoClass::Can_Player_Fire -- Determines if the player can give this object a fire order* - * TechnoClass::Can_Player_Move -- Determines if the object can move be moved by player. * - * TechnoClass::Can_Repair -- Determines if the object can and should be repaired. * - * TechnoClass::Captured -- Handles capturing this object. * - * TechnoClass::Clicked_As_Target -- Sets the flash count for this techno object. * - * TechnoClass::Crew_Type -- Fetches the kind of crew this object contains. * - * TechnoClass::Debug_Dump -- Displays the base class data to the monochrome screen. * - * TechnoClass::Desired_Load_Dir -- Fetches loading parameters for this object. * - * TechnoClass::Detach -- Handles removal of target from tracking system. * - * TechnoClass::Do_Cloak -- Start the object into cloaking stage. * - * TechnoClass::Do_Shimmer -- Causes this object to shimmer if it is cloaked. * - * TechnoClass::Do_Uncloak -- Cause the stealth tank to uncloak. * - * TechnoClass::Draw_It -- Draws the health bar (if necessary). * - * TechnoClass::Draw_Pips -- Draws the transport pips and other techno graphics. * - * TechnoClass::Enter_Idle_Mode -- Object enters its default idle condition. * - * TechnoClass::Evaluate_Cell -- Determine the value and object of specified cell. * - * TechnoClass::Evaluate_Object -- Determines score value of specified object. * - * TechnoClass::Exit_Object -- Causes specified object to leave this object. * - * TechnoClass::Find_Docking_Bay -- Searches for a close docking bay. * - * TechnoClass::Find_Exit_Cell -- Finds an appropriate exit cell for this object. * - * TechnoClass::Fire_At -- Fires projectile at target specified. * - * TechnoClass::Fire_Direction -- Fetches the direction projectile fire will take. * - * TechnoClass::Get_Ownable -- Fetches the ownable bits for this object. * - * TechnoClass::Greatest_Threat -- Determines best target given search criteria. * - * TechnoClass::Hidden -- Returns the object back into the hidden state. * - * TechnoClass::In_Range -- Determines if specified target is within weapon range. * - * TechnoClass::In_Range -- Determines if specified target is within weapon range. * - * TechnoClass::In_Range -- Determines if the specified coordinate is within range. * - * TechnoClass::Is_Techno -- Confirms that this is a TechnoClass object. * - * TechnoClass::Is_Weapon_Equipped -- Determines if this object has a combat weapon. * - * TechnoClass::Kill_Cargo -- Destroys any cargo attached to this object. * - * TechnoClass::Mark -- Handles marking of techno objects. * - * TechnoClass::Nearby_Location -- Radiates outward looking for clear cell nearby. * - * TechnoClass::Owner -- Who is the owner of this object? * - * TechnoClass::Per_Cell_Process -- Handles once-per-cell operations for techno type objects.* - * TechnoClass::Pip_Count -- Fetches the number of pips to display on this object. * - * TechnoClass::Player_Assign_Mission -- Assigns a mission as result of player input. * - * TechnoClass::Random_Animate -- Performs some idle animation for the object. * - * TechnoClass::Rearm_Delay -- Calculates the delay before firing can occur. * - * TechnoClass::Receive_Message -- Handles inbound message as appropriate. * - * TechnoClass::Record_The_Kill -- Records the death of this object. * - * TechnoClass::Remap_Table -- Fetches the appropriate remap table to use. * - * TechnoClass::Response_Attack -- Handles the voice response when given attack order. * - * TechnoClass::Response_Move -- Handles the voice repsonse to a movement request. * - * TechnoClass::Response_Select -- Handles the voice response when selected. * - * TechnoClass::Revealed -- Handles revealing an object to the house specified. * - * TechnoClass::Risk -- Fetches the risk associated with this object. * - * TechnoClass::Scatter -- Causes the object to scatter to an adjacent cell. * - * TechnoClass::Select -- Selects object and checks to see if can be selected. * - * TechnoClass::Set_Mission -- Forced mission set (used by editor). * - * TechnoClass::Stun -- Prepares the object for removal from the game. * - * TechnoClass::Take_Damage -- Records damage assessed to this object. * - * TechnoClass::Target_Something_Nearby -- Handles finding and assigning a nearby target. * - * TechnoClass::TechnoClass -- Constructor for techno type objects. * - * TechnoClass::TechnoClass -- Default constructor for techno objects. * - * TechnoClass::Techno_Draw_Object -- General purpose draw object routine. * - * TechnoClass::Threat_Range -- Returns the range to scan based on threat control. * - * TechnoClass::Tiberium_Load -- Fetches the current tiberium load percentage. * - * TechnoClass::Unlimbo -- Performs unlimbo process for all techno type objects. * - * TechnoClass::Value -- Fetches the target value for this object. * - * TechnoClass::Visual_Character -- Determine the visual character of the object. * - * TechnoClass::Weapon_Range -- Determines the maximum range for the weapon. * - * TechnoClass::What_Action -- Determines action to perform if cell is clicked on. * - * TechnoClass::What_Action -- Determines what action to perform if object is selected. * - * TechnoTypeClass::Cost_Of -- Fetches the cost of this object type. * - * TechnoTypeClass::Get_Cameo_Data -- Fetches the cameo image for this object type. * - * TechnoTypeClass::Get_Ownable -- Fetches the ownable bits for this object type. * - * TechnoTypeClass::Max_Passengers -- Fetches the maximum passengers allowed. * - * TechnoTypeClass::Repair_Cost -- Fetches the cost to repair one step. * - * TechnoTypeClass::Repair_Step -- Fetches the health to repair one step. * - * TechnoTypeClass::TechnoTypeClass -- Constructor for techno type objects. * - * TechnoTypeClass::Time_To_Build -- Fetches the time to build this object. * - * TechnoTypeClass::Raw_Cost -- Fetches the raw (base) cost of the object. * - * TechnoClass::Refund_Amount -- Returns with the money to refund if this object is sold. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*************************************************************************** -** Cloaking control values. -*/ -#define MAX_UNCLOAK_STAGE 38 -#define UNCLOAK_VIS_TIME (1*TICKS_PER_SECOND) - -//Added for getting the input for special character keys from the client -// - 6/26/2019 JAS -extern bool DLL_Export_Get_Input_Key_State(KeyNumType key); - - -/*************************************************************************** -** Which shape to use depending on which facing is controlled by these arrays. -*/ -int const TechnoClass::BodyShape[32] = {0,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; - - -/*********************************************************************************************** - * TechnoTypeClass::TechnoTypeClass -- Constructor for techno type objects. * - * * - * This is the normal constructor for techno type objects. It is called in the process of * - * constructing all the object type (constant) data for the various techno type objects. * - * * - * INPUT: see below... * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -TechnoTypeClass::TechnoTypeClass( - int name, - char const *ininame, - unsigned char level, - long pre, - bool is_leader, - bool is_scanner, - bool is_nominal, - bool is_transporter, - bool is_flammable, - bool is_crushable, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - bool is_theater, - bool is_twoshooter, - bool is_turret_equipped, - bool is_repairable, - bool is_buildable, - bool is_crew, - int ammo, - unsigned short strength, - MPHType maxspeed, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, - WeaponType secondary, - ArmorType armor) : - ObjectTypeClass( true, - is_flammable, - is_crushable, - is_stealthy, - is_selectable, - is_legal_target, - is_insignificant, - is_immune, - name, - ininame, - armor, - strength) -{ - Level = level; - Pre = pre; - MaxAmmo = ammo; - MaxSpeed = maxspeed; - CameoData = NULL; - Primary = primary, - Secondary = secondary, - Cost = cost; - IsLeader = is_leader; - IsScanner = is_scanner; - IsTransporter = is_transporter; - IsTwoShooter = is_twoshooter; - IsBuildable = is_buildable; - IsCrew = is_crew; - IsTheater = is_theater; - IsRepairable = is_repairable; - IsTurretEquipped= is_turret_equipped; - IsNominal = is_nominal; - Ownable = ownable; - Reward = reward; - Scenario = scenario; - SightRange = sightrange; - - /* - ** Units risk value is based on the type of weapon he has and the - ** rate of fire it shoots at. - */ - risk = risk; - Risk = 0; - if (primary != WEAPON_NONE) { - Risk = (Weapons[primary].Attack * (Weapons[primary].Range >> 4)) / Weapons[primary].ROF; - } -} - - -/*********************************************************************************************** - * TechnoTypeClass::Raw_Cost -- Fetches the raw (base) cost of the object. * - * * - * This routine is used to find the underlying cost for this object. The underlying cost * - * does not include any free items that normally come with the object when purchased * - * directly. Example: The raw cost of a refinery is the normal cost minus the cost of a * - * harvester. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the credit cost of the base object type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoTypeClass::Raw_Cost(void) const -{ - return(Cost); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Get_Ownable -- Fetches the ownable bits for this object type. * - * * - * This routine will return the ownable bits for this object type. The ownable bits are * - * a bitflag composite of the houses that can own (build) this object type. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the ownable bits for this object type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -unsigned short TechnoTypeClass::Get_Ownable(void) const -{ - return(Ownable); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Time_To_Build -- Fetches the time to build this object. * - * * - * This routine will return the time it takes to construct this object. Usually the time * - * to produce is directly related to cost. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the time to produce this object type. The time is expressed in the * - * form of game ticks. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoTypeClass::Time_To_Build(HousesType house) const -{ - /* - ** Base time is the raw cost. - */ - int time = Raw_Cost(); - - HouseClass* hptr = HouseClass::As_Pointer(house); - if (!hptr || !hptr->IsActive) { - return time; - } - - /* - ** For computer controlled buildings, slow down production on - ** cheaper buildings. - */ - if (PlayerPtr->Difficulty != DIFF_HARD && - GameToPlay == GAME_NORMAL && - What_Am_I() == RTTI_BUILDINGTYPE && - PlayerPtr->Class->House != hptr->Class->House) { - time = (time + (PlayerPtr->Difficulty == DIFF_EASY ? 4000 : 2000)) / 2; - } - - /* - ** Fudge factor, so that Nod builds a bit faster if the object must be delivered to - ** an airfield. - */ - if (What_Am_I() == RTTI_UNITTYPE && !(Ownable & HOUSEF_GOOD)) { - time -= (time / 4); - } - - /* - ** Adjust time according to IQ setting of computer controlled house. The - ** build time will range from double normal time at the slowest to - ** just normal time at the fastest. - */ - if (!hptr->IsHuman && Rule.Diff[hptr->Difficulty].IsBuildSlowdown) { - time = (int)((time * Rule.MaxIQ * 2.0f) / (hptr->IQ + Rule.MaxIQ)); - } - - /* - ** Adjust the time to build based on the power output of the owning house. - */ - int power = hptr->Power_Fraction(); - int inv_scale(256); - if (power == 0x000) { - inv_scale = 64; - } - else if (power < 0x080) { - inv_scale = 103; - } - else if (power < 0x0100) { - inv_scale = 171; - } - time = (time * 256) / inv_scale; - - return(time); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Cost_Of -- Fetches the cost of this object type. * - * * - * This routine will return the cost to produce an object of this type. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the cost to produce one object of this type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoTypeClass::Cost_Of(void) const -{ - return(Cost); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Get_Cameo_Data -- Fetches the cameo image for this object type. * - * * - * This routine will fetch the cameo (sidebar small image) shape of this object type. * - * If there is no cameo data available (typical for non-producable units), then NULL will * - * be returned. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the cameo data for this object type if present. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void const * TechnoTypeClass::Get_Cameo_Data(void) const -{ - return(CameoData); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Repair_Cost -- Fetches the cost to repair one step. * - * * - * This routine will return the cost to repair one step. At the TechnoTypeClass level, * - * this merely serves as a placeholder function. The derived classes will provide a * - * functional version of this routine. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the cost to repair one step. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoTypeClass::Repair_Cost(void) const -{ - return(0); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Repair_Step -- Fetches the health to repair one step. * - * * - * This routine merely serves as placeholder virtual function. The various type classes * - * will override this routine to return the number of health points to repair in one * - * "step". * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of health points to repair in one step. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoTypeClass::Repair_Step(void) const -{ - return(0); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * TechnoClass::Debug_Dump -- Displays the base class data to the monochrome screen. * - * * - * This routine is used to dump the status of the object class to the monochrome screen. * - * This display can be used to track down or prevent bugs. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Debug_Dump(MonoClass *mono) const -{ - mono->Set_Cursor(0,0);mono->Printf("(%04X)p=%d,d=%d", House->Power_Fraction(), House->Power, House->Drain); -// mono->Set_Cursor(0,0);mono->Printf("(%d)", House->Blockage); - mono->Text_Print("X", 16 + (IsALoaner?2:0), 11); - mono->Text_Print("X", 16 + (IsLocked?2:0), 9); - - mono->Text_Print("X", 16 + (IsInRecoilState?2:0), 17); - mono->Text_Print("X", 16 + (IsTethered?2:0), 8); - mono->Text_Print("X", 16 + (IsOwnedByPlayer?2:0), 5); - mono->Text_Print("X", 16 + (IsDiscoveredByPlayer?2:0), 6); -// mono->Text_Print("X", 16 + (IsALemon?2:0), 9); - mono->Set_Cursor(28, 7);mono->Printf("%2d", Arm); - mono->Set_Cursor(34, 1);mono->Printf("%04X", TarCom); - mono->Set_Cursor(29, 3);mono->Printf("%02X", PrimaryFacing.Current()); - - FlasherClass::Debug_Dump(mono); - StageClass::Debug_Dump(mono); - RadioClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * TechnoClass::TechnoClass -- Default constructor for techno objects. * - * * - * This default constructor for techno objects is used to reset all internal variables to * - * their default state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -TechnoClass::TechnoClass(void) : - TarCom(TARGET_NONE), - House(0) -{ - ArchiveTarget = TARGET_NONE; - Arm = 0; - Ammo = -1; - LineCount = 0; - LineFrame = 0; - LineMaxFrames = 0; - PurchasePrice = 0; - IsTickedOff = false; - Cloak = UNCLOAKED; - CloakingDevice.Set_Stage(1); - CloakingDevice.Set_Rate(0); - IsCloakable = false; - IsALemon = false; - IsALoaner = false; - IsDiscoveredByPlayer = false; - IsDiscoveredByComputer = false; - IsInRecoilState = false; - IsLeader = false; - IsLocked = false; - IsOwnedByPlayer = false; - IsSecondShot = true; - IsTethered = false; - SuspendedTarCom = TARGET_NONE; - PrimaryFacing.Set(DIR_N); - - // Added for multiplayer changes. ST - 3/6/2019 11:34AM - IsDiscoveredByPlayerMask = 0; -} - - - -/*********************************************************************************************** - * TechnoClass::Revealed -- Handles revealing an object to the house specified. * - * * - * When a unit moves out from under the shroud or when it gets delivered into already * - * explored terrain, then it must be "revealed". Objects that are revealed may be * - * announced to the player. The discovered bit updated accordingly. * - * * - * INPUT: house -- The house that this object is revealed to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - * 12/27/1994 JLB : Discovered trigger event processing. * - * 03/06/2019 ST : Per-player discovery * - *=============================================================================================*/ -bool TechnoClass::Revealed(HouseClass * house) -{ - //if (house == PlayerPtr && IsDiscoveredByPlayer) return(false); - //if (house != PlayerPtr && IsDiscoveredByComputer) return(false); - if (house == NULL) { - return false; - } - - if (Is_Discovered_By_Player(house)) { - return false; - } - - if (house->IsHuman == false) { - if (IsDiscoveredByComputer) { - return false; - } - } - - if (RadioClass::Revealed(house)) { - - /* - ** An enemy object that is discovered will go into hunt mode if - ** its current mission is to ambush. - */ - if (!house->IsHuman && Mission == MISSION_AMBUSH) { - Assign_Mission(MISSION_HUNT); - } - - if (GameToPlay == GAME_NORMAL) { - if (house == PlayerPtr) { - if (!IsOwnedByPlayer) { - - /* - ** If there is a trigger event associated with this object, then process - ** it for discovery purposes. - */ - if (Trigger) { - Trigger->Spring(EVENT_DISCOVERED, this); - } - - /* - ** Alert the enemy house to presence of the friendly side. - */ - House->IsDiscovered = true; - - if (house->IsHuman) { - Set_Discovered_By_Player(house); - } else { - IsDiscoveredByComputer = true; - } - - } else { - - if (house->IsHuman) { - Set_Discovered_By_Player(house); - } else { - IsDiscoveredByComputer = true; - } - Look(); - - } - } - } else { - - if (house->IsHuman) { - Set_Discovered_By_Player(house); - } else { - IsDiscoveredByComputer = true; - } - - Look(); - } - - return(true); - } - return(false); -} - -#if (0) // ST - 3/6/2019 11:35AM -/*********************************************************************************************** - * TechnoClass::Revealed -- Handles revealing an object to the house specified. * - * * - * When a unit moves out from under the shroud or when it gets delivered into already * - * explored terrain, then it must be "revealed". Objects that are revealed may be * - * announced to the player. The discovered bit updated accordingly. * - * * - * INPUT: house -- The house that this object is revealed to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - * 12/27/1994 JLB : Discovered trigger event processing. * - *=============================================================================================*/ -bool TechnoClass::Revealed(HouseClass * house) -{ - if (house == PlayerPtr && IsDiscoveredByPlayer) return(false); - if (house != PlayerPtr && IsDiscoveredByComputer) return(false); - - if (RadioClass::Revealed(house)) { - - /* - ** An enemy object that is discovered will go into hunt mode if - ** its current mission is to ambush. - */ - if (!house->IsHuman && Mission == MISSION_AMBUSH) { - Assign_Mission(MISSION_HUNT); - } - - if (house == PlayerPtr) { - - if (!IsOwnedByPlayer) { - - /* - ** If there is a trigger event associated with this object, then process - ** it for discovery purposes. - */ - if (Trigger) { - Trigger->Spring(EVENT_DISCOVERED, this); - } - - /* - ** Alert the enemy house to presence of the friendly side. - */ - House->IsDiscovered = true; - - } else { - - /* - ** A newly revealed object will always perform a look operation. - */ - if (house == PlayerPtr) IsDiscoveredByPlayer = true; - if (house != PlayerPtr) IsDiscoveredByComputer = true; - Look(); - } - } - - if (house == PlayerPtr) IsDiscoveredByPlayer = true; - if (house != PlayerPtr) IsDiscoveredByComputer = true; - - return(true); - } - return(false); -} -#endif - -/*********************************************************************************************** - * TechnoClass::Hidden -- Returns the object back into the hidden state. * - * * - * This routine is called for every object that returns to the darkness shroud or when * - * it gets destroyed. This also occurs when an object enters another (such as infantry * - * entering a transport helicopter). * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Hidden(void) -{ - // ST - 3/13/2019 4:56PM - if (!Is_Discovered_By_Player()) { - return; - } - //if (!IsDiscoveredByPlayer) return; - if (!House->IsHuman) { - Clear_Discovered_By_Players(); - } -} - - -/*********************************************************************************************** - * TechnoClass::Mark -- Handles marking of techno objects. * - * * - * On the Techno-level, marking handles transmission of the redraw command to any object * - * that it is 'connected' with. This only occurs during loading and unloading. * - * * - * INPUT: mark -- The marking method. This routine just passes this on to base classes. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Mark(MarkType mark) -{ - if (RadioClass::Mark(mark)) { - /* - ** When redrawing an object, if there is another object teathered to this one, - ** redraw it as well. - */ - if (IsTethered) { - Transmit_Message(RADIO_REDRAW); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::Receive_Message -- Handles inbound message as appropriate. * - * * - * This routine is used to handle inbound radio messages. It only handles those messages * - * that deal with techno objects. Typically, these include loading and unloading. * - * * - * INPUT: from -- Pointer to the originator of the radio message. * - * * - * message -- The inbound radio message. * - * * - * param -- Reference to optional parameter that might be used to transfer * - * more information than is possible with the simple radio message * - * type. * - * * - * OUTPUT: Returns with the radio response. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 06/17/1995 JLB : Handles tether contact messages. * - *=============================================================================================*/ -RadioMessageType TechnoClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - switch (message) { - - /* - ** Just received instructions to attack the specified target. - */ - case RADIO_ATTACK_THIS: - if (Techno_Type_Class()->Primary != WEAPON_NONE) { - Assign_Target(param); - Assign_Mission(MISSION_ATTACK); - return(RADIO_ROGER); - } - break; - - /* - ** Establish a tethered connection to the object in radio contact. - */ - case RADIO_TETHER: - if (!IsTethered) { - IsTethered = true; - Transmit_Message(RADIO_TETHER, from); - return(RADIO_ROGER); - } - break; - - /* - ** Break the tethered connection to the object in radio contact. - */ - case RADIO_UNTETHER: - if (IsTethered) { - IsTethered = false; - Transmit_Message(RADIO_UNTETHER, from); - return(RADIO_ROGER); - } - break; - - /* - ** A teathered unit has reached it's destination. All is - ** clear, so radio contact can be broken. - */ - case RADIO_UNLOADED: - Transmit_Message(RADIO_UNTETHER, from); - return(Transmit_Message(RADIO_OVER_OUT, from)); - - /* - ** When this message is received, it means that the other object - ** has already turned its radio off. Turn this radio off as well. - */ - case RADIO_OVER_OUT: - Transmit_Message(RADIO_UNTETHER, from); - RadioClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - - /* - ** Request to be informed when unloaded. This message is transmitted - ** by the transport unit to the transported unit as it is about to be - ** unloaded. It is saying, "All is clear. Drive off now." - */ - case RADIO_UNLOAD: - case RADIO_BACKUP_NOW: - case RADIO_HOLD_STILL: - Transmit_Message(RADIO_TETHER, from); - RadioClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - - /* - ** Handle reloading one ammo point for this unit. - */ - case RADIO_RELOAD: - if (Ammo == Techno_Type_Class()->MaxAmmo) return(RADIO_NEGATIVE); - Ammo++; - return(RADIO_ROGER); - - /* - ** Handle repair of this unit. - */ - case RADIO_REPAIR: - if (/*param > 0 &&*/ Health_Ratio() < 0x0100) { - int cost = Techno_Type_Class()->Repair_Cost(); -// int cost = Fixed_To_Cardinal(Techno_Type_Class()->Repair_Cost(), param); - cost = MAX(cost, 1); - int step = Techno_Type_Class()->Repair_Step(); -// int step = Fixed_To_Cardinal(Techno_Type_Class()->Repair_Step(), param); - step = MAX(step, 1); - if (House->Available_Money() >= cost) { -#ifdef OBSOLETE - if (Health_Ratio() >= 0x0100) { - Strength = Class_Of().MaxStrength; - from->Scatter(true); - return(RADIO_NEGATIVE); - } -#endif - House->Spend_Money(cost); - Strength += step; - return(RADIO_ROGER); - } - } - break; - - default: - break; - } - return(RadioClass::Receive_Message(from, message, param)); -} - - -/*********************************************************************************************** - * TechnoClass::TechnoClass -- Constructor for techno type objects. * - * * - * This constructor sets the owner of this object and its strength. Any object not owned * - * by the player is marked as a loaner. This is a special flag that indicates off-map * - * movement is allowed. The flag is cleared when the object finally enters the map. * - * * - * INPUT: house -- The house (owner) of this object. * - * * - * strength -- The strength to assign to this object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - *=============================================================================================*/ -TechnoClass::TechnoClass(HousesType house) : - House(HouseClass::As_Pointer(house)), - TarCom(TARGET_NONE) -{ - ArchiveTarget = TARGET_NONE; - Arm = 0; - Ammo = -1; - LineCount = 0; - LineFrame = 0; - LineMaxFrames = 0; - PurchasePrice = 0; - IsTickedOff = false; - Cloak = UNCLOAKED; - CloakingDevice.Set_Stage(1); - CloakingDevice.Set_Rate(0); - IsCloakable = false; - IsALemon = false; - IsALoaner = false; - IsDiscoveredByComputer = false; - //IsOwnedByPlayer = (house == PlayerPtr->Class->House); // ST - 4/24/2019 10:41AM - IsDiscoveredByPlayer = false; - IsInRecoilState = false; - IsLeader = false; - IsLocked = false; - IsSecondShot = false; - IsTethered = false; - - SuspendedTarCom = TARGET_NONE; - - PrimaryFacing.Set(DIR_N); - - // Added for multiplayer changes. ST - 4/24/2019 10:40AM - IsDiscoveredByPlayerMask = 0; - if (GameToPlay == GAME_NORMAL) { - IsOwnedByPlayer = (house == PlayerPtr->Class->House); - } else { - IsOwnedByPlayer = House->IsHuman; - } - - /* - ** There is a chance that a vehicle will be a "lemon". - */ - if (Random_Pick(0, 255) < (int)House->Class->Lemon) { - IsALemon = true; - } -} - - -/*********************************************************************************************** - * TechnoClass::Per_Cell_Process -- Handles once-per-cell operations for techno type objects. * - * * - * This routine handles marking a game object as not a loaner. It is set only if the unit * - * is not player owned and is on the regular map. This is necessary so that enemy objects * - * can exist off-map but as soon as they move onto the map, are flagged so that can never * - * leave it again. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 10/26/94 JLB : Handles scanner units. * - * 12/27/1994 JLB : Checks for an processes any trigger in cell. * - *=============================================================================================*/ -void TechnoClass::Per_Cell_Process(bool ) -{ - CELL cell = Coord_Cell(Center_Coord()); - - /* - ** When enemy units enter the proper map area from off map, they are - ** flagged so that they won't travel back off the map again. - */ - if (Map.In_Radar(cell)) { - - if (What_Am_I() == RTTI_UNIT) { - UnitClass * u = (UnitClass *)this; - - if (*u != UNIT_HOVER && *u != UNIT_GUNBOAT) { - IsLocked = true; - } - } else { - IsLocked = true; - } - } - - /* - ** If this object somehow moves into mapped terrain, but is not yet - ** discovered, then flag it to be discovered. - */ - // ST - 3/13/2019 4:56PM - if (!Is_Discovered_By_Player() && Map[cell].Is_Visible(House)) { - //if (!IsDiscoveredByPlayer && Map[cell].IsVisible) { - //Revealed(PlayerPtr); - Revealed(House); // ST - 8/7/2019 11:20AM - } -} - - -/*********************************************************************************************** - * TechnoClass::Draw_It -- Draws the health bar (if necessary). * - * * - * This routine will draw the common elements for techno type objects. This element is * - * the health bar. The main game object has already been rendered by the time this * - * routine is called. * - * * - * INPUT: x,y -- The coordinate of the center of the unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/17/1994 JLB : Created. * - * 10/26/94 JLB : Knows about radar scanned cells. * - * 12/13/1994 JLB : Clips health bar against map edge. * - * 01/23/1995 JLB : Dynamic selected object rectangle. * - *=============================================================================================*/ -void TechnoClass::Draw_It(int x, int y, WindowNumberType window) -{ - Clear_Redraw_Flag(); - - const bool show_health_bar = - (Strength > 0) && ((Cloak != CLOAKED) || Is_Owned_By_Player()) && - (Is_Selected_By_Player() || - ((Special.HealthBarDisplayMode == SpecialClass::HB_DAMAGED) && (Strength < Techno_Type_Class()->MaxStrength)) || - (Special.HealthBarDisplayMode == SpecialClass::HB_ALWAYS)); - - /* - ** Fetch the dimensions of the object. These dimensions will be used to draw - ** the selection box and the health bar. - */ - int width, height; - Class_Of().Dimensions(width, height); - int lx = width/2; - int ly = height/2; - int dx = width/5; - int dy = height/5; - int fudge = show_health_bar ? 4 : 0; - - /* - ** Draw lines - */ - if (LineFrame < LineMaxFrames) { - // Only draw the last line for virtual window - int start_line = (window == WINDOW_VIRTUAL) ? max(0, LineCount - 1) : 0; - for (int i = start_line; i < LineCount; i++) { - CC_Draw_Line(Lines[i][0], Lines[i][1], Lines[i][2], Lines[i][3], (unsigned char)Lines[i][4], LineFrame, window); - } - if (window == WINDOW_VIRTUAL) { - LineFrame++; - } - } - - if (Is_Selected_By_Player() || show_health_bar) { - GraphicViewPortClass draw_window( LogicPage->Get_Graphic_Buffer(), - (WindowList[window][WINDOWX] << 3) + LogicPage->Get_XPos(), - WindowList[window][WINDOWY] + LogicPage->Get_YPos(), - WindowList[window][WINDOWWIDTH] << 3, - WindowList[window][WINDOWHEIGHT]); - - - /* - ** The infantry select box should be a bit higher than normal. - */ - if (What_Am_I() == RTTI_INFANTRY) { - y -= 6; - } - - if (What_Am_I() == RTTI_BUILDING && ((BuildingTypeClass const &)Class_Of()).Type == STRUCT_BARRACKS) { - y -= 5; - } - - if (show_health_bar) { - unsigned ratio = Health_Ratio(); - int pwidth; // Pixel width of bar interior. - int color; // The color to give the interior of the bargraph. - - int xx = x-width/2; - int yy = y-(height/2); - - /* - ** Draw the outline of the bargraph. - */ - draw_window.Remap(xx+1, yy+1, width-1, 3-1, Map.FadingShade); - draw_window.Draw_Rect(xx, yy, xx+width-1, yy+3, BLACK); - - /* - ** Determine the width of the interior strength - ** graph. - */ - pwidth = Fixed_To_Cardinal(width-2, ratio); - - pwidth = Bound(pwidth, 1, width-2); - - color = LTGREEN; - if (ratio < 0x7F) { - color = YELLOW; - } - if (ratio < 0x3F) { - color = RED; - } - draw_window.Fill_Rect(xx+1, yy+1, xx+pwidth, yy+(3-1), color); - } - - /* - ** Draw the selected object graphic. - */ - if (Is_Selected_By_Player()) { - // Upper left corner. - draw_window.Draw_Line(x-lx, fudge+y-ly, x-lx+dx, fudge+y-ly, WHITE); - draw_window.Draw_Line(x-lx, fudge+y-ly, x-lx, fudge+y-ly+dy, WHITE); - - // Upper right corner. - draw_window.Draw_Line(x+lx, fudge+y-ly, x+lx-dx, fudge+y-ly, WHITE); - draw_window.Draw_Line(x+lx, fudge+y-ly, x+lx, fudge+y-ly+dy, WHITE); - - // Lower right corner. - draw_window.Draw_Line(x+lx, y+ly, x+lx-dx, y+ly, WHITE); - draw_window.Draw_Line(x+lx, y+ly, x+lx, y+ly-dy, WHITE); - - // Lower left corner. - draw_window.Draw_Line(x-lx, y+ly, x-lx+dx, y+ly, WHITE); - draw_window.Draw_Line(x-lx, y+ly, x-lx, y+ly-dy, WHITE); - } - } - - // MBL 04.21.2020 - bool selected = Is_Selected_By_Player() || Special.ResourceBarDisplayMode == SpecialClass::RB_ALWAYS; - // if ((window == WINDOW_VIRTUAL) || (Is_Selected_By_Player() && House->Is_Ally(PlayerPtr))) - if ((window == WINDOW_VIRTUAL) || (selected && House->Is_Ally(PlayerPtr))) - { - Draw_Pips((x-lx)+5, y+ly-3, window); - } -} - - -/*********************************************************************************************** - * TechnoClass::Unlimbo -- Performs unlimbo process for all techno type objects. * - * * - * This routine handles the common operation between techno objects when they are * - * unlimboed. This includes revealing the map. * - * * - * INPUT: coord -- The coordinate to unlimbo object at. * - * * - * dir (optional) -- initial facing direction for this object * - * * - * OUTPUT: bool; Was the unlimbo successful? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/14/1994 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Unlimbo(COORDINATE coord, DirType dir) -{ - if (RadioClass::Unlimbo(coord, dir)) { - PrimaryFacing = dir; - Enter_Idle_Mode(true); - Commence(); - - IsLocked = Map.In_Radar(Coord_Cell(coord)); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::In_Range -- Determines if specified target is within weapon range. * - * * - * This routine is used to compare the distance to the specified target with the range * - * of the weapon. If the target is outside of weapon range, then false is returned. * - * * - * INPUT: target -- The target to check if it is within weapon range. * - * * - * which -- Which weapon to use in determining range. 0=primary, 1=secondary. * - * * - * OUTPUT: bool; Is the specified target within weapon range? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/14/1994 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::In_Range(TARGET target, int which, bool reciprocal_check) const -{ - if (IsLocked && Target_Legal(target)) { - int range = Weapon_Range(which); - BuildingClass const * building = As_Building(target); - if (building) { - range += ((building->Class->Width() + building->Class->Height()) * (ICON_LEPTON_W / 4)); - } - if (::Distance(Fire_Coord(which), As_Coord(target)) <= range) { - return(true); - } - - /* - ** There's a longstanding bug where enemy units aligned north/south may have different perceptions of whether they - ** are in range of each other due to the turrets offset on the unit. This check will say that if either considers the - ** the other to be in range, then they both do. ST - 3/18/2020 10:44AM - */ - if (reciprocal_check && !building) { - ObjectClass *target_object = As_Object(target); - if (target_object) { - RTTIType my_type = What_Am_I(); - if (target_object->What_Am_I() == my_type) { - if (range == target_object->Weapon_Range(which)) { - TechnoClass *tech = As_Techno(target); - if (tech->In_Range(As_Target(), which, false)) { - return true; - } - } - } - } - } - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::In_Range -- Determines if specified target is within weapon range. * - * * - * This routine will determine if the pointer to the target object passed into this * - * routine is within weapon range. * - * * - * INPUT: target -- Pointer to the target object to check if within weapon range. * - * * - * which -- Which weapon to use in determining range. 0=primary, 1=secondary. * - * * - * OUTPUT: bool; Is the target within weapon range? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/14/1994 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::In_Range(ObjectClass const * target, int which, bool reciprocal_check) const -{ - if (IsLocked && target) { - int range = Weapon_Range(which); - if (target->What_Am_I() == RTTI_BUILDING) { - BuildingClass const * building = (BuildingClass const *)target; - range += ((building->Class->Width() + building->Class->Height()) * (ICON_LEPTON_W / 4)); - } - - if (::Distance(Fire_Coord(which), target->Center_Coord()) <= range) { - return(true); - } - - /* - ** There's a longstanding bug where enemy units aligned north/south may have different perceptions of whether they - ** are in range of each other due to the turrets offset on the unit. This check will say that if either considers the - ** the other to be in range, then they both do. ST - 3/18/2020 10:44AM - */ - if (reciprocal_check) { - RTTIType my_type = What_Am_I(); - if (my_type != RTTI_BUILDING) { - if (target->What_Am_I() == my_type) { - if (range == target->Weapon_Range(which)) { - if (((TechnoClass*)target)->In_Range(this, which, false)) { - return true; - } - } - } - } - } - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::In_Range -- Determines if the specified coordinate is within range. * - * * - * Use this routine to determine if the specified coordinate is within weapon range. * - * * - * INPUT: coord -- The coordinate to examine against the object to determine range. * - * * - * which -- The weapon to consider when determining range. 0=primary, 1=secondary. * - * * - * OUTPUT: bool; Is the weapon within range? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/16/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::In_Range(COORDINATE coord, int which) const -{ - return(IsLocked && ::Distance(Fire_Coord(which), coord) <= Weapon_Range(which)); -} - - -/*********************************************************************************************** - * TechnoClass::Evaluate_Object -- Determines score value of specified object. * - * * - * This routine is used to determing the score value (value as a potential target) of the * - * object specified. This routine will check the specified object for all the various * - * legality checks that threat scanning requires. This is the main workhorse routine for * - * target searching. * - * * - * INPUT: method -- The threat method requested. This is a combined bitflag value that * - * not only specified the kind of targets to consider, but how far away * - * they are allowed to be. * - * * - * mask -- This is an RTTI mask to use for quickly eliminating object types. * - * The mask is created outside of this routine because this routine is * - * usually called from within a loop and this value is constant in that * - * context. * - * * - * range -- The range at which potential target objects are rejected. * - * 0 = must be within weapon range. * - * >0 = must be within this lepton distance. * - * <0 = range doesn't matter. * - * * - * object -- Pointer to the object itself. * - * * - * value -- Reference to the value variable that this routine will fill in. The * - * higher the value the more likely this object will be selected as best. * - * * - * OUTPUT: Did the target pass all legality checks? If this value is returned true, then the * - * value parameter will be filled in correctly. * - * * - * WARNINGS: This routine is time consuming. Don't call unless necessary. * - * * - * HISTORY: * - * 06/30/1995 JLB : Created. * - * 07/14/1995 JLB : Forces SAM site to not fire on landed aircraft. * - *=============================================================================================*/ -bool TechnoClass::Evaluate_Object(ThreatType method, int mask, int range, TechnoClass const * object, int & value) const -{ - /* - ** An object in limbo can never be a valid target. - */ - if (object->IsInLimbo) return(false); - - /* - ** Friendly units are never considered a good target. Bail if this - ** object is a friend. - */ - if (House->Is_Ally(object)) return(false); - - /* - ** If the object is farther away than allowed, bail. - */ - int dist = Distance(object); - if (range > 0 && dist > range) return(false); - if (range == 0 && !In_Range(object, 0) && !In_Range(object, 1)) return(false); - - /* - ** If the object is not visible, then bail. Human controled units - ** are always considered to be visible. - */ - if (!object->IsOwnedByPlayer && !object->IsDiscoveredByPlayer && GameToPlay == GAME_NORMAL && object->What_Am_I() != RTTI_AIRCRAFT) { - return(false); - } - - /* - ** Quickly eliminate all unit types that are not allowed according to the mask - ** value. - */ - RTTIType otype = object->What_Am_I(); - if (!((1 << otype) & mask)) return(false); // Mask failure. - - /* - ** If the object is cloaked, then it isn't a legal target. - */ - if (object->Cloak == CLOAKED) return(false); - - /* - ** Determine if the target is theoretically allowed to be a target. If - ** not, then bail. - */ - TechnoTypeClass const * tclass = object->Techno_Type_Class(); - if (!tclass->IsLegalTarget) return(false); // Legality failure. - - /* - ** Never consider agent Delphi a valid target. - */ - if (otype == RTTI_INFANTRY && ((InfantryTypeClass const *)tclass)->Type == INFANTRY_DELPHI) { - return(false); - } - - /* - ** Special case so that SAM site doesn't fire on aircraft that are landed. - */ - if (otype == RTTI_AIRCRAFT && What_Am_I() == RTTI_BUILDING && *((BuildingClass *)this) == STRUCT_SAM) { - if (((AircraftClass *)object)->Altitude == 0) return(false); - } - - /* - ** If only allowed to attack civilians, then eliminate all other types. - */ - if ((method & THREAT_CIVILIANS) && object->Owner() != HOUSE_NEUTRAL) { - return(false); - } - - /* - ** If the scan is limited to capturable buildings only, then bail if the examined - ** object isn't a capturable building. - */ - if ((method & THREAT_CAPTURE) && (otype != RTTI_BUILDING || !((BuildingTypeClass const *)tclass)->IsCaptureable)) { - return(false); - } - - /* - ** If not allowed to attack boats, then eliminate them from consideration. - */ - if (!(method & THREAT_BOATS) && - otype == RTTI_UNIT && - (((UnitTypeClass const *)tclass)->Speed == SPEED_HOVER || ((UnitTypeClass const *)tclass)->Speed == SPEED_FLOAT)) { - return(false); - } - - /* - ** SPECIAL CASE: Friendly units won't automatically fire on buildings - ** if the building is not aggressive. - */ - if (House->IsHuman && otype == RTTI_BUILDING && tclass->Primary == WEAPON_NONE) return(false); - - /* - ** If the search is restricted to Tiberium processing objects, then - ** perform the special qualification check now. - */ - if (method & THREAT_TIBERIUM) { - switch (otype) { - case RTTI_UNIT: - if (!((UnitTypeClass const *)tclass)->IsToHarvest) return(false); - break; - - case RTTI_BUILDING: - if (!((BuildingTypeClass const *)tclass)->Capacity) return(false); - break; - - default: - return(false); - } - } - - /* - ** If this target value is better than the previously recorded best - ** target value then record this target for possible return as the - ** best target available. - */ - int rawval = object->Value(); - value = rawval + object->Kills; - -#ifdef USE_RA_AI - /* - ** If the candidate object is owned by the designated enemy of this house, then - ** give it a higher value. This will tend to gravitate attacks toward the main - ** antagonist of this house. - */ - if (House->Enemy != HOUSE_NONE && House->Enemy == object->House->Class->House) { - value += 500; - value *= 3; - } -#endif - -#ifdef ADVANCED - /* - ** Lessen threat as a factor of distance. - */ - if (rawval) { - - value = (value * 32000) / (((dist/ICON_LEPTON_W)*(dist/ICON_LEPTON_W))+1); - - //value = Fixed_To_Cardinal(value, Cardinal_To_Fixed(MAP_CELL_W*2, (MAP_CELL_W*2) - (dist/ICON_LEPTON_W))); - //value = MAX(value, 2); - - if (value < MAP_CELL_W*2) value = dist/ICON_LEPTON_W; - value = MAX(value, 1); - return(true); - } - value = 0; - return(false); - -#else - - /* - ** Lessen threat as a factor of distance. - */ - if (range == -1 && value) { - /* - ** Code from RA so that the value isn't always 2 on a mapwide scan with the range set to -1. ST - 3/2/2020 5:02PM - */ - value = (value * 32000) / ((dist/ICON_LEPTON_W)+1); - } else { - /* - ** Original TD code - */ - int modifier = dist; - int crange = range / ICON_LEPTON_W; - if (crange) modifier /= crange; - if (modifier) value /= modifier; - } - if (rawval) { - value = MAX(value, 2); - } - return(true); -#endif -} - - -/*********************************************************************************************** - * TechnoClass::Evaluate_Cell -- Determine the value and object of specified cell. * - * * - * This routine will examine the specified cell and return with the potential target * - * object it contains and the value of it. Use this routine when searching for threats. * - * * - * INPUT: method -- The scan method to use for target searching. * - * * - * mask -- Prebuilt mask of object RTTI types acceptable for scanning. * - * * - * range -- Scan range limit to use for elimination purposes. This ensures that * - * objects in the "corner" of a square scan get properly discarded. * - * * - * object -- Pointer to object pointer to be filled in with the object at this * - * cell as a valid target. * - * * - * value -- Reference to the value of the object in this cell. It will be set * - * according to the object's value. * - * * - * OUTPUT: Was a valid potential target found in this cell? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/19/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Evaluate_Cell(ThreatType method, int mask, CELL cell, int range, TechnoClass const * * object, int & value) const -{ - *object = NULL; - value = 0; - - /* - ** If the cell is not on the legal map, then always ignore it. - */ - if (cell & 0xF000) return(false); - if (!Map.In_Radar(cell)) return(false); - - /* - ** Fetch the techno object from the cell. If there is no - ** techno object there, then bail. - */ - CellClass * cellptr = &Map[cell]; - TechnoClass const * tentative = (TechnoClass const *)cellptr->Cell_Occupier(); - while (tentative) { - if (tentative->Is_Techno() && !House->Is_Ally(tentative)) break; - tentative = (TechnoClass const *)tentative->Next; - } - - if (!tentative) return(false); -// if (!tentative->Is_Techno()) return(false); - *object = tentative; - - return(Evaluate_Object(method, mask, range, tentative, value)); -} - - -/*********************************************************************************************** - * TechnoClass::Greatest_Threat -- Determines best target given search criteria. * - * * - * This routine will scan game objects looking for the best target. It is used by the * - * general target searching processes. The type of target scan to perform is controlled * - * by the method control parameter. * - * * - * INPUT: method -- The method control parameter is used to control the type of target * - * scan performed. It consists of a series of bit flags (see ThreatType) * - * that are combined to form the target scan desired. * - * * - * OUTPUT: Returns the target value of a suitable target. If no target was found then the * - * value TARGET_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/14/1994 JLB : Created. * - * 06/20/1995 JLB : Greatly optimized scan method. * - *=============================================================================================*/ -TARGET TechnoClass::Greatest_Threat(ThreatType method) const -{ - ObjectClass const * bestobject = NULL; - int bestval = -1; - - /* - ** Build a quick elimination mask. If the RTTI of the object doesn't - ** qualify with this mask, then we KNOW that it shouldn't be considered. - */ - int mask = 0; - if (method & THREAT_CIVILIANS) mask |= ((1 << RTTI_BUILDING) | (1 << RTTI_INFANTRY) | (1 << RTTI_UNIT)); - if (method & THREAT_AIR) mask |= (1 << RTTI_AIRCRAFT); - if (method & THREAT_CAPTURE) mask |= (1 << RTTI_BUILDING); - if (method & THREAT_BUILDINGS) mask |= (1 << RTTI_BUILDING); - if (method & THREAT_INFANTRY) mask |= (1 << RTTI_INFANTRY); - if (method & THREAT_VEHICLES) mask |= (1 << RTTI_UNIT); - - /* - ** Let's pick from the available contenders on a map-wide scan. ST - 3/2/2020 3:49PM - */ - static const int _max_best_objects = 128; - ObjectClass const *best_objects [_max_best_objects]; - int best_object_count = 0; - - /* - ** Limit area target scans use a method where the actual map cells are - ** examined for occupants. The occupant is then examined in turn. The - ** best target within the area is returned as a target. - */ - if (method & (THREAT_AREA|THREAT_RANGE)) { - int range = Threat_Range((method & THREAT_RANGE) ? 0 : 1); - -// int range = MAX(Weapon_Range(0), Weapon_Range(1)); -// if (!(method & THREAT_RANGE)) range *= 2; -// range = Bound(range, 0x0100, 0x1400); // Limit maximum scan distance. - int crange = range / ICON_LEPTON_W; - if (range == 0) { - crange = MAX(Weapon_Range(0), Weapon_Range(1)) / ICON_LEPTON_W; - crange++; - } - CELL cell = Coord_Cell(Fire_Coord(0)); -// CELL cell = Coord_Cell(Center_Coord()); - - /* - ** If aircraft are a legal target, then scan through all of them at this time. - ** Scanning by cell is not possible for aircraft since they are not recorded - ** at the cell level. - */ - if (method & THREAT_AIR) { - for (int index = 0; index < Aircraft.Count(); index++) { - TechnoClass * object = Aircraft.Ptr(index); - - int value = 0; - if (Evaluate_Object(method, mask, range, object, value)) { - if (value > bestval) { - bestobject = object; - bestval = value; - } - } - } - } - - /* - ** When scanning the ground, always consider landed aircraft as a valid - ** potential target. This is only true if vehicles are considered a - ** valid target. A landed aircraft is considered a vehicle. - */ - if (method & THREAT_VEHICLES) { - mask |= (1 << RTTI_AIRCRAFT); - } - - /* - ** Radiate outward from the object's location, looking for the best - ** target. - */ - TechnoClass const * object; - int value; - for (int radius = 1; radius < crange; radius++) { - - /* - ** Scan the top and bottom rows of the "box". - */ - for (int x = -radius; x <= radius; x++) { - CELL newcell; - - if ((Cell_X(cell) + x) < Map.MapCellX) continue; - if ((Cell_X(cell) + x) >= (Map.MapCellX+Map.MapCellWidth)) continue; - - if ((Cell_Y(cell) - radius) >= Map.MapCellY) { - newcell = XY_Cell(Cell_X(cell) + x, Cell_Y(cell)-radius); - if (Evaluate_Cell(method, mask, newcell, range, &object, value)) { - if (bestval < value) { - bestobject = object; - } - } - } - - if ((Cell_Y(cell) + radius) < (Map.MapCellY+Map.MapCellHeight)) { - newcell = XY_Cell(Cell_X(cell)+x, Cell_Y(cell)+radius); - if (Evaluate_Cell(method, mask, newcell, range, &object, value)) { - if (bestval < value) { - bestobject = object; - } - } - } - } - - /* - ** Scan the left and right columns of the "box". - */ - for (int y = -(radius-1); y < radius; y++) { - CELL newcell; - - if ((Cell_Y(cell) + y) < Map.MapCellY) continue; - if ((Cell_Y(cell) + y) >= (Map.MapCellY+Map.MapCellHeight)) continue; - - if ((Cell_X(cell) - radius) >= Map.MapCellX) { - newcell = XY_Cell(Cell_X(cell)-radius, Cell_Y(cell)+y); - if (Evaluate_Cell(method, mask, newcell, range, &object, value)) { - if (bestval < value) { - bestobject = object; - } - } - } - - if ((Cell_X(cell) + radius) < (Map.MapCellX+Map.MapCellWidth)) { - newcell = XY_Cell(Cell_X(cell)+radius, Cell_Y(cell)+y); - if (Evaluate_Cell(method, mask, newcell, range, &object, value)) { - if (bestval < value) { - bestobject = object; - } - } - } - } - - /* - ** Bail early if a target has already been found and the range is at - ** one of the breaking points (i.e., normal range or range * 2). - */ - if (bestobject) { - if (radius == crange/4) { - return(bestobject->As_Target()); - } - if (radius == crange/2) { - return(bestobject->As_Target()); - } - } - } - - } else { - - /* - ** A full map scan was requested. First scan through aircraft. The top map layer - ** is NOT scanned since that layer will probably contain more bullets and animations - ** than aircraft. - */ - int index; - for (index = 0; index < Aircraft.Count(); index++) { - TechnoClass * object = Aircraft.Ptr(index); - - int value = 0; - if (Evaluate_Object(method, mask, -1, object, value)) { - if (value > bestval) { - bestobject = object; - bestval = value; - best_object_count = 0; - best_objects[best_object_count++] = object; - } else { - if (value == bestval) { - if (best_object_count < _max_best_objects) { - best_objects[best_object_count++] = object; - } - } - } - } - } - - /* - ** Now scan through the entire ground layer. This is painful, but what other - ** choice is there? - */ - for (index = 0; index < Map.Layer[LAYER_GROUND].Count(); index++) { - ObjectClass const * object = Map.Layer[LAYER_GROUND][index]; - - int value = 0; - if (object->Is_Techno() && Evaluate_Object(method, mask, -1, (TechnoClass const *)object, value)) { - if (value > bestval) { - bestobject = object; - bestval = value; - best_object_count = 0; - best_objects[best_object_count++] = object; - } else { - if (value == bestval) { - if (best_object_count < _max_best_objects) { - best_objects[best_object_count++] = object; - } - } - } - } - } - } - - /* - ** If a good target object was found, then return with the target value - ** of it. - */ - if (bestobject) { - - /* - ** If there's only one, return that. Otherwise pick from the equal contenders - */ - if (best_object_count > 1) { - - /* - ** Pick one at random from our contenders - */ - int index = Random_Pick(0, best_object_count - 1); - bestobject = As_Object(best_objects[index]->As_Target()); - } - - return(bestobject->As_Target()); - } - return(TARGET_NONE); -} - - -/*********************************************************************************************** - * TechnoClass::Owner -- Who is the owner of this object? * - * * - * Use this routine to examine this object and return who the owner is. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the house number of the owner of this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -HousesType TechnoClass::Owner(void) const -{ - return(House->Class->House); -} - - -/*********************************************************************************************** - * TechnoClass::Clicked_As_Target -- Sets the flash count for this techno object. * - * * - * Use this routine to set the flash count for the object. This flash count is the number * - * of times the object will "flash". Typically it is called as a result of the player * - * clicking on this object in order to make it the target of a move or attack. * - * * - * INPUT: count -- The number of times the object should flash. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Clicked_As_Target(HousesType house, int count) // 2019/09/20 JAS - Added record of who clicked on the object -{ - FlashCount = count; - - // 2019/09/20 JAS - Flashing info needs to exist per player - if (house < HOUSE_COUNT) - { - FlashCountPerPlayer[house] = count; - } - else - { - //receiving HOUSE_COUNT means do it for every player - for (int i = 0; i < HOUSE_COUNT; ++i) - { - FlashCountPerPlayer[i] = count; - } - } -} - - -/*********************************************************************************************** - * TechnoClass::AI -- Handles AI processing for techno object. * - * * - * This routine handles AI processing for techno objects. Typically, this merely dispatches * - * to the appropriate AI routines for the base classes. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Make sure that this routine is only called ONCE per game tick. * - * * - * HISTORY: * - * 12/09/1994 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::AI(void) -{ - CargoClass::AI(); - RadioClass::AI(); - DoorClass::AI(); - - /* - ** Handle decision to re-cloak here. Process the cloaking/decloaking operation. - */ - if (IsCloakable) { - - /* - ** If this object is uncloaked, but it can be cloaked and it thinks that it - ** is a good time do so, then begin cloaking. - */ - if (Cloak == UNCLOAKED) { - // Changed for multiplayer so we can visually see the different players in the original renderer. ST - 3/13/2019 5:40PM - if (Is_Owned_By_Player()) Mark(MARK_CHANGE); - //if (IsOwnedByPlayer) Mark(MARK_CHANGE); - CloakingDevice.Graphic_Logic(); - if (!Arm && CloakingDevice.Fetch_Stage()) { - if (Health_Ratio() > 0x0040) { - Do_Cloak(); - } else { - if (Random_Pick(0, 25) == 1) { - Do_Cloak(); - } - } - } - } else { - - VisualType pre = Visual_Character(true); - CloakingDevice.Graphic_Logic(); - switch (Cloak) { - - /* - ** Handle the uncloaking process. Always mark to redraw - ** the object and when cloaking is complete, stabilize into - ** the normal uncloaked state. - */ - case UNCLOAKING: - Mark(MARK_CHANGE); - if (Visual_Character(true) == VISUAL_NORMAL) { - CloakingDevice.Set_Rate(UNCLOAK_VIS_TIME); - CloakingDevice.Set_Stage(0); // re-start the stage counter - Cloak = UNCLOAKED; - } - break; - - /* - ** Handle the cloaking process. Always mark to redraw the object - ** and when the cloaking process is complete, stabilize into the - ** normal cloaked state. - */ - case CLOAKING: - Mark(MARK_CHANGE); - switch (Visual_Character(true)) { - - /* - ** If badly damaged, then it can never fully cloak. - */ - case VISUAL_DARKEN: - if (Health_Ratio() < 0x0040 && Random_Pick(1, 3) == 1) { - Cloak = UNCLOAKING; - } - break; - -#ifdef NEVER - case VISUAL_SHADOWY: - if (pre != Visual_Character(true)) { - Detach_All(false); - } - break; -#endif - - case VISUAL_HIDDEN: - Cloak = CLOAKED; - CloakingDevice.Set_Rate(0); - - /* - ** Special check to ensure that if the unit is carring a captured - ** flag, it will never fully cloak. - */ - if (What_Am_I() == RTTI_UNIT && ((UnitClass *)this)->Flagged != HOUSE_NONE) { - Do_Shimmer(); - } else { - Detach_All(false); - } - - /* - ** A computer controlled unit will try to scatter if possible so - ** that it will be much harder to locate. - */ - if (What_Am_I() == RTTI_UNIT && !House->IsHuman) { - Scatter(0, true); - } - break; - } - break; - - /* - ** A cloaked object will always be redrawn if it is owned by the - ** player. This ensures that the shimmering effect will animate. - */ - case CLOAKED: - // Changed for multiplayer so we can visually see the different players in the original renderer. ST - 3/13/2019 5:40PM - if (Is_Owned_By_Player()) { - //if (IsOwnedByPlayer) { - Mark(MARK_CHANGE); - } - break; - } - } - } - - /* - ** Arming delay always counts down to zero. - */ - if (Arm) Arm--; - - /* - ** Handle line delay logic. - */ - if (LineMaxFrames > 0) { - Map.Flag_To_Redraw(true); - if (LineFrame >= LineMaxFrames) { - LineCount = 0; - LineFrame = 0; - LineMaxFrames = 0; - } - } - - /* - ** Update the animation timer system. If the animation stage - ** changes, then flag the object to be redrawn as well as determine - ** if the current animation process needs to change. - */ - if (What_Am_I() != RTTI_BUILDING) { - if (StageClass::Graphic_Logic() || Time_To_Redraw()) { - Mark(MARK_CHANGE); - } - } - - /* - ** If the object is flashing and a change of flash state has occured, then mark the - ** object to be redrawn. - */ - if (FlasherClass::Process()) { - Mark(MARK_CHANGE); - } -} - - -/*********************************************************************************************** - * TechnoClass::Select -- Selects object and checks to see if can be selected. * - * * - * This function checks to see if this techno object can be selected. If it can, then it * - * is selected. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/11/1994 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Select(bool allow_mixed) -{ - // ST - 3/13/2019 4:56PM - if (!Is_Discovered_By_Player() && !Is_Owned_By_Player() && !Debug_Unshroud) { - //if (!IsDiscoveredByPlayer && !IsOwnedByPlayer && !Debug_Unshroud) { - return(false); - } - - if (RadioClass::Select(allow_mixed)) { - - /* - ** Speak a confirmation of selection. - */ - // ST - 3/13/2019 4:59PM - if (Is_Owned_By_Player() && AllowVoice) { - //if (IsOwnedByPlayer && AllowVoice) { - Response_Select(); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::Can_Fire -- Determines if this techno object can fire. * - * * - * This performs a simple check to make sure that this techno object can fire. At this * - * level, the only thing checked for is the rearming delay. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the fire legality control code. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -FireErrorType TechnoClass::Can_Fire(TARGET target, int which) const -{ - /* - ** Don't allow firing if the target is illegal. - */ - if (!Target_Legal(target)) { - return(FIRE_ILLEGAL); - } - - ObjectClass * object = As_Object(target); - - /* - ** If the object is completely cloaked, then you can't fire on it. - */ -//Mono_Printf("Units[0]=%p.\n", Units.Raw_Ptr(0)); -//Mono_Printf("Infantry[0]=%p.\n", Infantry.Raw_Ptr(0)); -//Mono_Printf("Buildings[0]=%p.\n", Buildings.Raw_Ptr(0)); -//Mono_Printf("Aircraft[0]=%p.\n", Aircraft.Raw_Ptr(0)); -//Mono_Printf("object=%p, Strength=%d, IsActive=%d, IsInLimbo=%d.\n", object, (long)object->Strength, object->IsActive, object->IsInLimbo);Get_Key(); - if (object && /*(object->IsActive || GameToPlay != GAME_NORMAL) &&*/ object->Is_Techno() && ((TechnoClass *)object)->Cloak == CLOAKED) { - return(FIRE_CANT); - } - - /* - ** If there is no weapon, then firing is not allowed. - */ - WeaponType weap = (which == 0) ? Techno_Type_Class()->Primary : Techno_Type_Class()->Secondary; - if (weap == WEAPON_NONE) { - return(FIRE_CANT); - } - - /* - ** Can only fire anti-aircraft weapons against aircraft unless the aircraft is - ** sitting on the ground. - */ - if (object && object->What_Am_I() == RTTI_AIRCRAFT && - !BulletTypeClass::As_Reference(Weapons[weap].Fires).IsAntiAircraft && - ((AircraftClass *)object)->Altitude > 0) { - - return(FIRE_CANT); - } - - /* - ** Don't allow firing if still rearming. - */ - if (Arm) return(FIRE_REARM); - - /* - ** The target must be within range in order to allow firing. - */ - if (!In_Range(target, which)) { - return(FIRE_RANGE); - } - - /* - ** If there is no ammo left, then it can't fire. - */ - if (!Ammo) { - return(FIRE_AMMO); - } - - /* - ** If cloaked, then firing is disabled. - */ - if (Cloak != UNCLOAKED) { - return(FIRE_CLOAKED); - } - - return(FIRE_OK); -} - - -/*********************************************************************************************** - * TechnoClass::Stun -- Prepares the object for removal from the game. * - * * - * This routine handles cleaning up this techno object from the game system so that when * - * it is subsequently removed, it doesn't leave any loose ends. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Stun(void) -{ - Assign_Target(TARGET_NONE); - Assign_Destination(TARGET_NONE); - Transmit_Message(RADIO_OVER_OUT); - Detach_All(); - //Unselect(); - //When an object is stunned it needs to be deselected from all players, not just the current PlayerPtr. - // - 8/18/2019 JAS - Unselect_All_Players(); -} - - -/*********************************************************************************************** - * TechnoClass::Assign_Target -- Assigns the targeting computer with specified target. * - * * - * Use this routine to set the targeting computer for this object. It checks to make sure * - * that targeting of itself is prohibited. * - * * - * INPUT: target -- The target for this object to attack. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/23/1994 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Assign_Target(TARGET target) -{ - if (target == TarCom) return; - - if (!Target_Legal(target)) { - target = TARGET_NONE; - } else { - - /* - ** Prevent targeting of self. - */ - if (target == As_Target()) { - target = ::As_Target(Coord_Cell(Coord)); - } else { - - /* - ** Make sure that the target is not already dead. - */ - ObjectClass * object = As_Object(target); - if (object && (object->IsActive == false || object->Strength == 0)) { - target = TARGET_NONE; - } - } - } - - /* - ** Set the unit's targeting computer. - */ - TarCom = target; -} - - -/*********************************************************************************************** - * TechnoClass::Rearm_Delay -- Calculates the delay before firing can occur. * - * * - * This function calculates the delay between shots. It determines this from the standard * - * rate of fire (ROF) of the base class and modifies it according to game speed and * - * whether this is the first or second shot. All single shot attackers consider their * - * shots to be "second" since the second shot is the one handled normally. The first shot * - * usually gets assigned a much shorter delay time before the next shot can fire. * - * * - * INPUT: second -- bool; Is this the second of a two shot salvo? * - * * - * OUTPUT: Returns with the number of game frames to delay before the next shot may fire. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Rearm_Delay(bool second) const -{ - if (second) { - return(((int)Weapons[Techno_Type_Class()->Primary].ROF * House->ROFBias) + 3); - } - return(9); -} - - -/*********************************************************************************************** - * TechnoClass::Fire_At -- Fires projectile at target specified. * - * * - * This is the main projectile firing code. Buildings, units, and infantry route fire * - * requests through this function. * - * * - * INPUT: target -- The target that the projectile is to be fired at. * - * * - * which -- Which weapon to fire. * - * * - * OUTPUT: Returns with a pointer to the projectile object that was fired. If no projectile * - * could be created or there was some other illegality detected, the return value * - * will be NULL. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/26/1994 JLB : Created. * - * 07/03/1995 JLB : Moving platforms fire inaccurate projectiles. * - *=============================================================================================*/ -BulletClass * TechnoClass::Fire_At(TARGET target, int which) -{ - BulletClass *bullet; // Projectile. - DirType dir; // The facing to impart upon the projectile. - COORDINATE target_coord; // Coordinate of the target. - COORDINATE fire_coord; // Coordinate of firing position. - TechnoTypeClass const & tclass = *Techno_Type_Class(); - ObjectClass *object; - if ((which == 0 && tclass.Primary == WEAPON_NONE) || (which != 0 && tclass.Secondary == WEAPON_NONE)) { - return(NULL); - } - WeaponTypeClass const *weapon = (which == 0) ? &Weapons[tclass.Primary] : &Weapons[tclass.Secondary]; - BulletTypeClass const &btype = BulletTypeClass::As_Reference(weapon->Fires); - - /* - ** Perform a quick legality check to see if firing can occur. - */ - if (Debug_Map || weapon->Fires == BULLET_NONE || !Target_Legal(target)) { - return(NULL); - } - - /* - ** Fetch the target coordinate for the target specified. - */ - object = As_Object(target); - if (object) { - target_coord = object->Target_Coord(); - } else { - target_coord = As_Coord(target); - } - - /* - ** Get the location where the projectile should appear. - */ - fire_coord = Fire_Coord(which); - - /* - ** If the projectile is a homing type (such as a missile), then it will - ** launch in the direction the turret is facing, NOT necessarily the same - ** direction as the target. - */ - if (btype.IsHoming || btype.IsDropping) { - dir = Fire_Direction(); - if (btype.IsDropping) { - fire_coord = Center_Coord(); - } - } else { - dir = ::Direction(fire_coord, target_coord); - } - - /* - ** Create the projectile. Then process any special operations that - ** need to be performed according to the style of projectile - ** created. - */ - int firepower = (weapon->Attack > 0) ? ((int)weapon->Attack * House->FirepowerBias) : 0; - bullet = new BulletClass(weapon->Fires); - if (bullet) { - bullet->Assign_Target(target); - bullet->Payback = this; - bullet->Strength = (short)firepower; - - /* - ** If this is firing from a moving platform, then the projectile is inaccurate. - */ - if (Special.IsDefenderAdvantage && What_Am_I() != RTTI_BUILDING && ((FootClass const *)this)->IsDriving) { - bullet->IsInaccurate = true; - } - - if (bullet->Unlimbo(fire_coord, dir)) { -//Mono_Printf("Units[0]=%p.\n", Units.Raw_Ptr(0)); -//Mono_Printf("Infantry[0]=%p.\n", Infantry.Raw_Ptr(0)); -//Mono_Printf("Buildings[0]=%p.\n", Buildings.Raw_Ptr(0)); -//Mono_Printf("Aircraft[0]=%p.\n", Aircraft.Raw_Ptr(0)); -//Mono_Printf("object=%p, Strength=%d, IsActive=%d, IsInLimbo=%d.\n", object, (long)object->Strength, object->IsActive, object->IsInLimbo);Get_Key(); - bullet->Payback = this; - bullet->Strength = (short)firepower; - } else { - delete bullet; - } - if (!bullet->Class->IsFueled) { - IsInRecoilState = true; - } - Arm = Rearm_Delay(IsSecondShot); - if (tclass.IsTwoShooter) { - IsSecondShot = (IsSecondShot == false); - } - - /* - ** Perform any animation effect for this weapon. - */ - AnimType a = weapon->Anim; - switch (a) { - case ANIM_GUN_N: - case ANIM_CHEM_N: - case ANIM_FLAME_N: - a = (AnimType)(a + Dir_Facing(Fire_Direction())); - break; - } - - /* - ** If there is a special firing animation, then create and attach it - ** now. - */ - if (a != ANIM_NONE) { - AnimClass * anim = new AnimClass(a, Fire_Coord(which)); - if (anim) { - anim->Attach_To(this); - } - } - - /* - ** Reduce ammunition for this object. - */ - if (Ammo > 0) { - Ammo--; - } - - /* - ** Firing will in all likelihood, require the unit to be redraw. Flag it to be - ** redrawn here. - */ - Mark(MARK_CHANGE); - - /* - ** If a projectile was fired from a unit that is hidden in the darkness, - ** reveal that unit and a little area around it. - ** For multiplayer games, only reveal the unit if the target is the - ** local player. - */ -#if (0) - if ((!IsOwnedByPlayer && !IsDiscoveredByPlayer) || !Map[Coord_Cell(Center_Coord())].IsMapped) { - if (GameToPlay == GAME_NORMAL) { - Map.Sight_From(Coord_Cell(Center_Coord()), 1, false); - } else { - ObjectClass *obj = As_Object(target); - if (obj) { - HousesType tgt_owner = obj->Owner(); - - if (PlayerPtr->Class->House == tgt_owner) { - Map.Sight_From(Coord_Cell(Center_Coord()), 1, false); - } - } - } - } -#else - /* - ** Now need to reveal for any human player that is the target. ST - 3/13/2019 5:43PM - */ - - ObjectClass *obj = As_Object(target); - if (obj) { - HousesType tgt_owner = obj->Owner(); - - HouseClass *player = HouseClass::As_Pointer(tgt_owner); - if (player != nullptr && player->IsHuman) { - if ((!Is_Owned_By_Player(player) && !Is_Discovered_By_Player(player)) || !Map[Coord_Cell(Center_Coord())].Is_Mapped(House)) { - Map.Sight_From(player, Coord_Cell(Center_Coord()), 1, false); - } - } - } - -#endif - } - - if (weapon->Fires == BULLET_LASER) { - int x, y, x1, y1; - COORDINATE source, dest; - source = Fire_Coord(which); - dest = As_Coord(target); - if (SpecialDialog == SDLG_NONE) { - Map.Coord_To_Pixel(source, x, y); - Map.Coord_To_Pixel(dest, x1, y1); - x += Map.TacPixelX; - x1 += Map.TacPixelX; - y += Map.TacPixelY; - y1 += Map.TacPixelY; - Lines[0][0] = x + 1; - Lines[0][1] = y; - Lines[0][2] = x1; - Lines[0][3] = y1; - Lines[0][4] = 0x7D; - Lines[1][0] = x - 1; - Lines[1][1] = y; - Lines[1][2] = x1; - Lines[1][3] = y1; - Lines[1][4] = 0x7D; - Lines[2][0] = x; - Lines[2][1] = y; - Lines[2][2] = x1; - Lines[2][3] = y1; - Lines[2][4] = 0x7F; - LineCount = 3; - LineFrame = 0; - LineMaxFrames = 5; - Map.Flag_To_Redraw(true); - } - new SmudgeClass(Random_Pick(SMUDGE_SCORCH1, SMUDGE_SCORCH6), As_Coord(target)); - } - - return(bullet); -} - - -/*********************************************************************************************** - * TechnoClass::Player_Assign_Mission -- Assigns a mission as result of player input. * - * * - * This routine is called when the mission for an object needs to change as a result of * - * player input. The basic operation would be to queue the event and let the action * - * occur at the frame dictated by the queing system. However, if a voice response is * - * indicated, then perform it at this time. This will give a greater illusion of * - * immediate response. * - * * - * INPUT: order -- The mission order to assign to this object. * - * * - * target -- The target of this object. This will be used for combat and attack. * - * * - * destination -- The movement destination for this object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Player_Assign_Mission(MissionType mission, TARGET target, TARGET destination) -{ - if (AllowVoice) { - if (mission == MISSION_ATTACK) { - Response_Attack(); - } else { - Response_Move(); - } - } - Queue_Mission(As_Target(), mission, target, destination); -} - - -/*********************************************************************************************** - * TechnoClass::What_Action -- Determines what action to perform if object is selected. * - * * - * This routine will examine the object specified and return with the action that will * - * be performed if the mouse button were clicked over the object. * - * * - * INPUT: object -- The object that the mouse button might be clicked on. * - * * - * OUTPUT: Returns with the action that will be performed if the object was clicked on. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - * 03/21/1995 JLB : Special target control for trees. * - *=============================================================================================*/ -ActionType TechnoClass::What_Action(ObjectClass * object) const -{ - if (object) { - - /* - ** Return the ACTION_SELF flag if clicking on itself. However, if this - ** object cannot do anything special with itself, then just return with - ** the no action flag. - */ - if (object == this && CurrentObject.Count() == 1 && House == PlayerPtr) { - return(ACTION_SELF); - } - - //bool altdown = (Keyboard::Down(KN_LALT) || Keyboard::Down(KN_RALT)); - //bool ctrldown = (Keyboard::Down(KN_LCTRL) || Keyboard::Down(KN_RCTRL)); - //bool shiftdown = (Keyboard::Down(KN_LSHIFT) || Keyboard::Down(KN_RSHIFT)); - //Added for getting the input for special character keys from the client - // - 6/26/2019 JAS - bool altdown = DLL_Export_Get_Input_Key_State(KN_LALT); - bool ctrldown = DLL_Export_Get_Input_Key_State(KN_LCTRL); - bool shiftdown = DLL_Export_Get_Input_Key_State(KN_LSHIFT); - - /* - ** Special guard area mission is possible if both the control and the - ** alt keys are held down. - */ - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (Is_Owned_By_Player() && ctrldown && altdown && Can_Player_Move() && Can_Player_Fire()) { - //if (IsOwnedByPlayer && ctrldown && altdown && Can_Player_Move() && Can_Player_Fire()) { - return(ACTION_GUARD_AREA); - } - - /* - ** Special override to force a move regardless of what is occupying the location. - */ - if (altdown) { - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (Is_Owned_By_Player() && Can_Player_Move()) { - //if (IsOwnedByPlayer && Can_Player_Move()) { - return(ACTION_MOVE); - } - } - - /* - ** Override so that toggled select state can be performed while the key - ** is held down. - */ - bool is_a_loaner = object->Is_Techno() && ((TechnoClass*)object)->IsALoaner; - if (shiftdown) { - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (!is_a_loaner) { - //if (IsOwnedByPlayer && !IsALoaner) { - return(ACTION_TOGGLE_SELECT); - } - } - - /* - ** If firing is possible and legal, then return this action potential. - */ - bool control = Keyboard::Down(KN_LCTRL) || Keyboard::Down(KN_RCTRL); - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (Is_Owned_By_Player() && (ctrldown || !House->Is_Ally(object)) && (ctrldown || object->Class_Of().IsLegalTarget || (Special.IsTreeTarget && object->What_Am_I() == RTTI_TERRAIN))) { - //if (IsOwnedByPlayer && (ctrldown || !House->Is_Ally(object)) && (ctrldown || object->Class_Of().IsLegalTarget || (Special.IsTreeTarget && object->What_Am_I() == RTTI_TERRAIN))) { - if (Can_Player_Move() || In_Range(object, 0)) { - // Check for anti-air capability - if (object->What_Am_I() != RTTI_AIRCRAFT) { - return(ACTION_ATTACK); - } else { - AircraftClass* aircraft = (AircraftClass*)object; - if (*aircraft != AIRCRAFT_CARGO) { - if (((Techno_Type_Class()->Primary != WEAPON_NONE) && BulletTypeClass::As_Reference(Weapons[Techno_Type_Class()->Primary].Fires).IsAntiAircraft) || - ((Techno_Type_Class()->Secondary != WEAPON_NONE) && BulletTypeClass::As_Reference(Weapons[Techno_Type_Class()->Secondary].Fires).IsAntiAircraft) || - (aircraft->Altitude == 0)) { - return(ACTION_ATTACK); - } - } - } - } - } - - /* - ** Possibly try to select the specified object, if that is warranted. - */ - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (!Is_Weapon_Equipped() || !Is_Owned_By_Player() || object->Owner() == Owner()) { - if ((!is_a_loaner || !Is_Owned_By_Player()) && object->Class_Of().IsSelectable && (!object->Is_Selected_By_Player() || CurrentObject.Count())) { - //if (!Is_Weapon_Equipped() || !IsOwnedByPlayer || object->Owner() == Owner()) { - //if ((!IsALoaner || !IsOwnedByPlayer) && object->Class_Of().IsSelectable && !object->IsSelected) { - return(ACTION_SELECT); - } - return(ACTION_NONE); - } - } - return(ACTION_NONE); -} - - -/*********************************************************************************************** - * TechnoClass::What_Action -- Determines action to perform if cell is clicked on. * - * * - * Use this routine to determine what action will be performed if the specified cell * - * is clicked on. Usually this action is either a ACTION_MOVE or ACTION_NOMOVE. The action * - * nomove is used to perform special case checking for nearby cells if in fact the mouse * - * is clicked over the cell. * - * * - * INPUT: cell -- The cell to check for being clicked over. * - * * - * OUTPUT: Returns with the action that will occur if the cell is clicked on. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - * 07/10/1995 JLB : Force fire for buildings is explicitely disabled. * - *=============================================================================================*/ -ActionType TechnoClass::What_Action(CELL cell) const -{ - CellClass const * cellptr = &Map[cell]; - OverlayTypeClass const * optr = NULL; - - //bool ctrldown = Keyboard::Down(KN_LCTRL) || Keyboard::Down(KN_RCTRL); - //bool shiftdown = Keyboard::Down(KN_LSHIFT) || Keyboard::Down(KN_RSHIFT); - //bool altdown = (Keyboard::Down(KN_LALT) || Keyboard::Down(KN_RALT)); - //Added for getting the input for special character keys from the client - // - 6/26/2019 JAS - bool altdown = DLL_Export_Get_Input_Key_State(KN_LALT); - bool ctrldown = DLL_Export_Get_Input_Key_State(KN_LCTRL); - bool shiftdown = DLL_Export_Get_Input_Key_State(KN_LSHIFT); - - /* - ** Disable recognizing the key forced fire option when dealing with buildings. - */ - if (What_Am_I() == RTTI_BUILDING) ctrldown = false; - - if (cellptr->Overlay != OVERLAY_NONE) { - optr = &OverlayTypeClass::As_Reference(cellptr->Overlay); - } - - /* - ** Special guard area mission is possible if both the control and the - ** alt keys are held down. - */ - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (Is_Owned_By_Player() && ctrldown && altdown && Can_Player_Move() && Can_Player_Fire()) { - //if (IsOwnedByPlayer && ctrldown && altdown && Can_Player_Move() && Can_Player_Fire()) { - return(ACTION_GUARD_AREA); - } - - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (Is_Owned_By_Player() && Techno_Type_Class()->Primary != WEAPON_NONE && (ctrldown || (optr && optr->IsLegalTarget))) { - //if (IsOwnedByPlayer && Techno_Type_Class()->Primary != WEAPON_NONE && (ctrldown || (optr && optr->IsLegalTarget))) { - WarheadTypeClass const * whead = &Warheads[BulletTypeClass::As_Reference(Weapons[Techno_Type_Class()->Primary].Fires).Warhead]; - if (!optr || (optr->IsWall && (whead->IsWallDestroyer || (whead->IsWoodDestroyer && optr->IsWooden)))) { - if (Can_Player_Move() || In_Range(::As_Target(cell), 0)) { - return(ACTION_ATTACK); - } - } - } - - // Changed for multiplayer. ST - 3/13/2019 5:52PM - if (Is_Owned_By_Player() && Can_Player_Move()) { - //if (IsOwnedByPlayer && Can_Player_Move()) { - - /* - ** Special override to force a move regardless of what is occupying the location. - */ - if (shiftdown) { - return(ACTION_MOVE); - } - - /* - ** If the object can enter the cell specified, then allow - ** movement to it. - */ - if (Can_Enter_Cell(cell) <= MOVE_CLOAK) { - return(ACTION_MOVE); - } - return(ACTION_NOMOVE); - } - return(ACTION_NONE); -} - - -/*********************************************************************************************** - * TechnoClass::Can_Player_Move -- Determines if the object can move be moved by player. * - * * - * Use this routine to determine whether a movement order can be given to this object. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Can this object be given a movement order by the player? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Can_Player_Move(void) const -{ - return(PlayerPtr == House); -} - - -/*********************************************************************************************** - * TechnoClass::Can_Player_Fire -- Determines if the player can give this object a fire order. * - * * - * Call this routine to determine if this object can be given a fire order by the player. * - * Such objects will affect the mouse cursor accordingly -- usually causes the targeting * - * cursor to appear. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Can this object be given firing orders by the player? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Can_Player_Fire(void) const -{ - if (House->IsHuman && Is_Techno() && Techno_Type_Class()->Primary != WEAPON_NONE) { - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::Is_Weapon_Equipped -- Determines if this object has a combat weapon. * - * * - * Use this routine to determine if this object is equipped with a combat weapon. Such * - * determination is used by the AI system to gauge the threat potential of the object. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is this object equipped with a combat weapon? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Is_Weapon_Equipped(void) const -{ - return(Techno_Type_Class()->Primary != WEAPON_NONE); -} - - -/*********************************************************************************************** - * TechnoClass::Can_Repair -- Determines if the object can and should be repaired. * - * * - * Use this routine to determine if the specified object is a candidate for repair. In * - * order to qualify, the object must be allowed to be repaired (in theory) and it must * - * be below full strength. If these conditions are met, then it can be repaired. * - * * - * INPUT: none * - * * - * OUTPUT: bool; May this unit be repaired? A return value of false may mean that the object * - * is not allowed to be repaired, or it might be full strength already. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Can_Repair(void) const -{ - /* - ** Temporary hack to disable repair cursor over non-buildings. - */ - if (What_Am_I() == RTTI_UNIT || What_Am_I() == RTTI_INFANTRY || What_Am_I() == RTTI_AIRCRAFT) { - return(false); - } - return(Techno_Type_Class()->IsRepairable && Strength != Class_Of().MaxStrength); -} - - -/*********************************************************************************************** - * TechnoClass::Weapon_Range -- Determines the maximum range for the weapon. * - * * - * Use this routine to determine the maximum range for the weapon indicated. * - * * - * INPUT: which -- Which weapon to use when determining the range. 0=primary, 1=secondary. * - * * - * OUTPUT: Returns with the range of the weapon (in leptons). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/19/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Weapon_Range(int which) const -{ - WeaponType weapon = WEAPON_NONE; - TechnoTypeClass const & ttype = *Techno_Type_Class(); - - switch (which) { - case 0: - weapon = ttype.Primary; - break; - - case 1: - weapon = ttype.Secondary; - break; - } - if (weapon != WEAPON_NONE) { - if (weapon == WEAPON_NIKE && GameToPlay == GAME_NORMAL) { - return(Weapons[weapon].Range*2); - } - return(Weapons[weapon].Range); - } - return(0); -} - - -/*************************************************************************** - * TechnoClass::Override_Mission -- temporarily overides a units mission * - * * - * * - * * - * INPUT: MissionType mission - the mission we want to overide * - * TARGET tarcom - the new target we want to overide * - * TARGET navcom - the new navigation point to overide * - * * - * OUTPUT: none * - * * - * WARNINGS: If a mission is already overidden, the current mission is * - * just re-assigned. * - * * - * HISTORY: * - * 04/28/1995 PWG : Created. * - *=========================================================================*/ -void TechnoClass::Override_Mission(MissionType mission, TARGET tarcom, TARGET navcom) -{ - SuspendedTarCom = TarCom; - RadioClass::Override_Mission(mission, tarcom, navcom); - Assign_Target(tarcom); -} - - -/*************************************************************************** - * TechnoClass::Restore_Mission -- Restores an overidden mission * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/28/1995 PWG : Created. * - *=========================================================================*/ -bool TechnoClass::Restore_Mission(void) -{ - if (RadioClass::Restore_Mission()) { - Assign_Target(SuspendedTarCom); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::Captured -- Handles capturing this object. * - * * - * This routine is called when this object gets captured by the house specified. It handles * - * removing this object from any targeting computers and then changes the ownership of * - * the object to the new house. * - * * - * INPUT: newowner -- Pointer to the house that is now the new owner. * - * * - * OUTPUT: Was the object captured? Failure would mean that it is already under control of * - * the house specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Captured(HouseClass * newowner) -{ - if (newowner != House) { - - /* - ** Capture attempt springs any "entered" trigger. The entered trigger - ** occurs first since there may be a special trigger attached to this - ** object that flags a capture as a win and a destroy as a loss. This - ** order is necessary because the object is recorded as a kill as well. - */ - if (Trigger /*&& Trigger->House == newowner->Class->House*/) { - Trigger->Spring(EVENT_PLAYER_ENTERED, this); - } - - /* - ** Record this as a kill. - */ - Record_The_Kill(NULL); - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Remove(this); - newowner->Tracking_Add(this); -#endif // USE_RA_AI - - /* - ** Special kill record logic for capture process. - */ - switch (What_Am_I()) { - case RTTI_BUILDING: - if (newowner) newowner->BuildingsKilled[Owner()]++; - break; - - case RTTI_AIRCRAFT: - case RTTI_INFANTRY: - case RTTI_UNIT: - if (newowner) newowner->UnitsKilled[Owner()]++; - break; - - default: - break; - } - House->WhoLastHurtMe = newowner->Class->House; - - /* - ** Remove from targeting computers. - */ - Detach_All(false); - -#ifdef NEVER - /* - ** Break off any radio contact. - */ - Transmit_Message(RADIO_OVER_OUT); -#endif - - /* - ** Change ownership now. - */ - House = newowner; - IsOwnedByPlayer = (House == PlayerPtr); - - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TechnoClass::Take_Damage -- Records damage assessed to this object. * - * * - * This routine is called when this object has taken damage. It handles recording whether * - * this object has been destroyed. If it has, then mark the appropriate kill records as * - * necessary. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/20/1995 JLB : Created. * - *=============================================================================================*/ -ResultType TechnoClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - /* - ** Adjust damage according to house override armor value. - */ - if (damage > 0) { - damage = damage * House->ArmorBias; - } - - ResultType result = ObjectClass::Take_Damage(damage, distance, warhead, source); - - switch (result) { - case RESULT_DESTROYED: - Transmit_Message(RADIO_OVER_OUT); - Stun(); - - /* - ** May trigger an achievement. ST - 11/14/2019 1:56PM - */ - if (GameToPlay == GAME_NORMAL && !House->IsHuman && source && source->House && source->House->IsHuman) { - TechnoTypeClass const *object_type = Techno_Type_Class(); - if (object_type) { - RTTIType what = What_Am_I(); - if (what == RTTI_AIRCRAFT || what == RTTI_INFANTRY || what == RTTI_UNIT) { - On_Achievement_Event(source->House, "UNIT_DESTROYED", object_type->IniName); - } - } - } - break; - - /* - ** If some damage was received and this object is cloaked, shimmer - ** the cloak a bit. - */ - default: - if (source && !House->Is_Ally(source)) { - IsTickedOff = true; - } - Do_Shimmer(); - break; - - case RESULT_NONE: - break; - } - return(result); -} - - -/*********************************************************************************************** - * TechnoTypeClass::Max_Passengers -- Fetches the maximum passengers allowed. * - * * - * This routine will return with the maximum number of passengers allowed in this * - * transport. This typically applies to APCs and possibley transport helicopters. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of passengers this transport can carry. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoTypeClass::Max_Passengers(void) const -{ - if (IsTransporter) { - return(5); - } - return(0); -} - - -/*********************************************************************************************** - * TechnoClass::Record_The_Kill -- Records the death of this object. * - * * - * This routine is used to record the death of this object. It will handle updating the * - * owner house with the kill record as well as springing any trigger events associated with * - * this object's death. * - * * - * INPUT: source -- Pointer to the source of this object's death (if there is a source). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - * 08/23/1995 JLB : Building loss is only counted if it received damage. * - *=============================================================================================*/ -void TechnoClass::Record_The_Kill(TechnoClass * source) -{ - /* - ** Handle any trigger event associated with this object. - */ - if (Trigger && source) Trigger->Spring(EVENT_ATTACKED, this); - - if (Trigger && source) Trigger->Spring(EVENT_DISCOVERED, this); - - if (Trigger) Trigger->Spring(EVENT_DESTROYED, this); - - if (source) { - /* - ** Call the explicity cast versions of the Made_A_Kill function. This - ** is necessary because we don't want to add a virtual function to the - ** CrewClass. Doing so would complicate the save/load process. - */ - switch (source->What_Am_I()) { - case RTTI_INFANTRY: - ((InfantryClass *)source)->Made_A_Kill(); - break; - - case RTTI_UNIT: - ((UnitClass *)source)->Made_A_Kill(); - break; - - case RTTI_BUILDING: - ((BuildingClass *)source)->Made_A_Kill(); - break; - - case RTTI_AIRCRAFT: - ((AircraftClass *)source)->Made_A_Kill(); - break; - } - - House->WhoLastHurtMe = source->Owner(); - } - - switch (What_Am_I()) { - case RTTI_BUILDING: - if ( ((BuildingClass *)this)->WhoLastHurtMe != HOUSE_NONE) { - House->BuildingsLost++; - } - if (source){ - if (GameToPlay == GAME_INTERNET){ - source->House->DestroyedBuildings->Increment_Unit_Total( ((BuildingClass*)this)->Class->Type ); - } - source->House->BuildingsKilled[Owner()]++; - } - - /* - ** If the map is displaying the multiplayer player names & their - ** # of kills, tell it to redraw. - */ - if (Map.Is_Player_Names()) { - Map.Player_Names(true); - } - break; - - - case RTTI_AIRCRAFT: - House->UnitsLost++; - if (source){ - if (GameToPlay == GAME_INTERNET){ - source->House->DestroyedAircraft->Increment_Unit_Total( ((AircraftClass*)this)->Class->Type ); - } - source->House->UnitsKilled[Owner()]++; - } - /* - ** If the map is displaying the multiplayer player names & their - ** # of kills, tell it to redraw. - */ - if (Map.Is_Player_Names()) { - Map.Player_Names(true); - } - break; - - - case RTTI_INFANTRY: - House->UnitsLost++; - if (source){ - if (GameToPlay == GAME_INTERNET){ - source->House->DestroyedInfantry->Increment_Unit_Total( ((InfantryClass*)this)->Class->Type ); - } - source->House->UnitsKilled[Owner()]++; - } - /* - ** If the map is displaying the multiplayer player names & their - ** # of kills, tell it to redraw. - */ - if (Map.Is_Player_Names()) { - Map.Player_Names(true); - } - break; - - - case RTTI_UNIT: - House->UnitsLost++; - if (source){ - if (GameToPlay == GAME_INTERNET){ - source->House->DestroyedUnits->Increment_Unit_Total( ((UnitClass*)this)->Class->Type ); - } - source->House->UnitsKilled[Owner()]++; - } - - /* - ** If the map is displaying the multiplayer player names & their - ** # of kills, tell it to redraw. - */ - if (Map.Is_Player_Names()) { - Map.Player_Names(true); - } - break; - - default: - break; - } -} - - -/*********************************************************************************************** - * TechnoClass::Nearby_Location -- Radiates outward looking for clear cell nearby. * - * * - * This routine is used to find a nearby location from center of this object. It can lean * - * toward finding a location closest to an optional object. * - * * - * INPUT: object -- Optional object that the finding algorithm will try to find a close * - * spot to. * - * * - * OUTPUT: Returns with the cell that is closest to this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/06/1995 JLB : Created. * - *=============================================================================================*/ -CELL TechnoClass::Nearby_Location(TechnoClass const * ) const -{ - /* - ** Radiate outward from the object's location, looking for the best - ** target. - */ - CELL best = 0; - CELL cell = Coord_Cell(Center_Coord()); - for (int radius = 0; radius < MAP_CELL_W/2; radius++) { - - /* - ** Scan the top and bottom rows of the "box". - */ - for (int x = -radius; x <= radius; x++) { - CELL newcell = cell + XY_Cell(x, -radius); - if (Map.In_Radar(newcell) && Map[newcell].Is_Generally_Clear()) { - best = newcell; - } - - newcell = cell + XY_Cell(x, radius); - if (Map.In_Radar(newcell) && Map[newcell].Is_Generally_Clear()) { - best = newcell; - } - } - - /* - ** Scan the left and right columns of the "box". - */ - for (int y = -(radius-1); y < radius; y++) { - CELL newcell = cell + XY_Cell(-radius, y); - if (Map.In_Radar(newcell) && Map[newcell].Is_Generally_Clear()) { - best = newcell; - } - - newcell = cell + XY_Cell(radius, y); - if (Map.In_Radar(newcell) && Map[newcell].Is_Generally_Clear()) { - best = newcell; - } - } - - if (best) break; - } - - return(best); -} - - -/*********************************************************************************************** - * TechnoClass::Do_Uncloak -- Cause the stealth tank to uncloak. * - * * - * This routine will start the stealth tank to uncloak. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Do_Uncloak(void) -{ - if (IsCloakable && (Cloak == CLOAKED || Cloak == CLOAKING)) { - Sound_Effect(VOC_CLOAK, Coord); - Cloak = UNCLOAKING; - CloakingDevice.Set_Stage(0); - CloakingDevice.Set_Rate(1); - } -} - - -/*********************************************************************************************** - * TechnoClass::Do_Cloak -- Start the object into cloaking stage. * - * * - * This routine will start the object into its cloaking state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Do_Cloak(void) -{ - if (IsCloakable && (Cloak == UNCLOAKED || Cloak == UNCLOAKING)) { - Sound_Effect(VOC_CLOAK, Coord); - Detach_All(false); - Cloak = CLOAKING; - CloakingDevice.Set_Stage(0); - CloakingDevice.Set_Rate(1); - } -} - - -/*********************************************************************************************** - * TechnoClass::Do_Shimmer -- Causes this object to shimmer if it is cloaked. * - * * - * This routine is called when this object should shimmer. If the object is cloaked, then * - * a shimmering effect (partial decloak) occurs. For objects that are not cloaked, no * - * affect occurs. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Do_Shimmer(void) -{ - if (IsCloakable && Cloak == CLOAKED) { - Cloak = CLOAKING; - CloakingDevice.Set_Stage(MAX_UNCLOAK_STAGE/2); - CloakingDevice.Set_Rate(1); - } -} - - -/*********************************************************************************************** - * TechnoClass::Visual_Character -- Determine the visual character of the object. * - * * - * This routine will determine how this object should be drawn. Typically, this is the * - * unmodified visible state, but cloaked objects have a different character. * - * * - * INPUT: raw -- Should the check be based on the unmodified cloak condition of the * - * object? If false, then an object owned by the player will never become * - * completely invisible. * - * * - * OUTPUT: Returns with the visual character to use when displaying this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/07/1995 JLB : Created. * - *=============================================================================================*/ -VisualType TechnoClass::Visual_Character(bool raw) -{ - /* - ** When uncloaked or in map editor mode, always draw the object normally. - */ - if (Cloak == UNCLOAKED || Debug_Map) return(VISUAL_NORMAL); - - /* - ** A cloaked unit will not be visible at all unless it is owned - ** by the player. - */ - if (Cloak == CLOAKED) { - // Changed for multiplayer. Not needed except to test in the old renderer. ST - 3/13/2019 5:56PM - if (!raw && Is_Owned_By_Player()) return(VISUAL_SHADOWY); - //if (!raw && IsOwnedByPlayer) return(VISUAL_SHADOWY); - return(VISUAL_HIDDEN); - } - - int stage = CloakingDevice.Fetch_Stage(); - if (Cloak == UNCLOAKING) stage = MAX_UNCLOAK_STAGE - stage; - if (stage <= 0) { - return(VISUAL_NORMAL); - } - - stage = Cardinal_To_Fixed(MAX_UNCLOAK_STAGE, stage); - - if (stage < 0x0040) return(VISUAL_INDISTINCT); - if (stage < 0x0080) return(VISUAL_DARKEN); - if (stage < 0x00C0) return(VISUAL_SHADOWY); - if (!raw && Is_Owned_By_Player()) return(VISUAL_SHADOWY); // Changed for multiplayer. Not needed except to test in the old renderer. ST - 3/13/2019 5:56PM - //if (!raw && IsOwnedByPlayer) return(VISUAL_SHADOWY); - if (stage < 0x00FF) return(VISUAL_RIPPLE); - return(VISUAL_HIDDEN); -} - - -/*********************************************************************************************** - * TechnoClass::Techno_Draw_Object -- General purpose draw object routine. * - * * - * This routine is used to draw the object. It will handle any remapping or cloaking * - * effects required. This logic is isolated here since all techno object share the same * - * render logic when it comes to remapping and cloaking. * - * * - * INPUT: shapefile -- Pointer to the shape file that the shape will be drawn from. * - * * - * shapenum -- The shape number of the object in the file to use. * - * * - * x,y -- Center pixel coordinate to use for rendering this object. * - * * - * window -- The clipping window to use when rendering. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Techno_Draw_Object(void const * shapefile, int shapenum, int x, int y, WindowNumberType window) -{ - if (shapefile) { - VisualType visual = Visual_Character(); - void const * remap = Remap_Table(); - - // Server still needs to "render" hidden objects to the virtual window, so objects get created properly - SKY - if ((visual == VISUAL_HIDDEN) && (window == WINDOW_VIRTUAL)) { - visual = VISUAL_SHADOWY; - } - - if (visual != VISUAL_HIDDEN && visual != VISUAL_RIPPLE) { - if (visual == VISUAL_SHADOWY) { - CC_Draw_Shape(this, shapefile, shapenum, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING|SHAPE_PREDATOR, NULL, Map.FadingShade); - } else { - CC_Draw_Shape(this, shapefile, shapenum, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING|SHAPE_GHOST, remap, Map.UnitShadow); - } - if (visual == VISUAL_DARKEN) { - CC_Draw_Shape(this, shapefile, shapenum, x, y, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, remap, Map.FadingShade); - } - } - if (visual != VISUAL_NORMAL && visual != VISUAL_HIDDEN) { - CC_Draw_Shape(this, shapefile, shapenum, x, y, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL); - } - } -} - - - -/*********************************************************************************************** - * TechnoClass::Techno_Draw_Object_Virtual -- Draw object with virtual window support * - * * - * INPUT: shapefile -- Pointer to the shape file that the shape will be drawn from. * - * * - * shapenum -- The shape number of the object in the file to use. * - * * - * x,y -- Center pixel coordinate to use for rendering this object. * - * * - * window -- The clipping window to use when rendering. * - * * - * shape_name -- The name of the shapefile * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 6/20/2019 1:31PM - ST : Created. * - *=============================================================================================*/ -void TechnoClass::Techno_Draw_Object_Virtual(void const * shapefile, int shapenum, int x, int y, WindowNumberType window, const char *shape_name) -{ - if (shape_name == NULL || *shape_name == 0) { - /* - ** If there's no override shape name, then call the regular draw - */ - Techno_Draw_Object(shapefile, shapenum, x, y, window); - return; - } - - if (shapefile) { - VisualType visual = Visual_Character(); - void const * remap = Remap_Table(); - - // Server still needs to "render" hidden objects to the virtual window, so objects get created properly - SKY - if ((visual == VISUAL_HIDDEN) && (window == WINDOW_VIRTUAL)) { - visual = VISUAL_SHADOWY; - } - - if (visual != VISUAL_HIDDEN && visual != VISUAL_RIPPLE) { - if (visual == VISUAL_SHADOWY) { - CC_Draw_Shape(this, shape_name, shapefile, shapenum, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING|SHAPE_PREDATOR, NULL, Map.FadingShade); - } else { - CC_Draw_Shape(this, shape_name, shapefile, shapenum, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING|SHAPE_GHOST, remap, Map.UnitShadow); - } - if (visual == VISUAL_DARKEN) { - CC_Draw_Shape(this, shape_name, shapefile, shapenum, x, y, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, remap, Map.FadingShade); - } - } - if (visual != VISUAL_NORMAL && visual != VISUAL_HIDDEN) { - CC_Draw_Shape(this, shape_name, shapefile, shapenum, x, y, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL); - } - } -} - - - -/*********************************************************************************************** - * TechnoClass::Remap_Table -- Fetches the appropriate remap table to use. * - * * - * This routine is used to fetch the appropriate remap table to use for this object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the remap table to use for this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void const * TechnoClass::Remap_Table(void) -{ - return(House->Remap_Table(IsBlushing, true)); -} - - -/*********************************************************************************************** - * TechnoClass::Detach -- Handles removal of target from tracking system. * - * * - * This routine is called when the specified object is about to be removed from the game * - * system. The target object is removed from any tracking computers that this object may * - * have. * - * * - * INPUT: target -- The target object (as a target value) that is being removed from the * - * game. * - * * - * all -- Is the target about to die? A false value might indicate that the * - * object is merely cloaking. In such a case, radio contact will not * - * be affected. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Detach(TARGET target, bool all) -{ - RadioClass::Detach(target, all); - - if (SuspendedMission != MISSION_NONE && SuspendedTarCom == target) { - SuspendedMission = MISSION_NONE; - SuspendedTarCom = TARGET_NONE; - } - - /* - ** If the targeting computer is assigned to the target, then the targeting - ** computer must be cleared. - */ - if (TarCom == target) { - Assign_Target(TARGET_NONE); - Restore_Mission(); - } - - /* - ** If it is in radio contact with another object, then that radio contact - ** must be broken. - */ - if (all && In_Radio_Contact() && Contact_With_Whom()->As_Target() == target) { - Transmit_Message(RADIO_OVER_OUT); - } -} - - -/*********************************************************************************************** - * TechnoClass::Kill_Cargo -- Destroys any cargo attached to this object. * - * * - * This routine handles the destruction of any cargo this object may contain. Typical of * - * this would be when a transport helicopter gets destroyed. * - * * - * INPUT: source -- The source of the destruction of the cargo. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Kill_Cargo(TechnoClass * source) -{ - while (Is_Something_Attached()) { - FootClass * foot = Detach_Object(); - if (foot) { - foot->Record_The_Kill(source); - delete foot; - } - } -} - - -/*********************************************************************************************** - * TechnoClass::Crew_Type -- Fetches the kind of crew this object contains. * - * * - * This routine is called when generating survivors to this object. This routine returns * - * the type of survivor to generate. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the infantry type of a survivor. * - * * - * WARNINGS: This routine is designed to be called repeatedly. Once for each survivor to * - * generate. * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -InfantryType TechnoClass::Crew_Type(void) const -{ - InfantryType infantry = INFANTRY_E1; - if (House->ActLike == HOUSE_NEUTRAL) { - infantry = Random_Pick(INFANTRY_C1, INFANTRY_C9); - } else { - if (Techno_Type_Class()->Primary == WEAPON_NONE && Random_Pick(0, 6) == 1) { - if (Random_Pick(0, 1) == 0) { - infantry = INFANTRY_C1; - } else { - infantry = INFANTRY_C7; - } - } - } - return(infantry); -} - - -/*********************************************************************************************** - * TechnoClass::Value -- Fetches the target value for this object. * - * * - * This routine is used to fetch the target value for this object. The greater the value * - * returned, the better this object is as a target. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the target value for this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - * 08/16/1995 JLB : Adjusted for early mission lame-out. * - *=============================================================================================*/ -int TechnoClass::Value(void) const -{ - int value = 0; - - /* - ** In early missions, contents of transports are not figured - ** into the total value. - 8/16/95 - */ - if (BuildLevel > 8 || GameToPlay != GAME_NORMAL) { - if (Is_Something_Attached()) { - FootClass * object = Attached_Object(); - - while (object) { - value += object->Value(); - object = (FootClass *)object->Next; - } - } - } - return Risk() + Techno_Type_Class()->Reward + value; -} - - -/*********************************************************************************************** - * TechnoClass::Threat_Range -- Returns the range to scan based on threat control. * - * * - * This routine will return the range to scan based on the control value specified. The * - * value returned by this routine is typically used when scanning for enemies. * - * * - * INPUT: control -- The range control parameter. * - * 0 = Use weapon range (zero is returned in this special case). * - * -1 = Scan without range restrictions (-1 is returned in this case). * - * 1 = Scan up to twice weapon range. * - * * - * OUTPUT: Returns with a range (or special value) that can be used in the threat scan * - * process. If zero is returned, then always check threat against In_Range(). If * - * -1 is returned, then no range limitation restriction exists. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Threat_Range(int control) const -{ - if (control == -1) return(-1); - if (control == 0) return(0); - - int range = MAX(Weapon_Range(0), Weapon_Range(1)); - range *= 2; - range = Bound(range, 0x0000, 0x0A00); - return(range); -} - - -/*********************************************************************************************** - * TechnoClass::Base_Is_Attacked -- Handle panic response to base being attacked. * - * * - * This routine is called when the base is being attacked. It will pull units off of the * - * field and send them back to defend the base. This routine will make taking an enemy * - * base much more difficult. * - * * - * INPUT: enemy -- Pointer to the enemy object that did the damage on the base. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine can drastically affect the game play. The computer will probably * - * call off its attacks as a result. * - * * - * HISTORY: * - * 06/25/1995 JLB : Commented. * - *=============================================================================================*/ -void TechnoClass::Base_Is_Attacked(TechnoClass const *enemy) -{ - FootClass *defender[6]; - int value[6]; - int count = 0; - int weakest = 0; - int desired = enemy->Risk() * 2; - int risktotal = 0; - - /* - ** Humans have to deal with their own base is attacked problems. - */ - if (!enemy || House->Is_Ally(enemy) || House->IsHuman) { - return; - } - - /* - ** Don't overreact if this building can defend itself. - */ - if (Techno_Type_Class()->Primary != WEAPON_NONE) return; - - /* - ** If the enemy is not an infantry or a unit there is not much we can - ** do about it. - */ - if (enemy->What_Am_I() != RTTI_INFANTRY && enemy->What_Am_I() != RTTI_UNIT ) { - return; - } - - /* - ** If the enemy is a gunboat, then don't do anything. - */ - // This should allow helicopters to retaliate however. Hmmm. - if (enemy->What_Am_I() == RTTI_UNIT && (*((UnitClass const *)enemy) == UNIT_GUNBOAT || *((UnitClass const *)enemy) == UNIT_HOVER)) { - return; - } - - /* - ** If the threat has already been dealt with then we don't need to do - ** any work. Check for that here. - */ - if (!((FootClass *)enemy)->BaseAttackTimer.Expired()) { - return; - } - - /* - ** We will need units to defend our base. We need to suspend teams until - ** the situation has been dealt with. - */ - TeamClass::Suspend_Teams(20); - - /* - ** Loop through the infantry looking for those who are capable of going - ** on a rescue mission. - */ - int index; - for (index = 0; index < Infantry.Count() && desired > 0; index++) { - InfantryClass * infantry = Infantry.Ptr(index); - if (infantry && infantry->Owner() == Owner()) { - - /* - ** Never recruite sticky guard units to defend a base. - */ - if (infantry->Mission == MISSION_STICKY || infantry->Mission == MISSION_SLEEP) continue; - - /* - ** Find the amount of threat that this unit can apply to the - ** enemy. - */ - int threat = infantry->Rescue_Mission(enemy->As_Target()); - - /* - ** If it can't apply any threat then do just skip it and do not - ** add it to the list. - */ - if (!threat) { - continue; - } - - /* - ** If the value returned is negative then this unit is already - ** assigned to fighting the enemy, so subtract its value from - ** the enemys desired value. - */ - if (threat < 0) { - desired += threat; - continue; - } - - if (count < 6) { - defender[count] = (FootClass *)infantry; - value[count] = threat; - count++; - continue; - } - - if (threat > weakest) { - int newweakest = threat; - - for (int lp = 0; lp < count; lp ++) { - if (value[lp] == weakest) { - value[lp] = threat; - defender[lp] = (FootClass *) infantry; - continue; - } - if (value[count] < newweakest) { - newweakest = value[lp]; - } - } - weakest = newweakest; - } - } - } - - /* - ** Loop through the units looking for those who are capable of going - ** on a rescue mission. - */ - for (index = 0; index < Units.Count() && desired > 0; index++) { - UnitClass * unit = Units.Ptr(index); - if (unit && unit->Owner() == Owner()) { - - /* - ** Never recruite sticky guard units to defend a base. - */ - if (unit->Mission == MISSION_STICKY || unit->Mission == MISSION_SLEEP) continue; - - /* - ** Find the amount of threat that this unit can apply to the - ** enemy. - */ - int threat = unit->Rescue_Mission(enemy->As_Target()); - - /* - ** If it can't apply any threat then do just skip it and do not - ** add it to the list. - */ - if (!threat) { - continue; - } - - /* - ** If the value returned is negative then this unit is already - ** assigned to fighting the enemy, so subtract its value from - ** the enemys desired value. - */ - if (threat < 0) { - desired += threat; - continue; - } - - if (count < 6) { - defender[count] = (FootClass *)unit; - value[count] = threat; - count++; - continue; - } - if (threat > weakest) { - int newweakest = threat; - - for (int lp = 0; lp < count; lp ++) { - if (value[lp] == weakest) { - value[lp] = threat; - defender[lp] = (FootClass *) unit; - continue; - } - if (value[count] < newweakest) { - newweakest = value[lp]; - } - } - weakest = newweakest; - } - } - } - - if (desired > 0) { - - /* - ** Sort the defenders by value, this doesn't take very long and will - ** help the closest defenders to respond. - */ - int lp; - for (lp = 0; lp < count - 1; lp ++) { - for (int lp2 = lp + 1; lp2 < count; lp2++) { - if (value[lp] < value[lp2]) { - - value[lp] ^= value[lp2]; - value[lp2] ^= value[lp]; - value[lp] ^= value[lp2]; - - FootClass *temp; - temp = defender[lp]; - defender[lp] = defender[lp2]; - defender[lp2] = temp; - } - } - } - - for (lp = 0; lp < count; lp ++) { - defender[lp]->Assign_Mission(MISSION_RESCUE); - defender[lp]->Assign_Target(enemy->As_Target()); - risktotal += defender[lp]->Risk(); - if (risktotal > desired) { - break; - } - } - } - - if (risktotal > desired) { - ((FootClass *)enemy)->BaseAttackTimer.Set(15 * 15); - } -} - - -/*********************************************************************************************** - * TechnoClass::Get_Ownable -- Fetches the ownable bits for this object. * - * * - * This routine will return the ownable bits for this object. The ownable bits represent * - * the houses that are allowed to own this object. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the ownable bits for this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -unsigned char TechnoClass::Get_Ownable(void) const -{ - return ((TechnoTypeClass const &)Class_Of()).Ownable; -} - - -/*********************************************************************************************** - * TechnoClass::Is_Techno -- Confirms that this is a TechnoClass object. * - * * - * This routine is called to confirm if this object is derived from the TechnoClass * - * object. At this level, the return value will always be true. * - * * - * INPUT: none * - * * - * OUTPUT: Is this object a TechnoClass or derived from it? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Is_Techno(void) const -{ - return(true); -} - - -/*********************************************************************************************** - * TechnoClass::Risk -- Fetches the risk associated with this object. * - * * - * This routine is called when the risk value for this object needs to be determined. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the risk value for this object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Risk(void) const -{ - return(Techno_Type_Class()->Risk); -} - - -/*********************************************************************************************** - * TechnoClass::Tiberium_Load -- Fetches the current tiberium load percentage. * - * * - * This routine will return the current Tiberium load (expressed as a fixed point fraction) * - * that this object currently contains. Typical implementor of this function would be * - * the harvester. Any object that can return a non-zero value should derive from this * - * function in order to return the appropriate value. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the current Tiberium load expressed as a fixed point number. * - * 0x0000 = empty * - * 0x0080 = half full * - * 0x0100 = full * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Tiberium_Load(void) const -{ - return(0x0000); -} - - -/*********************************************************************************************** - * TechnoClass::Desired_Load_Dir -- Fetches loading parameters for this object. * - * * - * This routine is called when an object desires to load up on this object. The object * - * desiring to load is specified. The cell that the loading object should move to is * - * determined. The direction that this object should face is also calculated. This routine * - * will be overridden by those objects that can actually load up passengers. * - * * - * INPUT: object -- The object that is desiring to load up. * - * * - * moveto -- Reference to the cell that the loading object should move to before * - * the final load process occurs (this value will be filled in). * - * * - * OUTPUT: Returns with the direction that the transport object should face. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -DirType TechnoClass::Desired_Load_Dir(ObjectClass * , CELL & moveto) const -{ - moveto = 0; - return(DIR_N); -} - - -/*********************************************************************************************** - * TechnoClass::Pip_Count -- Fetches the number of pips to display on this object. * - * * - * This routine will return the number of pips to display on this object when the object * - * is selected. The default condition is to return no pips at all. This routine is * - * derived for those objects that can have pips. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of pips to display on this object when selected. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Pip_Count(void) const -{ - return(0); -} - - -/*********************************************************************************************** - * TechnoClass::Fire_Direction -- Fetches the direction projectile fire will take. * - * * - * This routine will fetch the direction that a fired projectile will take. This is * - * usually the facing of the object's weapon. This routine will be derived for the objects * - * that have their weapon barrel facing a different direction than the body. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the direction a fired projectile will take. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -DirType TechnoClass::Fire_Direction(void) const -{ - return(PrimaryFacing.Current()); -} - - -/*********************************************************************************************** - * TechnoClass::Response_Select -- Handles the voice response when selected. * - * * - * This routine is called when a voice reponse to a select action is desired. This routine * - * should be overridden for any object that actually has a voice response. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine can generate an audio response. * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Response_Select(void) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Response_Move -- Handles the voice repsonse to a movement request. * - * * - * This routine is called when a voice response to a movement order is desired. This * - * routine should be overridden for any object that actually has a voice response. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This can generate an audio repsonse. * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Response_Move(void) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Response_Attack -- Handles the voice response when given attack order. * - * * - * This routine is called when a voice response to an attack order is desired. This routine * - * should be overridden for any object that actually have a voice response. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This can generate an audio response. * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Response_Attack(void) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Target_Something_Nearby -- Handles finding and assigning a nearby target. * - * * - * This routine will search for a nearby target and assign it to this object's TarCom. * - * The method to use when scanning for a target is controlled by the parameter passed. * - * * - * INPUT: threat -- The threat control parameter used to control the range searched. The * - * only values recognized are THREAT_RANGE and THREAT_AREA. * - * * - * OUTPUT: Was a suitable target aquired and assigned to the TarCom? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -bool TechnoClass::Target_Something_Nearby(ThreatType threat) -{ - threat = threat & (THREAT_RANGE|THREAT_AREA); - - /* - ** Determine that if there is an existing target it is still legal - ** and within range. - */ - if (Target_Legal(TarCom)) { - if ((threat & THREAT_RANGE) && !In_Range(TarCom)) { - Assign_Target(TARGET_NONE); - } - } - - /* - ** If there is no target, then try to find one and assign it as - ** the target for this unit. - */ - if (!Target_Legal(TarCom)) { - Assign_Target(Greatest_Threat(threat)); - } - - /* - ** Return with answer to question: Does this unit have a target? - */ - return(Target_Legal(TarCom)); -} - - -/*********************************************************************************************** - * TechnoClass::Exit_Object -- Causes specified object to leave this object. * - * * - * This routine is called when there is an attached object that should detach and leave * - * this object. Typical of this would be the refinery and APC. * - * * - * INPUT: object -- The object that is trying to leave this object. * - * * - * OUTPUT: Was the object successfully launched from this object? Failure might indicate that * - * there is insufficient room to detach the specified object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Exit_Object(TechnoClass *) -{ - return(0); -} - - -/*********************************************************************************************** - * TechnoClass::Random_Animate -- Performs some idle animation for the object. * - * * - * This is a maintenance routine that is called when the object might want to check to see * - * if it should go into some idle animation. Infantry are a good example of objects that * - * perform idle animations. This routine must be overridden by the derived object types * - * in order to give it some functionality. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Random_Animate(void) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Assign_Destination -- Assigns movement destination to the object. * - * * - * This routine is called when the object needs to have a new movement destination * - * assigned. This routine must be overridden since at this level, movement is not allowed. * - * * - * INPUT: destination -- The destination to assign to this object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Assign_Destination(TARGET ) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Scatter -- Causes the object to scatter to an adjacent cell. * - * * - * This routine is called when the object needs to get out of the way. This might be as a * - * result of combat or findpath reasons. * - * * - * INPUT: coord -- The source of the reason to scatter. The object should try to run * - * away from this coordinate. * - * * - * forced -- Is the scatter a forced scatter? If false, then this is merely a * - * request that scattering might be a good idea. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Scatter(COORDINATE , bool , bool ) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Enter_Idle_Mode -- Object enters its default idle condition. * - * * - * This routine is called when the object should intelligently revert to an idle state. * - * Typically this routine is called after some mission has completed. This routine must * - * be overridden by the various object types. It is located at this level merely to provide * - * a virtual function entry point. * - * * - * INPUT: initial -- Is this called when the unit just leaves a factory or is initially * - * or is initially placed on the map? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/24/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Enter_Idle_Mode(bool ) -{ -} - - -/*********************************************************************************************** - * TechnoClass::Draw_Pips -- Draws the transport pips and other techno graphics. * - * * - * This routine is used to render the small transportation pip (occupant feedback graphic) * - * used for transporter object. It will also display if the techno object is "primary" * - * if necessary. * - * * - * INPUT: x,y -- The pixel coordinate for the center of the first pip. Subsiquent pips * - * are drawn rightward. * - * * - * window-- The window that pip clipping is relative to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/08/1995 JLB : Created. * - *=============================================================================================*/ -void TechnoClass::Draw_Pips(int x, int y, WindowNumberType window) -{ - /* - ** Transporter type objects have a different graphic representation for the pips. The - ** pip color represents the type of occupant. - */ - if (Techno_Type_Class()->IsTransporter) { - ObjectClass const * object = Attached_Object(); - - for (int index = 0; index < Class_Of().Max_Pips(); index++) { - PipEnum pip = PIP_EMPTY; - - if (object) { - pip = PIP_FULL; - if (object->What_Am_I() == RTTI_INFANTRY) { - if (*((InfantryClass *)object) == INFANTRY_RAMBO) { - pip = PIP_COMMANDO; - } - if (*((InfantryClass *)object) == INFANTRY_E7) { - pip = PIP_ENGINEER; - } - if (((InfantryClass *)object)->Class->IsCivilian) { - pip = PIP_CIVILIAN; - } - } - object = object->Next; - } - CC_Draw_Pip(this, Class_Of().PipShapes, pip, x+index*3, y, window, SHAPE_CENTER|SHAPE_WIN_REL); - } - - } else { - - /* - ** Display number of how many attached objects there are. This is also used - ** to display the fullness rating for a harvester. - */ - int pips = Pip_Count(); - for (int index = 0; index < Class_Of().Max_Pips(); index++) { - CC_Draw_Pip(this, Class_Of().PipShapes, (index < pips) ? PIP_FULL : PIP_EMPTY, x+index*3, y, window, SHAPE_CENTER|SHAPE_WIN_REL); - } - } - - /* - ** Display whether this unit is a leader unit or not. - */ - if (IsLeader && (window != WINDOW_VIRTUAL)) { - CC_Draw_Pip(this, Class_Of().PipShapes, PIP_PRIMARY, x-2, y-3, window, /*SHAPE_CENTER|*/SHAPE_WIN_REL); - } -} - - -/*********************************************************************************************** - * TechnoClass::Find_Docking_Bay -- Searches for a close docking bay. * - * * - * This routine will be used to find a building that can serve as a docking bay. The * - * closest building that qualifies will be returned. If no building could be found then * - * return with NULL. * - * * - * INPUT: b -- The structure type to look for. * - * * - * friendly -- Allow searching for allied buildings as well. * - * * - * OUTPUT: Returns with a pointer to the building that can serve as the best docking bay. * - * * - * WARNINGS: This routine might return NULL even if there are buildings of the specified * - * type available. This is the case when the building(s) are currently busy and * - * cannot serve as a docking bay at the moment. * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - * 08/13/1995 JLB : Recognizes the "IsLeader" method of building preference. * - *=============================================================================================*/ -BuildingClass * TechnoClass::Find_Docking_Bay(StructType b, bool friendly) const -{ - BuildingClass * best = 0; - - /* - ** First check to see if there are ANY buildings of the specified - ** type in thi house's inventory. If not, then don't bother to scan - ** for one. - */ - if (House->BScan & (1L << b)) { - int bestval = -1; - - /* - ** Loop through all the buildings and find the one that matches the specification - ** and is willing to dock with this object. - */ - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - /* - ** Check to see if the building qualifies (preliminary scan). - */ - if (building && - (friendly ? building->House->Is_Ally(this) : building->House == House) && - !building->IsInLimbo && - *building == b && - ((TechnoClass *)this)->Transmit_Message(RADIO_CAN_LOAD, building) == RADIO_ROGER) { - - /* - ** If the building qualifies and this building is better than the - ** last qualifying building (as rated by distance), then record - ** this building and keep scanning. - */ - if (bestval == -1 || Distance(building) < bestval || building->IsLeader) { - best = building; - bestval = Distance(building); - } - } - } - } - return(best); -} - - -/*********************************************************************************************** - * TechnoClass::Find_Exit_Cell -- Finds an appropriate exit cell for this object. * - * * - * This routine is called when an object would like to exit from this (presumed) transport. * - * A suitable cell should be returned by this routine. The specified object will probably * - * be unloaded at that cell. * - * * - * INPUT: techno -- Pointer to the object that would like to unload. This is used to * - * determine suitability for placement. * - * * - * OUTPUT: Returns with the cell that is recommended for object exit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/12/1995 JLB : Created. * - *=============================================================================================*/ -CELL TechnoClass::Find_Exit_Cell(TechnoClass const * ) const -{ - return(Coord_Cell(Docking_Coord())); -} - - -/*********************************************************************************************** - * TechnoClass::Refund_Amount -- Returns with the money to refund if this object is sold. * - * * - * This routine is used by the selling back mechanism in order to credit the owning house * - * with some refund credits. The value returned is the credits to refund to the owner. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the credits to refund to the owner. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Refund_Amount(void) const -{ - int cost = Techno_Type_Class()->Raw_Cost() * House->CostBias; - - /* - ** If the object is carrying Tiberium directly (i.e., the harvester), then - ** account for the credits of the load. - */ - cost += Fixed_To_Cardinal(UnitTypeClass::FULL_LOAD_CREDITS, Tiberium_Load())/2; - - if (House->IsHuman) { - cost /= 2; - } - return(cost); -} - - - - - - - - -/* -** Additions to TechnoClass to track discovery per-player. ST - 3/6/2019 11:18AM -** -** -** -** -** -*/ - - -/*********************************************************************************************** - * TechnoClass::Is_Discovered_By_Player -- Has this object been disovered by the given player * - * * - * INPUT: Player pointer * - * * - * OUTPUT: True if discovered by that player * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 3/6/2019 11:20AM - ST * - *=============================================================================================*/ -bool TechnoClass::Is_Discovered_By_Player(HouseClass *player) const -{ - if (player && player->Class) { - int shift = (int) player->Class->House; - return (IsDiscoveredByPlayerMask & (1 << shift)) ? true : false; - } else { - int shift = (int) PlayerPtr->Class->House; - return (IsDiscoveredByPlayerMask & (1 << shift)) ? true : false; - } - return false; -} - - -/*********************************************************************************************** - * TechnoClass::Set_Discovered_By_Player -- Mark that this object been disovered by the player * - * * - * INPUT: Player pointer * - * * - * OUTPUT: * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 3/6/2019 11:23AM - ST * - *=============================================================================================*/ -void TechnoClass::Set_Discovered_By_Player(HouseClass *player) -{ - int shift = 0; - if (player && player->Class) { - shift = (int) player->Class->House; - } else { - shift = (int)PlayerPtr->Class->House; - } - IsDiscoveredByPlayerMask |= (1 << shift); - - if (GameToPlay == GAME_NORMAL && player == PlayerPtr) { - IsDiscoveredByPlayer = true; - } -} - - - -/*********************************************************************************************** - * TechnoClass::Clear_Discovered_By_Players -- Clear player discovery flags * - * * - * INPUT: Player pointer * - * * - * OUTPUT: * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 4/27/2020 - SKY * - *=============================================================================================*/ -void TechnoClass::Clear_Discovered_By_Players() -{ - IsDiscoveredByPlayerMask = 0; - IsDiscoveredByPlayer = false; -} - - - -/*********************************************************************************************** - * TechnoClass::Is_Owned_By_Player -- Is this object owned by the active human player * - * * - * INPUT: Player pointer * - * * - * OUTPUT: * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 3/13/2019 5:00PM - ST * - *=============================================================================================*/ -bool TechnoClass::Is_Owned_By_Player(HouseClass *player) const -{ - if (player == NULL) { - return (House == PlayerPtr) ? true : false; - } - return (House == player) ? true : false; -} - - - - - - - - - - - -#ifdef USE_RA_AI - - /* - ** Additions for AI, from Red Alert. ST - 7/16/2019 11:36AM - */ - - -/*********************************************************************************************** - * TechnoClass::Anti_Air -- Determines the anti-aircraft strength of the object. * - * * - * This routine will calculate and return the anti-aircraft strength of this object. * - * Typical users of this strength value is the base defense expert system AI. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the anti-aircraft defense value of this object. The value returned * - * is an abstract number to be used for relative comparisons only. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Anti_Air(void) const -{ - //assert(IsActive); - - if (Is_Weapon_Equipped()) { - WeaponType weapon_type = Techno_Type_Class()->Primary; - WeaponTypeClass const * weapon = &Weapons[weapon_type]; - //BulletTypeClass const * bullet = weapon->Bullet; - const BulletTypeClass &bullet = BulletTypeClass::As_Reference(Weapons[weapon_type].Fires); - //WarheadTypeClass const * warhead = weapon->WarheadPtr; - WarheadTypeClass const * warhead = &Warheads[bullet.Warhead]; - - - //if (bullet->IsAntiAircraft) { - if (weapon_type != WEAPON_NONE && BulletTypeClass::As_Reference(Weapons[weapon_type].Fires).IsAntiAircraft) { - int value = ((weapon->Attack * warhead->Modifier[ARMOR_ALUMINUM]) * weapon->Range) / weapon->ROF; - - //if (Techno_Type_Class()->Is_Two_Shooter()) { - // value *= 2; - //} - return(value/50); - } - } - return(0); -} - - -/*********************************************************************************************** - * TechnoClass::Anti_Armor -- Determines the anti-armor strength of the object. * - * * - * This routine is used to examine and calculate the anti-armor strength of this object. * - * Typical user user of this would be the expert system base defense AI. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the relative anti-armor combat value for this object. The value * - * is abstract and is only to be used in relative comparisons. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Anti_Armor(void) const -{ - //assert(IsActive); - - if (Is_Weapon_Equipped()) { - - WeaponType weapon_type = Techno_Type_Class()->Primary; - //if (!Techno_Type_Class()->PrimaryWeapon->Bullet->IsAntiGround) return(0); - if (weapon_type != WEAPON_NONE && BulletTypeClass::As_Reference(Weapons[weapon_type].Fires).IsAntiAircraft) { - return 0; - } - - //WeaponTypeClass const * weapon = Techno_Type_Class()->PrimaryWeapon; - //BulletTypeClass const * bullet = weapon->Bullet; - //WarheadTypeClass const * warhead = weapon->WarheadPtr; - WeaponTypeClass const * weapon = &Weapons[weapon_type]; - const BulletTypeClass &bullet = BulletTypeClass::As_Reference(Weapons[weapon_type].Fires); - WarheadTypeClass const * warhead = &Warheads[bullet.Warhead]; - - int mrange = min(weapon->Range, 0x0400); - - int value = ((weapon->Attack * warhead->Modifier[ARMOR_STEEL]) * mrange * warhead->SpreadFactor) / weapon->ROF; - //if (Techno_Type_Class()->Is_Two_Shooter()) { - // value *= 2; - //} - if (bullet.IsInaccurate) { - value /= 2; - } - return(value/50); - } - return(0); -} - - -/*********************************************************************************************** - * TechnoClass::Anti_Infantry -- Calculates the anti-infantry strength of this object. * - * * - * This routine is used to determine the anti-infantry strength of this object. The * - * typical user of this routine is the expert system base defense AI. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the anti-infantry strength of this object. The value returned is * - * abstract and should only be used for relative comparisons. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/02/1995 JLB : Created. * - *=============================================================================================*/ -int TechnoClass::Anti_Infantry(void) const -{ - //assert(IsActive); - - if (Is_Weapon_Equipped()) { - //if (!Techno_Type_Class()->PrimaryWeapon->Bullet->IsAntiGround) return(0); - WeaponType weapon_type = Techno_Type_Class()->Primary; - if (weapon_type != WEAPON_NONE && BulletTypeClass::As_Reference(Weapons[weapon_type].Fires).IsAntiAircraft) { - return 0; - } - - //WeaponTypeClass const * weapon = Techno_Type_Class()->PrimaryWeapon; - //BulletTypeClass const * bullet = weapon->Bullet; - //WarheadTypeClass const * warhead = weapon->WarheadPtr; - WeaponTypeClass const * weapon = &Weapons[weapon_type]; - const BulletTypeClass &bullet = BulletTypeClass::As_Reference(Weapons[weapon_type].Fires); - WarheadTypeClass const * warhead = &Warheads[bullet.Warhead]; - int mrange = min(weapon->Range, 0x0400); - - int value = ((weapon->Attack * warhead->Modifier[ARMOR_NONE]) * mrange * warhead->SpreadFactor) / weapon->ROF; - //if (Techno_Type_Class()->Is_Two_Shooter()) { - // value *= 2; - //} - if (bullet.IsInaccurate) { - value /= 2; - } - return(value/50); - } - return(0); -} - - - -int TechnoTypeClass::Legal_Placement(CELL pos) const -{ - if (pos == -1) return(0); - - /* - ** Normal buildings must check to see that every foundation square is free of - ** obstacles. If this check passes for all foundation squares, only then does the - ** routine return that it is legal to place. - */ - short const * offset = Occupy_List(true); - bool build = (What_Am_I() == RTTI_BUILDINGTYPE); - - if (build) { - return ((BuildingTypeClass*)this)->Legal_Placement(pos); - } - - while (offset != NULL && *offset != REFRESH_EOL) { - CELL cell = pos + *offset++; - if (!Map.In_Radar(cell)) return(false); - //if (build) { - // if (!Map[cell].Is_Clear_To_Build(Speed)) { - // return(0); - // } - //} else { - //if (!Map[cell].Is_Clear_To_Move(Speed, false, false)) { - if (!Map[cell].Is_Clear_To_Move(false, false)) { - return(0); - } - //} - } - return(1); -} -#endif //USE_RA_AI \ No newline at end of file diff --git a/code/TIBERIANDAWN/TECHNO.H b/code/TIBERIANDAWN/TECHNO.H deleted file mode 100644 index 6690db6..0000000 --- a/code/TIBERIANDAWN/TECHNO.H +++ /dev/null @@ -1,372 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\techno.h_v 2.17 16 Oct 1995 16:46:58 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TECHNO.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 14, 1994 * - * * - * Last Update : April 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TECHNO_H -#define TECHNO_H - -#include "radio.h" -#include "stage.h" -#include "cargo.h" -#include "flasher.h" -#include "house.h" -#include "target.h" -#include "bullet.h" -#include "door.h" -#include "crew.h" - -/**************************************************************************** -** This is the common data between building and units. -*/ -class TechnoClass : public RadioClass, - public FlasherClass, - public StageClass, - public CargoClass, - public DoorClass, - public CrewClass -{ - public: - - /* - ** This flag will be true if the object has been damaged with malace. - ** Damage received due to friendly fire or wear and tear does not count. - ** The computer is not allowed to sell a building unless it has been - ** damaged with malace. - */ - unsigned IsTickedOff:1; - - /* - ** If this object has inherited the ability to cloak, then this bit will - ** be set to true. - */ - unsigned IsCloakable:1; - - /* - ** If this object is designated as special then this flag will be true. For - ** buildings, this means that it is the primary factory. For units, it means - ** that the unit is the team leader. - */ - unsigned IsLeader:1; - - /* - ** Certain units are flagged as "loaners". These units are typically transports that - ** are created solely for the purpose of delivering reinforcements. Such "loaner" - ** units are not owned by the player and thus cannot be directly controlled. These - ** units will leave the game as soon as they have fulfilled their purpose. - */ - unsigned IsALoaner:1; - - /* - ** Once a unit enters the map, then this flag is set. This flag is used to make - ** sure that a unit doesn't leave the map once it enters the map. - */ - unsigned IsLocked:1; - - /* - ** Buildings and units with turrets usually have a recoil animation when they - ** fire. If this flag is true, then the next rendering of the object will be - ** in the "recoil state". The flag will then be cleared pending the next - ** firing event. - */ - unsigned IsInRecoilState:1; - - /* - ** If this unit is "loosely attached" to another unit it is given special - ** processing. A unit is in such a condition when it is in the process of - ** unloading from a transport type object. During the unloading process - ** the transport object must stay still until the unit is free and clear. - ** At that time it radios the transport object and the "tether" is broken - - ** freeing both the unit and the transport object. - */ - unsigned IsTethered:1; - - /* - ** Is this object owned by the player? If not, then it is owned by the computer - ** or remote opponent. This flag facilitates the many logic differences when dealing - ** with player's or computer's units or buildings. - */ - unsigned IsOwnedByPlayer:1; - - /* - ** The more sophisticated game objects must keep track of whether they are discovered - ** or not. This is because the state of discovery can often control how the object - ** behaves. In addition, this fact is used in radar and user I/O processing. - */ - unsigned IsDiscoveredByPlayer:1; - - /* - ** This is used to control the computer recognizing this object. - */ - unsigned IsDiscoveredByComputer:1; - - /* - ** Some game objects can be of the "lemon" variety. This means that they take damage - ** even when everything is ok. This adds a little variety to the game. - */ - unsigned IsALemon:1; - - /* - ** This flag is used to control second shot processing for those units or buildings - ** that fire two shots in quick succession. When this flag is true, it indicates that - ** the second shot is ready to fire. After this shot is fired, regular rearm timing - ** is used rather than the short rearm time. - */ - unsigned IsSecondShot:1; - - /* - ** For units in area guard mode, this is the recorded home position. The guarding - ** unit will try to stay near this location in the course of it's maneuvers. This is - ** also used to record a pending transport for those passengers that are waiting for - ** the transport to become available. It is also used by harvesters so that they know - ** where to head back to after unloading. - */ - TARGET ArchiveTarget; - - /* - ** This is the house that the unit belongs to. - */ - HouseClass * House; - - /* - ** This records the current cloak state for this vehicle. - */ - CloakType Cloak; - StageClass CloakingDevice; - - /* (Targeting Computer) - ** This is the target value for the item that this vehicle should ATTACK. If this - ** is a vehicle with a turret, then it may differ from its movement destination. - */ - TARGET TarCom; - TARGET SuspendedTarCom; - - /* - ** This is the visible facing for the unit or building. - */ - FacingClass PrimaryFacing; - - /* - ** This is the arming countdown. It represents the time necessary - ** to reload the weapon. - */ - unsigned char Arm; - - /* - ** The number of shot this object can fire before running out of ammo. If this - ** value is zero, then firing is not allowed. If -1, then there is no ammunition - ** limit. - */ - int Ammo; - - /* - ** Used by the Obelisk laser to cache its laser weapon rendering data. - ** Line data is cleared after the specified delay. - ** Each line consists of: x, y, x1, y1, color, frame (max frame used to determine duration) - */ - int Lines[3][5]; - int LineCount; - int LineFrame; - int LineMaxFrames; - - /* - ** This is the amount of money spent to produce this object. This value really - ** only comes into play for the case of buildings that have special "free" - ** objects available when purchased at the more expensive rate. - */ - int PurchasePrice; - - /* - ** Per-player view of whether a techno object is discovered. One bit for each house type. ST - 3/6/2019 11:15AM - */ - unsigned int IsDiscoveredByPlayerMask; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[16]; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - TechnoClass(void); - TechnoClass(HousesType house); - virtual ~TechnoClass(void) {}; - - /* - ** Query functions. - */ - virtual int Refund_Amount(void) const; - virtual CELL Find_Exit_Cell(TechnoClass const * techno) const; - virtual BuildingClass * Find_Docking_Bay(StructType b, bool friendly) const; - virtual int Threat_Range(int control) const; - virtual InfantryType Crew_Type(void) const; - TechnoTypeClass const * Techno_Type_Class(void) const {return((TechnoTypeClass const *)&Class_Of());}; - CELL Nearby_Location(TechnoClass const * from=NULL) const; - virtual unsigned char Get_Ownable(void) const; - virtual bool Can_Player_Fire(void) const; - virtual bool Can_Player_Move(void) const; - virtual bool Is_Weapon_Equipped(void) const; - virtual bool Can_Repair(void) const; - virtual bool Is_Techno(void) const; - virtual HousesType Owner(void) const; - virtual int Risk(void) const; - virtual int Value(void) const; - virtual int Rearm_Delay(bool second=true) const; - virtual ActionType What_Action(ObjectClass * target) const; - virtual ActionType What_Action(CELL cell) const; - virtual int Tiberium_Load(void) const; - virtual DirType Desired_Load_Dir(ObjectClass * , CELL & moveto) const; - virtual int Pip_Count(void) const; - virtual DirType Fire_Direction(void) const; - - /* - ** User I/O. - */ - virtual void Clicked_As_Target(HousesType house, int count=7); // 2019/09/20 JAS - Added record of who clicked on the object - virtual bool Select(bool allow_mixed = false); - virtual void Response_Select(void); - virtual void Response_Move(void); - virtual void Response_Attack(void); - virtual void Player_Assign_Mission(MissionType order, TARGET target=TARGET_NONE, TARGET destination=TARGET_NONE); - - /* - ** Combat related. - */ - void Base_Is_Attacked(TechnoClass const *enemy); - void Kill_Cargo(TechnoClass * source); - virtual void Record_The_Kill(TechnoClass * source); - virtual bool Target_Something_Nearby(ThreatType threat=THREAT_NORMAL); - virtual void Stun(void); - virtual bool In_Range(COORDINATE coord, int which=0) const; - virtual bool In_Range(TARGET target, int which=0, bool reciprocal_check = true) const; - virtual bool In_Range(ObjectClass const * target, int which=0, bool reciprocal_check = true) const; - virtual void Death_Announcement(TechnoClass const * source=0) const = 0; - virtual FireErrorType Can_Fire(TARGET target, int which=0) const; - virtual TARGET Greatest_Threat(ThreatType threat) const; - virtual void Assign_Target(TARGET target); - virtual void Override_Mission(MissionType mission, TARGET tarcom, TARGET navcom); - virtual bool Restore_Mission(void); - virtual BulletClass * Fire_At(TARGET target, int which=0); - virtual int Weapon_Range(int which) const; - virtual bool Captured(HouseClass * newowner); - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source); - bool Evaluate_Cell(ThreatType method, int mask, CELL cell, int range, TechnoClass const ** object, int & value) const; - bool Evaluate_Object(ThreatType method, int mask, int range, TechnoClass const * object, int & value) const; - - /* - ** AI. - */ - virtual void AI(void); - virtual bool Revealed(HouseClass * house); - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual void const * Remap_Table(void); - VisualType Visual_Character(bool raw = false); - void Techno_Draw_Object(void const * shapefile, int shapenum, int x, int y, WindowNumberType window); - - // Added. ST - 6/20/2019 1:34PM - void Techno_Draw_Object_Virtual(void const * shapefile, int shapenum, int x, int y, WindowNumberType window, const char *shape_name); - - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual void Draw_Pips(int x, int y, WindowNumberType window); - virtual void Hidden(void); - virtual bool Mark(MarkType mark); - virtual int Exit_Object(TechnoClass *); - virtual void Do_Uncloak(void); - virtual void Do_Cloak(void); - virtual void Do_Shimmer(void); - - /* - ** Movement and animation. - */ - virtual void Random_Animate(void); - virtual void Assign_Destination(TARGET target); - virtual void Scatter(COORDINATE source = NULL, bool forced=false, bool nokidding=false); - virtual void Per_Cell_Process(bool); - virtual void Enter_Idle_Mode(bool initial=false); - - /* - ** Map entry and exit logic. - */ - virtual bool Unlimbo(COORDINATE , DirType facing=DIR_N); - virtual void Detach(TARGET target, bool all); - - - - - /* - ** New functions for per-player discovery for multiplayer. ST - 3/6/2019 11:17AM - */ - bool Is_Discovered_By_Player(HouseClass *player = NULL) const; - void Set_Discovered_By_Player(HouseClass *player = NULL); - void Clear_Discovered_By_Players(); - bool Is_Owned_By_Player(HouseClass *player = NULL) const; - - -#ifdef USE_RA_AI - /* - ** For AI, from Red Alert. ST - 7/16/2019 11:38AM - */ - int Anti_Air(void) const; - int Anti_Armor(void) const; - int Anti_Infantry(void) const; -#endif // USE_RA_AI - - /* - ** Facing translation tables that fix the flaw with 3D studio when - ** it renders 45 degree angles. - */ - static int const BodyShape[32]; -// static int const TurretShape[32]; - - -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TEMPLATE.CPP b/code/TIBERIANDAWN/TEMPLATE.CPP deleted file mode 100644 index e6694fc..0000000 --- a/code/TIBERIANDAWN/TEMPLATE.CPP +++ /dev/null @@ -1,408 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\template.cpv 2.18 16 Oct 1995 16:51:46 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEMPLATE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 17, 1994 * - * * - * Last Update : January 23, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TemplateClass::As_Target -- Converts a template object into a target number. * - * TemplateClass::Init -- Resets the template object system. * - * TemplateClass::Mark -- Lifts or drops a template object. * - * TemplateClass::Read_INI -- Reads the scenario control INI file. * - * TemplateClass::Select -- Select the template object. * - * TemplateClass::TemplateClass -- Default constructor for template class objects. * - * TemplateClass::TemplateClass -- Template object constructor. * - * TemplateClass::Unlimbo -- Places a template object into the game/map system. * - * TemplateClass::Write_INI -- Writes the template objects to the INI file. * - * TemplateClass::delete -- Returns a template object to the pool. * - * TemplateClass::new -- Allocates a template object from pool * - * TemplateClass::Validate -- validates template pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "template.h" - - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * TemplateClass::VTable; - - -/*********************************************************************************************** - * TemplateClass::Validate -- validates template pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int TemplateClass::Validate(void) const -{ - int num; - - num = Templates.ID(this); - if (num < 0 || num >= TEMPLATE_MAX) { - Validate_Error("TEMPLATE"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * TemplateClass::Read_INI -- Reads the scenario control INI file. * - * * - * This routine reads the scenario control INI file and creates all * - * templates specified therein. * - * * - * INPUT: buffer -- Pointer to the loaded scenario control INI file. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void TemplateClass::Read_INI(char *buffer) -{ - char *tbuffer; // Accumulation buffer of unit IDs. - int len; // Size of data in buffer. - CELL cell; // Cell of building. - char buf[128]; // Working string staging buffer. - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - while (*tbuffer != '\0') { - TemplateType temp; // Terrain type. - - cell = atoi(tbuffer); - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - temp = TemplateTypeClass::From_Name(strtok(buf, ",\r\n")); - if (temp != TEMPLATE_NONE) { - new TemplateClass(temp, cell); - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * TemplateClass::Write_INI -- Writes the template objects to the INI file. * - * * - * This routine is used to write all the template objects out to the INI file specified. * - * It is used by the scenario editor when saving the game. * - * * - * INPUT: buffer -- Pointer to the INI file staging buffer. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void TemplateClass::Write_INI(char *buffer) -{ - char uname[10]; - char buf[127]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing template data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Find all templates and write them to the file. - */ - for (int index = 0; index < MAP_CELL_TOTAL; index++) { - CellClass * ptr; - - ptr = &Map[index]; - if (ptr->TType != TEMPLATE_NONE && ptr->TIcon == 0) { - sprintf(uname, "%03d", index); - sprintf(buf, "%s", TemplateTypeClass::As_Reference(ptr->TType).IniName); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} - - -/*********************************************************************************************** - * TemplateClass::TemplateClass -- Default constructor for template class objects. * - * * - * This is the default constructor for a template class object. This construction method * - * should NEVER be used by the game except as a consequence of declaring an array of * - * uninitialized template objects. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -TemplateClass::TemplateClass(void) : - Class(0) -{ -} - - -/*********************************************************************************************** - * TemplateClass::As_Target -- Converts a template object into a target number. * - * * - * This routine will convert a template object into a target number. Because templates * - * never exist as a template object in the game system, this routine will never be called. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 09/25/1994 JLB : Created. * - *=============================================================================================*/ -TARGET TemplateClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_TEMPLATE, Templates.ID(this))); -} - - -/*********************************************************************************************** - * TemplateClass::Init -- Resets the template object system. * - * * - * This routine resets the template object system. It is called * - * prior to loading a new scenario. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void TemplateClass::Init(void) -{ - TemplateClass *ptr; - - Templates.Free_All(); - - ptr = new TemplateClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * TemplateClass::Mark -- Lifts or drops a template object. * - * * - * This routine handles placing or removing a template object. This * - * entails marking the map as appropriate and redisplaying affected * - * cells. * - * * - * INPUT: mark -- The marking operation to perform. * - * * - * OUTPUT: bool; Was the template successfully marked? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - * 12/23/1994 JLB : Examines low level legality before processing. * - *=============================================================================================*/ -bool TemplateClass::Mark(MarkType mark) -{ - Validate(); - static bool noup = false; - void const * iset = Class->Get_Image_Data(); - if (iset && ObjectClass::Mark(mark)) { - - void * map = Get_Icon_Set_Map(iset); - - for (int y = 0; y < Class->Height; y++) { - for (int x = 0; x < Class->Width; x++) { - CELL cell = Coord_Cell(Coord) + y*MAP_CELL_W + x; - if (Map.In_Radar(cell)) { - CellClass * cellptr = &Map[cell]; - int number = y*Class->Width + x; - - /* - ** Determine if this logical icon actually maps to a real icon. If no real - ** icon is associated with this logical position, then don't do any action - ** since none is required. - */ - char * mapptr = (char*)map; - bool real = (mapptr[number] != -1); - - if (real) { - /* - ** Lift the terrain object from the map. - */ - if (mark == MARK_UP && !noup) { - if (cellptr->TType == Class->Type && cellptr->TIcon == number) { - cellptr->TType = TEMPLATE_NONE; - cellptr->TIcon = 0; - } - } - - /* - ** Place the terrain object down. - */ - if (mark == MARK_DOWN) { - if (*this == TEMPLATE_CLEAR1) { - cellptr->TType = TEMPLATE_NONE; - cellptr->TIcon = 0; - } else { - cellptr->TType = Class->Type; - // cellptr->TIcon = real; - cellptr->TIcon = number; - } - } - - cellptr->Redraw_Objects(); - cellptr->Recalc_Attributes(); - } - } - } - } - - /* - ** When marking this template down onto the map, the map template numbers are update - ** but the template is removed from existence. Make sure that the deletion of the - ** template object doesn't also lift the template numbers up from the map. - */ - if (mark == MARK_DOWN) { - noup = true; - delete this; - noup = false; - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TemplateClass::new -- Allocates a template object from pool * - * * - * This routine is used to allocate a template object from the * - * template object pool. * - * * - * INPUT: size -- The size of a template object (not used). * - * * - * OUTPUT: Returns with a pointer to an available template object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -void * TemplateClass::operator new(size_t ) -{ - void * ptr = Templates.Allocate(); - if (ptr) { - ((TemplateClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * TemplateClass::delete -- Returns a template object to the pool. * - * * - * This routine will return a template object to the template object * - * pool. A template so returned is available for allocation again. * - * * - * INPUT: ptr -- Pointer to the object to be returned. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -void TemplateClass::operator delete(void *ptr) -{ - if (ptr) { - ((TemplateClass *)ptr)->IsActive = false; - } - Templates.Free((TemplateClass *)ptr); -} - - -/*********************************************************************************************** - * TemplateClass::TemplateClass -- Template object constructor. * - * * - * This is the constructor for a template object. * - * * - * INPUT: type -- The template object this is to become. * - * * - * pos -- The position on the map to place the object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -TemplateClass::TemplateClass(TemplateType type, CELL pos) : - Class(&TemplateTypeClass::As_Reference(type)) -{ - if (pos != -1) { - Unlimbo(Cell_Coord(pos)); - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/TEMPLATE.H b/code/TIBERIANDAWN/TEMPLATE.H deleted file mode 100644 index 43043cd..0000000 --- a/code/TIBERIANDAWN/TEMPLATE.H +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\template.h_v 2.18 16 Oct 1995 16:45:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEMPLATE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 17, 1994 * - * * - * Last Update : May 17, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TEMPLATE_H -#define TEMPLATE_H - -#include "object.h" -#include "type.h" - -/****************************************************************************** -** This class controls the template object. Template objects function congruously -** to carpet on a floor. They have no depth, but merely control the icon to be rendered -** as the cell's bottom most layer. -*/ -class TemplateClass : public ObjectClass -{ - public: - /*------------------------------------------------------------------- - ** Constructors and destructors. - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - TemplateClass(void); - TemplateClass(TemplateType type, CELL pos=-1); - virtual ~TemplateClass(void) {if (GameActive) TemplateClass::Limbo();}; - operator TemplateType(void) const {return Class->Type;}; - virtual RTTIType What_Am_I(void) const {return RTTI_TEMPLATE;}; - - static void Init(void); - - /* - ** Query functions. - */ - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - int Icon_Number(CELL cell); - - /* - ** Object entry and exit from the game system. - */ - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual void Draw_It(int , int , WindowNumberType ) {}; - virtual bool Mark(MarkType mark); - - /* - ** User I/O. - */ - - /* - ** Combat related. - */ - virtual TARGET As_Target(void) const; - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static char *INI_Name(void) {return "TEMPLATE";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - private: - - /* - ** This is a pointer to the template object's class. - */ - TemplateTypeClass const * const Class; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[8]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TERRAIN.CPP b/code/TIBERIANDAWN/TERRAIN.CPP deleted file mode 100644 index 6aa5e0c..0000000 --- a/code/TIBERIANDAWN/TERRAIN.CPP +++ /dev/null @@ -1,897 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\terrain.cpv 2.16 16 Oct 1995 16:51:44 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TERRAIN.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : May 8, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TerrainClass::AI -- Process the terrain object AI. * - * TerrainClass::As_Target -- Converts the terrain object into a target number. * - * TerrainClass::Can_Enter_Cell -- Determines if the terrain object can exist in the cell. * - * TerrainClass::Catch_Fire -- Catches the terrain object on fire. * - * TerrainClass::Center_Coord -- Fetches the center point coordinate for terrain object. * - * TerrainClass::Debug_Dump -- Displays the status of the terrain object. * - * TerrainClass::Draw_It -- Renders the terrain object at the location specified. * - * TerrainClass::Fire_Out -- Handles when fire has gone out. * - * TerrainClass::Heath_Ratio -- Determines the health ratio for the terrain object. * - * TerrainClass::Init -- Initialize the terrain object tracking system. * - * TerrainClass::Limbo -- Handles terrain specific limbo action. * - * TerrainClass::Mark -- Marks the terrain object on the map. * - * TerrainClass::Radar_Icon -- Fetches pointer to radar icon to use. * - * TerrainClass::Read_INI -- Reads terrain objects from INI file. * - * TerrainClass::Start_To_Crumble -- Initiates crumbling of terrain (tree) object. * - * TerrainClass::Take_Damage -- Damages the terrain object as specified. * - * TerrainClass::TerrainClass -- Constructor for a terrain class object. * - * TerrainClass::TerrainClass -- This is the constructor for a terrain object. * - * TerrainClass::Unlimbo -- Unlimbo terrain object onto the map. * - * TerrainClass::Write_INI -- Writes all terrain objects to the INI file. * - * TerrainClass::delete -- Deletes a terrain object. * - * TerrainClass::new -- Creates a new terrain object. * - * TerrainClass::~TerrainClass -- Default destructor for terrain class objects. * - * TerrainClass::Validate -- validates terrain pointer * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "terrain.h" - -#define BARNACLE_STAGE 22 -#define FIRST_SPORE_STAGE 30 -#define FIRST_SPORABLE_LEVEL 7 - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * TerrainClass::VTable; - - -/*********************************************************************************************** - * TerrainClass::Validate -- validates terrain pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int TerrainClass::Validate(void) const -{ - int num; - - num = Terrains.ID(this); - if (num < 0 || num >= TERRAIN_MAX) { - Validate_Error("TERRAIN"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * TerrainClass::~TerrainClass -- Default destructor for terrain class objects. * - * * - * This is the default destructor for terrain objects. It will remove the object from the * - * map and tracking systems, but only if the game is running. Otherwise, it does nothing. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -TerrainClass::~TerrainClass(void) -{ - if (GameActive && Class) { - TerrainClass::Limbo(); - } -} - - -/*********************************************************************************************** - * TerrainClass::Take_Damage -- Damages the terrain object as specified. * - * * - * This routine is called when damage is to be inflicted upon the terrain object. It is * - * through this routine that terrain objects are attacked and thereby destroyed. Not all * - * terrain objects can be damaged by this routine however. * - * * - * INPUT: damage -- The damage points to inflict (raw). * - * * - * warhead -- The warhead type the indicates the kind of damage. This is used to * - * determine if the terrain object is damaged and if so, by how much. * - * * - * OUTPUT: bool; Was the terrain object destroyed by this damage? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - * 11/22/1994 JLB : Shares base damage handler for techno objects. * - * 12/11/1994 JLB : Shortens attached burning animations. * - *=============================================================================================*/ -ResultType TerrainClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - Validate(); - ResultType res = RESULT_NONE; - - /* - ** Small arms can never destroy a terrain element. - */ - if ((!IsOnFire || warhead == WARHEAD_FIRE) && warhead != WARHEAD_SA && !Class->IsImmune) { - - res = ObjectClass::Take_Damage(damage, distance, warhead, source); - - if (damage && warhead == WARHEAD_FIRE) { - Catch_Fire(); - } - - /* - ** If the terrain object is destroyed by this damage, then only remove it if it - ** currently isn't on fire and isn't in the process of crumbling. - */ - if (res == RESULT_DESTROYED) { - - /* - ** Remove this terrain object from the targeting computers of all other - ** game objects. No use beating a dead horse. - */ - Detach_All(); - - if (IsOnFire) { - - /* - ** Attached flame animation should be shortened as much as possible so that - ** crumbling can begin soon. - */ - Shorten_Attached_Anims(this); - } else { - Start_To_Crumble(); - } - } - } - return(res); -} - - -/*********************************************************************************************** - * TerrainClass::As_Target -- Converts the terrain object into a target number. * - * * - * This routine will take the terrain object and generate a unique targeting number. This * - * number is used for the NavCom and TarCom of other units. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the target number of this terrain object. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -TARGET TerrainClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_TERRAIN, Terrains.ID(this))); -} - - -/*********************************************************************************************** - * TerrainClass::new -- Creates a new terrain object. * - * * - * This routine creates a new terrain object by grabbing a free slot * - * out of the terrain object pool. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the terrain object allocated. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - *=============================================================================================*/ -void * TerrainClass::operator new(size_t) -{ - void * ptr = Terrains.Allocate(); - if (ptr) { - ((TerrainClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * TerrainClass::delete -- Deletes a terrain object. * - * * - * This routine deletes a terrain object by returning it to the * - * terrain object pool. * - * * - * INPUT: ptr -- Pointer to the terrain object to delete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::operator delete(void *ptr) -{ - if (ptr) { - ((TerrainClass *)ptr)->IsActive = false; - } - Terrains.Free((TerrainClass *)ptr); -} - - -/*********************************************************************************************** - * TerrainClass::TerrainClass -- This is the constructor for a terrain object * - * * - * This constructor for a terrain object will initialize the terrain * - * object with it's proper type and insert it into the access * - * tracking system. * - * * - * INPUT: type -- The terrain object type. * - * * - * cell -- The location of the terrain object. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - *=============================================================================================*/ -TerrainClass::TerrainClass(TerrainType type, CELL cell) : - Class(&TerrainTypeClass::As_Reference(type)) -{ - IsBlossoming = false; - IsBarnacled = false; - IsSporing = false; - IsCrumbling = false; - IsOnFire = false; - Strength = Class->MaxStrength; - if (cell != -1) { - if (!Unlimbo(Cell_Coord(cell))) { - delete this; - } - } - Set_Rate(0); // turn off animation -} - - -/*********************************************************************************************** - * TerrainClass::Mark -- Marks the terrain object on the map. * - * * - * This routine will mark or remove the terrain object from the map * - * tracking system. This is typically called when the terrain object * - * is first created, when it is destroyed, and whenever it needs to be * - * redrawn. * - * * - * INPUT: mark -- The marking operation to perform. * - * * - * OUTPUT: bool; Was the terrain object successfully marked? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/02/1994 JLB : Created. * - * 12/23/1994 JLB : Performs low level legality check before proceeding. * - *=============================================================================================*/ -bool TerrainClass::Mark(MarkType mark) -{ - Validate(); - if (ObjectClass::Mark(mark)) { - short const *overlap = Class->Overlap_List(); - short const *occupy = Class->Occupy_List(); - CELL cell = Coord_Cell(Coord); - - switch (mark) { - case MARK_UP: - Map.Pick_Up(cell, this); - break; - - case MARK_DOWN: - Map.Place_Down(cell, this); - break; - - default: - Map.Refresh_Cells(cell, overlap); - Map.Refresh_Cells(cell, occupy); - break; - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TerrainClass::Draw_It -- Renders the terrain object at the location specified. * - * * - * This routine is used to render the terrain object at the location specified and * - * clipped to the window specified. This is the gruntwork drawing routine for the * - * terrain objects as they are displayed on the map. * - * * - * INPUT: x,y -- The coordinate to draw the terrain object at (centered). * - * * - * window -- The clipping window to draw to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/27/1994 JLB : Created. * - * 11/09/1994 JLB : Changed selected terrain highlight method. * - *=============================================================================================*/ -void TerrainClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - void const * shapedata; - - shapedata = Class->Get_Image_Data(); - if (shapedata) { - int shapenum = 0; - - /* - ** Determine the animation stage to render the terrain object. If it is crumbling, then - ** it will display the crumbling animation. - */ - if (IsCrumbling || Class->IsTransformable) { - shapenum = Fetch_Stage()+IsCrumbling; - } else { - if (Strength < 2) { - shapenum++; - } - } - - ShapeFlags_Type flags = SHAPE_NORMAL; - if (Is_Selected_By_Player() && Debug_Map) flags = flags | SHAPE_FADING; - - IsTheaterShape = true; - CC_Draw_Shape(this, shapedata, shapenum, x, y, window, flags|SHAPE_WIN_REL|SHAPE_GHOST, Map.FadingLight, Map.UnitShadow); - IsTheaterShape = false; - } -} - - -/*********************************************************************************************** - * TerrainClass::Init -- Initialize the terrain object tracking system. * - * * - * This routine will clear out the terrain object system so that no terrain objects will * - * exists. It is called prior to loading or starting a scenario. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::Init(void) -{ - TerrainClass *ptr; - - Terrains.Free_All(); - - ptr = new TerrainClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * TerrainClass::Can_Enter_Cell -- Determines if the terrain object can exist in the cell. * - * * - * This routine will examine the cell specified and determine if the the terrain object * - * can legally exist there. * - * * - * INPUT: cell -- The cell to examine. * - * * - * OUTPUT: If the terrain object can be placed in the cell specified, then a value less than * - * 256 will be returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/24/1994 JLB : Created. * - * 01/01/1995 JLB : Actually works now. * - *=============================================================================================*/ -MoveType TerrainClass::Can_Enter_Cell(CELL cell, FacingType) const -{ - Validate(); - short const *offset; // Pointer to cell offset list. - - if ((unsigned)cell >= MAP_CELL_TOTAL) return(MOVE_NO); - - offset = Occupy_List(); - while (*offset != REFRESH_EOL) { - if (!Map[(CELL)(cell + *offset++)].Is_Generally_Clear()) { - return(MOVE_NO); - } - } - return(MOVE_OK); -} - - -/*********************************************************************************************** - * TerrainClass::Catch_Fire -- Catches the terrain object on fire. * - * * - * This routine is called if the terrain object is supposed to catch on fire. The routine * - * performs checking to make sure that only flammable terrain objects that aren't already * - * on fire get caught on fire. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the terrain object caught on fire by this routine? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1994 JLB : Created. * - * 12/11/1994 JLB : Don't catch fire if already on fire or crumbling. * - *=============================================================================================*/ -bool TerrainClass::Catch_Fire(void) -{ - Validate(); - if (!IsCrumbling && !IsOnFire && Class->IsFlammable) { - AnimClass * anim = new AnimClass(ANIM_BURN_BIG, Coord_Add(Sort_Y(), 0xFFB00000L)); - if (anim) { - anim->Attach_To(this); - } - anim = new AnimClass(ANIM_BURN_MED, Coord_Add(Sort_Y(), 0xFF200000L), 15); - if (anim) { - anim->Attach_To(this); - } - IsOnFire = true; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TerrainClass::Fire_Out -- Handles when fire has gone out. * - * * - * When the fire has gone out on a burning terrain object, this routine is called. The * - * animation has already been terminated prior to calling this routine. All this routine * - * needs to perform is any necessary local flag updating. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::Fire_Out(void) -{ - Validate(); - if (IsOnFire) { - IsOnFire = false; - if (!IsCrumbling && !Strength) { - Detach_All(); - Mark(); - Start_To_Crumble(); - new AnimClass(ANIM_SMOKE_M, Coord_Add(Coord, Class->CenterBase)); - } - } -} - - -/*********************************************************************************************** - * TerrainClass::AI -- Process the terrain object AI. * - * * - * This is used to handle any AI processing necessary for terrain objects. This might * - * include animation effects. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1994 JLB : Created. * - * 09/28/1994 JLB : Crumbling animation. * - *=============================================================================================*/ -void TerrainClass::AI(void) -{ - Validate(); - ObjectClass::AI(); - - if (StageClass::Graphic_Logic()) { - Mark(); - - /* - ** If the terrain object is in the process of crumbling, then when at the - ** last stage of the crumbling animation, delete the terrain object. - */ - if (IsCrumbling && Fetch_Stage() == Get_Build_Frame_Count(Class->Get_Image_Data())-1) { - delete this; - } - } - - /* - ** if this is a blossom tree, let's update it at this time - */ - if (Class->IsTransformable) { - // If it's already blossomed, is it at barnacled stage? - if (IsBlossoming) { - // if it's not barnacled yet, check if we're at that stage - if (!IsBarnacled) { - if (Fetch_Stage() == BARNACLE_STAGE) { - IsBarnacled = true; - Set_Rate(0); // turn off animation - } - } else { - /* - ** If it's barnacled, see if it's pulsing and spore-ing - */ - if (IsSporing) { - if (Fetch_Stage() >= Get_Build_Frame_Count(Class->Get_Image_Data())-1) { - Explosion_Damage(Sort_Y(), 5, NULL, WARHEAD_SPORE); - Set_Stage(FIRST_SPORE_STAGE); - if (Random() & 1) { - IsSporing = false; - StageClass::Set_Rate(0); - } - } - } else { - if (Random() == 255) { // is it time to start sporing? - IsSporing = true; - StageClass::Set_Rate(Options.Normalize_Delay(1)); - } - } - } - } else { - - // If it hasn't tried to blossom yet, can it do so now? - if (Random_Picky((int)1, (int)5000, (char*)NULL, (int)0) == 1) { - IsBlossoming = true; - StageClass::Set_Stage(1); - StageClass::Set_Rate(Options.Normalize_Delay(1)); - } - } - } -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * TerrainClass::Debug_Dump -- Displays the status of the terrain object. * - * * - * This debugging support routine is used to display the status of the terrain object to * - * the debug screen. * - * * - * INPUT: mono -- The mono screen to display the status to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/27/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::Debug_Dump(MonoClass *mono) const -{ - Validate(); - ObjectClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * TerrainClass::Unlimbo -- Unlimbo terrain object onto the map. * - * * - * This routine is used to unlimbo the terrain object onto a location on the map. Normal * - * unlimbo procedures are sufficient except that the coordinate location of a terrain * - * object is based on the upper left corner of a cell rather than the center. Mask the * - * coordinate value so that it snaps to the upper left corner and then proceed with a * - * normal unlimbo process. * - * * - * INPUT: coord -- The coordinate to mark as the terrain's location. * - * * - * dir -- unused * - * * - * OUTPUT: bool; Was the terrain object successful in the unlimbo process? Failure could be * - * the result of illegal positioning. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 11/02/1994 JLB : Created. * - * 11/16/1994 JLB : Checks for theater legality. * - *=============================================================================================*/ -bool TerrainClass::Unlimbo(COORDINATE coord, DirType dir) -{ - Validate(); - if (Class->Theater & (1 << Map.Theater)) { - return(ObjectClass::Unlimbo(coord, dir)); - } - return(false); -} - - -/*********************************************************************************************** - * TerrainClass::Start_To_Crumble -- Initiates crumbling of terrain (tree) object. * - * * - * This routine is used to start the crumbling process for terrain object. This only * - * applies to trees. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::Start_To_Crumble(void) -{ - Validate(); - if (!IsCrumbling) { - IsCrumbling = true; - Set_Rate(2); - Set_Stage(0); - } -} - - -/*********************************************************************************************** - * TerrainClass::Limbo -- Handles terrain specific limbo action. * - * * - * This routine (called as a part of the limbo process) will remove the terrain occupation * - * flag in the cell it occupies. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the terrain object unlimboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -bool TerrainClass::Limbo(void) -{ - Validate(); - if (!IsInLimbo) { - CELL cell = Coord_Cell(Coord); - Map[cell].Flag.Occupy.Monolith = false; - } - return(ObjectClass::Limbo()); -} - - -/*********************************************************************************************** - * TerrainClass::Center_Coord -- Fetches the center point coordinate for terrain object. * - * * - * Use this routine to fetch the center point terrain * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -COORDINATE TerrainClass::Center_Coord(void) const -{ - Validate(); - return(Coord_Add(Coord, Class->CenterBase)); -} - - -/*********************************************************************************************** - * TerrainClass::TerrainClass -- Constructor for a terrain class object. * - * * - * This is the default constructor for a terrain class object. It basically initializes * - * the object to a null -- do nothing -- state. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -TerrainClass::TerrainClass(void) : - Class(0) -{ - IsOnFire = false; - IsCrumbling = false; - IsBlossoming = false; - IsBarnacled = false; - IsSporing = false; - Strength = 0; -} - - -/*********************************************************************************************** - * TerrainClass::Radar_Icon -- Fetches pointer to radar icon to use. * - * * - * This routine will return with a pointer to the radar icon to use for the cell number * - * specified. * - * * - * INPUT: cell -- The cell number to use when determine what icon pointer to return. * - * * - * OUTPUT: Returns with a pointer to the 9 pixel values that make up the icon of this * - * terrain object located at the cell specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -unsigned char * TerrainClass::Radar_Icon(CELL cell) -{ - Validate(); - unsigned char *icon = (unsigned char *)Class->Get_Radar_Data(); // get a pointer to radar icons - int width = *icon++; // extract the width from data - int height = *icon++; // extract the width from data - - /* - ** Icon number that we need can be found by converting the cell and base - ** cell to and x and y offset from the upper left of the cell, and then - ** multiplying it by the width of the terrain in icons, which we - ** conveniantly stored out as the first byte of every icon we made. - */ - int basecell = Coord_Cell(Coord); // find the base cell of terrain - int ydiff = Cell_Y(cell) - Cell_Y(basecell); - int xdiff = Cell_X(cell) - Cell_X(basecell); - if (xdiff < width && ydiff < height) { - int iconnum = (ydiff * width) + xdiff; - return(icon + (iconnum * 9)); - } - return(NULL); -} - - -/*********************************************************************************************** - * TerrainClass::Read_INI -- Reads terrain objects from INI file. * - * * - * This routine reads a scenario control INI file and creates all * - * terrain objects specified therein. Objects so created are placed * - * upon the map. * - * * - * INI entry format: * - * cellnum = TypeName, Triggername * - * * - * INPUT: buffer -- Pointer to the loaded scenario INI file data. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::Read_INI(char *buffer) -{ - char *tbuffer; // Accumulation buffer of unit IDs. - int len; // Size of data in buffer. - char buf[128]; - TerrainClass * tptr; - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - while (*tbuffer != '\0') { - TerrainType terrain; // Terrain type. - CELL cell; - - cell = atoi(tbuffer); - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - terrain = TerrainTypeClass::From_Name(strtok(buf, ",")); - if (terrain != TERRAIN_NONE) { - tptr = new TerrainClass(terrain, cell); - tptr->Trigger = TriggerClass::As_Pointer(strtok(NULL,",")); - if (tptr->Trigger) - tptr->Trigger->AttachCount++; - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * TerrainClass::Write_INI -- Writes all terrain objects to the INI file. * - * * - * This routine is used to write all the terrain objects out to the INI file specified. * - * It is used by the scenario editor to write out the map data. * - * * - * INI entry format: * - * cellnum = TypeName, Triggername * - * * - * INPUT: buffer -- Pointer to the INI file staging area. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void TerrainClass::Write_INI(char *buffer) -{ - int index; - char uname[10]; - char buf[127]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing terrain data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Write the terrain data out. - */ - for (index = 0; index < Terrains.Count(); index++) { - TerrainClass * terrain; - - terrain = Terrains.Ptr(index); - if (!terrain->IsInLimbo && terrain->IsActive) { - - sprintf(uname, "%d", Coord_Cell(terrain->Coord)); - sprintf(buf, "%s,%s", - terrain->Class->IniName, - terrain->Trigger ? terrain->Trigger->Get_Name() : "None" ); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/TERRAIN.H b/code/TIBERIANDAWN/TERRAIN.H deleted file mode 100644 index efc55ec..0000000 --- a/code/TIBERIANDAWN/TERRAIN.H +++ /dev/null @@ -1,179 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\terrain.h_v 2.16 16 Oct 1995 16:47:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TERRAIN.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 29, 1994 * - * * - * Last Update : April 29, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TERRAIN_H -#define TERRAIN_H - -#include "object.h" -#include "type.h" - - -/**************************************************************************** -** Each type of terrain has certain pieces of static information associated -** with it. This class elaborates this data. -*/ -class TerrainClass : public ObjectClass, public StageClass -{ - public: - TerrainTypeClass const * const Class; - operator TerrainType(void) const {return Class->Type;}; - - /* - ** Constructor for terrain object class. - */ - static void * TerrainClass::operator new(size_t size); - static void TerrainClass::operator delete(void *ptr); - TerrainClass(void); - TerrainClass(TerrainType id, CELL cell); - virtual ~TerrainClass(void); - virtual RTTIType What_Am_I(void) const {return RTTI_TERRAIN;}; - - static void Init(void); - - /* - ** Terrain specific support functions. - */ - void Start_To_Crumble(void); - - /* - ** Query functions. - */ - virtual ObjectTypeClass const & Class_Of(void) const {return *Class;}; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Center_Coord(void) const; - virtual COORDINATE Render_Coord(void) const {return Coord;}; - virtual COORDINATE Sort_Y(void) const {return Coord_Add(Coord, Class->CenterBase);}; - virtual COORDINATE Target_Coord(void) const {return Sort_Y();}; - - /* - ** Object entry and exit from the game system. - */ - virtual bool Unlimbo(COORDINATE coord, DirType dir=DIR_N); - virtual bool Limbo(void); - virtual MoveType Can_Enter_Cell(CELL cell, FacingType facing = FACING_NONE) const; - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual void Draw_It(int x, int y, WindowNumberType window); - virtual bool Mark(MarkType mark=MARK_CHANGE); - unsigned char *Radar_Icon(CELL cell); - - /* - ** User I/O. - */ - virtual void Clicked_As_Target(HousesType, int) {}; - - /* - ** Combat related. - */ - virtual void Fire_Out(void); - virtual bool Catch_Fire(void); - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source); - virtual TARGET As_Target(void) const; - - /* - ** AI. - */ - virtual void AI(void); - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static char *INI_Name(void) {return "TERRAIN";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - private: - - /* - ** If this terrain object is on fire, then this flag will be true. - */ - unsigned IsOnFire:1; - - /* - ** Is this a terrain object that undergoes crumbling animation and it is - ** in fact crumbling at this time? - */ - unsigned IsCrumbling:1; - - /* - ** If this is a tree that becomes a blossom tree, is it currently doing so? - */ - unsigned IsBlossoming:1; - - /* - ** If this is a blossom tree, is it barnacled? - */ - unsigned IsBarnacled:1; - - /* - ** If this is a blossom tree that is barnacled, is it pulsing and spewing - ** out spores? - */ - unsigned IsSporing:1; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[8]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TEXTBLIT.H b/code/TIBERIANDAWN/TEXTBLIT.H deleted file mode 100644 index df3f26d..0000000 --- a/code/TIBERIANDAWN/TEXTBLIT.H +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - - -#define MAX_ENTRIES 128 - -class TextBlitClass { - - public: - - TextBlitClass(void); - ~TextBlitClass(void){}; - - void Add (int x, int y, int dx, int dy, int w, int h); - void Clear (void); - void Update (void); - - - private: - - typedef struct { - int SourceX; - int SourceY; - int DestX; - int DestY; - int Width; - int Height; - } BlitEntryType; - - BlitEntryType BlitListo [MAX_ENTRIES]; - int Count; - -}; - - -extern GraphicBufferClass *TextPrintBuffer; -extern TextBlitClass BlitList; - diff --git a/code/TIBERIANDAWN/TEXTBTN.CPP b/code/TIBERIANDAWN/TEXTBTN.CPP deleted file mode 100644 index 82eb66d..0000000 --- a/code/TIBERIANDAWN/TEXTBTN.CPP +++ /dev/null @@ -1,374 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\textbtn.cpv 2.18 16 Oct 1995 16:49:16 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEXTBTN.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 19, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TextButtonClass::Draw_Background -- Draws the background to the text button. * - * TextButtonClass::Draw_Me -- Draws the text buttons as indicated. * - * TextButtonClass::Draw_Text -- This draws the text for the text button. * - * TextButtonClass::Set_Text -- Assigns a new text string to this button. * - * TextButtonClass::Set_Text -- Sets the text for this text button. * - * TextButtonClass::TextButtonClass -- Normal constructor for a text button. * - * TextButtonClass::TextButtonClass -- Normal constructor for a text button. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "textbtn.h" - - -/*********************************************************************************************** - * TextButtonClass::TextButtonClass -- Normal constructor for a text button. * - * * - * This is the constructor for text buttons if the text is provided as a string pointer. * - * * - * INPUT: id -- The ID number to assign to this button. * - * text -- Pointer to the text string to display on top of the button. * - * x,y -- Pixel coordinate of button's upper left corner. * - * w,h -- Dimensions of the button. If these are not filled in (or with -1), then * - * the dimensions are adapted to fit the text assigned to the button. * - * style -- The print style for the text in the button. These are the TPF_ flags * - * used by Fancy_Text_Print(). * - * border-- If the button is to be surrounded by a black border, then this flag * - * should be set to true. * - * * - * OUTPUT: none * - * WARNINGS: Call Set_Text & Set_Style, & init X,Y,Width,Height,ID before using this button. * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -TextButtonClass::TextButtonClass(unsigned id, char const * text, TextPrintType style, int x, int y, int w, int h, int blackborder) : - ToggleClass(id, x, y, w, h), - String(text) -{ - PrintFlags = style; - IsBlackBorder = blackborder; - - if (w == -1 || h == -1) { - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, PrintFlags); - if (w == -1) { - Width = String_Pixel_Width(String)+8; -// if (SeenBuff.Get_Width() != 320) Width *= 2; - } - if (h == -1) { - Height = FontHeight + FontYSpacing + 2; -// if (SeenBuff.Get_Height() != 200) Height *= 2; - } - } -} - - -/*********************************************************************************************** - * TextButtonClass::TextButtonClass -- Default constructor for a text button. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: 01/15/1995 JLB : Created. * - *=============================================================================================*/ -TextButtonClass::TextButtonClass(void) : - ToggleClass(0, 0, 0, 0, 0) -{ - X = Y = 0; - Width = Height = 0; - IsBlackBorder = 0; - String = 0; - PrintFlags = TPF_8POINT; -} - - -/*********************************************************************************************** - * TextButtonClass::TextButtonClass -- Normal constructor for a text button. * - * * - * This is the constructor for text buttons if the text is provided as a string pointer. * - * * - * INPUT: id -- The ID number to assign to this button. * - * * - * text -- The text number to use for displaying on top of the button. * - * * - * x,y -- Pixel coordinate of button's upper left corner. * - * * - * w,h -- Dimensions of the button. If these are not filled in (or with -1), then * - * the dimensions are adapted to fit the text assigned to the button. * - * * - * * - * style -- The print style for the text in the button. These are the TPF_ flags * - * used by Fancy_Text_Print(). * - * * - * border-- If the button is to be surrounded by a black border, then this flag * - * should be set to true. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -TextButtonClass::TextButtonClass (unsigned id, int text, TextPrintType style, int x, int y, int w, int h, int blackborder) : - ToggleClass (id, x, y, w, h), - String(0) -{ - PrintFlags = style; - IsBlackBorder = blackborder; - Set_Text(text); - - if (w == -1 || h == -1) { - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, PrintFlags); - if (w == -1) { - Width = String_Pixel_Width(String)+8; -// if (SeenBuff.Get_Width() != 320) Width *= 2; - } - if (h == -1) { - Height = FontHeight + FontYSpacing + 2; -// if (SeenBuff.Get_Height() != 200) Height *= 2; - } - } -} - - -/*********************************************************************************************** - * TextButtonClass::Draw_Me -- Draws the text buttons as indicated. * - * * - * This routine will draw the text button. * - * * - * INPUT: forced -- If the button is to be redrawn regardless of the state of the redraw * - * flag, then this parameter will be true. * - * * - * OUTPUT: bool; Was the button redrawn? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/03/1995 MML : Created. * - * 01/16/1995 JLB : Modified * - *=============================================================================================*/ -int TextButtonClass::Draw_Me(int forced) -{ - if (ControlClass::Draw_Me(forced)) { - /* - ** Hide the mouse. - */ - if (LogicPage == &SeenBuff) { - //Conditional_Hide_Mouse(X, Y, X+Width-1, Y+Height-1); - Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); - } - - /* - ** Draw the background and overlaying text. These are virtual function - ** calls so that they may be overridden. - */ - Draw_Background(); - Draw_Text(String); - - /* - ** Display the mouse. - */ - if (LogicPage == &SeenBuff) { - Conditional_Show_Mouse(); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TextButtonClass::Set_Text -- Assigns a new text string to this button. * - * * - * Use this routine to assign a new text string to this button. By using this function it * - * is possible to dynmaically change the button's text. An example of this would be an * - * on/off button that every time it is clicked, the text toggles between "on" and "off". * - * * - * INPUT: text -- Pointer to the text string to assign to this button. * - * * - * OUTPUT: none * - * * - * WARNINGS: The text is NOT copied to this button. You must make sure that the text * - * remains valid throughout the lifetime of this text button. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void TextButtonClass::Set_Text(char const * text, bool resize) -{ - String = text; - Flag_To_Redraw(); - if (resize && String) { - Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, PrintFlags); - Width = String_Pixel_Width(String)+8; - Height = FontHeight + FontYSpacing + 2; - } -} - - -/*********************************************************************************************** - * TextButtonClass::Set_Text -- Sets the text for this text button. * - * * - * This will set the text for this button. The text is provided as a text number. This * - * number is automatically converted to the appropriate text string before being stored * - * in the button's structure. * - * * - * INPUT: text -- The text number to assign to this button. * - * * - * OUTPUT: none * - * * - * WARNINGS: The text number information is lost when it is assigned to the button. Once * - * the assignment takes place, the text number is NOT remembered by the button. * - * Only the associated text string is. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void TextButtonClass::Set_Text(int text, bool resize) -{ - if (text != TXT_NONE) { - Set_Text(Text_String(text), resize); - } -} - - -/*********************************************************************************************** - * TextButtonClass::Draw_Background -- Draws the background to the text button. * - * * - * This localizes the drawing of the background for the text button. By overriding this * - * function you can give a different background to the button. The text is drawn using * - * a different routine. The mouse is hidden, if necessary, before this routine is called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void TextButtonClass::Draw_Background(void) -{ - /* - ** Draw a border if selected style. - */ - if (IsBlackBorder) { - LogicPage->Draw_Rect (X-1, Y-1, X+Width+2, Y+Height+2, BLACK); - } - - /* - ** Draw the body & set text color. - */ - BoxStyleEnum style; - //if (FontPtr == GradFont6Ptr) { - if (PrintFlags & TPF_6PT_GRAD) { - if (IsDisabled) { - style = BOXSTYLE_GREEN_DIS_RAISED; - } else { - if (IsPressed) { - style = BOXSTYLE_GREEN_DOWN; - } else { - style = BOXSTYLE_GREEN_RAISED; - } - } - } else { - if (IsDisabled) { - style = BOXSTYLE_DIS_RAISED; - } else { - if (IsPressed) { - style = BOXSTYLE_DOWN; - } else { - style = BOXSTYLE_RAISED; - } - } - } - Draw_Box(X, Y, Width, Height, style, true); -} - - -/*********************************************************************************************** - * TextButtonClass::Draw_Text -- This draws the text for the text button. * - * * - * This routine draws the text for the text button. You can override this routine if you * - * wish different text rendering styles or colors. The background has already been drawn * - * by the time this function is called. The mouse is hidden, if necessary, as well. * - * * - * INPUT: text -- Pointer to the text string to print over the button. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -void TextButtonClass::Draw_Text(char const * text) -{ - /* - ** Display the text. - */ - if (String) { - int color; - //if (FontPtr == GradFont6Ptr) { - if (PrintFlags & TPF_6PT_GRAD) { - TextPrintType flags; - - color = CC_GREEN; - - if (IsDisabled) { - flags = (TextPrintType)0; - } else { - if (IsPressed || IsOn) { - flags = TPF_USE_GRAD_PAL|TPF_BRIGHT_COLOR; - } else { - flags = TPF_USE_GRAD_PAL|TPF_MEDIUM_COLOR; - } - } - - Fancy_Text_Print(text, X+(Width>>1)-1, Y+1, color, TBLACK, PrintFlags|flags|TPF_CENTER); - } else { - if (IsDisabled) { -// color = DKGREY; - color = LTGREY; - } else { - if (IsPressed) { - if (PrintFlags & TPF_NOSHADOW) { - color = DKGREY; - } else { - color = LTGREY; - } - } else { - color = WHITE; - } - } - - Fancy_Text_Print(text, X+(Width>>1)-1, Y+1, IsOn ? RED : color, TBLACK, PrintFlags|TPF_CENTER); - } - - } -} diff --git a/code/TIBERIANDAWN/TEXTBTN.H b/code/TIBERIANDAWN/TEXTBTN.H deleted file mode 100644 index d8b3ae3..0000000 --- a/code/TIBERIANDAWN/TEXTBTN.H +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\textbtn.h_v 2.18 16 Oct 1995 16:46:54 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TEXTBTN.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TEXTBTN_H -#define TEXTBTN_H - -#include "toggle.h" - - -class TextButtonClass : public ToggleClass -{ - public: - TextButtonClass(void); - TextButtonClass(unsigned id, char const * text, TextPrintType style, int x, int y, int w=-1, int h=-1, int blackborder=false); - TextButtonClass(unsigned id, int text, TextPrintType style, int x, int y, int w=-1, int h=-1, int blackborder=false); - virtual int Draw_Me(int forced=false); - virtual void Set_Text(char const *text, bool resize = false); - virtual void Set_Text(int text, bool resize = false); - virtual void Set_Style (TextPrintType style) {PrintFlags = style;} - - protected: - - virtual void Draw_Background(void); - virtual void Draw_Text(char const * text); - - unsigned IsBlackBorder:1; - - /* - ** This points to a constant string that is used for the button's text. - */ - char const * String; - - /* - ** This is the print flags to use when rendering this button's text. - */ - TextPrintType PrintFlags; -}; - -#endif - diff --git a/code/TIBERIANDAWN/THEME.CPP b/code/TIBERIANDAWN/THEME.CPP deleted file mode 100644 index bbdd6a7..0000000 --- a/code/TIBERIANDAWN/THEME.CPP +++ /dev/null @@ -1,560 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\theme.cpv 2.18 16 Oct 1995 16:51:10 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : THEME.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 14, 1994 * - * * - * Last Update : May 29, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ThemeClass::Scan -- Scans all scores for availability. * - * ThemeClass::AI -- Process the theme engine and restart songs. * - * ThemeClass::Base_Name -- Fetches the base filename for the theme specified. * - * ThemeClass::From_Name -- Determines theme number from specified name. * - * ThemeClass::Full_Name -- Retrieves the full score name. * - * ThemeClass::Is_Allowed -- Checks to see if the specified theme is legal. * - * ThemeClass::Next_Song -- Calculates the next song number to play. * - * ThemeClass::Play_Song -- Starts the specified song play NOW. * - * ThemeClass::Queue_Song -- Queues the song to the play queue. * - * ThemeClass::Still_Playing -- Determines if music is still playing. * - * ThemeClass::Stop -- Stops the current theme from playing. * - * ThemeClass::ThemeClass -- Default constructor for the theme manager class. * - * ThemeClass::Theme_File_Name -- Constructs a filename for the specified theme. * - * ThemeClass::Track_Length -- Caclulates the length of the song (in seconds). * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -#include "theme.h" - - -/* -** These are the actual filename list for the theme sample files. -*/ -ThemeClass::ThemeControl ThemeClass::_themes[THEME_COUNT] = { - {"AIRSTRIK", TXT_THEME_AIRSTRIKE, 0, 200, false, false,false,true}, - {"80MX226M", TXT_THEME_80MX, 0, 248, false, false,false,true}, - {"CHRG226M", TXT_THEME_CHRG, 0, 256, true, false,false,true}, - {"CREP226M", TXT_THEME_CREP, 0, 222, true, false,false,true}, - {"DRIL226M", TXT_THEME_DRIL, 0, 272, true, false,false,true}, - {"DRON226M", TXT_THEME_DRON, 0, 275, true, false,false,true}, - {"FIST226M", TXT_THEME_FIST, 0, 212, true, false,false,true}, - {"RECN226M", TXT_THEME_RECON, 0, 261, true, false,false,true}, - {"VOIC226M", TXT_THEME_VOICE, 0, 306, true, false,false,true}, - {"HEAVYG", TXT_THEME_HEAVYG, 0, 180, true, false,false,true}, - {"J1", TXT_THEME_J1, 4, 187, true, false,false,true}, -// {"J1", TXT_THEME_J1, 4, 187, false, false,false,true}, - {"JDI_V2", TXT_THEME_JDI_V2, 5, 183, true, false,false,true}, - {"RADIO", TXT_THEME_RADIO, 6, 183, true, false,false,true}, - {"RAIN", TXT_THEME_RAIN, 7, 156, true, false,false,true}, - {"AOI", TXT_THEME_AOI, 0, 168, true, true, false,true}, - {"CCTHANG", TXT_THEME_CCTHANG, 12, 193, true, false,false,true}, - {"DIE", TXT_THEME_DIE, 11, 162, false, false,false,true}, - {"FWP", TXT_THEME_FWP, 10, 53, true, false,false,true}, - {"IND", TXT_THEME_IND, 1, 175, true, false,false,true}, - {"IND2", TXT_THEME_IND2, 1, 38, true, false,false,true}, - {"JUSTDOIT", TXT_THEME_JUSTDOIT, 9, 142, true, false,false,true}, - {"LINEFIRE", TXT_THEME_LINEFIRE, 8, 125, true, false,false,true}, - {"MARCH", TXT_THEME_MARCH, 7, 157, true, false,false,true}, - {"TARGET", TXT_THEME_TARGET, 0, 173, true, false,false,true}, - {"NOMERCY", TXT_THEME_NOMERCY, 2, 204, true, false,false,true}, - {"OTP", TXT_THEME_OTP, 3, 182, true, false,false,true}, - {"PRP", TXT_THEME_PRP, 4, 211, true, false,false,true}, - {"ROUT", TXT_THEME_ROUT, 12, 121, false, true, false,true}, - {"HEART", TXT_THEME_HEART, 5, 206, false, true, false,true}, - {"STOPTHEM", TXT_THEME_STOPTHEM, 0, 190, true, false,false,true}, - {"TROUBLE", TXT_THEME_TROUBLE, 6, 191, true, true, false,true}, - {"WARFARE", TXT_THEME_WARFARE, 0, 182, true, false,false,true}, - {"BEFEARED", TXT_THEME_BEFEARED, 13, 164, false, true, false,true}, - {"I_AM", TXT_THEME_IAM, 6, 161, false, false,false,true}, - {"WIN1", TXT_THEME_WIN1, 0, 41, false, true, true,true}, - {"MAP1", TXT_THEME_WIN1, 0, 61, false, false,true,true}, - {"VALKYRIE", TXT_THEME_VALK, 0, 306, false, false,true,true}, -}; - - -/*********************************************************************************************** - * ThemeClass::Base_Name -- Fetches the base filename for the theme specified. * - * * - * This routine is used to retrieve a pointer to the base filename for the theme * - * specified. * - * * - * INPUT: theme -- The theme number to convert into a base filename. * - * * - * OUTPUT: Returns with a pointer to the base filename for the theme specified. If the * - * theme number is invalid, then a pointer to "No Theme" is returned instead. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/29/1995 JLB : Created. * - *=============================================================================================*/ -char const * ThemeClass::Base_Name(ThemeType theme) const -{ - if (theme != THEME_NONE) { - return(_themes[theme].Name); - } - return("No theme"); -} - - -/*********************************************************************************************** - * ThemeClass::ThemeClass -- Default constructor for the theme manager class. * - * * - * This is the default constructor for the theme class object. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -ThemeClass::ThemeClass(void) -{ - Current = -1; - Score = THEME_NONE; - Pending = THEME_NONE; -} - - -/*********************************************************************************************** - * ThemeClass::Full_Name -- Retrieves the full score name. * - * * - * This routine will fetch and return with a pointer to the full name of the theme * - * specified. * - * * - * INPUT: theme -- The theme to fetch the full name for. * - * * - * OUTPUT: Returns with a pointer to the full name for this score. This pointer may point to * - * EMS memory. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -char const * ThemeClass::Full_Name(ThemeType theme) const -{ - if (theme != THEME_NONE) { - return(Text_String(_themes[theme].Fullname)); - } - return(NULL); -} - - -/*********************************************************************************************** - * ThemeClass::AI -- Process the theme engine and restart songs. * - * * - * This is a maintenance function that will restart an appropriate theme if the current one * - * has finished. This routine should be called frequently. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - * 01/23/1995 JLB : Picks new song just as it is about to play it. * - *=============================================================================================*/ -void ThemeClass::AI(void) -{ - if (SampleType && !Debug_Quiet) { - if (ScoresPresent && Options.ScoreVolume && !Still_Playing() && Pending != THEME_NONE) { - - /* - ** If the pending song needs to be picked, then pick it now. - */ - if (Pending == THEME_PICK_ANOTHER) { - Pending = Next_Song(Score); - } - - /* - ** Start the song playing and then flag it so that a new song will - ** be picked when this one ends. - */ - Play_Song(Pending); - Pending = THEME_PICK_ANOTHER; - } - Sound_Callback(); - } -} - - -/*********************************************************************************************** - * ThemeClass::Next_Song -- Calculates the next song number to play. * - * * - * use this routine to figure out what song number to play. It examines the option settings * - * for repeat and shuffle so that it can return the correct value. * - * * - * INPUT: theme -- The origin (last) index. The new value is related to this for all but * - * the shuffling method of play. * - * * - * OUTPUT: Returns with the song number for the next song to play. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - * 01/19/1995 JLB : Will not play the same song twice when in shuffle mode. * - *=============================================================================================*/ -ThemeType ThemeClass::Next_Song(ThemeType theme) -{ - if (theme == THEME_NONE) { - theme = Next_Song(THEME_PICK_ANOTHER); - } else { - if (theme == THEME_PICK_ANOTHER || (!_themes[theme].Repeat && !Options.IsScoreRepeat)) { - if (Options.IsScoreShuffle) { - - /* - ** Shuffle the theme, but never pick the same theme that was just - ** playing. - */ - ThemeType newtheme; - do { - newtheme = Sim_Random_Pick(THEME_FIRST, THEME_LAST); - } while(newtheme == theme || !Is_Allowed(newtheme)); - theme = newtheme; - - } else { - - /* - ** Sequential score playing. - */ - do { - theme++; - if (theme > THEME_LAST) { - theme = THEME_FIRST; - } - } while(!Is_Allowed(theme)); - } - } - } - return(theme); -} - - -/*********************************************************************************************** - * ThemeClass::Queue_Song -- Queues the song to the play queue. * - * * - * This routine will cause the current song to fade and the specified song to start. This * - * is the normal and friendly method of changing the current song. * - * * - * INPUT: theme -- The song to start playing. If -1 is pssed in, then just the current song * - * is faded. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -void ThemeClass::Queue_Song(ThemeType theme) -{ - if (ScoresPresent && SampleType && !Debug_Quiet && (Pending == THEME_NONE || Pending == THEME_PICK_ANOTHER)) { - if (!Options.ScoreVolume && theme != THEME_NONE) return; - - Pending = theme; - Fade_Sample(Current, THEME_DELAY); - } -} - - -/*********************************************************************************************** - * ThemeClass::Play_Song -- Starts the specified song play NOW. * - * * - * This routine is used to start the specified theme playing right now. If there is already * - * a theme playing, it is cut short so that this one may start. * - * * - * INPUT: theme -- The theme number to start playing. * - * * - * OUTPUT: Returns with the sample play handle. * - * * - * WARNINGS: This cuts off any current song in a abrubt manner. Only use this routine when * - * necessary. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ThemeClass::Play_Song(ThemeType theme) -{ - if (ScoresPresent && SampleType && !Debug_Quiet && Options.ScoreVolume) { - Stop(); - Score = theme; - if (theme >= THEME_FIRST) { - -#ifdef DEMO - if (_themes[theme].Scenario != 99) { - CCFileClass file(Theme_File_Name(theme)); - if (file.Is_Available()) { - Current = File_Stream_Sample_Vol(Theme_File_Name(theme), 0xFF, true); - } else { - Current = -1; - } - } else { - Current = -1; - } -#else - Current = File_Stream_Sample_Vol(Theme_File_Name(theme), 0xFF, true); -#endif - } - } - return(Current); -} - - -/*********************************************************************************************** - * ThemeClass::Theme_File_Name -- Constructs a filename for the specified theme. * - * * - * This routine will construct (into a static buffer) a filename that matches the theme * - * number specified. This constructed filename is returned as a pointer. The filename will * - * remain valid until the next call to this routine. * - * * - * INPUT: theme -- The theme number to convert to a filename. * - * * - * OUTPUT: Returns with a pointer to the constructed filename for the specified theme number. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - * 05/09/1995 JLB : Theme variation support. * - *=============================================================================================*/ -char const * ThemeClass::Theme_File_Name(ThemeType theme) -{ - static char name[_MAX_FNAME+_MAX_EXT]; - - if (_themes[theme].Variation && Special.IsVariation) { - _makepath(name, NULL, NULL, _themes[theme].Name, ".VAR"); - CCFileClass file(name); - if (file.Is_Available()) { - return((char const *)(&name[0])); - } - } - _makepath(name, NULL, NULL, _themes[theme].Name, ".AUD"); - return((char const *)(&name[0])); -} - - -/*********************************************************************************************** - * ThemeClass::Track_Length -- Caclulates the length of the song (in seconds). * - * * - * Use this routine to calculate the length of the song. The length is determined by * - * reading the header of the song and dividing the sample rate into the sample length. * - * * - * INPUT: theme -- The song number to examine to find its length. * - * * - * OUTPUT: Returns with the length of the specified theme. This length is in the form of * - * seconds. * - * * - * WARNINGS: This routine goes to disk to fetch this information. Don't call frivolously. * - * * - * HISTORY: * - * 01/16/1995 JLB : Created. * - *=============================================================================================*/ -int ThemeClass::Track_Length(ThemeType theme) -{ - if ((unsigned)theme < THEME_COUNT) { - return(_themes[theme].Duration); - } - return(0); -} - - -/*********************************************************************************************** - * ThemeClass::Stop -- Stops the current theme from playing. * - * * - * Use this routine to stop the current theme. After this routine is called, no more music * - * will play until the Start() function is called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/08/1994 JLB : Created. * - *=============================================================================================*/ -void ThemeClass::Stop(void) -{ - if (ScoresPresent && SampleType && !Debug_Quiet) { - if (Current != -1) { - Stop_Sample(Current); - Current = -1; - Score = THEME_NONE; - Pending = THEME_NONE; - } - } -} - - -/*********************************************************************************************** - * ThemeClass::Still_Playing -- Determines if music is still playing. * - * * - * Use this routine to determine if music is still playing. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the music still audible? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/20/1994 JLB : Created. * - *=============================================================================================*/ -int ThemeClass::Still_Playing(void) -{ - if (ScoresPresent && SampleType && Current != -1 && !Debug_Quiet) { - return(Sample_Status(Current)); - } - return(false); -} - - -/*********************************************************************************************** - * ThemeClass::Is_Allowed -- Checks to see if the specified theme is legal. * - * * - * Use this routine to determine if a theme is allowed to be played. A theme is not allowed * - * if the scenario is too early for that score, or the score only is allowed in special * - * cases. * - * * - * INPUT: index -- The score the check to see if it is allowed to play. * - * * - * OUTPUT: Is the specified score allowed to play in the normal score playlist? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/09/1995 JLB : Created. * - *=============================================================================================*/ -bool ThemeClass::Is_Allowed(ThemeType index) const -{ -#ifdef DEMO - char buffer[128]; - - sprintf(buffer, "%s.AUD", Base_Name(index)); - CCFileClass file(buffer); - if (_themes[index].Scenario == 99 || !file.Is_Available()) { - _themes[index].Scenario = 99; - return(false); - } -#endif - - return( - _themes[index].Available && - (_themes[index].Normal || -// (index == THEME_MAP1 && ScenarioInit) || - ((Special.IsVariation && _themes[index].Variation && index != THEME_WIN1) && -#ifndef DEMO - (GameToPlay != GAME_NORMAL || _themes[index].Scenario <= (int)Scenario) && -#endif - (index != THEME_J1 || Special.IsJurassic)))); -} - - -/*********************************************************************************************** - * ThemeClass::From_Name -- Determines theme number from specified name. * - * * - * Use this routine to convert a name (either the base filename of the theme, or a partial * - * substring of the full name) into the matching ThemeType value. Typical use of this is * - * when parsing the INI file for theme control values. * - * * - * INPUT: name -- Pointer to base filename of theme or a partial substring of the full * - * theme name. * - * * - * OUTPUT: Returns with the matching theme number. If no match could be found, then * - * THEME_NONE is returned. * - * * - * WARNINGS: If a filename is specified the comparison is case insensitive. When scanning * - * the full theme name, the comparison is case sensitive. * - * * - * HISTORY: * - * 05/29/1995 JLB : Created. * - *=============================================================================================*/ -ThemeType ThemeClass::From_Name(char const * name) -{ - if (name && strlen(name) > 0) { - /* - ** First search for an exact name match with the filename - ** of the theme. This is guaranteed to be unique. - */ - ThemeType theme; - for (theme = THEME_FIRST; theme < THEME_COUNT; theme++) { - if (stricmp(_themes[theme].Name, name) == 0) { - return(theme); - } - } - - /* - ** If the filename scan failed to find a match, then scan for - ** a substring within the full name of the score. This might - ** yeild a match, but is not guaranteed to be unique. - */ - for (theme = THEME_FIRST; theme < THEME_COUNT; theme++) { - if (strstr(Text_String(_themes[theme].Fullname), name) != NULL) { - return(theme); - } - } - } - - return(THEME_NONE); -} - - -/*********************************************************************************************** - * ThemeClass::Scan -- Scans all scores for availability. * - * * - * This routine should be called whenever a score mixfile is registered. It will scan * - * to see if any score is unavailable. If this is the case, then the score will be so * - * flagged in order not to appear on the play list. This condition is likely to occur * - * when expansion mission disks contain a different score mix than the release version. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/04/1996 JLB : Created. * - *=============================================================================================*/ -void ThemeClass::Scan(void) -{ - for (ThemeType theme = THEME_FIRST; theme < THEME_COUNT; theme++) { -// if (theme == THEME_J1 && !Special.IsJurassic) { -// _themes[theme].Available = false; -// } else { - _themes[theme].Available = CCFileClass(Theme_File_Name(theme)).Is_Available(); -// } - } -} - diff --git a/code/TIBERIANDAWN/THEME.H b/code/TIBERIANDAWN/THEME.H deleted file mode 100644 index 7583e95..0000000 --- a/code/TIBERIANDAWN/THEME.H +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\theme.h_v 2.16 16 Oct 1995 16:45:48 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : THEME.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 14, 1994 * - * * - * Last Update : August 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef THEME_H -#define THEME_H - -class ThemeClass -{ - private: - static char const * Theme_File_Name(ThemeType theme); - - int Current; // Handle to current score. - ThemeType Score; // Score number currently being played. - ThemeType Pending; // Score to play next. - - typedef struct { - char const * Name; // Filename of score. - int Fullname; // Text number for full score name. - int Scenario; // Scenario when it first becomes available. - int Duration; // Duration of theme in seconds. - bool Normal; // Allowed in normal game play? - bool Variation; // Is there a variation to the score? - bool Repeat; // Always repeat this score? - bool Available; // Is the score available? - } ThemeControl; - - static ThemeControl _themes[THEME_COUNT]; - - enum { - THEME_DELAY=TIMER_SECOND - }; - - public: - ThemeClass(void); - - ThemeType From_Name(char const * name); - int Track_Length(ThemeType index); - int Max_Themes(void) {return THEME_COUNT;}; - char const * Full_Name(ThemeType index) const; - char const * Base_Name(ThemeType index) const; - void AI(void); - void Queue_Song(ThemeType index); - int Play_Song(ThemeType index); - ThemeType What_Is_Playing(void) {return Score;}; - void Stop(void); - void Fade_Out(void) {Queue_Song(THEME_NONE);}; - int Still_Playing(void); - ThemeType Next_Song(ThemeType index); - bool Is_Allowed(ThemeType index) const; - static void /*_pascal*/ Scan(void); -}; - -#endif diff --git a/code/TIBERIANDAWN/TOGGLE.CPP b/code/TIBERIANDAWN/TOGGLE.CPP deleted file mode 100644 index 47c3992..0000000 --- a/code/TIBERIANDAWN/TOGGLE.CPP +++ /dev/null @@ -1,196 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\toggle.cpv 2.18 16 Oct 1995 16:50:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TOGGLE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : February 2, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * ToggleClass::ToggleClass -- Normal constructor for toggle button gadgets. * - * ToggleClass::Turn_Off -- Turns the toggle button to the "OFF" state. * - * ToggleClass::Turn_On -- Turns the toggle button to the "ON" state. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "toggle.h" - - -/*********************************************************************************************** - * ToggleClass::ToggleClass -- Normal constructor for toggle button gadgets. * - * * - * This is the normal constructor for toggle buttons. A toggle button is one that most * - * closesly resembles the Windows style. It has an up and down state as well as an on * - * and off state. * - * * - * INPUT: id -- ID number for this button. * - * * - * x,y -- Pixel coordinate of upper left corner of this button. * - * * - * w,h -- Width and height of the button. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -ToggleClass::ToggleClass(unsigned id, int x, int y, int w, int h) - : ControlClass(id, x, y, w, h, LEFTPRESS|LEFTRELEASE, true) -{ - IsPressed = false; - IsOn = false; - IsToggleType = false; -} - - -/*********************************************************************************************** - * ToggleClass::Turn_On -- Turns the toggle button to the "ON" state. * - * * - * This routine will turn the button on. The button will also be flagged to be redrawn * - * at the next opportunity. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void ToggleClass::Turn_On(void) -{ - IsOn = true; - Flag_To_Redraw(); -} - - -/*********************************************************************************************** - * ToggleClass::Turn_Off -- Turns the toggle button to the "OFF" state. * - * * - * This routine will turn the toggle button "off". It will also be flagged to be redrawn * - * at the next opportunity. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/15/1995 JLB : Created. * - *=============================================================================================*/ -void ToggleClass::Turn_Off(void) -{ - IsOn = false; - Flag_To_Redraw(); -} - - -/*********************************************************************************************** - * ToggleClass::Action -- Handles mouse clicks on a text button. * - * * - * This routine will process any mouse or keyboard event that is associated with this * - * button object. It detects and flags the text button so that it will properly be drawn * - * in a pressed or raised state. It also handles any toggle state for the button. * - * * - * INPUT: flags -- The event flags that triggered this button. * - * * - * key -- The keyboard code associated with this event. Usually this is KN_LMOUSE * - * or similar, but it could be a regular key if this text button is given * - * a hotkey. * - * * - * OUTPUT: Returns whatever the lower level processing for buttons decides. This is usually * - * true. * - * * - * WARNINGS: The button is flagged to be redrawn by this routine. * - * * - * HISTORY: * - * 01/14/1995 JLB : Created. * - * 02/02/1995 JLB : Left press doesn't get passed to other buttons now * - *=============================================================================================*/ -int ToggleClass::Action(unsigned flags, KeyNumType &key) -{ - /* - ** If there are no action flag bits set, then this must be a forced call. A forced call - ** must never actually function like a real call, but rather only performs any necessary - ** graphic updating. - */ - if (!flags) { - if ((unsigned)(Get_Mouse_X() - X) < (unsigned)Width && (unsigned)(Get_Mouse_Y() - Y) < (unsigned)Height ) { - if (!IsPressed) { - IsPressed = true; - Flag_To_Redraw(); - } - } else { - if (IsPressed) { - IsPressed = false; - Flag_To_Redraw(); - } - } - } - - /* - ** Handle the sticky state for this gadget. It must be processed here - ** because the event flags might be cleared before the action function - ** is called. - */ - Sticky_Process(flags); - - /* - ** Flag the button to show the pressed down imagery if this mouse button - ** was pressed over this gadget. - */ - if (flags & LEFTPRESS) { - IsPressed = true; - Flag_To_Redraw(); - flags &= ~LEFTPRESS; - ControlClass::Action(flags, key); - key = KN_NONE; // erase the event - return(true); // stop processing other buttons now - } - - if (flags & LEFTRELEASE) { - if (IsPressed) { - if (IsToggleType) { - IsOn = (IsOn == false); - } - IsPressed = false; - } else { - flags &= ~LEFTRELEASE; - } - } - - /* - ** Do normal button processing. This ends up causing the button's ID number to - ** be returned from the controlling Input() function. - */ - return(ControlClass::Action(flags, key)); -} - - diff --git a/code/TIBERIANDAWN/TOGGLE.H b/code/TIBERIANDAWN/TOGGLE.H deleted file mode 100644 index b45460c..0000000 --- a/code/TIBERIANDAWN/TOGGLE.H +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\toggle.h_v 2.16 16 Oct 1995 16:47:34 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TOGGLE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 01/15/95 * - * * - * Last Update : January 15, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TOGGLE_H -#define TOGGLE_H - -#include "control.h" - -/* -** This class handles gadgets that behave like the Windows buttons. That is, once the mouse -** button is clicked over them, they capture the focus until the mouse button is released. -** They have a different imagery for the pressed and released states. They only recognize -** a valid selection when the mouse button is release while over the button. -*/ -class ToggleClass : public ControlClass -{ - public: - ToggleClass(unsigned id, int x, int y, int w, int h); - virtual void Turn_On(void); - virtual void Turn_Off(void); - - /* - ** Is this button in a pressed down state? This occurs when the mouse is clicked on the - ** button and the mouse is still being held down. - */ - unsigned IsPressed:1; - - /* - ** This is the button on/off state. Sometimes a button that is "on" has a different - ** imagery than one that is "off". If the on/off state is not necessary, then just - ** ignore this flag. - */ - unsigned IsOn:1; - - /* - ** If this button can be turned "on" or "off", then this flag should be set to - ** true. Sometimes a button needs to display its on/off state. In the render routine, - ** examine the IsOn flag and display accordingly. If this flag is false, then the - ** IsOn flag will not be changed, regardless of button clicking. - */ - unsigned IsToggleType:1; - - protected: - - virtual int Action(unsigned flags, KeyNumType &key); -}; - -#endif diff --git a/code/TIBERIANDAWN/TRIGGER.CPP b/code/TIBERIANDAWN/TRIGGER.CPP deleted file mode 100644 index 4255ce7..0000000 --- a/code/TIBERIANDAWN/TRIGGER.CPP +++ /dev/null @@ -1,1483 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\trigger.cpv 2.17 16 Oct 1995 16:51:20 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TRIGGER.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 11/12/94 * - * * - * Last Update : August 27, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Do_All_To_Hunt -- Forces all computer controlled units into hunt mode. * - * TriggerClass::Action_From_Name -- retrieves ActionType for given name * - * TriggerClass::Action_Need_Team -- Determines if this action event requires a team. * - * TriggerClass::As_Pointer -- returns pointer for the given trigger name * - * TriggerClass::As_Target -- Converts trigger to a target value * - * TriggerClass::Event_From_Name -- retrieves EventType for given name * - * TriggerClass::Event_Need_Data -- Determines if this event requires a data value. * - * TriggerClass::Event_Need_House -- Determines if this event requires a house identifier. * - * TriggerClass::Event_Need_Object -- Determines if the specified event requires an object. * - * TriggerClass::Init -- clears triggers for new scenario * - * TriggerClass::Name_From_Action -- retrieves name for ActionType * - * TriggerClass::Name_From_Event -- retrieves name for EventType * - * TriggerClass::Read_INI -- reads triggers from the INI file * - * TriggerClass::Remove -- removes this trigger from the game * - * TriggerClass::Spring -- Trigger processing routine for cell-based triggers * - * TriggerClass::Spring -- Trigger processing routine for house-based triggers * - * TriggerClass::Spring -- Trigger processing routine for object-based triggers * - * TriggerClass::TriggerClass -- constructor * - * TriggerClass::Validate -- validates trigger pointer * - * TriggerClass::Write_INI -- writes triggers to the INI file * - * TriggerClass::operator delete -- 'delete' operator * - * TriggerClass::operator new -- 'new' operator * - * TriggerClass::~TriggerClass -- Destructor for trigger objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -static void Do_All_To_Hunt(void); - -#define FIXUP 0 - -/* -********************************** Globals ********************************** -*/ -static const char * EventText[EVENT_COUNT + 1] = { - "None", - "Player Enters", - "Discovered", - "Attacked", - "Destroyed", - "Any", - "House Discov.", - "Units Destr.", - "Bldgs Destr.", - "All Destr.", - "Credits", - "Time", - "# Bldgs Dstr.", - "# Units Dstr.", - "No Factories", - "Civ. Evac.", - "Built It" -}; - - -static const char * ActionText[TriggerClass::ACTION_COUNT + 1] = { - "None", - "Win", - "Lose", - "Production", - "Create Team", - "Dstry Teams", - "All to Hunt", - "Reinforce.", - "DZ at 'Z'", - "Airstrike", - "Nuclear Missile", - "Ion Cannon", - "Dstry Trig 'XXXX'", - "Dstry Trig 'YYYY'", - "Dstry Trig 'ZZZZ'", - "Autocreate", - "Cap=Win/Des=Lose", - "Allow Win" -}; - - -/*********************************************************************************************** - * TriggerClass::Validate -- validates trigger pointer * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int TriggerClass::Validate(void) const -{ - int num; - - num = Triggers.ID(this); - if (num < 0 || num >= TRIGGER_MAX) { - Validate_Error("TRIGGER"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * TriggerClass::Event_Need_Object -- Determines if the specified event requires an object. * - * * - * This routine determines if the specified event must be attached to an object. Such * - * events can only exist in a parasitic fashion attached to object(s) in the game. * - * * - * INPUT: event -- The event type to examine. * - * * - * OUTPUT: Does the specified event require attachement to an object? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -bool TriggerClass::Event_Need_Object(EventType event) -{ - switch (event) { - case EVENT_PLAYER_ENTERED: - case EVENT_DISCOVERED: - case EVENT_ATTACKED: - case EVENT_DESTROYED: - case EVENT_ANY: - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TriggerClass::Event_Need_House -- Determines if this event requires a house identifier. * - * * - * This routine is used to determine if the specified event requires a house identifier. * - * All trigger events that affect a house will require a house identifier. * - * * - * INPUT: event -- The event type to examine. * - * * - * OUTPUT: Does the specified event type require a house identifier? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -bool TriggerClass::Event_Need_House(EventType event) -{ - switch (event) { - case EVENT_PLAYER_ENTERED: - case EVENT_HOUSE_DISCOVERED: - case EVENT_UNITS_DESTROYED: - case EVENT_BUILDINGS_DESTROYED: - case EVENT_ALL_DESTROYED: - case EVENT_CREDITS: - case EVENT_TIME: - case EVENT_NBUILDINGS_DESTROYED: - case EVENT_NUNITS_DESTROYED: - case EVENT_NOFACTORIES: - case EVENT_EVAC_CIVILIAN: - case EVENT_BUILD: - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TriggerClass::Event_Need_Data -- Determines if this event requires a data value. * - * * - * This routine will determine if the specified event requires a data number parameter. * - * This is commonly needed for trigger events. * - * * - * INPUT: event -- The event to examine. * - * * - * OUTPUT: Does the specified event require a data number parameter? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -bool TriggerClass::Event_Need_Data(EventType event) -{ - switch (event) { - case EVENT_CREDITS: - case EVENT_TIME: - case EVENT_NBUILDINGS_DESTROYED: - case EVENT_NUNITS_DESTROYED: - case EVENT_BUILD: - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TriggerClass::Action_Need_Team -- Determines if this action event requires a team. * - * * - * This routine will determine if the specified action requires a team name parameter. * - * Typically, this is needed for reinforcements or other trigger events that affect * - * a particular team type. * - * * - * INPUT: action -- The action that is to be examined. * - * * - * OUTPUT: Does the specified action require a team type name? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/27/1995 JLB : Created. * - *=============================================================================================*/ -bool TriggerClass::Action_Need_Team(TriggerClass::ActionType action) -{ - switch (action) { - case ACTION_CREATE_TEAM: - case ACTION_DESTROY_TEAM: - case ACTION_REINFORCEMENTS: - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TriggerClass::TriggerClass -- constructor * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -TriggerClass::TriggerClass(void) -{ - IsPersistant = VOLATILE; - AttachCount = 0; - Event = EVENT_NONE; - Action = ACTION_NONE; - House = HOUSE_NONE; - DataCopy = Data = 0L; - Name[0] = '\0'; - Team = NULL; -} - - -/*********************************************************************************************** - * TriggerClass::~TriggerClass -- Destructor for trigger objects. * - * * - * This destructor will update the house blockage value if necessary. No other action need * - * be performed on trigger destruction. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1995 JLB : Created. * - *=============================================================================================*/ -TriggerClass::~TriggerClass(void) -{ - if (GameActive && House != HOUSE_NONE && Action == ACTION_ALLOWWIN) { - if (Houses.Ptr(House)->Blockage) Houses.Ptr(House)->Blockage--; - Houses.Ptr(House)->BorrowedTime = TICKS_PER_SECOND*4; - } -} - - -/*********************************************************************************************** - * TriggerClass::Init -- clears triggers for new scenario * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=============================================================================================*/ -void TriggerClass::Init(void) -{ - Triggers.Free_All(); -} - - -/*********************************************************************************************** - * TriggerClass::Spring -- Trigger processing routine * - * * - * Checks whether this trigger should "spring" for the given event & object; * - * If it should, then some really cool undocumented stuff magically happens. * - * * - * INPUT: * - * event EventType: What happened? * - * object Ptr to object containing this trigger: What did it happen to? * - * * - * OUTPUT: * - * 0 = nothing happened; 1 = the trigger was sprung * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/06/1994 BR : Created. * - * 06/25/1995 JLB : Added more trigger events. * - *=============================================================================================*/ -bool TriggerClass::Spring(EventType event, ObjectClass *obj) -{ - Validate(); - /* - ** If this is not the event for this trigger, just return. - */ - if (event != Event && Event != EVENT_ANY) { - return(false); - } - - /* - ** If time-based, decrement the minute counter; return if it's not time yet - */ - if (Event == EVENT_TIME) { - Data--; - if (Data > 0) { - return(false); - } - Data = DataCopy; - } - - /* - ** Semi-persistant trigger: first detach it from the calling object, then - ** see if this is the last object we're attached to; if so, the trigger - ** will spring. - */ - if (IsPersistant == SEMIPERSISTANT) { - - /* - ** Detach ourselves from the object - */ - obj->Trigger = NULL; - - /* - ** Decrement our attachment counter - */ - AttachCount--; - - /* - ** If we're attached to more objects, don't spring; otherwise, spring. - ** And, mark ourselves as volatile so we'll completely remove ourselves - ** from the game after we go off. - */ - if (AttachCount > 0) { - return(false); - } else { - IsPersistant = VOLATILE; - } - } - - /* - ** Otherwise, take an appropriate action. - */ - bool success = true; - TriggerClass * trig = NULL; - switch (Action) { - case ACTION_NUKE: - HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Enable(true, false); - HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Forced_Charge(PlayerPtr->Class->House == HOUSE_BAD); - break; - - case ACTION_ION: - HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Enable(true, false); - HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Forced_Charge(PlayerPtr->Class->House == HOUSE_GOOD); - break; - - case ACTION_WINLOSE: - switch (event) { - case EVENT_DESTROYED: - if (!PlayerPtr->IsToWin || PlayerPtr->Blockage > 0) PlayerPtr->Flag_To_Lose(); - success = true; - break; - - case EVENT_PLAYER_ENTERED: - if (!PlayerPtr->IsToLose) PlayerPtr->Flag_To_Win(); - success = true; - break; - - default: - success = false; - break; - } - break; - - case ACTION_DESTROY_XXXX: - trig = As_Pointer("XXXX"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_DESTROY_YYYY: - trig = As_Pointer("YYYY"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_DESTROY_ZZZZ: - trig = As_Pointer("ZZZZ"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_AIRSTRIKE: - PlayerPtr->IsAirstrikePending = true; -// PlayerPtr->Make_Air_Strike_Available(true); - break; - - case ACTION_DZ: - new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Waypoint[25])); - break; - - case ACTION_NONE: - break; - - case ACTION_WIN: - PlayerPtr->Flag_To_Win(); - break; - - case ACTION_LOSE: - PlayerPtr->Flag_To_Lose(); - break; - - case ACTION_BEGIN_PRODUCTION: - HouseClass::As_Pointer(House)->Begin_Production(); - break; - - case ACTION_AUTOCREATE: - if (obj && obj->Is_Techno()) { - ((TechnoClass *)obj)->House->IsAlerted = true; - } - break; - - case ACTION_CREATE_TEAM: - if (Team) { - ScenarioInit++; - Team->Create_One_Of(); - ScenarioInit--; - } - break; - - case ACTION_DESTROY_TEAM: - if (Team) { - Team->Destroy_All_Of(); - } - break; - - case ACTION_REINFORCEMENTS: - if (Team) { - success = Do_Reinforcements(Team); - } - break; - - case ACTION_ALL_HUNT: - Do_All_To_Hunt(); - break; - - default: - break; - } - - if (!success && Event == EVENT_TIME) Data = 1; - - /* - ** Remove trigger from the game. - */ - if (success && IsPersistant == VOLATILE) { - Remove(); - } - - return(true); -} - - -/*********************************************************************************************** - * TriggerClass::Spring -- Trigger processing routine * - * * - * This version of Spring is for cell-based triggers. * - * * - * INPUT: * - * data elapsed time, or credits, depending on what 'Event' is. * - * * - * OUTPUT: * - * 0 = nothing happened; 1 = the trigger was sprung * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/06/1994 BR : Created. * - *=============================================================================================*/ -bool TriggerClass::Spring(EventType event, CELL cell) -{ - Validate(); - /* - ** If this is not the event for this trigger, just return. - */ - if (event != Event) { - return(false); - } - - /* - ** If time-based, decrement the minute counter; return if it's not time yet - */ - if (Event == EVENT_TIME) { - Data--; - if (Data > 0) { - return(false); - } - Data = DataCopy; - } - - /* - ** Semi-persistant trigger: first detach it from the calling cell, then - ** see if this is the last cell we're attached to; if so, the trigger - ** will spring. - */ - if (IsPersistant == SEMIPERSISTANT) { - - /* - ** Detach ourselves from the cell - */ - Map[cell].IsTrigger = 0; - - /* - ** Decrement our attachment counter - */ - AttachCount--; - - /* - ** If we're attached to more cells, don't spring; otherwise, spring. - ** And, mark ourselves as volatile so we'll completely remove ourselves - ** from the game after we go off. - */ - if (AttachCount > 0) { - return(false); - } else { - IsPersistant = VOLATILE; - } - } - - /* - ** Otherwise, take an appropriate action. - */ - bool success = true; - TriggerClass * trig = NULL; - int index; - switch (Action) { - case ACTION_NUKE: - HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Enable(true, false); - HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Forced_Charge(PlayerPtr->Class->House == HOUSE_BAD); - break; - - case ACTION_ION: - HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Enable(true, false); - HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Forced_Charge(PlayerPtr->Class->House == HOUSE_GOOD); - break; - - case ACTION_AUTOCREATE: - for (index = 0; index < Houses.Count(); index++) { - Houses.Ptr(index)->IsAlerted = true; - } - break; - - case ACTION_DESTROY_XXXX: - trig = As_Pointer("XXXX"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_DESTROY_YYYY: - trig = As_Pointer("YYYY"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_DESTROY_ZZZZ: - trig = As_Pointer("ZZZZ"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_AIRSTRIKE: - HouseClass::As_Pointer(House)->AirStrike.Enable(false, true); - if (House == PlayerPtr->Class->House) { - PlayerPtr->AirStrike.Forced_Charge(true); - Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE); - Map.Column[1].Flag_To_Redraw(); - } -// PlayerPtr->Make_Air_Strike_Available(true); - break; - - case ACTION_DZ: - new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Waypoint[25])); - break; - - case ACTION_NONE: - break; - - case ACTION_WIN: - PlayerPtr->Flag_To_Win(); - break; - - case ACTION_LOSE: - PlayerPtr->Flag_To_Lose(); - break; - - case ACTION_BEGIN_PRODUCTION: - if (PlayerPtr->Class->House == HOUSE_GOOD) { - HouseClass::As_Pointer(HOUSE_BAD)->Begin_Production(); - } else { - HouseClass::As_Pointer(HOUSE_GOOD)->Begin_Production(); - } - break; - - case ACTION_CREATE_TEAM: - if (Team) { - ScenarioInit++; - Team->Create_One_Of(); - ScenarioInit--; - } - break; - - case ACTION_DESTROY_TEAM: - if (Team) { - Team->Destroy_All_Of(); - } - break; - - case ACTION_REINFORCEMENTS: - if (Team) { - success = Do_Reinforcements(Team); - } - break; - - case ACTION_ALL_HUNT: - Do_All_To_Hunt(); - break; - - default: - break; - } - - if (!success && Event == EVENT_TIME) Data = 1; - - /* - ** Remove trigger from the game. - */ - if (success && IsPersistant == VOLATILE) { - Remove(); - } - - return(true); -} - - -/*********************************************************************************************** - * TriggerClass::Spring -- Trigger processing routine * - * * - * This version of Spring is for house-specific triggers. * - * For a time-based trigger, 'data' will the the current TickCount. * - * For a credit-based trigger, 'data' will be the credits for the HouseClass * - * containing this trigger. * - * * - * INPUT: * - * event the event that happened * - * house house that this event relates to * - * data elapsed time, or credits, depending on what 'Event' is. * - * * - * OUTPUT: * - * 0 = nothing happened; 1 = the trigger was sprung * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/06/1994 BR : Created. * - * 06/25/1995 JLB : Added more trigger events. * - *=============================================================================================*/ -bool TriggerClass::Spring(EventType event, HousesType house, long data) -{ - Validate(); - /* - ** If this is not the event for this trigger, just return. - */ - if (event != Event || house != House) { - return(false); - } - - /* - ** If credits-based, check 'data' - */ - if (Event == EVENT_CREDITS && data < Data) { - return(false); - } - - /* - ** Building event check to ensure that the building number matches. - */ - if (Event == EVENT_BUILD && data != Data) { - return(false); - } - - /* - ** Number of objects destroyed checker. If the data supplied indicates that - ** the correct number of objects have been destroyed, then this trigger - ** will succeed. - */ - if (Event == EVENT_NBUILDINGS_DESTROYED || Event == EVENT_NUNITS_DESTROYED) { - if (data < Data) { - return(false); - } - } - - /* - ** If time-based, decrement the minute counter; return if it's not time yet - */ - if (Event == EVENT_TIME) { - Data--; - if (Data > 0) { - return(false); - } - Data = DataCopy; - } - - /* - ** The trigger has gone off; take appropriate action - */ - bool success = true; - TriggerClass * trig = NULL; - switch (Action) { - - case ACTION_NUKE: - HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Enable(true, false); - HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Forced_Charge(PlayerPtr->Class->House == HOUSE_BAD); - break; - - case ACTION_ION: - HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Enable(true, false); - HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Forced_Charge(PlayerPtr->Class->House == HOUSE_GOOD); - break; - - /* - ** This will remove a blockage to the win condition. No action need - ** be performed here since the act of deleting the trigger will - ** remove the blockage. - */ - case ACTION_ALLOWWIN: - break; - - case ACTION_AUTOCREATE: - HouseClass::As_Pointer(House)->IsAlerted = true; - break; - - case ACTION_DESTROY_XXXX: - trig = As_Pointer("XXXX"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_DESTROY_YYYY: - trig = As_Pointer("YYYY"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_DESTROY_ZZZZ: - trig = As_Pointer("ZZZZ"); - if (trig) { - trig->Remove(); - } - delete trig; - break; - - case ACTION_AIRSTRIKE: - PlayerPtr->AirStrike.Enable(false, true); - if (House == PlayerPtr->Class->House) { - PlayerPtr->AirStrike.Forced_Charge(true); - Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE); - Map.Column[1].Flag_To_Redraw(); - } - break; - - case ACTION_NONE: - break; - - case ACTION_DZ: - new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Waypoint[25])); - break; - - case ACTION_WIN: - PlayerPtr->Flag_To_Win(); - break; - - case ACTION_LOSE: - PlayerPtr->Flag_To_Lose(); - break; - - case ACTION_BEGIN_PRODUCTION: - HouseClass::As_Pointer(House)->Begin_Production(); - break; - - case ACTION_CREATE_TEAM: - if (Team) { - ScenarioInit++; - Team->Create_One_Of(); - ScenarioInit--; - } - break; - - case ACTION_DESTROY_TEAM: - if (Team) { - Team->Destroy_All_Of(); - } - break; - - case ACTION_REINFORCEMENTS: - if (Team) { - success = Do_Reinforcements(Team); - } - break; - - case ACTION_ALL_HUNT: - Do_All_To_Hunt(); - break; - - default: - break; - } - - if (!success && Event == EVENT_TIME) Data = 1; - - /* - ** Remove trigger from the game. - */ - if (success && IsPersistant == VOLATILE) { - Remove(); - } - - return(true); -} - - -/*********************************************************************************************** - * TriggerClass::Remove -- removes this trigger from the game * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = trigger was removed, 0 = it wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 12/06/1994 BR : Created. * - *=============================================================================================*/ -bool TriggerClass::Remove(void) -{ - Validate(); - CELL cell; - HousesType h; - int index; - - /* - ** Loop through all cells; remove any reference to this trigger - */ - for (cell = 0; cell < MAP_CELL_TOTAL; cell++) { - if (Map[cell].IsTrigger) { - if (CellTriggers[cell] == this) { - Map[cell].IsTrigger = 0; - CellTriggers[cell] = NULL; - } - } - } - - /* - ** Loop through all objects, removing any reference to this trigger - */ - for (index = 0; index < Infantry.Count(); index++) { - if (Infantry.Ptr(index)->Trigger == this) { - Infantry.Ptr(index)->Trigger = NULL; - } - } - for (index = 0; index < Buildings.Count(); index++) { - if (Buildings.Ptr(index)->Trigger == this) { - Buildings.Ptr(index)->Trigger = NULL; - } - } - for (index = 0; index < Units.Count(); index++) { - if (Units.Ptr(index)->Trigger == this) { - Units.Ptr(index)->Trigger = NULL; - } - } - for (index = 0; index < Terrains.Count(); index++) { - if (Terrains.Ptr(index)->Trigger == this) { - Terrains.Ptr(index)->Trigger = NULL; - } - } - - /* - ** Remove this trigger from any house list it's in. Invoking '-=' with a - ** pointer not in the list has no effect; loop through all houses just to - ** be on the safe side. - */ - for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { - HouseTriggers[h].Delete(this); - } - - delete this; - - return(true); -} - - -/*********************************************************************************************** - * TriggerClass::Read_INI -- reads triggers from the INI file * - * * - * INI entry format: * - * Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant * - * * - * This routine reads in the triggers & creates them. Then, other classes can * - * get pointers to the triggers they're linked to. * - * * - * The routine relies on the TeamTypeClasses already being loaded so it can resolve * - * references to teams in this function. * - * * - * Cell Trigger pointers & IsTrigger flags are set in DisplayClass::Read_INI(), * - * and cleared in the Map::Init() routine (which clears all cell objects to 0's). * - * * - * Object's pointers are set in: * - * InfantryClass::Read_INI() * - * BuildingClass::Read_INI() * - * UnitClass::Read_INI() * - * TerrainClass::Read_INI() * - * The object trigger pointers are cleared in the ObjectClass constructor. * - * * - * The House's EMSListOf triggers is set in this routine, and cleared in the * - * HouseClass::Init() routine. * - * * - * INPUT: * - * buffer buffer to hold the INI data * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * This function must be called before any other class's Read_INI. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -void TriggerClass::Read_INI(char *buffer) -{ - TriggerClass *trigger; // Working trigger pointer. - char *tbuffer; // Accumulation buffer of trigger IDs. - int len; // Length of data in buffer. - char buf[128]; - - /* - ** Set 'tbuffer' to point just past the INI buffer - */ - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - /* - ** Read all TRIGGER entry names into 'tbuffer' - */ - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - - /* - ** Loop for all trigger entries. - */ - while (*tbuffer != '\0') { - - /* - ** Create a new trigger. - */ - trigger = new TriggerClass(); - - /* - ** Set its name. - */ - trigger->Set_Name (tbuffer); - - /* - ** Get the trigger entry. - */ - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - - /* - ** Fill in the trigger. - */ - trigger->Fill_In(tbuffer,buf); - - /* - ** Add 'trigger' to the House's list. - */ -// if (trigger->House != HOUSE_NONE && trigger->Event != EVENT_PLAYER_ENTERED) { -// if (Event_Need_House(trigger->Event) && !Event_Need_Object(trigger->Event)) { - if (trigger->House != HOUSE_NONE) { - if (trigger->Action == ACTION_ALLOWWIN) HouseClass::As_Pointer(trigger->House)->Blockage++; - HouseTriggers[trigger->House].Add(trigger); - trigger->AttachCount++; - } - - /* - ** Go to next entry. - */ - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * TriggerClass::Fill_In -- fills in trigger from the given INI entry * - * * - * This routine fills in the given trigger with the given name, and values from * - * the given INI entry. * - * * - * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) * - * * - * INI entry format: * - * Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant * - * * - * INPUT: * - * name mnemonic for the desired trigger * - * entry INI entry to parse * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -void TriggerClass::Fill_In(char * name, char *entry) -{ - Validate(); - char *p; - - /* - ** Set its name. - */ - Set_Name(name); - - /* - ** 1st token: Event. - */ - Event = Event_From_Name(strtok(entry, ",")); - - /* - ** 2nd token: Action. - */ - Action = Action_From_Name(strtok(NULL, ",")); - - /* - ** 3rd token: Data. - */ - DataCopy = Data = atol(strtok(NULL, ",")); - - /* - ** 4th token: House. - */ - House = HouseTypeClass::From_Name(strtok(NULL, ",")); - if (House == HOUSE_NONE && Event == EVENT_PLAYER_ENTERED) { - House = PlayerPtr->Class->House; - } - - /* - ** 5th token: Team. - */ - Team = TeamTypeClass::As_Pointer(strtok(NULL, ",")); - - /* - ** 6th token: IsPersistant. This token was added later, so we must check - ** for its existence. - */ - p = strtok(NULL, ","); - if (p) { - IsPersistant = (PersistantType)atoi(p); - } else { - IsPersistant = VOLATILE; - } -} - - -/*********************************************************************************************** - * TriggerClass::Write_INI -- writes triggers to the INI file * - * * - * INI entry format: * - * Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant * - * * - * INPUT: * - * buffer buffer to hold the INI data * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -void TriggerClass::Write_INI(char *buffer, bool refresh) -{ - int index; - char buf[128]; - TriggerClass *trigger; - char const *hname; - char const *tname; - - /* - ** First, clear out all existing trigger data from the INI file. - */ - if (refresh) { - WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer); - } - - /* - ** Now write all the trigger data out - */ - for (index = 0; index < Triggers.Count(); index++) { - - /* - ** Get ptr to next active trigger. - */ - trigger = Triggers.Ptr(index); - - /* - ** Generate INI entry. - */ - if (trigger->House==HOUSE_NONE) { - hname = "None"; - } else { - hname = HouseClass::As_Pointer(trigger->House)->Class->IniName; - } - - if (trigger->Team==NULL) { - tname = "None"; - } else { - tname = trigger->Team->IniName; - } - - sprintf(buf,"%s,%s,%ld,%s,%s,%d", - TriggerClass::Name_From_Event(trigger->Event), - TriggerClass::Name_From_Action(trigger->Action), - trigger->Data, - hname, - tname, - trigger->IsPersistant); - WWWritePrivateProfileString(INI_Name(), trigger->Get_Name(), buf, buffer); - } -} - - -/*********************************************************************************************** - * TriggerClass::As_Pointer -- returns pointer for the given trigger name * - * * - * This function is designed for use at initialization time, ie when the * - * trigger mnemonics are read from the INI and the Read_INI functions need * - * to get a pointer to that trigger. * - * * - * INPUT: * - * name mnemonic for the desired trigger * - * * - * OUTPUT: * - * near pointer to that trigger, NULL if not found * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -TriggerClass * TriggerClass::As_Pointer(char const * name) -{ - if (name == NULL) { - return(NULL); - } - - for (int i = 0; i < Triggers.Count(); i++) { - TriggerClass * trigger = Triggers.Ptr(i); - - if (!stricmp(name, trigger->Name)) { - return(trigger); - } - } - - return(NULL); -} - - -/*********************************************************************************************** - * TriggerClass::operator new -- 'new' operator * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * pointer to new trigger * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -void * TriggerClass::operator new(size_t ) -{ - void * ptr = Triggers.Allocate(); - if (ptr) { - ((TriggerClass *)ptr)->IsActive = true; - } - return(ptr); -} - - -/*********************************************************************************************** - * TriggerClass::operator delete -- 'delete' operator * - * * - * INPUT: * - * ptr pointer to delete * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/28/1994 BR : Created. * - *=============================================================================================*/ -void TriggerClass::operator delete(void *ptr) -{ - if (ptr) { - ((TriggerClass *)ptr)->IsActive = false; - } - Triggers.Free((TriggerClass *)ptr); -} - - -/*********************************************************************************************** - * TriggerClass::Event_From_Name -- retrieves EventType for given name * - * * - * INPUT: * - * name name to get event for * - * * - * OUTPUT: * - * EventType for given name * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=============================================================================================*/ -EventType TriggerClass::Event_From_Name (char const *name) -{ - int i; - - if (name == NULL) { - return(EVENT_NONE); - } - - for (i = EVENT_NONE; i < EVENT_COUNT; i++) { - if (!stricmp(name,EventText[i + 1])) { - return((EventType)i); - } - } - - return(EVENT_NONE); -} - - -/*********************************************************************************************** - * TriggerClass::Name_From_Event -- retrieves name for EventType * - * * - * INPUT: * - * event EventType to get name for * - * * - * OUTPUT: * - * name for EventType * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=============================================================================================*/ -char const *TriggerClass::Name_From_Event(EventType event) -{ - return(EventText[event + 1]); -} - - -/*********************************************************************************************** - * TriggerClass::Action_From_Name -- retrieves ActionType for given name * - * * - * INPUT: * - * name name to get ActionType for * - * * - * OUTPUT: * - * ActionType for given name * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=============================================================================================*/ -TriggerClass::ActionType TriggerClass::Action_From_Name (char const *name) -{ - int i; - - if (name == NULL) { - return(ACTION_NONE); - } - - for (i = ACTION_NONE; i < ACTION_COUNT; i++) { - if (!stricmp(name,ActionText[i + 1])) { - return((ActionType)i); - } - } - - return(ACTION_NONE); -} - - -/*********************************************************************************************** - * TriggerClass::Name_From_Action -- retrieves name for ActionType * - * * - * INPUT: * - * action ActionType to get name for * - * * - * OUTPUT: * - * name of ActionType * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 11/29/1994 BR : Created. * - *=============================================================================================*/ -char const *TriggerClass::Name_From_Action(ActionType action) -{ - return(ActionText[action + 1]); -} - - -/*********************************************************************************************** - * TriggerClass::As_Target -- Converts trigger to a target value * - * * - * INPUT: none * - * * - * OUTPUT: TARGET value * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -TARGET TriggerClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_TRIGGER, Triggers.ID(this))); -} - - -/*********************************************************************************************** - * Do_All_To_Hunt -- Forces all computer controlled units into hunt mode. * - * * - * This trigger action will cause the computer units and infantry to go into hunt mode. * - * Use it to bring a scenario to a sudden conclusion. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/20/1995 JLB : Created. * - * 08/14/1995 JLB : Removes the member from a team if necessary. * - *=============================================================================================*/ -static void Do_All_To_Hunt(void) -{ - int index; - - for (index = 0; index < Units.Count(); index++) { - UnitClass * unit = Units.Ptr(index); - - if (!unit->House->IsHuman && unit->IsDown && !unit->IsInLimbo) { - if (unit->Team) unit->Team->Remove(unit); - unit->Assign_Mission(MISSION_HUNT); - } - } - - for (index = 0; index < Infantry.Count(); index++) { - InfantryClass * infantry = Infantry.Ptr(index); - - if (!infantry->House->IsHuman && infantry->IsDown && !infantry->IsInLimbo) { - if (infantry->Team) infantry->Team->Remove(infantry); - infantry->Assign_Mission(MISSION_HUNT); - } - } -} diff --git a/code/TIBERIANDAWN/TRIGGER.H b/code/TIBERIANDAWN/TRIGGER.H deleted file mode 100644 index fc0ab3d..0000000 --- a/code/TIBERIANDAWN/TRIGGER.H +++ /dev/null @@ -1,261 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\trigger.h_v 2.15 16 Oct 1995 16:46:32 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TRIGGER.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 11/12/94 * - * * - * Last Update : November 12, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TRIGGER_H -#define TRIGGER_H - -typedef enum EventType : char { - EVENT_NONE=-1, - - /* - .......................... Cell-specific events .......................... - */ - EVENT_PLAYER_ENTERED, // player enters this square - EVENT_CELLFIRST = EVENT_PLAYER_ENTERED, - - /* - ......................... Object-specific events ......................... - */ - EVENT_DISCOVERED, // player discovers this object - EVENT_OBJECTFIRST = EVENT_DISCOVERED, - EVENT_ATTACKED, // player attacks this object - EVENT_DESTROYED, // player destroys this object - EVENT_ANY, // Any object event will cause the trigger. - - /* - ......................... House-specific events .......................... - */ - EVENT_HOUSE_DISCOVERED, // any object in this house discovered - EVENT_HOUSEFIRST = EVENT_HOUSE_DISCOVERED, - EVENT_UNITS_DESTROYED, // all house's units destroyed - EVENT_BUILDINGS_DESTROYED, // all house's buildings destroyed - EVENT_ALL_DESTROYED, // all house's units & buildings destroyed - EVENT_CREDITS, // house reaches this many credits - EVENT_TIME, // time elapses for this house - EVENT_NBUILDINGS_DESTROYED, // Number of buildings destroyed. - EVENT_NUNITS_DESTROYED, // Number of units destroyed. - EVENT_NOFACTORIES, // No factories left. - EVENT_EVAC_CIVILIAN, // Civilian has been evacuated. - EVENT_BUILD, // If specified building has been built. - - EVENT_COUNT, - EVENT_FIRST=0 -} EventType; - - -class TriggerClass { - public: - typedef enum ActionType { - ACTION_NONE=-1, - - ACTION_WIN, // player wins! - ACTION_LOSE, // player loses. - ACTION_BEGIN_PRODUCTION, // computer begins production - ACTION_CREATE_TEAM, // computer creates a certain type of team - ACTION_DESTROY_TEAM, - ACTION_ALL_HUNT, // all enemy units go into hunt mode (teams destroyed). - ACTION_REINFORCEMENTS, // player gets reinforcements - // (house that gets them is determined by - // the Reinforcement instance) - ACTION_DZ, // Deploy drop zone smoke. - ACTION_AIRSTRIKE, // Enable airstrike. - ACTION_NUKE, // Enable nuke for computer. - ACTION_ION, // Give ion cannon to computer. - ACTION_DESTROY_XXXX, // Destroy trigger XXXX. - ACTION_DESTROY_YYYY, // Destroy trigger YYYY. - ACTION_DESTROY_ZZZZ, // Destroy trigger ZZZZ. - ACTION_AUTOCREATE, // Computer to autocreat teams. - ACTION_WINLOSE, // Win if captured, lose if destroyed. - ACTION_ALLOWWIN, // Allows winning if triggered. - - ACTION_COUNT, - ACTION_FIRST=0 - } ActionType; - - typedef enum PersistantType { - VOLATILE = 0, - SEMIPERSISTANT = 1, - PERSISTANT = 2, - } PersistantType; - - /* - ** Functions: - ** - ** Constructor/Destructor - */ - TriggerClass(void); - ~TriggerClass(void); - - /* - ** Initialization: clears all triggers in preparation for new scenario - */ - static void Init(void); - - /* - ** Processing routines - */ - bool Spring(EventType event, ObjectClass * object); // object-based - bool Spring(EventType event, CELL cell); // cell-based - bool Spring(EventType event, HousesType house, long data=0); // house-based - bool Remove(void); - - /* - ** File I/O routines - */ - static void Read_INI (char *buffer); - void Fill_In(char *name, char *entry); - static void Write_INI (char *buffer, bool refresh); - static char * INI_Name(void) {return "Triggers";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - void Code_Pointers(void); - void Decode_Pointers(void); - - /* - ** As_Pointer gets a pointer to the trigger object give the mnemonic - */ - static TriggerClass * As_Pointer(char const * name); - - /* - ** Data Access routines - */ -// EventType Get_Event(void) const {return (Event);} -// void Set_Event(EventType event) {Event = event;} -// ActionType Get_Action(void) const {return (Action);} -// void Set_Action(ActionType action) {Action = action;} -// HousesType Get_House(void) const {return(House);} -// void Set_House(HousesType house) {House = house;} -// long Get_Data(void) const {return(Data);} -// void Set_Data(long credits) {Data = credits;} - char const * Get_Name(void) const {return (Name);} - void Set_Name(char const *buf) {strncpy(Name, buf, sizeof(Name)); Name[sizeof(Name)-1] = '\0';} - - /* - ** Utility routines - */ - TARGET As_Target(void) const; - static bool Event_Need_Object(EventType event); - static bool Event_Need_House(EventType event); - static bool Event_Need_Data(EventType event); - static bool Action_Need_Team(ActionType action); - static EventType Event_From_Name(char const *name); - static char const *Name_From_Event(EventType event); - static ActionType Action_From_Name(char const *name); - static char const *Name_From_Action(ActionType action); - - /* - ** Overloaded operators - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - /* - ** This is the pointer to the team that gets created or destroyed when - ** a team-related trigger goes off, or for reinforcements. The house - ** for reinforcements is determined by the house for that team. - */ - TeamTypeClass *Team; - - /* - ** If this trigger object is active, then this flag will be true. Trigger - ** objects that are not active are either not yet created or have been - ** deleted after fulfilling their action. - */ - unsigned IsActive:1; - - /* - ** This flag controls whether the trigger destroys itself after it goes - ** off. - ** 0 = trigger destroys itself immediately after going off, and removes - ** itself from all objects it's attached to - ** 1 = trigger is "Semi-Persistent"; it maintains a count of all objects - ** it's attached to, and only actually "springs" after its been - ** triggered from all the objects; then, it removes itself. - ** 2 = trigger is Fully Persistent; it just won't go away. - */ - PersistantType IsPersistant; - - /* - ** This value tells how many objects or cells this trigger is attached - ** to. The Read_INI routine for all classes that point to a trigger must - ** increment this value! - */ - int AttachCount; - - /* - ** Each trigger must have an event which activates it. This is the event that is - ** used to activate this trigger. - */ - EventType Event; - - /* - ** This is the action to perform when the trigger event occurs. - */ - ActionType Action; - - /* - ** For house-specific events, this is the house for that event. - */ - HousesType House; - - /* - ** For credit-related triggers, this is the number of credits that - ** generate the trigger. For time-based triggers, this is the number - ** of minutes that must elapse. - */ - long Data; - long DataCopy; - - private: - - /* - ** Triggers can be referred to by their name, which can be up to 4 - ** characters. - */ - char Name[5]; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - -}; - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/TURRET.CPP b/code/TIBERIANDAWN/TURRET.CPP deleted file mode 100644 index 409fe1e..0000000 --- a/code/TIBERIANDAWN/TURRET.CPP +++ /dev/null @@ -1,508 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\turret.cpv 2.18 16 Oct 1995 16:50:38 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TURRET.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 25, 1994 * - * * - * Last Update : August 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * TurretClass::AI -- Handles the reloading of the turret weapon. * - * TurretClass::Can_Fire -- Determines if turret can fire upon target. * - * TurretClass::Debug_Dump -- Debug printing of turret values. * - * TurretClass::Fire_At -- Try to fire upon the target specified. * - * TurretClass::Fire_Coord -- Determines the coorindate that projectile would appear. * - * TurretClass::Fire_Direction -- Determines the directinon of firing. * - * TurretClass::Ok_To_Move -- Queries whether the vehicle can move. * - * TurretClass::TurretClass -- Normal constructor for the turret class. * - * TurretClass::TurretClass -- The default constructor for turret class objects. * - * TurretClass::Unlimbo -- Unlimboes turret object. * - * TurretClass::~TurretClass -- Default destructor for turret class objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "turret.h" - - -/*********************************************************************************************** - * TurretClass::~TurretClass -- Default destructor for turret class objects. * - * * - * This is the default destructor for turret class objects. It does nothing. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -TurretClass::~TurretClass(void) -{ -} - - -/*********************************************************************************************** - * TurretClass::TurretClass -- The default constructor for turret class objects. * - * * - * This is the default constructor for turret class objects. It does nothing. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -TurretClass::TurretClass(void) -{ -} - - -/*********************************************************************************************** - * TurretClass::TurretClass -- Normal constructor for the turret class. * - * * - * This is the normal constructor for the turret class. It merely sets the turret up to * - * face north. * - * * - * INPUT: classid -- The type id for this particular unit. * - * * - * house -- The house that this unit will belong to. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 02/02/1995 JLB : Created. * - *=============================================================================================*/ -TurretClass::TurretClass(UnitType classid, HousesType house) : - DriveClass(classid, house) -{ - Reload = 0; -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * TurretClass::Debug_Dump -- Debug printing of turret values. * - * * - * This routine is used to display the current values of this turret * - * class instance. It is primarily used in the debug output screen. * - * * - * INPUT: x,y -- Monochrome screen coordinates to display data. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/12/1994 JLB : Created. * - *=============================================================================================*/ -void TurretClass::Debug_Dump(MonoClass *mono) const -{ - mono->Set_Cursor(36, 3);mono->Printf("%02X:%02X", SecondaryFacing.Current(), SecondaryFacing.Desired()); - mono->Set_Cursor(28, 7);mono->Printf("%2d", Arm); - DriveClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * TurretClass::Ok_To_Move -- Queries whether the vehicle can move. * - * * - * This virtual routine is used to determine if the vehicle is allowed * - * to start moving. It is typically called when the vehicle desires * - * to move but needs confirmation from the turret logic before * - * proceeding. This happens when dealing with a vehicle that must have * - * its turret face the same direction as the body before the vehicle * - * may begin movement. * - * * - * INPUT: dir -- The facing the unit wants to travel in. * - * * - * OUTPUT: bool; Can the unit begin forward movement now? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/12/1994 JLB : Created. * - *=============================================================================================*/ -bool TurretClass::Ok_To_Move(DirType dir) -{ - if (Class->IsLockTurret) { - if (IsRotating) { - return(false); - } else { - if (SecondaryFacing.Difference(dir)) { - SecondaryFacing.Set_Desired(dir); - return(false); - } - } - } - return(true); -} - - -/*********************************************************************************************** - * TurretClass::AI -- Handles the reloading of the turret weapon. * - * * - * This processes the reloading of the turret. It does this by decrementing the arming * - * countdown timer and when it reaches zero, the turret may fire. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/21/1994 JLB : Created. * - *=============================================================================================*/ -void TurretClass::AI(void) -{ - DriveClass::AI(); - - /* - ** A unit with a constant rotating radar dish is handled here. - */ - if (Class->IsRadarEquipped) { - SecondaryFacing.Set((DirType)(SecondaryFacing.Current() + 8)); - Mark(MARK_CHANGE); - } else { - - IsRotating = false; - if (Class->IsTurretEquipped) { - if (IsTurretLockedDown) { - SecondaryFacing.Set_Desired(PrimaryFacing.Current()); - } - - if (SecondaryFacing.Is_Rotating()) { - if (SecondaryFacing.Rotation_Adjust(Class->ROT+1)) { - Mark(MARK_CHANGE); - } - - /* - ** If no further rotation is necessary, flag that the rotation - ** has stopped. - */ - IsRotating = SecondaryFacing.Is_Rotating(); - } else { - if (!IsTurretLockedDown && !Target_Legal(TarCom)) { - if (!Target_Legal(NavCom)) { - SecondaryFacing.Set_Desired(PrimaryFacing.Current()); - } else { - SecondaryFacing.Set_Desired(Direction(NavCom)); - } - } - } - } - } -} - - -/*********************************************************************************************** - * TurretClass::Fire_At -- Try to fire upon the target specified. * - * * - * This routine is the auto-fire logic for the turret. It will check * - * to see if firing is technically legal given the specified target. * - * If it is legal to fire, it does so. It is safe to call this routine * - * every game tick. * - * * - * INPUT: target -- The target to fire upon. * - * * - * which -- Which weapon to use when firing. 0=primary, 1=secondary. * - * * - * OUTPUT: bool; Did firing occur? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/26/1994 JLB : Created. * - *=============================================================================================*/ -BulletClass * TurretClass::Fire_At(TARGET target, int which) -{ - BulletClass * bullet = NULL; - WeaponTypeClass const * weapon = (which == 0) ? &Weapons[Class->Primary] : &Weapons[Class->Secondary]; - - if (Can_Fire(target, which) == FIRE_OK) { - bullet = DriveClass::Fire_At(target, which); - - if (bullet) { - - /* - ** Possible reload timer set. - */ - if (*this == UNIT_MSAM && Reload == 0) { - Reload = TICKS_PER_SECOND * 30; - } - } - } - - return(bullet); -} - - -/*********************************************************************************************** - * TurretClass::Can_Fire -- Determines if turret can fire upon target. * - * * - * This routine determines if the turret can fire upon the target * - * specified. * - * * - * INPUT: target -- The target to fire upon. * - * * - * which -- Which weapon to use to determine legality to fire. 0=primary, * - * 1=secondary. * - * * - * OUTPUT: Returns the fire status type that indicates if firing is allowed and if not, why. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/26/1994 JLB : Created. * - * 06/01/1994 JLB : Returns reason why it can't fire. * - *=============================================================================================*/ -FireErrorType TurretClass::Can_Fire(TARGET target, int which) const -{ - DirType dir; // The facing to impart upon the projectile. - int diff; - FireErrorType fire = DriveClass::Can_Fire(target, which); - - if (fire == FIRE_OK) { - WeaponTypeClass const * weapon = (which == 0) ? &Weapons[Class->Primary] : &Weapons[Class->Secondary]; - - /* - ** If this unit cannot fire while moving, then bail. - */ - if ((!Class->IsTurretEquipped || Class->IsLockTurret) && Target_Legal(NavCom)) { - return(FIRE_MOVING); - } - - /* - ** If the turret is rotating and the projectile isn't a homing type, then - ** firing must be delayed until the rotation stops. - */ - if (!IsFiring && IsRotating && !BulletTypeClass::As_Reference(weapon->Fires).IsHoming) { - return(FIRE_ROTATING); - } - - dir = Direction(target); - - /* - ** Determine if the turret facing isn't too far off of facing the target. - */ - if (Class->IsTurretEquipped) { - diff = SecondaryFacing.Difference(dir); - } else { - diff = PrimaryFacing.Difference(dir); - } - diff = ABS(diff); - - /* - ** Special flame tank logic. - */ - if (weapon->Fires == BULLET_FLAME) { - if (Dir_Facing(dir) == Dir_Facing(PrimaryFacing)) { - diff = 0; - } - } - - if (BulletTypeClass::As_Reference(weapon->Fires).IsHoming) { - diff >>= 2; - } - if (diff < 8) { - return(DriveClass::Can_Fire(target, which)); - } - return(FIRE_FACING); - } - return(fire); -} - - -/*********************************************************************************************** - * TurretClass::Fire_Coord -- Determines the coorindate that projectile would appear. * - * * - * Use this routine to determine the exact coordinate that a projectile would appear if it * - * were fired from this unit. For units with turrets, typically, this would be at the end * - * of the barrel. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with coordinate of where a projectile should appear if this unit were * - * to fire one. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/28/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE TurretClass::Fire_Coord(int which) const -{ - COORDINATE coord = Center_Coord(); - int dist = 0; - int lateral = 0; - DirType dir = PrimaryFacing.Current(); - - if (Class->IsTurretEquipped) { - dir = SecondaryFacing.Current(); - } - - switch (Class->Type) { - case UNIT_GUNBOAT: - coord = Coord_Move(coord, PrimaryFacing.Current(), Pixel2Lepton[Class->TurretOffset]); - dist = 0x0060; - break; - - case UNIT_ARTY: - coord = Coord_Move(coord, DIR_N, 0x0040); - dist = 0x0060; - break; - - case UNIT_FTANK: - dist = 0x30; - if (IsSecondShot) { - coord = Coord_Move(coord, (DirType)(dir+DIR_E), 0x20); - } else { - coord = Coord_Move(coord, (DirType)(dir+DIR_W), 0x20); - } - break; - - case UNIT_HTANK: - coord = Coord_Move(coord, DIR_N, 0x0040); - if (which == 0) { - dist = 0x00C0; - lateral = 0x0028; - } else { - dist = 0x0008; - lateral = 0x0040; - } - if (IsSecondShot) { - coord = Coord_Move(coord, (DirType)(dir+DIR_E), lateral); - } else { - coord = Coord_Move(coord, (DirType)(dir+DIR_W), lateral); - } - break; - - case UNIT_LTANK: - coord = Coord_Move(coord, DIR_N, 0x0020); - dist = 0x00C0; - break; - - case UNIT_MTANK: - coord = Coord_Move(coord, DIR_N, 0x0030); - dist = 0x00C0; - break; - - case UNIT_APC: - case UNIT_JEEP: - case UNIT_BUGGY: - coord = Coord_Move(coord, DIR_N, 0x0030); - dist = 0x0030; - break; - -#ifdef PETROGLYPH_EXAMPLE_MOD - case UNIT_NUKE_TANK: - coord = Coord_Move(coord, DIR_N, 0x00A0); - dist = 0x00A0; - break; -#endif //PETROGLYPH_EXAMPLE_MOD - } - - if (dist) { - coord = Coord_Move(coord, dir, dist); - } - - return(coord); -} - - -/*********************************************************************************************** - * TurretClass::Unlimbo -- Unlimboes turret object. * - * * - * This routine is called when a turret equipped unit unlimboes. It sets the turret to * - * face the same direction as the body. * - * * - * INPUT: coord -- The coordinate where the unit is unlimboing. * - * * - * dir -- The desired body and turret facing to use. * - * * - * OUTPUT: Was the unit unlimboed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -bool TurretClass::Unlimbo(COORDINATE coord, DirType dir) -{ - if (DriveClass::Unlimbo(coord, dir)) { - SecondaryFacing = dir; - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * TurretClass::Fire_Direction -- Determines the directinon of firing. * - * * - * This routine will return with the facing that a projectile will travel if it was * - * fired at this instant. The facing should match the turret facing for those units * - * equipped with a turret. If the unit doesn't have a turret, then it will be the facing * - * of the body. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the default firing direction for a projectile. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -DirType TurretClass::Fire_Direction(void) const -{ - if (Class->IsTurretEquipped) { - if (*this == UNIT_MSAM) { - int diff1 = SecondaryFacing.Difference(DIR_E); - int diff2 = SecondaryFacing.Difference(DIR_W); - diff1 = ABS(diff1); - diff2 = ABS(diff2); - int diff = MIN(diff1, diff2); - int adj = Fixed_To_Cardinal(ABS(SecondaryFacing.Difference(DIR_N)), 64-diff); - if (SecondaryFacing.Difference(DIR_N) < 0) { - return(DirType)(SecondaryFacing - (DirType)adj); - } else { - return(DirType)(SecondaryFacing + (DirType)adj); - } - } - return(SecondaryFacing.Current()); - } - - return(PrimaryFacing.Current()); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/TURRET.H b/code/TIBERIANDAWN/TURRET.H deleted file mode 100644 index 35b478e..0000000 --- a/code/TIBERIANDAWN/TURRET.H +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\turret.h_v 2.17 16 Oct 1995 16:48:00 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TURRET.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 25, 1994 * - * * - * Last Update : April 25, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TURRET_H -#define TURRET_H - -#include "drive.h" - -class TurretClass : public DriveClass -{ - public: - - /* - ** This is the timer that controls the reload rate. The MSAM rocket - ** launcher is the primary user of this. - */ - TCountDownTimerClass Reload; - - /* - ** This is the facing of the turret. It can be, and usually is, - ** rotated independently of the body it is attached to. - */ - FacingClass SecondaryFacing; - - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - virtual bool Unlimbo(COORDINATE , DirType facing=DIR_N); - - /* - ** File I/O. - */ - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - protected: - TurretClass(UnitType classid, HousesType house); - TurretClass(void); - virtual ~TurretClass(void); - - BulletClass * Fire_At(TARGET target, int which); - - virtual DirType Fire_Direction(void) const; - virtual FireErrorType Can_Fire(TARGET target, int which) const; - virtual bool Ok_To_Move(DirType facing); - virtual void AI(void); - virtual COORDINATE Fire_Coord(int which) const; -}; - - -#endif diff --git a/code/TIBERIANDAWN/TXTLABEL.CPP b/code/TIBERIANDAWN/TXTLABEL.CPP deleted file mode 100644 index b8885e9..0000000 --- a/code/TIBERIANDAWN/TXTLABEL.CPP +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\txtlabel.cpv 1.9 16 Oct 1995 16:49:44 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TXTLABEL.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : 02/06/95 * - * * - * Last Update : February 6, 1995 [BR] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - - -/*********************************************************************************************** - * TextLabelClass -- Constructor * - * * - * INPUT: * - * txt pointer to text buffer to print from * - * x x-coord for text printing * - * y y-coord for text printing * - * color color to print in * - * style style to print (determines the meaning of x & y) * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -TextLabelClass::TextLabelClass(char *txt, int x, int y, int color, - TextPrintType style) : GadgetClass(x,y,1,1,0,0) -{ - Text = txt; - Color = color; - Style = style; - UserData = 0; - PixWidth = -1; - Segments = 0; -} - - -/*********************************************************************************************** - * Draw_Me -- Graphical update routine * - * * - * INPUT: * - * forced true = draw regardless of the current redraw flag state * - * * - * OUTPUT: * - * true = gadget was redrawn, false = wasn't * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 03/24/1995 BRR : Created. * - *=============================================================================================*/ -int TextLabelClass::Draw_Me(int forced) -{ - if (GadgetClass::Draw_Me(forced)) { - if (PixWidth == -1) { - Fancy_Text_Print("%s", X, Y, Color, TBLACK, Style, Text); - } else { - Conquer_Clip_Text_Print(Text, X, Y, Color, TBLACK, Style, PixWidth); - } - return(true); - } - return(false); -} diff --git a/code/TIBERIANDAWN/TXTLABEL.H b/code/TIBERIANDAWN/TXTLABEL.H deleted file mode 100644 index d5b014c..0000000 --- a/code/TIBERIANDAWN/TXTLABEL.H +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\txtlabel.h_v 1.14 16 Oct 1995 16:46:08 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TXTLABEL.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : 02/06/95 * - * * - * Last Update : February 6, 1995 [BR] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TXTLABEL_H -#define TXTLABEL_H - -class TextLabelClass : public GadgetClass -{ - public: - /* - ** Constructor/Destructor - */ - TextLabelClass(char *txt, int x, int y, int color, TextPrintType style); - - /* - ** Overloaded draw routine - */ - virtual int Draw_Me(int forced = false); - - /* - ** Sets the displayed text of the label - */ - virtual void Set_Text(char *txt) {Text = txt;}; - - /* - ** General-purpose data field - */ - unsigned long UserData; - TextPrintType Style; - char *Text; - int Color; - int PixWidth; - char Segments; - unsigned short CRC; -}; - -#endif - diff --git a/code/TIBERIANDAWN/TXTPRNT.ASM b/code/TIBERIANDAWN/TXTPRNT.ASM deleted file mode 100644 index ae4fffc..0000000 --- a/code/TIBERIANDAWN/TXTPRNT.ASM +++ /dev/null @@ -1,520 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : TXTPRNT.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : January 17, 1995 * -;* * -;* Last Update : January 17, 1995 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Buffer_Print -- Assembly text print to a buffer * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -;IDEAL -;P386 -;MODEL USE32 FLAT -.MODEL FLAT - - -;INCLUDE "mcgaprim.inc" -;INCLUDE ".\gbuffer.inc" - -externdef C Buffer_Print : NEAR - -GraphicViewPort STRUCT -GVPOffset DD ? ; offset to virtual viewport -GVPWidth DD ? ; width of virtual viewport -GVPHeight DD ? ; height of virtual viewport -GVPXAdd DD ? ; x mod to get to next line -GVPXPos DD ? ; x pos relative to Graphic Buff -GVPYPos DD ? ; y pos relative to Graphic Buff -GVPPitch DD ? ; modulo of graphic view port -GVPBuffPtr DD ? ; ptr to associated Graphic Buff -GraphicViewPort ENDS - - -;*=========================================================================* -;* Extern the font pointer which is defined by the font class * -;*=========================================================================* -extern C FontPtr:DWORD -extern C FontXSpacing:DWORD -extern C FontYSpacing:DWORD -externdef C ColorXlat:byte - -;*=========================================================================* -;* Define the necessary equates for structures and bounds checking * -;*=========================================================================* -; The header of the font file looks like this: -; UWORD FontLength; 0 -; BYTE FontCompress; 2 -; BYTE FontDataBlocks; 3 -; UWORD InfoBlockOffset; 4 -; UWORD OffsetBlockOffset; 6 -; UWORD WidthBlockOffset; 8 -; UWORD DataBlockOffset; 10 -; UWORD HeightOffset; 12 -; For this reason the following equates have these values: -FONTINFOBLOCK EQU 4 -FONTOFFSETBLOCK EQU 6 -FONTWIDTHBLOCK EQU 8 -FONTDATABLOCK EQU 10 -FONTHEIGHTBLOCK EQU 12 - -FONTINFOMAXHEIGHT EQU 4 -FONTINFOMAXWIDTH EQU 5 - - -;LOCALS ?? -;*=========================================================================* -;* Define the color xlate table in the data segment * -;*=========================================================================* - ;DATASEG - .data - -ColorXlat DB 00H,01H,02H,03H,04H,05H,06H,07H - DB 08H,09H,0AH,0BH,0CH,0DH,0EH,0FH - - DB 01H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 02H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 03H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 04H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 05H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 06H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 07H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 08H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 09H,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 0AH,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 0BH,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 0CH,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 0DH,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 0EH,00H,00H,00H,00H,00H,00H,00H - DB 00H,00H,00H,00H,00H,00H,00H,00H - - DB 0FH - - ;CODESEG - .code - - - -;*************************************************************************** -;* Buffer_Print -- Assembly text print to graphic buffer routine * -;* * -;* * -;* * -;* INPUT: * -;* * -;* OUTPUT: * -;* * -;* PROTO: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 01/17/1995 PWG : Created. * -;*=========================================================================* -Buffer_Print proc C public USES ebx ecx edx esi edi this_object:DWORD, string:DWORD, x_pixel:DWORD, y_pixel:DWORD, fcolor:DWORD, bcolor:DWORD - - ;PROC Buffer_Print C near - ;USES ebx,ecx,edx,esi,edi - - ;ARG this_object:DWORD - ;ARG string:DWORD - ;ARG x_pixel:DWORD - ;ARG y_pixel:DWORD - ;ARG fcolor:DWORD - ;ARG bcolor:DWORD - - LOCAL infoblock:DWORD ; pointer to info block - LOCAL offsetblock:DWORD ; pointer to offset block (UWORD *) - LOCAL widthblock:DWORD ; pointer to width block (BYTE *) - LOCAL heightblock:DWORD ; pointer to height block (UWORD *) - - LOCAL curline:DWORD ; pointer to first column of current row. - LOCAL bufferwidth:DWORD ; width of buffer (vpwidth + Xadd) - LOCAL nextdraw:DWORD ; bufferwidth - width of cur character. - LOCAL startdraw:DWORD ; where next character will start being drawn. - - LOCAL char:DWORD ; current character value. - - LOCAL maxheight:BYTE ; max height of characters in font. - LOCAL bottomblank:BYTE ; amount of empty space below current character. - LOCAL charheight:BYTE ; true height of current character. - LOCAL vpwidth:DWORD - LOCAL vpheight:DWORD - LOCAL original_x:DWORD ; Starting X position. - - -;-------------------------------- Where to draw ----------------------------------------------- - ; Set up memory location to start drawing. - mov ebx,[this_object] ; get a pointer to dest - mov eax,[ebx].GraphicViewPort.GVPHeight ; get height of viewport - mov [vpheight],eax ; save off height of viewport - mov eax,[ebx].GraphicViewPort.GVPWidth ; get width of viewport - mov [vpwidth],eax ; save it off for later - add eax,[ebx].GraphicViewPort.GVPXAdd ; add in xadd for bytes_per_line - add eax,[ebx].GraphicViewPort.GVPPitch ; add in pitch for direct daraw - mov [bufferwidth],eax ; save it off for later use. - - mul [y_pixel] ; multiply rowsize * y_pixel start. - mov edi,[ebx].GraphicViewPort.GVPOffset ; get start of the viewport - add edi,eax ; add y position to start of vp - mov [curline],edi ; save 0,y address for line feed stuff. - add edi,[x_pixel] ; add to get starting column in starting row. - mov [startdraw],edi ; save it off. - - mov eax,[x_pixel] - mov [original_x],eax - -;-------------------------------- Create block pointers ---------------------------------------- - ; Get the pointer to the font. - ; We could check for NULL but why waste the time. - ; It is up to programmer to make sure it is set. - mov esi,[FontPtr] ; Get the font pointer - or esi,esi - jz overflow - - ; Set up some pointers to the different memory blocks. - ; esi (FontPtr) is added to each to get the true address of each block. - ; Many registers are used for P5 optimizations. - ; ebx is used for InfoBlock which is then used in the next section. - movzx eax,WORD PTR [esi+FONTOFFSETBLOCK] ; get offset to offset block - movzx ebx,WORD PTR [esi+FONTINFOBLOCK] ; get offset to info block (must be ebx for height test) - movzx ecx,WORD PTR [esi+FONTWIDTHBLOCK] ; get offset to width block - movzx edx,WORD PTR [esi+FONTHEIGHTBLOCK] ; get offset to height block - - add eax,esi ; add offset of FontPtr to offset block - add ebx,esi ; add offset of FontPtr to info block - add ecx,esi ; add offset of FontPtr to width block - add edx,esi ; add offset of FontPtr to height block - - mov [offsetblock],eax ; save offset to offset block - mov [infoblock],ebx ; save offset to info block - mov [widthblock],ecx ; save offset to width block - mov [heightblock],edx ; save offset to height block - -;------------------------------------------ Test for fit ---------------------------------------------- - ; Test to make sure the height of the max character will fit on this line - ; and and not fall out of the viewport. - ; remember we set ebx to FONTINFOBLOCK above. - movzx eax,BYTE PTR [ebx + FONTINFOMAXHEIGHT]; get the max height in font. - mov [maxheight],al ; save it for later use. - add eax,[y_pixel] ; add current y_value. - cmp eax,[vpheight] ; are we over the edge? - jg overflow ; if so, we're outa here. - - mov [y_pixel],eax ; save for next line feed. y value for next line. - - cld ; Make sure we are always forward copying. - -;------------------------ Set palette foreground and background ---------------------------------- - mov eax,[fcolor] ; foreground color - mov byte ptr [ColorXlat+1],al - mov byte ptr [ColorXlat+16],al - - mov eax,[bcolor] ; background color - mov byte ptr [ColorXlat],al - -;------------------------------------------------------------------------------------------------- -;----------------------------------------- Main loop ---------------------------------------------- - ; Now we go into the main loop of reading each character in the string and doing - ; something with it. -next_char: - ; while (*string++) - xor eax,eax ; zero out since we will just load al. - mov esi,[string] ; get address on next character. - lodsb ; load the character into al. - test eax,0FFH ; test to see if character is a NULL - jz done ; character is NULL, get outa here. - - mov edi,[startdraw] ; Load the starting address. - - mov [string],esi ; save index into string. (incremented by lodsb) - - cmp al,10 ; is the character a line feed? - je line_feed ; if so, go to special case. - - cmp al,13 ; is the character a line feed? - je line_feed ; if so, go to special case. - - mov [char],eax ; save the character off for later reference. - mov ebx,eax ; save it in ebx for later use also. - - add eax,[widthblock] ; figure address of width of character. - mov ecx,[x_pixel] ; get current x_pixel. - movzx edx,BYTE PTR [eax] ; get the width of the character in dl. - add ecx,edx ; add width of char to current x_pixel. - mov eax,[FontXSpacing] - add ecx,eax - add [startdraw],edx ; save start draw for next character. - add [startdraw],eax ; adjust for the font spacing value - - cmp ecx,[vpwidth] ; is the pixel greater then the vp width? - jg force_line_feed ; if so, force a line feed. - - mov [x_pixel],ecx ; save value of start of next character. - mov ecx,[bufferwidth] ; get amount to next y same x (one row down) - sub ecx,edx ; take the current width off. - mov [nextdraw],ecx ; save it to add to edi when done with a row. - - ; At this point we got the character. It is now time to find out specifics - ; about drawing the darn thing. - ; ebx = char so they can be used as an indexes. - ; edx = width of character for loop later. - - ; get offset of data for character into esi. - shl ebx,1 ; mult by 2 to later use as a WORD index. - mov esi,[offsetblock] ; get pointer to begining of offset block. - add esi,ebx ; index into offset block. - movzx esi,WORD PTR [esi] ; get true offset into data block from FontPtr. - add esi,[FontPtr] ; Now add FontPtr address to get true address. - - ; Get top and bottom blank sizes and the true height of the character. - add ebx,[heightblock] ; point ebx to element in height array. - mov al,[ebx+1] ; load the data height into dl. - mov cl,[ebx] ; load the first data row into cl. - mov bl,[maxheight] ; get the max height of characters. - mov [charheight],al ; get number of rows with data. - add al,cl ; add the two heights. - sub bl,al ; subract topblank + char height from maxheight. - mov [bottomblank],bl ; save off the number of blank rows on the bottom. - ; leaving this section: - ; dl is still the width of the character. - ; cl is the height of the top blank area. - - mov ebx,OFFSET ColorXlat ; setup ebx for xlat commands. - mov dh,dl ; save the width of the character to restore each loop. - - cmp cl,0 ; is there any blank rows on top? - jz draw_char ; if not go and draw the real character. - - xor eax,eax ; get color 0 for background. - xlat ;[ebx] ; get translated color into al - test al,al ; is it transparent black - jnz loop_top ; if not go and write the color - -;----------------------------------------- skip Top blank area ---------------------------------------- - ; this case, the top is transparrent, but we need to increase our dest pointer to correct row. - movzx eax,cl ; get number of rows into eax; - mov ecx,edx ; save width since edx will be destroyed by mul. - mul [bufferwidth] ; multiply that by the width of the buffer. - mov edx,ecx ; restore the width - add edi,eax ; update the pointer. - jmp short draw_char ; now go draw the character. - -;----------------------------------------- fill Top blank area ---------------------------------------- - ; edi was set a long time ago. - ; al is the translated color -loop_top: - stosb ; store the value - dec dh ; decrement our width. - jnz loop_top ; if more width, continue on. - - add edi,[nextdraw] ; add amount for entire row. - - dec cl ; decrement or row count - mov dh,dl ; restore width in dh for loop. - jz draw_char ; we are done here, go draw the character. - jmp short loop_top ; go back to top of loop. - - -;----------------------------------------- Draw character ---------------------------------------------- -draw_char: - movzx ecx,[charheight] ; get the height of character to count down rows. - test ecx,ecx ; is there any data? (blank would not have any) - jz next_char ; if no data, go on to next character. - -while_data: - lodsb ; get byte value from font data - mov ah,al ; save hinibble - and eax,0F00FH ; mask of low nibble in al hi nibble in ah. - xlat ;[ebx] ; get new color - - test al,al ; is it a transparent? - jz short skiplo ; skip over write - mov [edi],al ; write it out -skiplo: - inc edi - dec dh ; decrement our width. - jz short nextrow ; check if done with width of char - - mov al,ah ; restore to get - ; test the time difference between looking up in a large table when shr al,4 is not done as - ; compared to using only a 16 byte table when using the shr al,4 - ;shr al,4 ; shift the hi nibble down to low nibble - xlat ;[ebx] ; get new color - - test al,al ; is it a transparent? - jz short skiphi ; skip over write - mov [edi],al ; write it out -skiphi: - - inc edi - dec dh ; decrement our width. - jnz short while_data ; check if done with width of char - -nextrow: - add edi,[nextdraw] ; go to next line. - dec ecx ; decrement the number of rows to go - mov dh,dl ; restore our column count for row. - jnz while_data ; more data for character. - - ; Now it is time to setup for clearing out the bottom of the character. - movzx ecx,[bottomblank] ; get amount on bottom that is blank - cmp ecx,0 ; if there is no blank bottom... - jz next_char ; then skip to go to next character - - xor eax,eax ; get color 0 for background. - xlat ;[ebx] ; get translated color into al - test al,al ; is it transparent black - jz next_char ; skip the top black section to let the background through - - mov dh,dl ; restore width in dh for loop. - -;----------------------------------------- Blank below character ----------------------------------- -loop_bottom: - stosb ; store the value - dec dh ; decrement our width. - jnz loop_bottom ; if more width, continue on. - - add edi,[nextdraw] ; add amount for entire row. - - mov dh,dl ; restore width in dh for loop. - dec cl ; decrement or row count - jz next_char ; we are done here, go to the next character. - jmp short loop_bottom ; go back to top of loop. - -;----------------------------------- end of next_char (main) loop ------------------------------------ -;------------------------------------------------------------------------------------------------- - - -;----------------------------------- special case line feeds ---------------------------------------- - -force_line_feed: - ; decrement pointer *string so that it will be back at same character - ; when it goes through the loop. - mov eax,[string] ; get string pointer. - dec eax ; decrement it to point to previos char - mov [string],eax ; save it back off. - xor eax,eax - ; Now go into the line feed code..... - -line_feed: - mov bl,al - mov edx,[y_pixel] ; get the current y pixel value. - movzx ecx,[maxheight] ; get max height for later use. - add ecx,[FontYSpacing] - add edx,ecx ; add max height to y_pixel - cmp edx,[vpheight] ; are we over the edge? - jg overflow ; if so, we are outa here. - - mov eax,[bufferwidth] ; get bytes to next line. - mov edi,[curline] ; get start of current line. - mul ecx ; mult max height * next line. - - add edi,eax ; add adjustment to current line. - add [y_pixel],ecx ; increment to our next y position. -;;; DRD - mov [curline],edi ; save it off for next line_feed. - - ; Move the cursor to either the left edge of the screen - ; or the left margin of the print position depending - ; on whether or was specified. = left margin - ; = left edge of screen - xor eax,eax - cmp bl,10 - je lfeed - mov eax,[original_x] -lfeed: - mov [x_pixel],eax ; zero out x_pixel - - add edi,eax -;;; DRD mov [curline],edi ; save it off for next line_feed. - mov [startdraw],edi ; save it off so we know where to draw next char.w - - jmp next_char - -overflow: - mov [startdraw],0 ; Indicate that there is no valid next pos. -done: - mov eax,[startdraw] ; return this so calling routine - ret ; can figure out where to draw next. - -Buffer_Print endp - - - -;*************************************************************************** -;* GET_FONT_PALETTE_PTR -- Returns a pointer to the 256 byte font palette * -;* * -;* INPUT: none * -;* * -;* OUTPUT: none * -;* * -;* PROTO: void *Get_Font_Palette_Ptr(void); * -;* * -;* HISTORY: * -;* 08/18/1995 PWG : Created. * -;*=========================================================================* - -Get_Font_Palette_Ptr proc C public - - ;GLOBAL C Get_Font_Palette_Ptr:NEAR - - ;PROC Get_Font_Palette_Ptr C near - - mov eax, OFFSET ColorXlat - ret - -Get_Font_Palette_Ptr endp - - -END \ No newline at end of file diff --git a/code/TIBERIANDAWN/TYPE.H b/code/TIBERIANDAWN/TYPE.H deleted file mode 100644 index 5efab0e..0000000 --- a/code/TIBERIANDAWN/TYPE.H +++ /dev/null @@ -1,2016 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\type.h_v 2.20 16 Oct 1995 16:45:42 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : TYPE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 14, 1994 * - * * - * Last Update : April 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TYPE_H -#define TYPE_H - -#include "mission.h" -#include "target.h" - -class MapEditClass; -class HouseClass; - - -/********************************************************************** -** This is the constant data associated with a weapon. Some objects -** can have multiple weapons and this class is used to isolate and -** specify this data in a convenient and selfcontained way. -*/ -class WeaponTypeClass -{ - public: - - /* - ** This is the unit class of the projectile fired. A subset of the unit types - ** represent projectiles. It is one of these classes that is specified here. - ** If this object does not fire anything, then this value will be UNIT_NONE. - */ - BulletType Fires; - - /* - ** This is the damage (explosive load) to be assigned to the projectile that - ** this object fires. - */ - unsigned char Attack; - - /* - ** Objects that fire (which can be buildings as well) will fire at a - ** frequency controlled by this value. This value serves as a count - ** down timer between shots. The smaller the value, the faster the - ** rate of fire. - */ - unsigned char ROF; - - /* - ** When this object fires, the range at which it's projectiles travel is - ** controlled by this value. The value represents the number of cells the - ** projectile will travel. Objects outside of this range will not be fired - ** upon (in normal circumstances). - */ - int Range; - - /* - ** This is the typical sound generated when firing. - */ - VocType Sound; - - /* - ** This is the animation to display at the firing coordinate. - */ - AnimType Anim; -}; - - -/********************************************************************** -** Each of the warhead types has specific characteristics. This structure -** holds these characteristics. -*/ -class WarheadTypeClass -{ - public: - - /* - ** This value control how damage from this warhead type will reduce - ** over distance. The larger the number, the less the damage is reduced - ** the farther the distance from the source of the damage. - */ - int SpreadFactor; - - /* - ** If this warhead type can destroy walls, then this flag will be true. - */ - bool IsWallDestroyer; - - /* - ** If this warhead can destroy wooden walls, then this flag will be true. - */ - bool IsWoodDestroyer; - - /* - ** Does this warhead damage tiberium? - */ - bool IsTiberiumDestroyer; - - /* - ** The warhead damage is reduced depending on the the type of armor the - ** defender has. This table is what gives weapons their "character". - */ - unsigned Modifier[ARMOR_COUNT]; -}; - - -/********************************************************************** -** Each house has certain unalienable characteristics. This structure -** elaborates these. -*/ -class HouseTypeClass { - public: - - /* - ** This is the house number (enum). This is a unique identification - ** number for the house. - */ - HousesType House; - - /* - ** The INI name of the house is pointed to by this element. This is the - ** identification name used in the scenario INI file. - */ - char const *IniName; - - /* - ** The full name (translated) of the house is identified by this number. - ** The actual text of the name is located in a text file loaded at run - ** time. - */ - int FullName; - - /* - ** This is the filename suffix to use when creating a house specific - ** file name. It is three characters long. - */ - char Suffix[4]; - - /* - ** This is the "lemon percentage" to use when determining if a particular - ** object owned by this house is to be flagged as a "lemon". Objects so - ** flagged have a greater break-down chance. The percentage is expressed - ** as a fixed point number with 0x000 meaning 0% and 0x100 meaning 100%. - */ - unsigned Lemon; - - /* - ** Each house is assigned a unique identification color to be used on the - ** radar map and other color significant areas. - */ - unsigned char Color; - - unsigned char BrightColor; - - /* - ** This points to the default remap table for this house. - */ - unsigned char const * RemapTable; - PlayerColorType RemapColor; - - /* - ** This is a unique ASCII character used when constructing filenames. It - ** serves a similar purpose as the "Suffix" element, but is only one - ** character long. - */ - char Prefix; - - /* - ** This controls the various general adjustments to the house owned - ** unit and building ratings. The default value for these ratings is 1.0. - */ - float FirepowerBias; - float GroundspeedBias; - float AirspeedBias; - float ArmorBias; - float ROFBias; - float CostBias; - float BuildSpeedBias; - - //------------------------------------------------------------------------ - HouseTypeClass(HousesType house, - char const *ini, - int fullname, - char const *ext, - int lemon, - int color, - int bright_color, - PlayerColorType remapcolor, - unsigned char const * remap, - char prefix); - - static HousesType From_Name(char const *name); - static HouseTypeClass const & As_Reference(HousesType house); - static void One_Time(void); - - private: - static HouseTypeClass const * const Pointers[HOUSE_COUNT]; -}; - - -/*************************************************************************** -** This is the abstract type class. It holds information common to all -** objects that might exist. This contains the name of -** the object type. -*/ -class AbstractTypeClass -{ - public: - - /* - ** This is the internal control name of the object. This name does - ** not change regardless of language specified. This is the name - ** used in scenario control files and for other text based unique - ** identification purposes. - */ - char IniName[9]; - - /* - ** The translated (language specific) text name number of this object. - ** This number is used to fetch the object's name from the language - ** text file. Whenever the name of the object needs to be displayed, - ** this is used to determine the text string. - */ - int Name; - - AbstractTypeClass(void) {}; - AbstractTypeClass(int name, char const * ini); - virtual RTTIType What_Am_I(void) const; - - virtual COORDINATE Coord_Fixup(COORDINATE coord) const; - virtual int Full_Name(void) const; - void Set_Name(char const *buf) const - { - strncpy((char *)IniName, buf, sizeof(IniName)); - ((char &)IniName[sizeof(IniName)-1]) = '\0'; - }; - virtual unsigned short Get_Ownable(void) const; -}; - - -/*************************************************************************** -** This the the common base class of game objects. Since these values -** represent the unchanging object TYPES, this data is initialized at game -** start and not changed during play. It is "const" data. -*/ -class ObjectTypeClass : public AbstractTypeClass -{ - public: - - /* - ** Is this object squashable by heavy vehicles? If it is, then the vehicle - ** can travel over this object and destroy it in the process. - */ - unsigned IsCrushable:1; - - /* - ** Does this object type NOT show up on radar scans? If true, then in any - ** radar display, only the underlying ground will be show, not this object. - ** Most terrain falls into this category, but only a few special real units/buildings - ** do. - */ - unsigned IsStealthy:1; - - /* - ** It is legal to "select" some objects in the game. If it is legal to select this - ** object type then this flag will be true. Selected game objects typically display - ** a floating health bar and allows special user I/O control. - */ - unsigned IsSelectable:1; - - /* - ** Can this object be the target of an attack or move command? Typically, only objects - ** that take damage or can be destroyed are allowed to be a target. - */ - unsigned IsLegalTarget:1; - - /* - ** "Insignificant" objects will not be announced when they are destroyed or when they - ** appear. Terrain elements and some lesser vehicles have this characteristic. - */ - unsigned IsInsignificant:1; - - /* - ** Is this object immune to normal combat damage? Rocks and other inert type terrain - ** object are typically of this type. - */ - unsigned IsImmune:1; - - /* - ** If this terrain object is flammable (such as trees are) then this - ** flag will be true. Flammable objects can catch fire if damaged by - ** flame type weapons. - */ - unsigned IsFlammable:1; - - /* - ** "Sentient" objects are ones that have logic AI processing performed on them. All - ** vehicles, buildings, infantry, and aircraft are so flagged. Terrain elements also - ** fall under this category, but only because certain animation effects require this. - */ - unsigned IsSentient:1; - - /* - ** The defense of this object is greatly affected by the type of armor - ** it possesses. This value specifies the type of armor. - */ - ArmorType Armor; - - /* - ** This is the maximum strength of this object type. - */ - unsigned short MaxStrength; - - /* - ** These point to the shape imagery for this object type. Since the shape imagery - ** exists in a separate file, the data is filled in after this object is constructed. - ** The "mutable" keyword allows easy modification to this otherwise const object. - */ - void const * ImageData; - - /* - ** This points to the radar imagery for this object. - */ - void const * RadarIcon; - - //-------------------------------------------------------------------- - ObjectTypeClass( bool is_sentient, - bool is_flammable, - bool is_crushable, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - int fullname, - char const *name, - ArmorType armor, - unsigned short strength); - - static void One_Time(void); - - virtual int Max_Pips(void) const; - virtual void Dimensions(int &width, int &height) const; - virtual bool Create_And_Place(CELL , HousesType =HOUSE_NONE) const = 0; - virtual int Cost_Of(void) const; - virtual int Time_To_Build(HousesType house) const; - virtual ObjectClass * Create_One_Of(HouseClass *) const = 0; - virtual short const * Occupy_List(bool placement=false) const; - virtual short const * Overlap_List(void) const; - virtual BuildingClass * Who_Can_Build_Me(bool, bool, HousesType) const; - virtual void const * Get_Cameo_Data(void) const; - void const * Get_Image_Data(void) const {return ImageData;}; - void const * Get_Radar_Data(void) const {return RadarIcon;}; - - #ifdef SCENARIO_EDITOR - virtual void Display(int, int, WindowNumberType, HousesType) const {}; - #endif - - static void const * SelectShapes; - static void const * PipShapes; -}; - - -/*************************************************************************** -** This class is the common data for all objects that can be owned, produced, -** or delivered as reinforcements. These are objects that typically contain -** crews and weapons -- the fighting objects of the game. -*/ -class TechnoTypeClass : public ObjectTypeClass -{ - public: - - /* - ** If this object can serve as a good leader for a group selected - ** series of objects, then this flag will be true. Unarmed or - ** ability challenged units do not make good leaders. - */ - unsigned IsLeader:1; - - /* - ** Does this object have the ability to detect the presence of a nearby - ** cloaked object? - */ - unsigned IsScanner:1; - - /* - ** If this object is always given its proper name rather than a generic - ** name, then this flag will be true. Typically, civilians and Dr. Mobius - ** fall under this catagory. - */ - unsigned IsNominal:1; - - /* - ** If the artwork for this object (only for generics) is theater specific, then - ** this flag will be true. Civilian buildings are a good example of this. - */ - unsigned IsTheater:1; - - /* - ** Does this object type contain a rotating turret? Gun emplacements, SAM launchers, - ** and many vehicles contain a turret. If a turret is present, special rendering and - ** combat logic must be performed. - */ - unsigned IsTurretEquipped:1; - - /* - ** Certain units and buildings fire two shots in quick succession. If this is - ** the case, then this flag is true. - */ - unsigned IsTwoShooter:1; - - /* - ** Certain objects can be repaired. For buildings, they repair "in place". For units, - ** they must travel to a repair center to be repaired. If this flag is true, then - ** allow the player or computer AI to repair the object. - */ - unsigned IsRepairable:1; - - /* - ** Is this object possible to be constructed? Certain buildings and units cannot - ** be constructed using normal means. They are either initially placed in the scenario - ** or can only arrive by pre arranged reinforcement scheduling. Civilian buildings and - ** vehicles are typical examples of this type of object. They would set this flag to - ** false. - */ - unsigned IsBuildable:1; - - /* - ** Does this object contain a crew? If it does, then when the object is destroyed, there - ** is a distinct possibility that infantry will "pop out". Only units with crews can - ** become "heros". - */ - unsigned IsCrew:1; - - /* - ** Is this object typically used to transport reinforcements or other cargo? - ** Transport aircraft, helicopters, and hovercraft are typicall examples of - ** this. - */ - unsigned IsTransporter:1; - - /* - ** Most objects have the ability to reveal the terrain around themselves. - ** This sight range (expressed in cell distance) is specified here. If - ** this value is 0, then this unit never reveals terrain. Bullets are - ** typically of this nature. - */ - int SightRange; - - /* - ** These values control the cost to produce, the time to produce, and - ** the scenario when production can first start. - */ - int Cost; - unsigned char Scenario; - - /* - ** Special build prerequisite control values. These are primarily used for - ** multi-player or special events. - */ - unsigned char Level; - long Pre; - - /* - ** The risk and reward values are used to determine targets and paths - ** toward targets. When heading toward a target, a path of least - ** risk will be followed. When picking a target, the object of - ** greatest reward will be selected. The values assigned are - ** arbitrary. - */ - int Risk,Reward; - - /* - ** This value indicates the maximum speed that this object can achieve. - */ - MPHType MaxSpeed; - - /* - ** This is the maximum number of ammo shots this object can hold. If - ** this number is -1, then this indicates unlimited ammo. - */ - int MaxAmmo; - - /* - ** This is a bit field representing the houses that are allowed to - ** own (by normal means) this particular object type. This value is - ** typically used in production contexts. It is possible for a side - ** to take possession of an object type otherwise not normally allowed. - ** This event usually occurs as a result of capture. - */ - unsigned short Ownable; - - /* - ** This is the small icon image that is used to display the object in - ** the sidebar for construction selection purposes. - */ - void const * CameoData; - - /* - ** These are the weapons that this techno object is armed with. - */ - WeaponType Primary; - WeaponType Secondary; - - //-------------------------------------------------------------------- - TechnoTypeClass( - int name, - char const *ininame, - unsigned char level, - long pre, - bool is_leader, - bool is_scanner, - bool is_nominal, - bool is_transporter, - bool is_flammable, - bool is_crushable, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - bool is_theater, - bool is_twoshooter, - bool is_turret_equipped, - bool is_repairable, - bool is_buildable, - bool is_crew, - int ammo, - unsigned short strength, - MPHType maxspeed, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, - WeaponType secondary, - ArmorType armor); - - virtual int Raw_Cost(void) const; - virtual int Max_Passengers(void) const; - virtual int Repair_Cost(void) const; - virtual int Repair_Step(void) const; - virtual void const * Get_Cameo_Data(void) const; - virtual int Cost_Of(void) const; - virtual int Time_To_Build(HousesType house) const; - virtual unsigned short Get_Ownable(void) const; - -#ifdef USE_RA_AI - int Legal_Placement(CELL pos) const; // From RA for AI. ST - 7/24/2019 5:20PM -#endif // USE_RA_AI - -}; - - -/*************************************************************************** -** Building types need some special information custom to buildings. This -** is a derived class that elaborates these additional data elements. -*/ -class BuildingTypeClass : public TechnoTypeClass { - enum BuildingTypeClassRepairEnums { - //REPAIR_COST=1, // Cost to repair a single "step". - REPAIR_PERCENT=102, // 40% fixed point number. - REPAIR_STEP=5 // Number of damage points recovered per "step". - }; - - public: - - /* - ** This flag controls whether the building is equiped with a dirt - ** bib or not. A building with a bib has a dirt patch automatically - ** attached to the structure when it is placed. - */ - unsigned IsBibbed:1; - - /* - ** If this building is a special wall type, such that it exists as a building - ** for purposes of construction but transforms into an overlay wall object when - ** it is placed on the map, then this flag will be true. - */ - unsigned IsWall:1; - - /* - ** Some buildings are producers. This flag will be true in that case. Producer, - ** or factory, type buildings have special logic performed. - */ - unsigned IsFactory:1; - - /* - ** Buildings can have either simple or complex damage stages. If simple, - ** then the second to the last frame is the half damage stage, and the last - ** frame is the complete damage stage. For non-simple damage, buildings - ** have a complete animation set for damaged as well as undamaged condition. - ** Turrets, oil pumps, and repair facilities are a few examples. - */ - unsigned IsSimpleDamage:1; - - /* - ** Some buildings can be placed directly on raw ground. Such buildings don't require - ** and are not affected by concrete or lack thereof. Typically, concrete itself is - ** considered sturdy. The same goes for walls and similar generic type structures. - ** The more sophisticated buildings are greatly affected by lack of concrete and thus - ** would have this flag set to false. - */ - unsigned IsSturdy:1; - - /* - ** Certain building types can be captures by enemy infantry. For those - ** building types, this flag will be true. Typically, military or hardened - ** structures such as turrets cannot be captured. - */ - unsigned IsCaptureable:1; - - /* - ** If this building really only has cosmetic idle animation, then this flag will be - ** true if this animation should run at a relatively constant rate regardless of game - ** speed setting. - */ - unsigned IsRegulated:1; - - /* - ** If this flag is true, then the building cannot be sold even if it could have been built. This - ** is especially useful for mines which can be built but cannot be sold. - */ - unsigned IsUnsellable:1; - - /* - ** This flag specifies the type of object this factory building can "produce". For non - ** factory buildings, this value will be RTTI_NONE. - */ - RTTIType ToBuild; - - /* - ** For building that produce ground units (infantry and vehicles), there is a default - ** exit poit defined. This point is where the object is first placed on the map. - ** Typically, this is located next to a door. The unit will then travel on to a clear - ** terrain area and enter normal game processing. - */ - COORDINATE ExitPoint; - - /* - ** When determine which cell to head toward when exiting a building, use the - ** list elaborated by this variable. There are directions of exit that are - ** more suitable than others. This list is here to inform the system which - ** directions those are. - */ - short const *ExitList; - - /* - ** This is the structure type identifier. It can serve as a unique - ** identification number for building types. - */ - StructType Type; - - /* - ** This is a bitflag that represents which unit types can enter this - ** building. Determine if a unit can enter by taking 1 and shifting it - ** left by the unit type ID. If the corresponding bit is set, then that - ** unit type can enter this building. - */ - unsigned long CanEnter; - - /* - ** This is the starting facing to give this building when it first - ** gets constructed. The facing matches the final stage of the - ** construction animation. - */ - DirType StartFace; - - /* - ** This is the Tiberium storage capacity of the building. The sum of all - ** building's storage capacity is used to determine how much Tiberium can - ** be accumulated. - */ - unsigned Capacity; - - /* - ** Each building type produces and consumes power. These values tell how - ** much. - */ - int Power; - int Drain; - - /* - ** This is the size of the building. This size value is a rough indication - ** of the building's "footprint". - */ - BSizeType Size; - - /********************************************************************** - ** For each stage that a building may be in, its animation is controlled - ** by this structure. It dictates the starting and length of the animation - ** frames needed for the specified state. In addition it specifies how long - ** to delay between changes in animation. With this data it is possible to - ** control the appearance of all normal buildings. Turrets and SAM sites are - ** an exception since their animation is not merely cosmetic. - */ - typedef struct { - int Start; // Starting frame of animation. - int Count; // Number of frames in this animation. - int Rate; // Number of ticks to delay between each frame. - } AnimControlType; - AnimControlType Anims[BSTATE_COUNT]; - - /* - ** This is a mask flag used to determine if all the necessary prerequisite - ** buildings have been built. - */ - // long Prerequisite; - - /*--------------------------------------------------------------------------- - ** This is the building type explicit constructor. - */ - BuildingTypeClass ( - StructType type, - int name, - char const *ininame, - COORDINATE exitpoint, - unsigned char level, - long pre, - bool is_scanner, - bool is_regulated, - bool is_bibbed, - bool is_nominal, - bool is_wall, - bool is_factory, - bool is_capturable, - bool is_flammable, - bool is_simpledamage, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - bool is_theater, - bool is_turret_equipped, - bool is_twoshooter, - bool is_repairable, - bool is_buildable, - bool is_crew, - bool is_sturdy, - RTTIType tobuild, - DirType sframe, - unsigned short strength, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, - WeaponType secondary, - ArmorType armor, - unsigned long canenter, - unsigned capacity, - int power, - int drain, - BSizeType size, - short const *exitlist, - short const *sizelist, - short const *overlap, - bool is_unsellable=false); - virtual RTTIType What_Am_I(void) const {return RTTI_BUILDINGTYPE;}; - operator StructType(void) const {return(Type);}; - - static BuildingTypeClass const & As_Reference(StructType type); - static StructType From_Name(char const *name); - static void Init(TheaterType theater); - static void One_Time(void); - static void Prep_For_Add(void); - - int Width(void) const; - int Height(void) const; - - virtual int Cost_Of(void) const; - virtual int Full_Name(void) const; - virtual COORDINATE Coord_Fixup(COORDINATE coord) const {return coord & 0xFF00FF00L;} - virtual int Max_Pips(void) const; - virtual void Dimensions(int &width, int &height) const; - virtual int Legal_Placement(CELL pos) const; - virtual bool Create_And_Place(CELL cell, HousesType house) const; - virtual ObjectClass * Create_One_Of(HouseClass * house) const; - virtual short const * Occupy_List(bool placement=false) const; - virtual short const * Overlap_List(void) const; - virtual BuildingClass * Who_Can_Build_Me(bool intheory, bool legal, HousesType house) const; - virtual void const * Get_Buildup_Data(void) const {return(BuildupData);}; - - virtual int Raw_Cost(void) const; - virtual int Repair_Cost(void) const; - virtual int Repair_Step(void) const; - bool Bib_And_Offset(SmudgeType & bib, CELL & cell) const; - - #ifdef SCENARIO_EDITOR - virtual void Display(int x, int y, WindowNumberType window, HousesType house) const; - #endif - - - private: - - /* - ** This is a pointer to a list of offsets (from the upper left corner) that - ** are used to indicate the building's "footprint". This footprint is used - ** to determine building placement legality and terrain passibility. - */ - short const *OccupyList; - - /* - ** Buildings can often times overlap a cell but not actually "occupy" it for - ** purposes of movement. This points to a list of offsets that indicate which - ** cells the building has visual overlap but does not occupy. - */ - short const *OverlapList; - - static BuildingTypeClass const * const Pointers[STRUCT_COUNT]; - - /* - ** The construction animation graphic data pointer is - ** pointed to by this element. - */ - void const * BuildupData; - - void Init_Anim(BStateType state, int start, int count, int rate) const; -}; - - -/*************************************************************************** -** The various unit types need specific data that is unique to units as -** opposed to buildings. This derived class elaborates these additional -** data types. -*/ -class UnitTypeClass : public TechnoTypeClass -{ - public: - enum UnitTypeClassRepairEnums { - TIBERIUM_STEP=25, // Credits per step of Tiberium. - STEP_COUNT=28, // Number of steps a harvester can carry. - FULL_LOAD_CREDITS=(TIBERIUM_STEP*STEP_COUNT), - REPAIR_PERCENT=102, // 40% fixed point number. - REPAIR_STEP=4 // Number of damage points recovered per "step". - }; - - /* - ** If this unit can appear out of a crate, then this flag will be true. - */ - unsigned IsCrateGoodie:1; - - /* - ** Does this unit have only 8 facings? Special test units have limited - ** facings. - */ - unsigned IsPieceOfEight:1; - - /* - ** Can this unit squash infantry? If it can then if the player selects - ** an (enemy) infantry unit as the movement target, it will ride over and - ** squish the infantry unit. - */ - unsigned IsCrusher:1; - - /* - ** Does this unit go into harvesting mode when it stops on a tiberium - ** field? Typically, only one unit does this and that is the harvester. - */ - unsigned IsToHarvest:1; - - /* - ** Does this unit's shape data consist of "chunky" facings? This kind of unit - ** art has the unit in only 4 facings (N, W, S, and E) and in each of those - ** directions, the unit's turrets rotates 32 facings (counter clockwise from north). - ** This will result in 32 x 4 = 128 unit shapes in the shape data file. - */ - unsigned IsChunkyShape:1; - - /* - ** Some units are equipped with a rotating radar dish. These units have special - ** animation processing. The rotating radar dish is similar to a turret, but - ** always rotates and does not affect combat. - */ - unsigned IsRadarEquipped:1; - - /* - ** If this unit has a firing animation, this flag is true. Infantry and some special - ** vehicles are the ones with firing animations. - */ - unsigned IsFireAnim:1; - - /* - ** Many vehicles have a turret with restricted motion. These vehicles must move the - ** turret into a locked down position while travelling. Rocket launchers and artillery - ** are good examples of this kind of unit. - */ - unsigned IsLockTurret:1; - - /* - ** Does this unit lay tracks when it travels? Most tracked vehicles and some wheeled - ** vehicles have this ability. - */ - unsigned IsTracked:1; - - /* - ** Is this unit of the humongous size? Harvesters and mobile construction vehicles are - ** of this size. If the vehicle is greater than 24 x 24 but less than 48 x 48, it is - ** considered "Gigundo". - */ - unsigned IsGigundo:1; - - /* - ** Is the unit capable of cloaking? Only Stealth Tank can do so now. - */ - unsigned IsCloakable:1; - - /* - ** Does this unit have a constant animation (like Visceroid?) - */ - unsigned IsAnimating:1; - - /* - ** This value represents the unit class. It can serve as a unique - ** identification number for this unit class. - */ - UnitType Type; - - /* - ** This indicates the speed (locomotion) type for this unit. Through this - ** value the movement capabilities are deduced. - */ - SpeedType Speed; - - /* - ** This is the rotational speed of the unit. This value represents the - ** turret rotation speed. - */ - unsigned char ROT; - - /* - ** This is the distance along the centerline heading in the direction the body - ** is facing used to reach the center point of the turret. This distance is - ** in leptons. - */ - signed char TurretOffset; - - /* - ** This value is used to provide the unit with a default mission order when - ** first created. Usually, this is a resting or idle type of order. - */ - MissionType Mission; - - /* - ** This is the default explosion to use when this vehicle is destroyed. - */ - AnimType Explosion; - - /* - ** The width or height of the largest dimension for this unit. - */ - int MaxSize; - - /* - ** This is the explicit unit class constructor. - */ - UnitTypeClass ( - UnitType type, - int name, - char const *ininame, - AnimType exp, - unsigned char level, - long pre, - bool is_goodie, - bool is_leader, - bool is_eight, - bool is_nominal, - bool is_transporter, - bool is_crushable, - bool is_crusher, - bool is_harvest, - bool is_stealthy, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - bool is_turret_equipped, - bool is_twoshooter, - bool is_repairable, - bool is_buildable, - bool is_crew, - bool is_radar_equipped, - bool is_fire_anim, - bool is_lock_turret, - bool is_tracked, - bool is_gigundo, - bool is_chunky, - bool is_cloakable, - bool is_animating, - int ammo, - unsigned short strength, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, - WeaponType secondary, - ArmorType armor, - SpeedType speed, - MPHType maxSpeed, - unsigned rot, - int toffset, - MissionType order); - virtual RTTIType What_Am_I(void) const {return RTTI_UNITTYPE;}; - - static UnitType From_Name(char const *name); - static UnitTypeClass const & As_Reference(UnitType type); - static void Init(TheaterType ); - static void One_Time(void); - static void Prep_For_Add(void); - - virtual void Dimensions(int &width, int &height) const; - virtual bool Create_And_Place(CELL cell, HousesType house) const; - virtual ObjectClass * Create_One_Of(HouseClass * house) const; - virtual short const * Occupy_List(bool placement=false) const; - virtual BuildingClass * Who_Can_Build_Me(bool intheory, bool legal, HousesType house) const; - virtual int Max_Pips(void) const; - - virtual int Repair_Cost(void) const; - virtual int Repair_Step(void) const; - - #ifdef SCENARIO_EDITOR - virtual void Display(int x, int y, WindowNumberType window, HousesType house) const; - #endif - - /* - ** This is a pointer to the wake shape (as needed by the gunboat). - */ - static void const * WakeShapes; - - private: - static UnitTypeClass const * const Pointers[UNIT_COUNT]; -}; - - -/*************************************************************************** -** The various unit types need specific data that is unique to units as -** opposed to buildings. This derived class elaborates these additional -** data types. -*/ -class InfantryTypeClass : public TechnoTypeClass -{ - private: - static InfantryTypeClass const * const Pointers[INFANTRY_COUNT]; - - public: - - /* - ** If this civilian infantry type is female, then this flag - ** will be true. This information is used to get the correct - ** voice response. - */ - unsigned IsFemale:1; - - /* - ** Does this infantry unit have crawling animation? If not, then this - ** means that the "crawling" frames are actually running animation frames. - */ - unsigned IsCrawling:1; - - /* - ** For those infantry types that can capture buildings, this flag - ** will be set to true. Typically, this is minigun soldiers. - */ - unsigned IsCapture:1; - - /* - ** For infantry types that will run away from any damage causing - ** events, this flag will be true. Typically, this is so for all - ** civilians as well as the flame thrower guys. - */ - unsigned IsFraidyCat:1; - - /* - ** This flags whether this infantry is actually a civilian. A - ** civilian uses different voice responses, has less ammunition, - ** and runs from danger more often. - */ - unsigned IsCivilian:1; - - /* - ** For "fraidycat" infantry types that will run away from any damage causing - ** events, this controls whether they avoid wandering into Tiberium. - */ - unsigned IsAvoidingTiberium:1; - - /* - ** This value represents the unit class. It can serve as a unique - ** identification number for this unit class. - */ - InfantryType Type; - - /* - ** This is an array of the various animation frame data for the actions that - ** the infantry may perform. - */ - DoInfoStruct DoControls[DO_COUNT]; - - /* - ** There are certain units with special animation sequences built into the - ** shape file. These values tell how many frames are used for the firing animation. - */ - char FireLaunch; - char ProneLaunch; - - /* - ** This is the explicit unit class constructor. - */ - InfantryTypeClass ( - InfantryType type, - int name, - char const *ininame, - unsigned char level, - long pre, - bool is_female, - bool is_leader, - bool is_crawling, - bool is_civilian, - bool is_nominal, - bool is_fraidycat, - bool is_capture, - bool is_theater, - int ammo, - int *do_table, - int firelaunch, - int pronelaunch, - unsigned short strength, - int sightrange, - int cost, - int scenario, - int risk, - int reward, - int ownable, - WeaponType primary, - WeaponType secondary, - MPHType maxSpeed); - virtual RTTIType What_Am_I(void) const {return RTTI_INFANTRYTYPE;}; - - static InfantryType From_Name(char const *name); - static InfantryTypeClass const & As_Reference(InfantryType type) {return *Pointers[type];}; - static void Init(TheaterType ); - static void One_Time(void); - static void Prep_For_Add(void); - - virtual void Dimensions(int &width, int &height) const {width = 12;height = 16;}; - virtual bool Create_And_Place(CELL cell, HousesType house) const; - virtual ObjectClass * Create_One_Of(HouseClass * house) const; - virtual short const * Occupy_List(bool placement=false) const; - virtual BuildingClass * Who_Can_Build_Me(bool intheory, bool legal, HousesType house) const; - virtual int Full_Name(void) const; - - #ifdef SCENARIO_EDITOR - virtual void Display(int x, int y, WindowNumberType window, HousesType house) const; - #endif -}; - - -/*************************************************************************** -** Bullets and other projectiles need some specific information according -** to their type. -*/ -class BulletTypeClass : public ObjectTypeClass -{ - public: - - /* - ** Does this bullet type fly over walls? - */ - unsigned IsHigh:1; - - /* - ** If this projecile is one that balistically arcs from ground level, up into the air and - ** then back to the ground, where it explodes. Typical uses of this are for grenades and - ** artillery shells. - */ - unsigned IsArcing:1; - - /* - ** If the projectile changes course as it flies in order to home in on the - ** projectile's target, then this flag is true. Missiles are typically ones - ** that do this. - */ - unsigned IsHoming:1; - - /* - ** Certain projectiles do not travel horizontally, but rather, vertically -- they drop - ** from a height. Bombs fall into this category and will have this value set to - ** true. Dropping projectiles do not calculate collision with terrain (such as walls). - */ - unsigned IsDropping:1; - - /* - ** Is this projectile invisible? Some bullets and weapon effects are not directly - ** rendered. Small caliber bullets and flame thrower flames are treated like - ** normal projectiles for damage purposes, but are displayed using custom - ** rules. - */ - unsigned IsInvisible:1; - - /* - ** Does this bullet explode when near the target? Some bullets only explode if - ** it actually hits the target. Some explode even if nearby. - */ - unsigned IsProximityArmed:1; - - /* - ** Does this projectile spew puffs of smoke out its tail while it - ** travels? Missiles are prime examples of this projectile type. - */ - unsigned IsFlameEquipped:1; - - /* - ** Should fuel consumption be tracked for this projectile? Rockets are the primary - ** projectile with this characteristic, but even for bullets it should be checked so that - ** bullets don't travel too far. - */ - unsigned IsFueled:1; - - /* - ** Is this projectile without different facing visuals? Most plain bullets do not change - ** visual imagery if their facing changes. Rockets, on the other hand, are equipped with - ** the full 32 facing imagery. - */ - unsigned IsFaceless:1; - - /* - ** If this is a typically inaccurate projectile, then this flag will be true. Artillery - ** is a prime example of this type. - */ - unsigned IsInaccurate:1; - - /* - ** If the bullet contains translucent pixels, then this flag will be true. These - ** translucent pixels really are "shadow" pixels in the same style as the shadow - ** cast by regular ground units. - */ - unsigned IsTranslucent:1; - - /* - ** If this bullet can be fired on aircraft, then this flag will be true. - */ - unsigned IsAntiAircraft:1; - - /* - ** This element is a unique identification number for the bullet - ** type. - */ - BulletType Type; - - /* - ** Maximum speed for this bullet type. - */ - MPHType MaxSpeed; - - /* - ** This projectile has a certain style of warhead. This value specifies - ** what that warhead type is. - */ - WarheadType Warhead; - - /* - ** This is the "explosion" effect to use when this projectile impacts - */ - AnimType Explosion; - - /* - ** This is the rotation speed of the bullet. It only has practical value - ** for those projectiles that performing homing action during flight -- such - ** as with rockets. - */ - unsigned char ROT; - - /* - ** Some projectiles have a built in arming distance that must elapse before the - ** projectile may explode. If this value is non-zero, then this override is - ** applied. - */ - int Arming; - - /* - ** Some projectiles have a built in override for distance travelled before it - ** automatically explodes. This value, if non-zero, specifies this distance. - */ - int Range; - - //--------------------------------------------------------------------- - BulletTypeClass( - BulletType type, - char const *ininame, - bool is_high, - bool is_homing, - bool is_arcing, - bool is_dropping, - bool is_invisible, - bool is_proximity_armed, - bool is_flame_equipped, - bool is_fueled, - bool is_faceless, - bool is_inaccurate, - bool is_translucent, - bool is_antiair, - int arming, - int range, - MPHType maxspeed, - unsigned rot, - WarheadType warhead, - AnimType explosion); - - virtual RTTIType What_Am_I(void) const {return RTTI_BULLETTYPE;}; - - static BulletTypeClass const & As_Reference(BulletType type) {return *Pointers[type];}; - static void Init(TheaterType ) {}; - static void One_Time(void); - - virtual bool Create_And_Place(CELL , HousesType =HOUSE_NONE) const {return false;}; - virtual ObjectClass * Create_One_Of(HouseClass *) const {return 0;}; - - private: - static BulletTypeClass const * const Pointers[BULLET_COUNT]; -}; - - -/**************************************************************************** -** These are the different TYPES of terrain objects. Every terrain object must -** be one of these types. -*/ -class TerrainTypeClass : public ObjectTypeClass -{ - public: - /* - ** Which terrain object does this class type represent. - */ - TerrainType Type; - - /* - ** Does this terrain element consist of a normal frame followed by a - ** series of crumble frames? Trees fall under this case. - */ - unsigned IsDestroyable:1; - - /* - ** Does this object have the capability to transform after a period - ** of time (such as a blossom tree? - */ - unsigned IsTransformable:1; - - /* - ** Does this terrain object spawn the growth of Tiberium? Blossom trees are - ** a good example of this. - */ - unsigned IsTiberiumSpawn:1; - - /* - ** This is the fully translated name for the terrain element. - */ - short FullName; - - /* - ** This is the coordinate offset (from upper left) of where the center base - ** position of the terrain object lies. For trees, this would be the base of - ** the trunk. This is used for sorting purposes. - */ - COORDINATE CenterBase; - - /* - ** This is the bitfield control that tells which theater this terrain object is - ** valid for. If the bit (1 << TheaterType) is true, then this terrain object - ** is allowed. - */ - unsigned char Theater; - - //---------------------------------------------------------------- - TerrainTypeClass( - TerrainType terrain, - int theater, - COORDINATE centerbase, - bool is_spawn, - bool is_destroyable, - bool is_transformable, - bool is_flammable, - bool is_crushable, - bool is_selectable, - bool is_legal_target, - bool is_insignificant, - bool is_immune, - char const *ininame, - int fullname, - unsigned short strength, - ArmorType armor, - short const *occupy, - short const *overlap); - virtual RTTIType What_Am_I(void) const {return RTTI_TERRAINTYPE;}; - - static TerrainType From_Name(char const*name); - static TerrainTypeClass const & As_Reference(TerrainType type) {return *Pointers[type];}; - static void Init(TheaterType theater = THEATER_TEMPERATE); - static void One_Time(void) {}; - static void Prep_For_Add(void); - - virtual COORDINATE Coord_Fixup(COORDINATE coord) const {return coord & 0xFF00FF00L;} - virtual bool Create_And_Place(CELL cell, HousesType house) const; - virtual ObjectClass * Create_One_Of(HouseClass *) const; - virtual short const * Occupy_List(bool placement=false) const; - virtual short const * Overlap_List(void) const; - - #ifdef SCENARIO_EDITOR - virtual void Display(int x, int y, WindowNumberType window, HousesType house=HOUSE_NONE) const; - #endif - - private: - short const *Occupy; - short const *Overlap; - - static TerrainTypeClass const * const Pointers[TERRAIN_COUNT]; -}; - - -/**************************************************************************** -** The tile type objects are controlled by this class. It specifies the form -** of the tile set for the specified object as well as other related datum. -** It is derived from the ObjectTypeClass solely for the purpose of scenario -** editing and creation. -*/ -class TemplateTypeClass: public ObjectTypeClass -{ - public: - /* - ** What template is this. - */ - TemplateType Type; - - /* - ** A bitfield container that indicates which theaters this template is allowed - ** in. A bit set in the (1<IniName, name) == 0) { - return(classid); - } - } - } - return(UNIT_NONE); -} - - -#ifdef SCENARIO_EDITOR -/*********************************************************************************************** - * UnitTypeClass::Display -- Displays a generic unit shape. * - * * - * This routine displays a generic representation of a unit of this * - * type. Typically, it is used when adding objects to the game map. * - * * - * INPUT: x,y -- Coordinate to render the unit shape. * - * * - * window-- Window to render within. * - * * - * house -- House to render the unit colors. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/14/1994 JLB : Created. * - * 11/08/1994 JLB : Handles chunky type vehicles now. * - *=============================================================================================*/ -void UnitTypeClass::Display(int x, int y, WindowNumberType window, HousesType house) const -{ - int shape = 0; - void const * ptr = Get_Cameo_Data(); - if (!ptr) { - ptr = Get_Image_Data(); - shape = IsChunkyShape ? 0 : 5; - } - CC_Draw_Shape(ptr, shape, x, y, window, SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL, HouseTypeClass::As_Reference(house).RemapTable); -} - - -/*********************************************************************************************** - * UnitTypeClass::Prep_For_Add -- Prepares scenario editor to add unit. * - * * - * This routine is used to prepare the generic object adder dialog * - * box so that it will be able to add a unit object. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1994 JLB : Created. * - * 06/04/1994 JLB : Uses map editing interface functions. * - *=============================================================================================*/ -void UnitTypeClass::Prep_For_Add(void) -{ - for (UnitType index = UNIT_FIRST; index < UNIT_COUNT; index++) { - if (As_Reference(index).Get_Image_Data() != NULL) { - Map.Add_To_List(&As_Reference(index)); - } - } -} -#endif - - -/*********************************************************************************************** - * UnitTypeClass::One_Time -- Performs one time processing for unit type class objects. * - * * - * This routine is used to perform the action necessary only once for the unit type class. * - * It loads unit shapes and brain files. This routine should only be called once. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: Only call this routine once. * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void UnitTypeClass::One_Time(void) -{ - for (UnitType index = UNIT_FIRST; index < UNIT_COUNT; index++) { - char fullname[_MAX_FNAME+_MAX_EXT]; - char buffer[_MAX_FNAME]; - UnitTypeClass const & uclass = As_Reference(index); - CCFileClass file; - int largest; // Largest dimension of shape (so far). - - void const *ptr = NULL; // Shape pointer and set pointer. - - largest = 0; - if (uclass.IsBuildable) { - - /* - ** Fetch the supporting data files for the unit. - */ - if ( Get_Resolution_Factor() ) { - sprintf(buffer, "%sICNH", uclass.IniName); - } else { - sprintf(buffer, "%sICON", uclass.IniName); - } - _makepath(fullname, NULL, NULL, buffer, ".SHP"); - ((void const *&)uclass.CameoData) = MixFileClass::Retrieve(fullname); - } - - /* - ** Fetch a pointer to the unit's shape data. - */ - // Assume funpark mode might be required. ST - 10/14/2019 11:53AM - //if (!uclass.IsPieceOfEight || (Special.IsJurassic && AreThingiesEnabled) ) { - _makepath(fullname, NULL, NULL, uclass.IniName, ".SHP"); - ptr = MixFileClass::Retrieve(fullname); - //} else { - // ptr = NULL; - //} - -#ifdef PETROGLYPH_EXAMPLE_MOD - /* - ** Need some kind of shape data for our modded unit - */ - if (index == UNIT_NUKE_TANK && ptr == NULL) { - _makepath(fullname, NULL, NULL, "HTNK", ".SHP"); - ptr = MixFileClass::Retrieve(fullname); - } -#endif //PETROGLYPH_EXAMPLE_MOD - - ((void const *&)uclass.ImageData) = ptr; - if (ptr) { - - if (index == UNIT_MLRS || index == UNIT_MSAM) { - largest = 26; - } else { - largest = MAX(largest, (int)Get_Build_Frame_Width(ptr)); - largest = MAX(largest, (int)Get_Build_Frame_Height(ptr)); - } - } - - ((int &)uclass.MaxSize) = MAX(largest, 8); - } - - /* - ** Load the wake shapes in at this time. - */ - if (!WakeShapes) { - WakeShapes = MixFileClass::Retrieve("WAKE.SHP"); - } -} - - - -/*********************************************************************************************** - * UTC::Init -- fetches the sidebar icons for the unittypeclass objects * - * * - * * - * * - * INPUT: theater type * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 4/26/96 4:07PM ST : Created * - *=============================================================================================*/ - -void UnitTypeClass::Init(TheaterType theater) -{ - - if (Get_Resolution_Factor()){ - - if (theater != LastTheater){ - - void const * cameo_ptr; - char fullname[_MAX_FNAME+_MAX_EXT]; - char buffer[_MAX_FNAME]; - - for (UnitType index = UNIT_FIRST; index < UNIT_COUNT; index++) { - - UnitTypeClass const & uclass = As_Reference(index); - - ((void const *&)uclass.CameoData) = NULL; - - if (uclass.IsBuildable) { - sprintf(buffer, "%sICNH", uclass.IniName); - _makepath(fullname, NULL, NULL, buffer, Theaters[theater].Suffix); - cameo_ptr = MixFileClass::Retrieve(fullname); - if (cameo_ptr){ - ((void const *&)uclass.CameoData) = cameo_ptr; - } - } - } - } - } -} - - -/*********************************************************************************************** - * UnitTypeClass::Create_And_Place -- Creates and places a unit object onto the map. * - * * - * This routine is used by the scenario editor to create and place a unit object of this * - * type onto the map. * - * * - * INPUT: cell -- The cell that the unit is to be placed into. * - * * - * house -- The house that the unit belongs to. * - * * - * OUTPUT: bool; Was the unit created and placed successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitTypeClass::Create_And_Place(CELL cell, HousesType house) const -{ - UnitClass * unit = new UnitClass(Type, house); - if (unit) { - return(unit->Unlimbo(Cell_Coord(cell), Random_Pick(DIR_N, DIR_MAX))); - } - return(false); -} - - -/*********************************************************************************************** - * UnitTypeClass::Create_One_Of -- Creates a unit in limbo. * - * * - * This function creates a unit of this type and keeps it in limbo. A pointer to the * - * created unit object is returned. It is presumed that this object will later be * - * unlimboed at the correct time and place. * - * * - * INPUT: house -- Pointer to the house that is to own the unit. * - * * - * OUTPUT: Returns with a pointer to the created unit object. If the unit object * - * could not be created, then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/07/1994 JLB : Created. * - *=============================================================================================*/ -ObjectClass * UnitTypeClass::Create_One_Of(HouseClass * house) const -{ - return(new UnitClass(Type, house->Class->House)); -} - - -/*********************************************************************************************** - * UnitTypeClass::Who_Can_Build_Me -- Determines which factory can build this unit type. * - * * - * Use this routine to examine the buildings on the map in order to determine which one * - * can build the unit type. * - * * - * INPUT: intheory -- If this parameter is true, then no examination of whether the factory * - * is currently busy is performed. It just checks to see if the unit * - * could be produced "in theory". * - * * - * legal -- Should building prerequisite legality checks be performed as well? * - * For building placements, this is usually false. For sidebar button * - * adding, this is usually true. * - * * - * house -- The owner of the unit to be produced. * - * * - * OUTPUT: Returns with pointer to the factory that can produce the unit. If no suitable * - * factory could be found then NULL is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/12/1994 JLB : Created. * - *=============================================================================================*/ -BuildingClass * UnitTypeClass::Who_Can_Build_Me(bool intheory, bool legal, HousesType house) const -{ - BuildingClass * anybuilding = NULL; - - for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass * building = Buildings.Ptr(index); - - if (building && - !building->IsInLimbo && - building->House->Class->House == house && - building->Class->ToBuild == RTTI_UNITTYPE && - building->Mission != MISSION_DECONSTRUCTION && - ((1L << building->ActLike) & Ownable) && - (!legal || building->House->Can_Build(Type, building->ActLike)) && - (intheory || !building->In_Radio_Contact())) { - - if (building->IsLeader) return(building); - anybuilding = building; - } - } - return(anybuilding); -} - - -/*********************************************************************************************** - * UnitTypeClass::As_Reference -- Fetches a reference to the unit type class specified. * - * * - * Use this routine to return a reference to the UnitTypeClass object as indicated by * - * the unit type number speicified. * - * * - * INPUT: type -- The unit type number to convert into a UnitTypeClass object reference. * - * * - * OUTPUT: Returns with a reference to the unit type class object specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -UnitTypeClass const & UnitTypeClass::As_Reference(UnitType type) -{ - return(*Pointers[type]); -} - - -/*********************************************************************************************** - * UnitTypeClass::Dimensions -- Determines the unit's pixel dimensions. * - * * - * This routine will fill in the width and height for this unit type. This width and * - * height are used to render the selection rectangle and the positioning of the health * - * bargraph. * - * * - * INPUT: width -- Reference to the width of the unit (to be filled in). * - * * - * height -- Reference to the height of the unit (to be filled in). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/23/1995 JLB : Created. * - *=============================================================================================*/ -void UnitTypeClass::Dimensions(int &width, int &height) const -{ - if (Type == UNIT_GUNBOAT) { - width = 46; - height = 18; - } else { - width = MaxSize-(MaxSize/4); - height = MaxSize-(MaxSize/4); - } -} - -/*********************************************************************************************** - * UnitTypeClass::Repair_Cost -- Determines cost per "step" of repair. * - * * - * Use this routine to determine how much it will cost to repair the unit one * - * step. A step is defined as the number of hit points returned from the Repair_Step() * - * function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the credit cost to repair this unit one step. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/03/1995 BWG : Created. * - *=============================================================================================*/ -int UnitTypeClass::Repair_Cost(void) const -{ - return(Fixed_To_Cardinal(Cost/(MaxStrength/REPAIR_STEP), REPAIR_PERCENT)); -} - - -/*********************************************************************************************** - * UnitTypeClass::Repair_Step -- Determines the repair step rate. * - * * - * This routine will determine how many strength points get healed for each "step". The * - * cost to repair one step is determine from the Repair_Cost() function. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of health points repaired for each "step". * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/03/1995 BWG : Created. * - *=============================================================================================*/ -int UnitTypeClass::Repair_Step(void) const -{ - return(REPAIR_STEP); -} - - -/*********************************************************************************************** - * UnitTypeClass::Max_Pips -- Fetches the maximum pips allowed for this unit. * - * * - * This routine will determine the number of pips (maximum) allowed for this unit type. * - * Typically, this is the number of passengers allowed, but for harvesters, it is the * - * number of credits it holds divided by 100. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the maximum number of pips allowed for this unit type. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/26/1995 JLB : Created. * - *=============================================================================================*/ -int UnitTypeClass::Max_Pips(void) const -{ - if (Type == UNIT_HARVESTER) { - return(FULL_LOAD_CREDITS/100); - } - - if (IsTransporter) { - return(Max_Passengers()); - } - return(0); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/UNIT.CPP b/code/TIBERIANDAWN/UNIT.CPP deleted file mode 100644 index 8cf678d..0000000 --- a/code/TIBERIANDAWN/UNIT.CPP +++ /dev/null @@ -1,4338 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\unit.cpv 2.17 16 Oct 1995 16:48:28 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : UNIT.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 10, 1993 * - * * - * Last Update : August 16, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * Recoil_Adjust -- Adjust pixel values in direction specified. * - * Turret_Adjust -- Turret adjustment routine for MLRS and MSAM units. * - * UnitClass::AI -- AI processing for the unit. * - * UnitClass::APC_Close_Door -- Closes an APC door. * - * UnitClass::APC_Open_Door -- Opens an APC door. * - * UnitClass::Active_Click_With -- Intercepts the active click to see if deployment is possib* - * UnitClass::As_Target -- Returns the unit as a target value. * - * UnitClass::Blocking_Object -- Determines how a object blocks a unit * - * UnitClass::Can_Enter_Building -- Determines building entry legality. * - * UnitClass::Can_Fire -- Determines if this unit can fire. * - * UnitClass::Can_Player_Move -- Determines if the player is legally allowed to move it. * - * UnitClass::Click_With -- Handles player map clicking while this unit is selected. * - * UnitClass::Crew_Type -- Fetches the kind of crew that this object produces. * - * UnitClass::Debug_Dump -- Displays the status of the unit to the mono monitor. * - * UnitClass::Desired_Load_Dir -- Determines the best cell and facing for loading. * - * UnitClass::Draw_It -- Draws a unit object. * - * UnitClass::Enter_Idle_Mode -- Unit enters idle mode state. * - * UnitClass::Find_LZ -- Maintenance function for transport units. * - * UnitClass::Flag_Attach -- Attaches a house flag to this unit. * - * UnitClass::Flag_Remove -- Removes the house flag from this unit. * - * UnitClass::Goto_Clear_Spot -- Finds a clear spot to deploy. * - * UnitClass::Goto_Tiberium -- Search for and head toward nearest available Tiberium patch. * - * UnitClass::Harvesting -- Harvests tiberium at the current location. * - * UnitClass::Init -- Clears all units for scenario preparation. * - * UnitClass::Limbo -- Prepares vehicle and then limbos it. * - * UnitClass::Look -- Perform map revelation from a unit's position. * - * UnitClass::Mission_Attack -- Handles the mission attack logic. * - * UnitClass::Mission_Guard -- Special guard mission override processor. * - * UnitClass::Mission_Harvest -- Handles the harvesting process used by harvesters. * - * UnitClass::Mission_Hunt -- This is the AI process for aggressive enemy units. * - * UnitClass::Mission_Move -- Handles special move mission overrides. * - * UnitClass::Mission_Unload -- Handles unloading cargo. * - * UnitClass::Overlap_List -- Determines overlap list for units. * - * UnitClass::Per_Cell_Process -- Performs operations necessary on a per cell basis. * - * UnitClass::Pip_Count -- Fetchs the number of pips to display on unit. * - * UnitClass::Random_Animate -- Handles random idle animation for the unit. * - * UnitClass::Read_INI -- Reads units from scenario INI file. * - * UnitClass::Receive_Message -- Handles receiving a radio message. * - * UnitClass::Remap_Table -- Fetches the remap table to use for this object. * - * UnitClass::Response_Attack -- Voice feedback when ordering the unit to attack a target. * - * UnitClass::Response_Move -- Voice feedback when ordering the unit to move. * - * UnitClass::Response_Select -- Voice feedback when selecting the unit. * - * UnitClass::Scatter -- Causes the unit to travel to a nearby safe cell. * - * UnitClass::Set_Speed -- Initiate unit movement physics. * - * UnitClass::Sort_Y -- Give Y coordinate sort value for unit. * - * UnitClass::Start_Driver -- Starts driving and reserves destination cell. * - * UnitClass::Stop_Driver -- Handles removing occupation bits when driving stops. * - * UnitClass::Stun -- Stuns the unit in preparation for unit removal. * - * UnitClass::Take_Damage -- Inflicts damage points on a unit. * - * UnitClass::Target_Coord -- The coordinate to use when targeting this unit. * - * UnitClass::Try_To_Deploy -- The unit attempts to "deploy" at current location. * - * UnitClass::UnitClass -- Constructor for units. * - * UnitClass::Unlimbo -- Removes unit from stasis. * - * UnitClass::Unload_Hovercraft_Process -- Handles unloading hovercraft transport. * - * UnitClass::Validate -- validates unit pointer. * - * UnitClass::What_Action -- Determines what action would occur if clicked on object. * - * UnitClass::What_Am_I -- Returns with the RTTI type this object is. * - * UnitClass::Write_INI -- Writes all the units out to an INI file. * - * UnitClass::delete -- Deletion operator for units. * - * UnitClass::new -- Allocate a unit slot and adjust access arrays. * - * UnitClass::~UnitClass -- Destructor for unit objects. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" - -/* -** This contains the value of the Virtual Function Table Pointer -*/ -void * UnitClass::VTable; - - -/*********************************************************************************************** - * UnitClass::Validate -- validates unit pointer. * - * * - * INPUT: * - * none. * - * * - * OUTPUT: * - * 1 = ok, 0 = error * - * * - * WARNINGS: * - * none. * - * * - * HISTORY: * - * 08/09/1995 BRR : Created. * - *=============================================================================================*/ -#ifdef CHEAT_KEYS -int UnitClass::Validate(void) const -{ - int num; - - num = Units.ID(this); - if (num < 0 || num >= UNIT_MAX) { - Validate_Error("UNIT"); - return (0); - } - else - return (1); -} -#else -#define Validate() -#endif - - -/*********************************************************************************************** - * Recoil_Adjust -- Adjust pixel values in direction specified. * - * * - * This is a helper routine that modifies the pixel coordinates provided according to the * - * direction specified. The effect is the simulate recoil effects by moving an object 'back'* - * one pixel. Since the pixels moved depend on facing, this routine handles the pixel * - * adjustment quickly. * - * * - * INPUT: dir -- The direction to base the recoil on. * - * * - * x,y -- References to the pixel coordinates that will be adjusted. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void Recoil_Adjust(DirType dir, int &x, int &y) -{ - static struct { - signed char X,Y; - } _adjust[32] = { - {0,1}, // N - {0,1}, - {0,1}, - {-1,1}, - {-1,1}, // NE - {-1,1}, - {-1,0}, - {-1,0}, - {-1,0}, // E - {-1,0}, - {-1,-1}, - {-1,-1}, - {-1,-1}, // SE - {-1,-1}, - {-1,-1}, - {0,-1}, - {0,-1}, // S - {0,-1}, - {0,-1}, - {1,-1}, - {1,-1}, // SW - {1,-1}, - {1,0}, - {1,0}, - {1,0}, // W - {1,0}, - {1,1}, - {1,1}, - {1,1}, // NW - {1,1}, - {0,1}, - {0,1} - }; - - int index = Facing_To_32(dir); - x += _adjust[index].X; - y += _adjust[index].Y; -} - - -/*********************************************************************************************** - * Turret_Adjust -- Turret adjustment routine for MLRS and MSAM units. * - * * - * This routine adjusts the pixel coordinates specified to account for the displacement of * - * the turret on the MLRS and MSAM vehicles. * - * * - * INPUT: dir -- The direction of the body of the vehicle. * - * * - * x,y -- References to the turret center pixel position. These will be modified as * - * necessary. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -void Turret_Adjust(DirType dir, int &x, int &y) -{ - static struct { - signed char X,Y; - } _adjust[32] = { - {1,2}, // N - {-1,1}, - {-2,0}, - {-3,0}, - {-3,1}, // NW - {-4,-1}, - {-4,-1}, - {-5,-2}, - {-5,-3}, // W - {-5,-3}, - {-3,-3}, - {-3,-4}, - {-3,-4}, // SW - {-3,-5}, - {-2,-5}, - {-1,-5}, - {0,-5}, // S - {1,-6}, - {2,-5}, - {3,-5}, - {4,-5}, // SE - {6,-4}, - {6,-3}, - {6,-3}, - {6,-3}, // E - {5,-1}, - {5,-1}, - {4,0}, - {3,0}, // NE - {2,0}, - {2,1}, - {1,2} - }; - - int index = Facing_To_32(dir); - x += _adjust[index].X; - y += _adjust[index].Y; -} - - -/*********************************************************************************************** - * UnitClass::As_Target -- Returns the unit as a target value. * - * * - * This routine will convert the unit into a target value that is then returned. Target * - * values are typically used for navigation and other computer uses. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with target value of unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -TARGET UnitClass::As_Target(void) const -{ - Validate(); - return(Build_Target(KIND_UNIT, Units.ID(this))); -} - - -#ifdef CHEAT_KEYS -/*********************************************************************************************** - * UnitClass::Debug_Dump -- Displays the status of the unit to the mono monitor. * - * * - * This displays the current status of the unit class to the mono monitor. By this display * - * bugs may be tracked down or prevented. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/02/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Debug_Dump(MonoClass *mono) const -{ - Validate(); - mono->Set_Cursor(0, 0); - mono->Print( - "ÚName:ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂMission:ÄÄÄÂTarCom:ÂNavCom:ÂRadio:ÂCoord:ÄÄÂHeadTo:ÄÂSt:Ä¿\n" - "³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂNÂYÂHealth:ÄÂBody:ÂTurret:ÂSpeed:ÂPath:ÁÄÄÄÄÄÄÂCargo:ÄÄÄÄÁÄÄÄÄ´\n" - "³Active........³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Limbo.........³ ³ ÃÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n" - "³Owned.........³ ³ ³Last Message: ³\n" - "³Discovered....³ ³ ÃTimer:ÂArm:ÂTrack:ÂTiberium:ÂFlash:ÂStage:ÂTeam:ÄÄÄÄÂArch:´\n" - "³Selected......³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³\n" - "³Teathered.....³ ³ ÃÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÙ\n" - "³Locked on Map.³ ³ ³ \n" - "³Turret Locked.³ ³ ³ \n" - "³Is A Loaner...³ ³ ³ \n" - "³Deploying.....³ ³ ³ \n" - "³Rotating......³ ³ ³ \n" - "³Firing........³ ³ ³ \n" - "³Driving.......³ ³ ³ \n" - "³To Look.......³ ³ ³ \n" - "³Recoiling.....³ ³ ³ \n" - "³To Display....³ ³ ³ \n" - "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÙ \n"); - mono->Set_Cursor(1, 1);mono->Printf("%s:%s", House->Class->IniName, Class->IniName); - CargoClass::Debug_Dump(mono); - MissionClass::Debug_Dump(mono); - TarComClass::Debug_Dump(mono); -} -#endif - - -/*********************************************************************************************** - * UnitClass::Sort_Y -- Give Y coordinate sort value for unit. * - * * - * This routine is used by the rendering system in order to sort the * - * game objects in a back to front order. This is now the correct * - * overlap effect is achieved. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a coordinate value that can be used for sorting. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/17/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE UnitClass::Sort_Y(void) const -{ - Validate(); - if (IsTethered && *this == UNIT_HOVER) { - return(Coord_Add(Coord, 0xFF800000L)); - } - return(Coord_Add(Coord, 0x00800000L)); -} - - -/*********************************************************************************************** - * UnitClass::AI -- AI processing for the unit. * - * * - * This routine will perform the AI processing necessary for the unit. These are non- * - * graphic related operations. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::AI(void) -{ - Validate(); - - /* - ** Act on new orders if the unit is at a good position to do so. - */ - if (!IsDriving && Is_Door_Closed() /*Mission != MISSION_UNLOAD*/) { - Commence(); - } - - TarComClass::AI(); - - /* - ** Delete this unit if it finds itself off the edge of the map and it is in - ** guard or other static mission mode. - */ - if (!Team && Mission == MISSION_GUARD && !Map.In_Radar(Coord_Cell(Coord))) { - Stun(); - Delete_This(); - return; - } - - /* - ** Rocket launchers will reload every so often. - */ - if (*this == UNIT_MSAM && Ammo < Class->MaxAmmo) { - if (IsDriving) { - Reload = Reload + 1; - } else { - if (Reload.Expired()) { - Ammo++; - if (Ammo < Class->MaxAmmo) { - Reload = TICKS_PER_SECOND*30; - } - Mark(MARK_CHANGE); - } - } - } - - /* - ** Hover landers always are flagged to redraw since they don't record themselves - ** on the map in the normal fashion. - */ - if (*this == UNIT_HOVER) { -// Mark_For_Redraw(); -//if (IsDown) Mono_Printf("*"); - Mark(MARK_CHANGE); - } - - /* - ** If this is a vehicle that heals itself (e.g., Mammoth Tank), then it will perform - ** the heal logic here. - */ - if (*this == UNIT_HTANK && (Frame % 16) == 0 && Health_Ratio() < 0x0080) { - Strength++; - Mark(MARK_CHANGE); - } - if (*this == UNIT_VICE && Map[Coord_Cell(Coord)].Land_Type() == LAND_TIBERIUM && Health_Ratio() < 0x0100 && (Frame % 16) == 0) { - Strength++; - Mark(MARK_CHANGE); - } - - /* - ** Transporters require special logic handled here since there isn't a MISSION_WAIT_FOR_PASSENGERS - ** mission that they can follow. Passenger loading is merely a part of their normal operation. - */ - if (Class->IsTransporter) { - - /* - ** Double check that there is a passenger that is trying to load or unload. - ** If not, then close the door. - */ - if (!Is_Door_Closed() && Mission != MISSION_UNLOAD && Transmit_Message(RADIO_TRYING_TO_LOAD) != RADIO_ROGER) { - APC_Close_Door(); - } - } - - /* - ** Don't start a new mission unless the vehicle is in the center of - ** a cell (not driving) and the door (if any) is closed. - */ - if (!IsDriving && Is_Door_Closed()/*&& Mission != MISSION_UNLOAD*/) { - Commence(); - } - - /* - ** Handle recoil recovery here. - */ - if (IsInRecoilState) { - IsInRecoilState = false; - Mark(MARK_CHANGE); - } - - /* - ** For animating objects such as Visceroids, max-out their animation - ** stages here - */ - if (Class->IsAnimating) { - if (!Fetch_Rate()) Set_Rate(2); - StageClass::Graphic_Logic(); - if (Fetch_Stage() >= Get_Build_Frame_Count(Class->Get_Image_Data())-1) { - Set_Stage(0); - } - } - - /* - ** for Jurassic objects, animate them if they're walking - */ - // Assume funpark mode might be required. ST - 10/14/2019 11:53AM - if (Class->IsPieceOfEight) { // && Special.IsJurassic && AreThingiesEnabled) { - // Only animate if they're walking - if (IsDriving || IsFiring) { - if (!Fetch_Rate()) { - Set_Rate(Options.Normalize_Delay(2)); - Set_Stage(0); - } - StageClass::Graphic_Logic(); - if (Fetch_Stage() >= ( (IsDriving || *this == UNIT_TREX || *this == UNIT_RAPT) ? 8 : 12) ) { - Set_Stage(0); - if (IsFiring) { - Set_Rate(0); - IsFiring = false; - } - } - } - } - - /* - ** A cloaked object that is carrying the flag will always shimmer. - */ - if (Cloak == CLOAKED && Flagged != HOUSE_NONE) { - Do_Shimmer(); - } - -} - - -/*********************************************************************************************** - * UnitClass::Can_Fire -- Determines if this unit can fire. * - * * - * INPUT: target -- The target that is desired to fire upon. * - * * - * which -- The weapon (primary=0, secondary=1) to fire. * - * * - * OUTPUT: Returns with the fire error number if it cannot fire or else FIRE_OK. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - *=============================================================================================*/ -FireErrorType UnitClass::Can_Fire(TARGET target, int which) const -{ - Validate(); - FireErrorType cf; - - cf = TarComClass::Can_Fire(target, which); - if (cf == FIRE_OK) { - - /* - ** If it's a dinosaur, when it's OK to fire we should start the firing - ** animation, but wait for the proper attack stage before starting the - ** bullet, so things won't die prematurely. - */ - if (Class->IsFireAnim) { - if (!IsFiring) { - UnitClass *nonconst; - - nonconst = (UnitClass *)this; - nonconst->Set_Rate(Options.Normalize_Delay(2)); - nonconst->Set_Stage(0); -// Cast out the const. ST - 12/18/2018 1:03PM -((UnitClass*)this)->IsFiring = true; - cf = FIRE_BUSY; - } else { - if (Fetch_Stage() < 4) cf = FIRE_BUSY; - } - } - } - return(cf); -} - - -/*********************************************************************************************** - * UnitClass::Receive_Message -- Handles receiving a radio message. * - * * - * This is the handler function for when a unit receives a radio * - * message. Typical use of this is when a unit unloads from a hover * - * class so that clearing of the transport is successful. * - * * - * INPUT: from -- Pointer to the originator of the message. * - * * - * message -- The radio message received. * - * * - * param -- Reference to an optional parameter the might be needed to return * - * information back to the originator of the message. * - * * - * OUTPUT: Returns with the radio message response. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1994 JLB : Created. * - *=============================================================================================*/ -RadioMessageType UnitClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param) -{ - Validate(); - switch (message) { - - /* - ** Checks to see if this object is in need of service depot processing. - */ - case RADIO_NEED_REPAIR: - if (!IsDriving && !Target_Legal(NavCom) && Health_Ratio() >= 0x100) return(RADIO_NEGATIVE); - break; - - /* - ** Asks if the passenger can load on this transport. - */ - case RADIO_CAN_LOAD: - if (Class->IsTransporter && How_Many() < Class->Max_Passengers() && from && House->Class->House == from->Owner()) { - return(RADIO_ROGER); - } - return(RADIO_NEGATIVE); - - /* - ** The refinery has told this harvester that it should begin the backup procedure - ** so that proper unloading may take place. - */ - case RADIO_BACKUP_NOW: - TarComClass::Receive_Message(from, message, param); - if (!IsRotating && PrimaryFacing != DIR_SW) { - Do_Turn(DIR_SW); - } else { - if (!IsDriving) { - Force_Track(BACKUP_INTO_REFINERY, Adjacent_Cell(Center_Coord(), FACING_N)); - Set_Speed(128); - } - } - return(RADIO_ROGER); - - /* - ** This message is sent by the passenger when it determines that it has - ** entered the transport. - */ - case RADIO_IM_IN: - if (How_Many() == Class->Max_Passengers()) { - APC_Close_Door(); - } - return(RADIO_ATTACH); - - /* - ** Docking maintenance message received. Check to see if new orders should be given - ** to the impatient unit. - */ - case RADIO_DOCKING: - - /* - ** Check for the case of a docking message arriving from a unit that does not - ** have formal radio contact established. This might be a unit that is standing - ** by. If this transport is free to proceed with normal docking operation, then - ** establish formal contact now. If the transport is completely full, then break - ** off contact. In all other cases, just tell the pending unit to stand by. - */ - if (Contact_With_Whom() != from) { - - /* - ** Can't ever load up so tell the passenger to bug off. - */ - if (How_Many() >= Class->Max_Passengers()) { - return(RADIO_NEGATIVE); - } - - /* - ** Establish contact and let the loading process proceed normally. - */ - if (!In_Radio_Contact()) { - Transmit_Message(RADIO_HELLO, from); - } else { - - /* - ** This causes the potential passenger to think that all is ok and to - ** hold on for a bit. - */ - return(RADIO_ROGER); - } - } - - if (Class->IsTransporter && *this == UNIT_APC && How_Many() < Class->Max_Passengers()) { - TarComClass::Receive_Message(from, message, param); - - /* - ** Check if the APC is busy with an order - */ - bool is_busy = Mission == MISSION_MOVE; - - if ((!IsRotating || Target_Legal(TarCom)) && !IsTethered) { - - /* - ** If the potential passenger needs someplace to go, then figure out a good - ** spot and tell it to go. - */ - if (Transmit_Message(RADIO_NEED_TO_MOVE, from) == RADIO_ROGER) { - - /* - ** If the unit has a target, don't bother with turning logic - */ - CELL cell; - DirType dir; - if (Target_Legal(TarCom)) { - dir = PrimaryFacing.Current(); - cell = Adjacent_Cell(Coord_Cell(Coord), Direction(from)); - } - else { - dir = Desired_Load_Dir(from, cell); - } - - /* - ** If no adjacent free cells are detected, then passenger loading - ** cannot occur. Break radio contact. - */ - if (cell == 0) { - Transmit_Message(RADIO_OVER_OUT, from); - } else { - param = (long)::As_Target(cell); - - if (!is_busy && !IsDriving) { - Do_Turn(dir); - - /* - ** If it is now facing the correct direction, then open the - ** transport doors. Close the doors if the transport is or needs - ** to rotate. - */ - if (IsRotating) { - if (!Is_Door_Closed()) { - APC_Close_Door(); - } - } else { - if (!Is_Door_Open()) { - APC_Open_Door(); - } - } - } - - /* - ** Tell the potential passenger where it should go. If the passenger is - ** already at the staging location, then tell it to move onto the transport - ** directly. - */ - if (Transmit_Message(RADIO_MOVE_HERE, param, from) == RADIO_YEA_NOW_WHAT) { - if (Is_Door_Open() || Target_Legal(TarCom)) { - param = (long)As_Target(); - Transmit_Message(RADIO_TETHER); - if (Transmit_Message(RADIO_MOVE_HERE, param, from) != RADIO_ROGER) { - Transmit_Message(RADIO_OVER_OUT, from); - } else { - Contact_With_Whom()->Unselect(); - } - } - } - } - } - } - return(RADIO_ROGER); - } - break; - - /* - ** When this message is received, it means that the other object - ** has already turned its radio off. Turn this radio off as well. - */ - case RADIO_OVER_OUT: - if (Mission == MISSION_RETURN) { - Assign_Mission(MISSION_GUARD); - } - TarComClass::Receive_Message(from, message, param); - return(RADIO_ROGER); - - } - return(TarComClass::Receive_Message(from, message, param)); -} - - -/*********************************************************************************************** - * UnitClass::Unlimbo -- Removes unit from stasis. * - * * - * This routine will place a unit into the game and out of its limbo * - * state. This occurs whenever a unit is unloaded from a transport. * - * * - * INPUT: coord -- The coordinate to make the unit appear. * - * * - * dir -- The initial facing to impart upon the unit. * - * * - * OUTPUT: bool; Was the unit unlimboed successfully? If the desired * - * coordinate is illegal, then this might very well return * - * false. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Unlimbo(COORDINATE coord, DirType dir) -{ - Validate(); - /* - ** All units must start out facing one of the 8 major directions. - */ - dir = Facing_Dir(Dir_Facing(dir)); - - if (TarComClass::Unlimbo(coord, dir)) { - - /* - ** Ensure that the owning house knows about the - ** new object. - */ - House->UScan |= (1L << Class->Type); - House->ActiveUScan |= (1L << Class->Type); - - /* - ** If it starts off the edge of the map, then it already starts cloaked. - */ - if (IsCloakable && !IsLocked) Cloak = CLOAKED; - - /* - ** Units default to no special animation. - */ - Set_Rate(0); - Set_Stage(0); - - /* - ** A gun boat and a hover craft are allowed to exit the map thus we - ** flag them so they can. This undoes the work of Techno::Unlimbo which - ** stole their IsALoaner flag. - */ - if (*this == UNIT_GUNBOAT || *this == UNIT_HOVER) { - IsALoaner = true; - } - - /* - ** Start the gunboat animating when it is unlimboed. - */ - if (*this == UNIT_GUNBOAT) { - Set_Rate(2); - Set_Stage(0); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Take_Damage -- Inflicts damage points on a unit. * - * * - * This routine will inflict the specified number of damage points on * - * the given unit. If the unit is destroyed, then this routine will * - * remove the unit cleanly from the game. The return value indicates * - * whether the unit was destroyed. This will allow appropriate death * - * animation or whatever. * - * * - * INPUT: damage-- The number of damage points to inflict. * - * * - * distance -- The distance from the damage center point to the object's center point.* - * * - * warhead--The type of damage to inflict. * - * * - * source -- Who is responsible for this damage? * - * * - * OUTPUT: Returns the result of the damage process. This can range from RESULT_NONE up to * - * RESULT_DESTROYED. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/30/1991 JLB : Created. * - * 07/12/1991 JLB : Script initiated by unit destruction. * - * 04/15/1994 JLB : Converted to member function. * - * 04/16/1994 JLB : Warhead modifier. * - * 06/03/1994 JLB : Added the source of the damage target value. * - * 06/20/1994 JLB : Source is a base class pointer. * - * 11/22/1994 JLB : Shares base damage handler for techno objects. * - * 06/30/1995 JLB : Lasers do maximum damage against gunboat. * - * 08/16/1995 JLB : Harvester crushing doesn't occur on early missions. * - *=============================================================================================*/ -ResultType UnitClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source) -{ - Validate(); - ResultType res = RESULT_NONE; - - /* - ** Special case: If this is a laser attacking a gunboat, then the gunboat is ALWAYS toasted. - */ - if (*this == UNIT_GUNBOAT && warhead == WARHEAD_LASER) { - damage = Strength*3; - } - - /* - ** Remember if this object was selected. If it was and it gets destroyed and it has - ** passengers that pop out, then the passengers will inherit the select state. - */ - bool select = (Is_Selected_By_Player() && Is_Owned_By_Player()); // Fox for GlyphX multiplayer. ST - 4/16/2019 9:46AM - - /* - ** In order for a this to be damaged, it must either be a unit - ** with a crew or a sandworm. - */ - res = TarComClass::Take_Damage(damage, distance, warhead, source); - - if (res == RESULT_DESTROYED) { - Death_Announcement(source); - if (Class->Explosion != ANIM_NONE) { - AnimType anim = Class->Explosion; - - /* - ** SSM launchers will really explode big if they are carrying - ** missiles at the time of the explosion. - */ - if (*this == UNIT_MSAM && Ammo) { - anim = ANIM_NAPALM3; - } - - if (*this == UNIT_TRIC || *this == UNIT_TREX || *this == UNIT_RAPT || *this == UNIT_STEG) { - Sound_Effect(VOC_DINODIE1, Coord); - } - - new AnimClass(anim, Coord); - - /* - ** When the flame tank blows up, it really blows up. It is - ** equivalent to a napalm strike. - */ - if (Class->Explosion == ANIM_NAPALM3) { - Explosion_Damage(Coord, 200, source, WARHEAD_FIRE); - } - - /* - ** Very strong units that have an explosion will also rock the - ** screen when they are destroyed. - */ - if (Class->MaxStrength > 400) { - Shake_The_Screen(3, Owner()); - if (source && Owner() != source->Owner()) { - Shake_The_Screen(3, source->Owner()); - } - } - } - - /* - ** Possibly have the crew member run away. - */ - Mark(MARK_UP); - if (Class->IsCrew && !Class->IsTransporter) { - if (Random_Pick(0, 1) == 0) { - InfantryClass * i = 0; - if (Class->Primary == WEAPON_NONE) { - i = new InfantryClass(INFANTRY_C1, House->Class->House); - i->IsTechnician = true; - } else { - i = new InfantryClass(INFANTRY_E1, House->Class->House); - } - if (i) { - if (i->Unlimbo(Coord, DIR_N)) { - i->Strength = Random_Pick(5, (int)i->Class->MaxStrength/2); - i->Scatter(0, true); - if (!House->IsHuman) { - i->Assign_Mission(MISSION_HUNT); - } else { - i->Assign_Mission(MISSION_GUARD); - } - if (select) i->Select(); - } else { - delete i; - } - } - } - } else { - if (*this != UNIT_HOVER) { - while (Is_Something_Attached()) { - FootClass * object = Detach_Object(); - - if (!object) break; // How can this happen? - - /* - ** Only infantry can run from a destroyed vehicle. Even then, it is not a sure - ** thing. - */ - if (object->Is_Infantry() && object->Unlimbo(Coord, DIR_N)) { - // object->Strength = Random_Pick(5, (int)((InfantryClass*)object)->Class->MaxStrength/2); - object->Look(false); - object->Scatter(0, true); - if (select) object->Select(); - } else { - object->Record_The_Kill(source); - delete object; - } - } - } else { - Kill_Cargo(source); - } - } - - /* - ** When the mobile head quarters blows up, the entire side blows up. - */ - if (*this == UNIT_MHQ) { - House->Flag_To_Die(); - } - - if (*this == UNIT_MCV) { - if (House) { - House->Check_Pertinent_Structures(); - } - } - - /* - ** Finally, delete the vehicle. - */ - Delete_This(); - - } else { - - /* - ** When damaged and below half strength, start smoking if - ** it isn't already smoking. - */ - if (Health_Ratio() < 0x0080 && !IsAnimAttached && *this != UNIT_VICE && *this != UNIT_STEG && *this != UNIT_TREX && *this != UNIT_TRIC && *this != UNIT_RAPT) { - AnimClass * anim = new AnimClass(ANIM_SMOKE_M, Coord_Add(Coord, XYP_Coord(0, -8))); - if (anim) anim->Attach_To(this); - } - - /* - ** If at half damage, then start smoking or burning as appropriate. - */ - if (res == RESULT_HALF) { - if (*this == UNIT_GUNBOAT) { - AnimClass * anim = new AnimClass(ANIM_ON_FIRE_MED, Coord_Add(Coord, XYP_Coord(Random_Pick(0, 16)-8, -2))); - if (anim) anim->Attach_To(this); - } - } - - /* - ** Try to crush anyone that fires on this unit if possible. The harvester - ** typically is the only one that will qualify here. - */ - if (!Team && source && !IsTethered && !House->Is_Ally(source) && (!House->IsHuman || Special.IsSmartDefense)) { - - /* - ** Try to crush the attacker if it can be crushed by this unit and this unit is - ** not equipped with a flame type weapon. If this unit has a weapon and the target - ** is not very close, then fire on it instead. In easy mode, they never run over the - ** player. In hard mode, they always do. In normal mode, they only overrun past - ** mission #8. - */ - if ((Class->Primary == WEAPON_NONE || (Distance(source) < 0x0180 && BulletTypeClass::As_Reference(Weapons[Class->Primary].Fires).Warhead != WARHEAD_FIRE)) && - (GameToPlay != GAME_NORMAL || - *this != UNIT_HARVESTER || - BuildLevel > 8 || - PlayerPtr->Difficulty == DIFF_HARD) && - !(GameToPlay == GAME_NORMAL && PlayerPtr->Difficulty == DIFF_EASY) && - Class->IsCrusher && source->Is_Techno() && ((TechnoTypeClass const &)source->Class_Of()).IsCrushable) { - - Assign_Destination(source->As_Target()); - Assign_Mission(MISSION_MOVE); - } else { - - /* - ** Try to return to base if possible. - */ - if (*this == UNIT_HARVESTER && Pip_Count() && Health_Ratio() < 0x0080) { - /* - ** Find nearby refinery and head to it? - */ - BuildingClass * building = Find_Docking_Bay(STRUCT_REFINERY, false); - - /* - ** Since the refinery said it was ok to load, establish radio - ** contact with the refinery and then await docking orders. - */ - if (building && Transmit_Message(RADIO_HELLO, building) == RADIO_ROGER) { - Assign_Mission(MISSION_ENTER); - } - } - } - } - - /* - ** Computer controlled harvester will radio for help if they are attacked. - */ - if (*this == UNIT_HARVESTER && !House->IsHuman && source) { - Base_Is_Attacked(source); - } - } - return(res); -} - - -/*********************************************************************************************** - * UnitClass::new -- Allocate a unit slot and adjust access arrays. * - * * - * This routine will allocate a unit from the available unit pool and * - * fixup all the access lists to match. It will allocate a unit slot * - * from within the range allowed for the specified unit type. If no * - * slot was found, then it will fail. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the allocated unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/11/1994 JLB : Created. * - * 04/21/1994 JLB : Converted to operator new. * - *=============================================================================================*/ -void * UnitClass::operator new(size_t) -{ - void * ptr = (UnitClass *)Units.Allocate(); - if (ptr) { - ((UnitClass *)ptr)->Set_Active(); - } - return(ptr); -} - - -/*********************************************************************************************** - * UnitClass::delete -- Deletion operator for units. * - * * - * This removes the unit from the local allocation system. Since this * - * is a fixed block of memory, not much has to be done to delete the * - * unit. Merely marking it as inactive is enough. * - * * - * INPUT: ptr -- Pointer to the unit to delete. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/21/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::operator delete(void *ptr) -{ - if (ptr) { - ((UnitClass *)ptr)->IsActive = false; - } - Units.Free((UnitClass *)ptr); - - //Map.Validate(); -} - - -/*********************************************************************************************** - * UnitClass::~UnitClass -- Destructor for unit objects. * - * * - * This destructor will lower the unit count for the owning house as well as inform any * - * other units in communication, that this unit is about to leave reality. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/15/1994 JLB : Created. * - *=============================================================================================*/ -UnitClass::~UnitClass(void) -{ - if (GameActive && Class) { - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Remove(this); -#endif // USE_RA_AI - - /* - ** If there are any cargo members, delete them. - */ - while (Is_Something_Attached()) { - delete Detach_Object(); - } - - Limbo(); - } - if (GameActive && Team) Team->Remove(this); -} - - -/*********************************************************************************************** - * UnitClass::UnitClass -- Constructor for units. * - * * - * This constructor for units will initialize the unit into the game * - * system. It will be placed in all necessary tracking lists. The initial condition will * - * be in a state of limbo. * - * * - * INPUT: classid -- The type of unit to create. * - * * - * house -- The house owner of this unit. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/21/1994 JLB : Created. * - *=============================================================================================*/ -UnitClass::UnitClass(UnitType classid, HousesType house) : - TarComClass(classid, house) -{ - Flagged = HOUSE_NONE; - Reload = 0; - Ammo = Class->MaxAmmo; - IsCloakable = Class->IsCloakable; - if (Class->IsAnimating) Set_Rate(Options.Normalize_Delay(3)); - - /* - ** Keep count of the number of units created. - */ - if (GameToPlay == GAME_INTERNET){ - House->UnitTotals->Increment_Unit_Total((int)classid); - } - -#ifdef USE_RA_AI - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - House->Tracking_Add(this); -#endif // USE_RA_AI -} - - -/*********************************************************************************************** - * UnitClass::Active_Click_With -- Intercepts the active click to see if deployment is possible* - * * - * This routine intercepts the active click operation. It check to see if this is a self * - * deployment request (MCV's have this ability). If it is, then the object is initiated * - * to self deploy. In the other cases, it passes the operation down to the lower * - * classes for processing. * - * * - * INPUT: action -- The action requested of the unit. * - * * - * object -- The object that the mouse pointer is over. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Active_Click_With(ActionType action, ObjectClass * object) -{ - Validate(); - if (action != What_Action(object)) { - switch (action) { - case ACTION_SABOTAGE: - case ACTION_CAPTURE: - action = ACTION_ATTACK; - break; - - case ACTION_ENTER: - action = ACTION_MOVE; - break; - - default: - action = ACTION_NONE; - break; - } - } - TarComClass::Active_Click_With(action, object); -} - - -void UnitClass::Active_Click_With(ActionType action, CELL cell) {TarComClass::Active_Click_With(action, cell);}; - - -void UnitClass::Player_Assign_Mission(MissionType mission, TARGET target, TARGET destination) -{ - Validate(); - if (mission == MISSION_HARVEST) { - ArchiveTarget = TARGET_NONE; - } - TarComClass::Player_Assign_Mission(mission, target, destination); -} - - -/*********************************************************************************************** - * UnitClass::Enter_Idle_Mode -- Unit enters idle mode state. * - * * - * This routine is called when the unit completes one mission but does not have a clear * - * follow up mission to perform. In such a case, the unit should enter a default idle * - * state. This idle state varies depending on what the current internal computer * - * settings of the unit is as well as what kind of unit it is. * - * * - * INPUT: initial -- Is this called when the unit just leaves a factory or is initially * - * or is initially placed on the map? * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 06/03/1994 JLB : Fixed to handle non-combat vehicles. * - * 06/18/1995 JLB : Allows a harvester to stop harvesting. * - *=============================================================================================*/ -void UnitClass::Enter_Idle_Mode(bool initial) -{ - Validate(); - MissionType order; - - /* - ** A movement mission without a NavCom would be pointless to have a radio contact since - ** no radio coordination occurs on a just a simple movement mission. - */ - if (Mission == MISSION_MOVE && !Target_Legal(NavCom)) { - Transmit_Message(RADIO_OVER_OUT); - } - - if (Class->Primary == WEAPON_NONE) { - if (Class->IsToHarvest) { - if (!In_Radio_Contact() && Mission != MISSION_HARVEST) { - if (initial || !House->IsHuman || Map[Coord_Cell(Coord)].Land_Type() == LAND_TIBERIUM) { - order = MISSION_HARVEST; - } else { - order = MISSION_GUARD; - } - Assign_Target(TARGET_NONE); - Assign_Destination(TARGET_NONE); - } else { - return; - } - } else { - if (IsALoaner && Class->IsTransporter && Is_Something_Attached() && !Team) { - order = MISSION_UNLOAD; - } else { - order = MISSION_GUARD; - Assign_Target(TARGET_NONE); - Assign_Destination(TARGET_NONE); - } - } - } else { - if (Target_Legal(TarCom)) { - order = MISSION_ATTACK; - } else { - if (Target_Legal(NavCom)) { - order = MISSION_MOVE; - } else { - if (GameToPlay == GAME_NORMAL || House->IsHuman) { - order = MISSION_GUARD; - } else { - //if (GameToPlay != GAME_NORMAL) { -#ifndef USE_RA_AI - // Don't use MISSION_TIMED_HUNT since this can trigger the Blitz behavior - order = MISSION_TIMED_HUNT; -#else - // - // Added for RA AI in TD. ST - 7/26/2019 9:12AM - // - // This applies only to non-human houses in a non-normal game type - // - order = MISSION_GUARD; - - if (Mission == MISSION_GUARD || Mission == MISSION_GUARD_AREA) { - return; - } - - if (!Team) { - if (House->IQ >= Rule.IQGuardArea) { - if (Is_Weapon_Equipped()) { - order = MISSION_GUARD_AREA; - } - } - } - -#endif - //} else { - // order = MISSION_HUNT; - //} - } - } - } - } - Assign_Mission(order); -} - - -/*********************************************************************************************** - * UnitClass::Find_LZ -- Maintenance function for transport units. * - * * - * This is a maintenance function for transport units. It checks to see if it is loaded * - * with cargo, but it doesn't know where to put it. In such a case, the unit must look * - * for a landing zone (LZ) to unload the cargo. This routine should be called every so * - * often. Typically, calling this routine is controlled by the scripts. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Find_LZ(void) -{ - Validate(); - CELL cell; // Map exit cell number. - - if (*this == UNIT_HOVER) { - - if (!IsRotating && Is_Something_Attached() && !Target_Legal(NavCom)) { - cell = Map.Calculated_Cell(SOURCE_BEACH, House->Class->House); - Assign_Destination(::As_Target(cell)); - } - } -} - - -/*********************************************************************************************** - * UnitClass::Unload_Hovercraft_Process -- Handles unloading hovercraft transport. * - * * - * This is a maintenance routine to handle the special operations necessary for a * - * hovercraft transport. This routine checks to see if special unloading operations are * - * necessary and performs them. These operations can include unloading the transported * - * object, finding a new beach cell, and rotating to a convenient unloading facing. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Has the transport finished its unloading mission? This is true after the * - * hovercraft has completely dispatched its cargo. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/31/1994 JLB : Created. * - * 07/31/1995 JLB : Second infantry unloaded MUST be the one tethered. * - *=============================================================================================*/ -bool UnitClass::Unload_Hovercraft_Process(void) -{ - Validate(); - bool unloaded = false; - FootClass *unit; // The unit to be unloaded. - CELL cell; // Cell to unload to. - - /* - ** If the hovercraft is currently waiting for the last unit - ** to completely unload, then don't do anything. - */ - if (IsTethered || IsRotating) { - return(false); - } - - if (Is_Something_Attached()) { - - /* - ** Only unload if the hovercraft has reached the beach. - */ - if (!Target_Legal(NavCom)) { - - cell = Coord_Cell(Adjacent_Cell(Coord, Dir_Facing(PrimaryFacing.Current()))); - - unit = (FootClass *)Attached_Object(); - - Mark(MARK_UP); - if (Map.In_Radar(cell) && !Map[cell].Cell_Unit()) { - - if (unit->Can_Enter_Cell(cell, FACING_NONE) == MOVE_OK) { - - /* - ** Place all the transported units onto the map. - */ - int count = 0; - bool first = true; - FootClass * secondary = 0; - while (Attached_Object()) { - FootClass * u = (FootClass *)Detach_Object(); - - if (!first && !secondary) secondary = u; - first = false; - - /* - ** Place the unit on the map and start it heading in the right direction. - */ - ScenarioInit++; - if (u->Unlimbo(Coord_Add(Coord & 0xFF00FF00L, StoppingCoordAbs[count]), DIR_N)) { - u->Assign_Mission(MISSION_MOVE); - u->NavCom = ::As_Target(cell); - u->Path[0] = Dir_Facing(u->PrimaryFacing.Current()); - u->Path[1] = FACING_NONE; - u->Set_Speed(0x80); - u->IsUnloading = true; - u->Look(false); - } else { - - /* - ** Couldn't unlimbo for some strange reason. Kill the unit off. - */ - delete u; - } - ScenarioInit--; - count++; - } - if (secondary) unit = secondary; - - /* - ** Establish radio contact bond with the transport - ** hovercraft. This bond tells the hovercraft to - ** not move until the unit has completely unloaded. - */ - if (Transmit_Message(RADIO_HELLO, unit) == RADIO_ROGER) { - Transmit_Message(RADIO_UNLOAD); - } - Mark(MARK_DOWN); - Map.Layer[LAYER_GROUND].Sort(); - Map.Layer[LAYER_GROUND].Sort(); - Map.Layer[LAYER_GROUND].Sort(); - return(false); - } else { - - /* - ** If the attached object cannot unload because the desired destination - ** cell is impassable, then abort the landing. This is faked by pretending - ** that the unload was successful. The controlling routine will cause - ** the transport to leave. - */ -Mark(MARK_DOWN); -return(false); -// return(true); - } - } - - Mark(MARK_DOWN); - } - } else { - return(true); - } - - return(unloaded); -} - - -/*********************************************************************************************** - * UnitClass::Goto_Clear_Spot -- Finds a clear spot to deploy. * - * * - * This routine is used by the MCV to find a clear spot to deploy. If a clear spot * - * is found, then the MCV will assign that location to its navigation computer. This only * - * occurs if the MCV isn't already heading toward a spot. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the located at a spot where it can deploy? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/27/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Goto_Clear_Spot(void) -{ - Validate(); - Mark(MARK_UP); - if (!Target_Legal(NavCom) && BuildingTypeClass::As_Reference(STRUCT_CONST).Legal_Placement(Coord_Cell(Adjacent_Cell(Center_Coord(), FACING_NW)))) { - Mark(MARK_DOWN); - return(true); - } - - if (!Target_Legal(NavCom)) { - -#ifndef USE_RA_AI - /* - ** This scan table is skewed to north scanning only. This should - ** probably be converted to a more flexible method. - */ - static int _offsets[] = { - -MAP_CELL_W*1, - -MAP_CELL_W*2, - -(MAP_CELL_W*2)+1, - -(MAP_CELL_W*2)-1, - -MAP_CELL_W*3, - -(MAP_CELL_W*3)+1, - -(MAP_CELL_W*3)-1, - -(MAP_CELL_W*3)+2, - -(MAP_CELL_W*3)-2, - -MAP_CELL_W*4, - -(MAP_CELL_W*4)+1, - -(MAP_CELL_W*4)-1, - -(MAP_CELL_W*4)+2, - -(MAP_CELL_W*4)-2, - 0 - }; - int *ptr; - - ptr = &_offsets[0]; - while (*ptr) { - CELL cell = Coord_Cell(Coord)+*ptr++; - - if (BuildingTypeClass::As_Reference(STRUCT_CONST).Legal_Placement(cell)) { - Assign_Destination(::As_Target(cell)); - break; - } - } - -#else //USE_RA_AI - - // - // Pulled in the extra offsets from RA, and started at a random position in the array. ST - 7/26/2019 2:07PM - // - static int _offset_count = 36; - static int _offsets[] = { - -MAP_CELL_W*1, - -MAP_CELL_W*2, - -(MAP_CELL_W*2)+1, - -(MAP_CELL_W*2)-1, - -MAP_CELL_W*3, - -(MAP_CELL_W*3)+1, - -(MAP_CELL_W*3)-1, - -(MAP_CELL_W*3)+2, - -(MAP_CELL_W*3)-2, - -MAP_CELL_W*4, - -(MAP_CELL_W*4)+1, - -(MAP_CELL_W*4)-1, - -(MAP_CELL_W*4)+2, - -(MAP_CELL_W*4)-2, -//BG: Added south scanning - MAP_CELL_W*1, - MAP_CELL_W*2, - (MAP_CELL_W*2)+1, - (MAP_CELL_W*2)-1, - MAP_CELL_W*3, - (MAP_CELL_W*3)+1, - (MAP_CELL_W*3)-1, - (MAP_CELL_W*3)+2, - (MAP_CELL_W*3)-2, - MAP_CELL_W*4, - (MAP_CELL_W*4)+1, - (MAP_CELL_W*4)-1, - (MAP_CELL_W*4)+2, - (MAP_CELL_W*4)-2, - -//BG: Added some token east/west scanning - -1,-2,-3,-4, - - 1, 2, 3, 4, - 0 - }; - - int offset_index = Random_Pick(0, _offset_count); - - for (int i=0 ; i<_offset_count ; i++) { - CELL cell = Coord_Cell(Coord) + _offsets[offset_index++]; - if (offset_index >= _offset_count || _offsets[offset_index] == 0) { - offset_index = 0; - } - - if (BuildingTypeClass::As_Reference(STRUCT_CONST).Legal_Placement(cell)) { - Assign_Destination(::As_Target(cell)); - break; - } - } - -#endif //USE_RA_AI - } - Mark(MARK_DOWN); - - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Try_To_Deploy -- The unit attempts to "deploy" at current location. * - * * - * Certain units have the ability to deploy into a building. When this routine is called * - * for one of those units, it will attempt to deploy at its current location. If the unit * - * is in motion to a destination or it isn't one of the special units that can deploy or * - * it isn't allowed to deploy at this location for some reason it won't deploy. In all * - * other cases, it will begin to deploy and once it begins only a player abort action will * - * stop it. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was deployment begun? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/18/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Try_To_Deploy(void) -{ - Validate(); - if (!Target_Legal(NavCom) && !IsRotating) { - if (*this == UNIT_MCV) { - - /* - ** Determine if it is legal to deploy at this location. If not, tell the - ** player. - */ - Mark(MARK_UP); - if (!BuildingTypeClass::As_Reference(STRUCT_CONST).Legal_Placement(Coord_Cell(Adjacent_Cell(Center_Coord(), FACING_NW)))) { - if (PlayerPtr == House) { - Speak(VOX_DEPLOY); - } - Mark(MARK_DOWN); - IsDeploying = false; - return(false); - } - Mark(MARK_DOWN); - - /* - ** If the unit is not facing the correct direction, then start it rotating - ** toward the right facing, but still flag it as if it had deployed. This is - ** because it will deploy as soon as it reaches the correct facing. - */ - if (PrimaryFacing.Current() != DIR_SW) { - Do_Turn(DIR_SW); -// PrimaryFacing.Set_Desired(DIR_SW); - IsDeploying = true; - return(true); - } - - /* - ** Since the unit is already facing the correct direction, actually do the - ** deploy logic. If for some reason this cannot occur, then don't delete the - ** unit, just mark it as not deploying. - */ - Mark(MARK_UP); - BuildingClass * building = new BuildingClass(STRUCT_CONST, House->Class->House); - if (building) { - if (building->Unlimbo(Adjacent_Cell(Coord, FACING_NW))) { - - /* - ** Always reveal the construction yard to the player that owned the - ** mobile construction vehicle. - */ - building->Revealed(House); - - /* - ** Force the newly placed construction yard to be in the same strength - ** ratio as the MCV that deployed into it. - */ - int ratio = Health_Ratio(); - building->Strength = Fixed_To_Cardinal(building->Class->MaxStrength, ratio); - /* - ** Force the MCV to drop any flag it was carrying. This will also set - ** the owner house's flag home cell (since the house's FlagHome is - ** presumably 0 at this point). - */ - Stun(); - Delete_This(); - return(true); - } else { - - /* - ** Could not deploy the construction yard at this location! Just revert - ** back to normal "just sitting there" mode and await further instructions. - */ - delete building; - } - } - Mark(MARK_DOWN); - IsDeploying = false; - } - } - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Per_Cell_Process -- Performs operations necessary on a per cell basis. * - * * - * This routine will perform the operations necessary that occur when a unit is at the * - * center of a cell. These operations could entail deploying into a construction yard, * - * radioing a transport unit, and looking around for the enemy. * - * * - * INPUT: center -- Is the unit safely at the center of a cell? If it is merely "close" * - * to the center, then this parameter will be false. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/18/1994 JLB : Created. * - * 06/17/1995 JLB : Handles case when building says "NO!" * - * 06/30/1995 JLB : Gunboats head back and forth now. * - *=============================================================================================*/ -void UnitClass::Per_Cell_Process(bool center) -{ - Validate(); - CELL cell = Coord_Cell(Coord); - TechnoClass * whom; - HousesType house; - - /* - ** If this is a unit that is driving onto a building then the unit must enter - ** the building as the final step. - */ - whom = Contact_With_Whom(); - if (IsTethered && whom && center) { - if (whom->What_Am_I() == RTTI_BUILDING && Mission == MISSION_ENTER) { - if (whom == Map[cell].Cell_Building()) { - switch (Transmit_Message(RADIO_IM_IN, whom)) { - case RADIO_ROGER: - break; - - case RADIO_ATTACH: - Mark(MARK_UP); - SpecialFlag = true; - Limbo(); - SpecialFlag = false; - whom->Attach(this); - return; - - default: - Scatter(0, true); - break; - } - } - } - } - - /* - ** When breaking away from a transport object or building, possibly - ** scatter or otherwise begin normal unit operations. - */ - if (IsTethered && center && - (Mission != MISSION_ENTER || (As_Techno(NavCom) != NULL && Contact_With_Whom() != As_Techno(NavCom))) && - Mission != MISSION_UNLOAD) { - /* - ** Special hack check to make sure that even though it has moved one - ** cell, if it is still on the building (e.g., service depot), have - ** it scatter again. - */ - if (Map[cell].Cell_Building() != NULL && !Target_Legal(NavCom)) { - Scatter(0, true, true); - } else { - TechnoClass * contact = Contact_With_Whom(); - if (Transmit_Message(RADIO_UNLOADED) == RADIO_RUN_AWAY) { - if (*this == UNIT_HARVESTER && contact && contact->What_Am_I() == RTTI_BUILDING) { - Assign_Mission(MISSION_HARVEST); - } else if (!Target_Legal(NavCom)) { - Scatter(0, true); - } - } else { - if (*this == UNIT_HARVESTER) { - if (Target_Legal(ArchiveTarget)) { - Assign_Mission(MISSION_HARVEST); - Assign_Destination(ArchiveTarget); - ArchiveTarget = TARGET_NONE; - } else { - - /* - ** Since there is no place to go, move away to clear - ** the pad for another harvester. - */ - if (!Target_Legal(NavCom)) { - Scatter(0, true); - } - } - } - } - } - } - -#ifdef OBSOLETE - /* - ** If this unit is on a teather, then cut it at this time so that - ** the "parent" unit is free to proceed. Note that the parent - ** unit might actually be a building. - */ - if (IsTethered && center && !Map[cell].Cell_Building()) { - if (!Tiberium || *this != UNIT_HARVESTER) { - Transmit_Message(RADIO_UNLOADED); - if (*this == UNIT_HARVESTER) { - if (Target_Legal(ArchiveTarget)) { - Assign_Mission(MISSION_HARVEST); - Assign_Destination(ArchiveTarget); - ArchiveTarget = TARGET_NONE; - } else { - - /* - ** Since there is no place to go, move away to clear - ** the pad for another harvester. - */ - Scatter(0, true); - } - } - } - } -#endif - -#ifdef OBSOLETE - /* - ** If the unit is at the center of the repair facility, and that was his - ** destination, then start him repairing. - */ - if (center && !IsRepairing) { - BuildingClass * b = As_Building(NavCom); - if (b && *b==STRUCT_REPAIR && Coord == b->Center_Coord()) { - NavCom = 0; - IsRepairing = true; - Transmit_Message(RADIO_REPAIR_BEGIN_ANIM); - } - } -#endif - - /* - ** Check to see if this is merely the end of a rotation for the MCV as it is - ** preparing to deploy. In this case, it should begin its deploy process. - */ - if (center && IsDeploying) { - Try_To_Deploy(); - if (!IsActive) return; // Unit no longer exists -- bail. - } - - /* - ** If this is a loaner unit and is is off the edge of the - ** map, then it gets eliminated. That is, unless it is carrying cargo. This means that - ** it is probably carrying an incoming reinforcement and it should not be eliminated. - */ - if (center && IsALoaner && !Map.In_Radar(cell)) { - if (IsReturning || !Is_Something_Attached()) { - if (*this == UNIT_GUNBOAT) { - CELL cell = Coord_Cell(Coord); - if (Cell_X(cell) <= Map.MapCellX) { - Assign_Mission(MISSION_HUNT); - Assign_Destination(::As_Target(XY_Cell(Map.MapCellX+Map.MapCellWidth, Cell_Y(cell)))); - Set_Speed(255); - PrimaryFacing = DIR_E; - } else { - Assign_Mission(MISSION_HUNT); - Assign_Destination(::As_Target(XY_Cell(Map.MapCellX-1, Cell_Y(cell)))); - Set_Speed(255); - PrimaryFacing = DIR_W; - } - Mark(MARK_DOWN); - } else { - Mark(MARK_DOWN); - Stun(); - Delete_This(); - return; - } - } - } - -#ifdef OBSOLETE - /* - ** Destroy any crushable wall that is driven over by a tracked vehicle. - */ - CellClass * cellptr = &Map[cell]; - if (center && Class->Speed == SPEED_TRACK && cellptr->Overlay != OVERLAY_NONE) { - OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay); - - if (optr->IsCrushable) { - cellptr->Reduce_Wall(100); - cellptr->Reduce_Wall(100); - cellptr->Reduce_Wall(100); - cellptr->Reduce_Wall(100); - cellptr->Reduce_Wall(100); - cellptr->Reduce_Wall(100); - } - } -#endif - - /* - ** Check to see if crushing of any unfortunate infantry is warranted. - */ - Overrun_Square(Coord_Cell(Coord), false); - - /* - ** The unit performs looking around at this time. If the - ** unit moved further than one square during the last track - ** move, don't do an incremental look. Do a full look around - ** instead. - */ - if (IsPlanningToLook) { - IsPlanningToLook = false; - Look(false); - } else { - Look(true); - } - - /* - ** Act on new orders if the unit is at a good position to do so. - */ - if (center) { - Commence(); - } - - /* - ** Certain units require some setup time after they come to a halt. - */ - if (Special.IsDefenderAdvantage && /*center &&*/ !Target_Legal(NavCom) && Path[0] == FACING_NONE) { - if (*this == UNIT_MLRS || *this == UNIT_ARTY || *this == UNIT_MSAM) { - Arm = Rearm_Delay(false)*2; - } - } - - /* - ** If there is a house flag here, then this unit just might pick it up. - */ - if (center && Flagged == HOUSE_NONE) { - - if (Map[cell].IsFlagged && !House->Is_Ally(Map[cell].Owner)) { - HouseClass::As_Pointer(Map[cell].Owner)->Flag_Attach(this); - } - } - - /* - ** If this is the unit's own flag-home-cell and the unit is carrying - ** a flag, destroy the house of the flag the unit is carrying. - */ - if (Flagged != HOUSE_NONE) { - - /* - ** If this vehicle is carrying your flag, then it will reveal the - ** map for you as well as itself. This gives you and opportunity to - ** attack the unit. - */ - if (!IsOwnedByPlayer && Flagged == PlayerPtr->Class->House) { - Map.Sight_From(House, Coord_Cell(Coord), Class->SightRange, true); // Passed our house into Map.Sight_From since it now needs to know who it is performing the action on behalf of. ST - 3/28/2019 2:55PM - } - - /* - ** If the flag reaches the home cell for the player, then the flag's - ** owner will be destroyed. - */ - if (cell == HouseClass::As_Pointer(Owner())->FlagHome && center) { - house = Flagged; // Flag_Remove will clear 'Flagged', so save it - HouseClass::As_Pointer(house)->Flag_Remove(As_Target(),true); - HouseClass::As_Pointer(house)->Flag_To_Die(); - } - } - - TarComClass::Per_Cell_Process(center); -} - - - -/*********************************************************************************************** - * UnitClass::Draw_It -- Draws a unit object. * - * * - * This routine is the one that actually draws a unit object. It displays the unit * - * according to its current state flags and centered at the location specified. * - * * - * INPUT: x,y -- The X and Y coordinate of where to draw the unit. * - * * - * window -- The clipping window to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1994 JLB : Created. * - * 06/27/1994 JLB : Takes a window parameter. * - * 08/15/1994 JLB : Removed infantry support. * - * 01/07/1995 JLB : Harvester animation support. * - * 07/08/1995 JLB : Uses general purpose draw routine. * - *=============================================================================================*/ -void UnitClass::Draw_It(int x, int y, WindowNumberType window) -{ - Validate(); - int shapenum; // Working shape number. - void const *shapefile; // Working shape file pointer. - int facing = Facing_To_32(PrimaryFacing.Current()); - int tfacing = Facing_To_32(SecondaryFacing.Current()); - int shapestart; - int xx, yy; - - /* - ** Verify the legality of the unit class. - */ - shapefile = Class->Get_Image_Data(); - if (!shapefile) return; - - /* - ** If drawing of this unit is not explicitly prohibited, then proceed - ** with the render process. - */ - const bool is_hidden = (Visual_Character() == VISUAL_HIDDEN) && (window != WINDOW_VIRTUAL); - if (!is_hidden) { - - /* - ** For eight facing units, adjust the facing number accordingly. - */ - if (Class->IsPieceOfEight) { - facing = Dir_Facing(PrimaryFacing.Current()); - } - - /* - ** Calculations for special wake drawing. - */ - xx = x; - yy = y; - switch (Dir_Facing(PrimaryFacing.Current())) { - case FACING_NE: - case FACING_E: - case FACING_SE: - shapenum = UnitClass::BodyShape[tfacing] + 96; - shapestart = 0; - //xx -= 4; - break; - - case FACING_W: - default: - shapenum = UnitClass::BodyShape[tfacing]; - shapestart = 6; - xx += 4; - break; - } - - /* - ** Some units have only four facings, but are equipped with a turret - ** that has 32 facings. - */ - if (Class->IsChunkyShape) { - - /* - ** Special wake drawing occurs here for non-virtual rendering - */ - if (*this == UNIT_GUNBOAT) { - - if (window != WINDOW_VIRTUAL) { - //Added this and wake name parameters. ST - 8/20/2019 10:54AM - CC_Draw_Shape(this, "WAKE", UnitTypeClass::WakeShapes, shapestart + (Fetch_Stage() % 6), xx-1, yy+3, window, SHAPE_CENTER|SHAPE_WIN_REL); - } - - if (Health_Ratio() < 0x0080) shapenum += 32; - if (Health_Ratio() < 0x0040) shapenum += 32; - - } else { - - /* - ** Special hovercraft shape is ALWAYS N/S. - */ - shapenum = 0; - - //shapenum = ((UnitClass::BodyShape[facing] + 4) / 8) & 0x03; - } - - } else { - - /* - ** Fetch the harvesting animation stage as appropriate. - */ - if (IsHarvesting && !PrimaryFacing.Is_Rotating() && !NavCom && !IsDriving) { - static char _hstage[6] = { - 0, 1, 2, 3, 2, 1 - }; - shapenum = 32 + (((UnitClass::BodyShape[facing]+2)/4)*4)+_hstage[Fetch_Stage()%sizeof(_hstage)]; - } else { - shapenum = UnitClass::BodyShape[facing]; - if (Class->IsAnimating) { - shapenum = Fetch_Stage(); - } - if (Class->IsPieceOfEight) { - shapenum = 0; - int numshapes = (IsDriving || (*this == UNIT_TREX) || (*this == UNIT_RAPT)) ? 8 : 12; - if (facing) shapenum = UnitClass::BodyShape[24+facing]; - if (IsDriving) shapenum = (Fetch_Stage()%numshapes) + 16 + (shapenum*numshapes); - else if (IsFiring) shapenum = (Fetch_Stage()%numshapes) + 80 + (shapenum*numshapes); - } else { - - /* - ** Door opening and closing animation must be handled carefully. There are only - ** certain directions where this door animation will work. - */ - if (!Is_Door_Closed() && (PrimaryFacing == DIR_NW || PrimaryFacing == DIR_NE)) { - if (PrimaryFacing == DIR_NE) { - shapenum = 32; - } else { - if (PrimaryFacing == DIR_NW) { - shapenum = 35; - } - } - shapenum += Door_Stage(); - } - } - } - } - - /* - ** The artillery unit should have its entire body recoil when it fires. - */ - if (*this == UNIT_ARTY && IsInRecoilState) { - Recoil_Adjust(PrimaryFacing.Current(), x, y); - } - - /* - ** Actually perform the draw. Overlay an optional shimmer effect as necessary. - */ -//if (*this == UNIT_HOVER) { -// Mono_Printf("Display hover %p %d.\n", shapefile, shapenum); -//} - Techno_Draw_Object(shapefile, shapenum, x, y, window); - - /* - ** Special wake drawing occurs here for virtual rendering - */ - if (Class->IsChunkyShape && (*this == UNIT_GUNBOAT) && (window == WINDOW_VIRTUAL)) { - //Added this and wake name parameters. ST - 8/20/2019 10:54AM - CC_Draw_Shape(this, "WAKE", UnitTypeClass::WakeShapes, shapestart + (Fetch_Stage() % 6), xx-1, yy+3, window, SHAPE_CENTER|SHAPE_WIN_REL); - } - - /* - ** If there is a rotating radar dish, draw it now. - */ - if (Class->IsRadarEquipped) { - shapenum = 32 + (Frame % 32); - Techno_Draw_Object(shapefile, shapenum, x, y-5, window); - } - - /* - ** If there is a turret, then it must be rendered as well. This may include - ** firing animation if required. - */ - if (!Class->IsChunkyShape && Class->IsTurretEquipped) { - int x1 = x; - int y1 = y; - - /* - ** Determine which turret shape to use. This depends on if there - ** is any firing animation in progress. - */ - shapenum = TechnoClass::BodyShape[tfacing]+32; - - /* - ** The shape to use for the rocket launcher is dependant on the - ** ammo remaining. - */ - if (*this == UNIT_MSAM) { - if (Ammo == 0) shapenum += 64; - if (Ammo == 1) shapenum += 32; - } - - /* - ** A recoiling turret moves "backward" one pixel. - */ - if (IsInRecoilState) { - Recoil_Adjust(SecondaryFacing.Current(), x1, y1); - } - - /* - ** The Mobile SAM and the Missile Launchers need their turrets moved based - ** on the facing of the vehicle. - */ - if (*this == UNIT_MSAM || *this == UNIT_MLRS) { - Turret_Adjust(PrimaryFacing, x1, y1); - } - if (*this == UNIT_JEEP || *this == UNIT_BUGGY) { - y1 -= 4; - } - - /* - ** Actually perform the draw. Overlay an optional shimmer effect as necessary. - */ - Techno_Draw_Object(shapefile, shapenum, x1, y1, window); - } - - /* - ** If this unit has "piggy back" unit(s), then render it at the same time. - */ - if (*this == UNIT_HOVER && Is_Something_Attached()) { - TechnoClass * u = (TechnoClass *)Attached_Object(); - - int counter = 0; - for (;;) { - int x1,y1; - - if (Map.Coord_To_Pixel(Coord_Add(Coord_Add(Coord, 0xFF80FF80L), StoppingCoordAbs[counter++]), x1, y1)) { - // Pass the window through, so that the virtual window will also work. ST - 6/18/2019 12:00PM - //u->Draw_It(x1, y1, WINDOW_TACTICAL); - u->Draw_It(x1, y1, window); - } - if (!u->Next) break; - u = (TechnoClass *)u->Next; - } - } - } - - /* - ** If this unit is carrying the flag, then draw that on top of everything else. - */ - if (Flagged != HOUSE_NONE) { - shapefile = MixFileClass::Retrieve("FLAGFLY.SHP"); - int flag_x = x + (ICON_PIXEL_W / 2) - 2; - int flag_y = y + (3 * ICON_PIXEL_H / 4) - Get_Build_Frame_Height(shapefile); - CC_Draw_Shape(this, "FLAGFLY", shapefile, Frame % 14, flag_x, flag_y, window, SHAPE_CENTER|SHAPE_FADING|SHAPE_GHOST, HouseClass::As_Pointer(Flagged)->Remap_Table(false, false), Map.UnitShadow, Flagged); - } - - TarComClass::Draw_It(x, y, window); -} - - -/*********************************************************************************************** - * UnitClass::Goto_Tiberium -- Search for and head toward nearest available Tiberium patch. * - * * - * This routine is used to move a harvester to a place where it can load up with * - * Tiberium. It will return true only if it can start harvesting. Otherwise, it sets * - * the navigation computer toward the nearest Tiberium and lets the unit head there * - * automatically. * - * * - * INPUT: none * - * * - * OUTPUT: int; Amount of Tiberium at this location. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int UnitClass::Tiberium_Check(CELL ¢er, int x, int y) -{ - Validate(); - /* - ** If the specified offset from the origin will cause it - ** to spill past the map edge, then abort this cell check. - */ - if (Cell_X(center)+x < Map.MapCellX) return(0); - if (Cell_X(center)+x >= Map.MapCellX+Map.MapCellWidth) return(0); - if (Cell_Y(center)+y < Map.MapCellY) return(0); - if (Cell_Y(center)+y >= Map.MapCellY+Map.MapCellHeight) return(0); - - center = XY_Cell(Cell_X(center)+x, Cell_Y(center)+y); - - //using function for IsVisible so we have different results for different players - JAS 2019/09/30 - if ((GameToPlay != GAME_NORMAL || (!IsOwnedByPlayer || Map[center].Is_Visible(PlayerPtr)))) { - if (!Map[center].Cell_Techno() && Map[center].Land_Type() == LAND_TIBERIUM) { - return(Map[center].OverlayData); - } - } - return(0); -} - - -bool UnitClass::Goto_Tiberium(void) -{ - Validate(); - if (!Target_Legal(NavCom)) { - CELL center = Coord_Cell(Center_Coord()); - if (Map[center].Land_Type() == LAND_TIBERIUM) { - return(true); - } else { - - /* - ** Perform a ring search outward from the center. - */ - for (int radius = 1; radius < 64; radius++) { - CELL cell = center; - CELL bestcell = 0; - int tiberium = 0; - int besttiberium = 0; - for (int x = -radius; x <= radius; x++) { - tiberium = Tiberium_Check(cell, x, -radius); - if (tiberium > besttiberium) { - bestcell = cell; - besttiberium = tiberium; - } - - cell = center; - tiberium = Tiberium_Check(cell, x, +radius); - if (tiberium > besttiberium) { - bestcell = cell; - besttiberium = tiberium; - } - - cell = center; - tiberium = Tiberium_Check(cell, -radius, x); - if (tiberium > besttiberium) { - bestcell = cell; - besttiberium = tiberium; - } - - cell = center; - tiberium = Tiberium_Check(cell, +radius, x); - if (tiberium > besttiberium) { - bestcell = cell; - besttiberium = tiberium; - } - } - if (bestcell) { - Assign_Destination(::As_Target(bestcell)); - return(false); - } - } - } - } - - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Harvesting -- Harvests tiberium at the current location. * - * * - * This routine is used to by the harvester to harvest Tiberium at the current location. * - * When harvesting is complete, this routine will return true. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is harvesting complete? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Harvesting(void) -{ - Validate(); - CELL cell = Coord_Cell(Coord); - CellClass * ptr = &Map[cell]; - - /* - ** Keep waiting if still heading toward a spot to harvest or the harvest timer hasn't expired yet. - */ - if (Target_Legal(NavCom) || !HarvestTimer.Expired() || IsDriving || IsRotating) return(true); - - if (Tiberium_Load() < 0x0100 && ptr->Land_Type() == LAND_TIBERIUM) { - - /* - ** Lift some Tiberium from the ground. Try to lift a complete - ** "level" of Tiberium. A level happens to be 6 steps. If there - ** is a partial level, then lift that instead. Never lift more - ** than the harvester can carry. - */ - int reducer = (ptr->OverlayData % 6) + 1; - reducer = ptr->Reduce_Tiberium(MIN(reducer, UnitTypeClass::STEP_COUNT-Tiberium)); - Tiberium += reducer; - Set_Stage(0); - Set_Rate(2); - - HarvestTimer = TICKS_PER_SECOND; - - } else { - - /* - ** If the harvester is stopped on a non Tiberium field and the harvester - ** isn't loaded with Tiberium, then no further action can be performed - ** by this logic routine. Bail with a failure and thus cause a branch to - ** a better suited logic processor. - */ - Set_Stage(0); - Set_Rate(0); - return(false); - } - return(true); -} - - -/*********************************************************************************************** - * UnitClass::Mission_Unload -- Handles unloading cargo. * - * * - * This is the AI control sequence for when a transport desires to unload its cargo and * - * then exit the map. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int UnitClass::Mission_Unload(void) -{ - Validate(); - enum { - INITIAL_CHECK, - MANEUVERING, - OPENING_DOOR, - UNLOADING, - CLOSING_DOOR - }; - DirType dir; - CELL cell; - - switch (Class->Type) { - case UNIT_APC: - switch (Status) { - case INITIAL_CHECK: - dir = Desired_Load_Dir(NULL, cell); - if (How_Many() && cell != 0) { - Do_Turn(dir); - Status = MANEUVERING; - return(1); - } else { - Assign_Mission(MISSION_GUARD); - } - break; - - case MANEUVERING: - if (!IsRotating) { - APC_Open_Door(); - if (Is_Door_Opening()) { - Status = OPENING_DOOR; - return(1); - } - } - break; - - case OPENING_DOOR: - if (Is_Door_Open()) { - Status = UNLOADING; - return(1); - } else { - if (!Is_Door_Opening()) { - Status = INITIAL_CHECK; - } - } - break; - - case UNLOADING: - if (How_Many()) { - FootClass * passenger = Detach_Object(); - - if (passenger) { - DirType toface = DIR_S + PrimaryFacing; - bool placed = false; - - for (FacingType face = FACING_N; face < FACING_COUNT; face++) { - DirType newface = toface + face; - CELL newcell = Adjacent_Cell(Coord_Cell(Coord), newface); - - if (passenger->Can_Enter_Cell(newcell) == MOVE_OK) { - ScenarioInit++; - passenger->Unlimbo(Coord_Move(Coord, newface, 0x0080), newface); - ScenarioInit--; - passenger->Assign_Mission(MISSION_MOVE); - passenger->Assign_Destination(::As_Target(newcell)); - placed = true; - break; - } - } - - /* - ** If the attached unit could NOT be deployed, then re-attach - ** it and then bail out of this deploy process. - */ - if (!placed) { - Attach(passenger); - Status = CLOSING_DOOR; - } - else { - passenger->Look(false); - } - } - } else { - Status = CLOSING_DOOR; - } - break; - - /* - ** Close APC door in preparation for normal operation. - */ - case CLOSING_DOOR: - if (Is_Door_Open()) { - APC_Close_Door(); - } - if (Is_Door_Closed()) { - Assign_Mission(MISSION_GUARD); - } - break; - } - break; - - case UNIT_MCV: - switch (Status) { - case 0: - Path[0] = FACING_NONE; - Status = 1; - break; - - case 1: - if (!IsDriving) { - Try_To_Deploy(); - if (IsDeploying) { - Status = 2; - } else { - /* - ** Functionality from Red Alert for AI. ST - 7/25/2019 3:09PM - */ -#ifndef USE_RA_AI - Assign_Mission(MISSION_GUARD); -#else //USE_RA_AI - if (!House->IsHuman && GameToPlay != GAME_NORMAL) { - Assign_Mission(MISSION_HUNT); - } else { - Assign_Mission(MISSION_GUARD); - } -#endif //USE_RA_AI - } - } - break; - - case 2: -#ifdef USE_RA_AI - /* - ** Functionality from Red Alert for AI. ST - 7/25/2019 3:09PM - */ - if (GameToPlay != GAME_NORMAL) { - if (!IsDeploying) { - Assign_Mission(MISSION_GUARD); - } - } -#endif // USE_RA_AI - break; - } - return(1); - - case UNIT_HOVER: - switch (Status) { - case 0: - if (Unload_Hovercraft_Process()) { - Status = 1; - } - break; - - /* - ** Hovercraft always leave the map when they finish - ** unloading. - */ - case 1: - if (Team) { - Team->Remove(this); - } - Exit_Map(); - break; - } - break; - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * UnitClass::Mission_Harvest -- Handles the harvesting process used by harvesters. * - * * - * This is the AI process used by harvesters when they are doing their harvesting action. * - * This entails searching for nearby Tiberium, heading there, harvesting, and then * - * returning to a refinery for unloading. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - * 06/21/1995 JLB : Force guard mode if no Tiberium found. * - *=============================================================================================*/ -int UnitClass::Mission_Harvest(void) -{ - Validate(); - enum { - LOOKING, - HARVESTING, - FINDHOME, - HEADINGHOME, - GOINGTOIDLE, - }; - - /* - ** A non-harvesting type unit will just sit still if it is given the harvest mission. This - ** allows combat units to act "brain dead". - */ - if (!Class->IsToHarvest) return(TICKS_PER_SECOND*30); - - switch (Status) { - - /* - ** Go and find a Tiberium field to harvest. - */ - case LOOKING: - IsHarvesting = false; - if (Goto_Tiberium()) { - IsHarvesting = true; - Set_Rate(2); - Set_Stage(0); - Status = HARVESTING; - ArchiveTarget = ::As_Target(Coord_Cell(Coord)); - return(1); - } else { - - /* - ** If the harvester isn't on Tiberium and it is not heading toward Tiberium, then - ** force it to go into guard mode. This will prevent the harvester from repeatedly - ** searching for Tiberium. - */ - if (!Target_Legal(NavCom)) { - - /* - ** If the archive target is legal, then head there since it is presumed - ** that the archive target points to the last place it harvested at. This might - ** solve the case where the harvester gets stuck and can't find Tiberium just because - ** it is greater than 32 squares away. - */ - if (Target_Legal(ArchiveTarget)) { - Assign_Destination(ArchiveTarget); - } else { - Status = GOINGTOIDLE; - return(TICKS_PER_SECOND*15); - } - } - } - break; - - /* - ** Harvest at current location until full or Tiberium exhausted. - */ - case HARVESTING: - if (!Harvesting()) { - IsHarvesting = false; - if (Tiberium_Load() == 0x0100) { - Status = FINDHOME; - } else { - if (!Goto_Tiberium() && !Target_Legal(NavCom)) { - ArchiveTarget = TARGET_NONE; - Status = FINDHOME; - } else { - Status = HARVESTING; - IsHarvesting = true; - } - } - return(1); - } else if (!Target_Legal(NavCom) && ArchiveTarget == TARGET_NONE) { - ArchiveTarget = ::As_Target(Coord_Cell(Coord)); - } - break; - - /* - ** Find and head to refinery. - */ - case FINDHOME: - if (!Target_Legal(NavCom)) { - - /* - ** Find nearby refinery and head to it? - */ - BuildingClass * nearest = Find_Docking_Bay(STRUCT_REFINERY, false); - - /* - ** Since the refinery said it was ok to load, establish radio - ** contact with the refinery and then await docking orders. - */ - if (nearest && Transmit_Message(RADIO_HELLO, nearest) == RADIO_ROGER) { - Status = HEADINGHOME; - } else { - ScenarioInit++; - nearest = Find_Docking_Bay(STRUCT_REFINERY, false); - ScenarioInit--; - if (nearest) { - Assign_Destination(::As_Target(nearest->Nearby_Location(this))); - } - } - } - break; - - /* - ** In communication with refinery so that it will successfully dock and - ** unload. If, for some reason, radio contact was lost, then hunt for - ** another refinery to unload at. - */ - case HEADINGHOME: - Assign_Mission(MISSION_ENTER); - return(1); - - case GOINGTOIDLE: - Assign_Mission(MISSION_GUARD); - break; - - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * UnitClass::Mission_Hunt -- This is the AI process for aggressive enemy units. * - * * - * Computer controlled units must be intelligent enough to find enemies as well as to * - * attack them. This AI process will handle both the simple attack process as well as the * - * scanning for enemy units to attack. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the delay before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1994 JLB : Created. * - *=============================================================================================*/ -int UnitClass::Mission_Hunt(void) -{ - Validate(); - if (*this == UNIT_MCV) { - switch (Status) { - - /* - ** This stage handles locating a convenient spot, rotating to face the correct - ** direction and then commencing the deployment operation. - */ - case 0: - if (Goto_Clear_Spot()) { - if (Try_To_Deploy()) { - Status = 1; - } - } - break; - - /* - ** This stage watchdogs the deployment operation and if for some reason, the deployment - ** is aborted (the IsDeploying flag becomes false), then it reverts back to hunting for - ** a convenient spot to deploy. - */ - case 1: - if (!IsDeploying) { - Status = 0; - } - break; - } - } else { - - if (*this == UNIT_GUNBOAT) { - if (!Target_Legal(NavCom)) { - if (PrimaryFacing == DIR_W) { - Assign_Destination( ::As_Target(XY_Cell(Map.MapCellX-1, Cell_Y(Coord_Cell(Coord)))) ); - } else { - Assign_Destination( ::As_Target(XY_Cell(Map.MapCellX+Map.MapCellWidth, Cell_Y(Coord_Cell(Coord)))) ); - } - Set_Speed(255); - } - if (!Speed) { - Set_Speed(255); - } - if (!Target_Legal(TarCom) || !In_Range(TarCom, 0)) { - Target_Something_Nearby(THREAT_AREA); - } - } else { - return(TarComClass::Mission_Hunt()); - } - } - return(TICKS_PER_SECOND); -} - - -/*********************************************************************************************** - * UnitClass::Look -- Perform map revelation from a unit's position. * - * * - * Reveal the map around the specified unit with the sighting range * - * associated with the specified unit. * - * * - * INPUT: incremental -- If looking is to process only the cells in the * - * outer ring of the unit's search radius, then * - * set this parameter to true. This method is * - * quite a bit faster than processing all cells, * - * but must be used with caution. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/08/1992 JLB : Created. * - * 03/08/1994 JLB : Added incremental option. * - * 04/15/1994 JLB : Converted to member function. * - *=============================================================================================*/ -void UnitClass::Look(bool incremental) -{ - Validate(); - //if (!IsInLimbo && IsOwnedByPlayer) { // Changed for mapping of multiple players - if (!IsInLimbo && House && House->IsHuman) { - int sight = Class->SightRange; - - if (sight) { - Map.Sight_From(House, Coord_Cell(Coord), sight, (*this == UNIT_GUNBOAT) ? false : incremental); // Passed our house into Map.Sight_From since it now needs to know who it is performing the action on behalf of. ST - 3/28/2019 2:55PM - } - } -} - - -/*********************************************************************************************** - * UnitClass::Overlap_List -- Determines overlap list for units. * - * * - * The unit overlap list is used to keep track of which cells are to * - * be marked for redraw. This is critical in order to keep the units * - * displayed correctly. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the overlap list pointer for the unit at its * - * present position. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/26/1994 JLB : Created. * - * 06/19/1994 JLB : Uses Coord_Spillable_List function. * - *=============================================================================================*/ -short const * UnitClass::Overlap_List(void) const -{ - Validate(); - static short const _gunboat[] = {-3, -2, 2, 3, REFRESH_EOL}; - int size; - - /* - ** The gunboat is a special case. - */ - if (*this == UNIT_GUNBOAT) { - return(&_gunboat[0]); - } - - size = ICON_PIXEL_W; - if (Is_Selected_By_Player() || IsFiring) { - size += 24; - } - if (Is_Selected_By_Player() || Class->IsGigundo || IsAnimAttached || Flagged != HOUSE_NONE) { - size = ICON_PIXEL_W*2; - } - return(Coord_Spillage_List(Coord, size)+1); -} - - -#ifdef NEVER -/********************************************************************************************* * - * UnitClass::Blocking_Object -- Determines how a object blocks a unit * - * * - * This routine is used by the Can_Enter_Cell logic when an object is in the desired cell * - * and it needs to know if that causes blockage. If blocked, this routine will return why. * - * * - * INPUT: TechnoClass * pointer to object that is blocking unit * - * * - * CELL the cell the unit is being blocked in * - * * - * OUTPUT: MoveBitType the way that the object is blocking the unit * - * * - * HISTORY: * - * 06/08/1995 PWG : Created. * - *=============================================================================================*/ -MoveBitType UnitClass::Blocking_Object(TechnoClass const *techno, CELL cell) const -{ - Validate(); - /* - ** There are some extra checks we need to make if the techno is a unit - */ - bool unit = (techno->What_Am_I() == RTTI_INFANTRY || techno->What_Am_I() == RTTI_UNIT); - CellClass const * cellptr = &Map[cell]; - - if (House->Is_Ally(techno)) { - - if (techno == Contact_With_Whom() && IsTethered) { - return(MOVE_BIT_OK); - } - - if (unit) { - /* - ** If the unit in question has a destination than we should - ** be prepared to wait for the unit to get out of our way. - */ - if (((FootClass *)techno)->NavCom != TARGET_NONE) { - int face = Dir_Facing(PrimaryFacing); - int techface = Dir_Facing(((FootClass const *)techno)->PrimaryFacing) ^4; - if (face != techface && Distance((AbstractClass const *)techno) > 0x1FF) { - return(MOVE_BIT_MOVING_BLOCK); - } else { -// Mono_Printf("Move No!\r"); - return(MOVE_BIT_NO); - } - } - - return(MOVE_BIT_TEMP); - } - } else { - - /* - ** If its an enemy unit, things are dealt with a little differently - */ - if (unit) { - -#ifdef NEVER - /* - ** If this is an enemy unit and we are not doing a find path then - ** we need to tell the unit to uncloak just in case it is a - ** stealth tank. - */ - if (!IsFindPath) { - techno->Do_Uncloak(); - } -#endif - - /* - ** Can we just run it over? - */ - if (techno->Class_Of().IsCrushable && (cellptr->Flag.Composite & 0xE0) == 0 && Class->IsCrusher) { - - /* - ** Now lets run it over. - */ - return(MOVE_BIT_OK); - } - - /* - ** If the object is cloaked, then consider it passable for findpath purposes, - ** but not so for all other cases. - */ - if (techno->Cloak == CLOAKED) { - if (House == techno->House) return(MOVE_BIT_NO); - if (IsFindPath) return(MOVE_BIT_OK); - return(MOVE_BIT_CLOAK); - } - - /* - ** If our vehicle is weapon equipped, then report that the cell occupier - ** needs only to be destroyed in order to make the cell passable. - */ - if (Class->Primary != WEAPON_NONE) { - return(MOVE_BIT_DESTROYABLE); - } - } - } - return(MOVE_BIT_NO); -} -#endif - - -/*********************************************************************************************** - * UnitClass::Can_Enter_Cell -- Determines cell entry legality. * - * * - * Use this routine to determine if the unit can enter the cell * - * specified and given the direction of entry specified. Typically, * - * this is used when determining unit travel path. * - * * - * INPUT: cell -- The cell to examine. * - * * - * facing -- The facing that the unit would enter the specified * - * cell. If this value is -1, then don't consider * - * facing when performing the check. * - * * - * OUTPUT: Returns the reason why it couldn't enter the cell or MOVE_OK if movement is * - * allowed. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/07/1992 JLB : Created. * - * 04/16/1994 JLB : Converted to member function. * - * 07/04/1995 JLB : Allowed to drive on building trying to enter it. * - *=============================================================================================*/ -MoveType UnitClass::Can_Enter_Cell(CELL cell, FacingType ) const -{ - Validate(); - CellClass const * cellptr = &Map[cell]; - - if ((unsigned)cell >= MAP_CELL_TOTAL) return(MOVE_NO); - - /* - ** The gunboat can always move. This prevents it from trying to move around possible hover - ** craft blockage. - */ - if (*this == UNIT_GUNBOAT) return(MOVE_OK); - - /* - ** Moving off the edge of the map is not allowed unless - ** this is a loaner vehicle. - */ - if (IsLocked && !IsALoaner && !ScenarioInit && !Map.In_Radar(cell)) { - return(MOVE_NO); - } - - MoveType retval = MOVE_OK; - - /* - ** Certain vehicles can drive over walls. Check for this case and - ** and return the appropriate flag. Other units treat walls as impassable. - */ - if (cellptr->Overlay != OVERLAY_NONE) { - OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay); - - if (optr->IsCrate && !House->IsHuman) { - return(MOVE_NO); - } - - if (optr->IsWall) { - if (Class->Primary != WEAPON_NONE) { - WarheadTypeClass const * whead = &Warheads[BulletTypeClass::As_Reference(Weapons[Class->Primary].Fires).Warhead]; - - if (whead->IsWallDestroyer || (whead->IsWoodDestroyer && optr->IsWooden)) { - if (!House->IsHuman && !House->Is_Ally(cellptr->Owner)) { - if (retval < MOVE_DESTROYABLE) retval = MOVE_DESTROYABLE; - } else { - return(MOVE_NO); - } - } else { - return(MOVE_NO); - } - } else { - return(MOVE_NO); - } - } - } - - /* - ** If the cell is out and out impassable because of underlying terrain, then - ** return this immutable fact. - */ -#ifdef ADVANCED - if (retval != MOVE_DESTROYABLE && !Ground[cellptr->Land_Type()].Cost[Class->Speed]) { -#else - if (!Ground[cellptr->Land_Type()].Cost[Class->Speed]) { -#endif - return(MOVE_NO); - } - - /* - ** Loop through all of the objects in the square setting a bit - ** for how they affect movement. - */ - bool crushable = false; - ObjectClass *obj = cellptr->Cell_Occupier(); - while (obj) { - - if (obj != this) { - - /* - ** Always allow entry if trying to move on a cell with - ** authorization from the occupier. - */ - if (obj == Contact_With_Whom() && (IsTethered || (obj->What_Am_I() == RTTI_BUILDING && *((BuildingClass *)obj) == STRUCT_REPAIR))) { - return(MOVE_OK); - } - - bool is_moving = (obj->What_Am_I() == RTTI_INFANTRY || obj->What_Am_I() == RTTI_UNIT) && Target_Legal(((FootClass *)obj)->NavCom); - - if (House->Is_Ally(obj)) { - if (is_moving) { - int face = Dir_Facing(PrimaryFacing); - int techface = Dir_Facing(((FootClass const *)obj)->PrimaryFacing) ^4; - if (face == techface && Distance((AbstractClass const *)obj) <= 0x1FF) { - return(MOVE_NO); - } - if (retval < MOVE_MOVING_BLOCK) retval = MOVE_MOVING_BLOCK; - } else { - if (obj->What_Am_I() == RTTI_BUILDING) return(MOVE_NO); - if (retval < MOVE_TEMP) retval = MOVE_TEMP; - } - } else { - - /* - ** Cloaked enemy objects are not considered if this is a Find_Path() - ** call. - */ - if (!obj->Is_Techno() || ((TechnoClass *)obj)->Cloak != CLOAKED) { - - /* - ** If this unit can crush infantry, and there is an enemy infantry in the - ** cell, don't consider the cell impassible. This is true even if the unit - ** doesn't contain a legitimate weapon. - */ - if (!Class->IsCrusher || !obj->Class_Of().IsCrushable) { - - /* - ** Any non-allied blockage is considered impassible if the unit - ** is not equipped with a weapon. - */ - if (Class->Primary == WEAPON_NONE) return(MOVE_NO); - - /* - ** Some kinds of terrain are considered destroyable if the unit is equipped - ** with the weapon that can destroy it. Otherwise, the terrain is considered - ** impassable. - */ - switch (obj->What_Am_I()) { - case RTTI_TERRAIN: - if (((TerrainClass *)obj)->Class->IsFlammable && - BulletTypeClass::As_Reference(Weapons[Class->Primary].Fires).Warhead == WARHEAD_FIRE) { - - if (retval < MOVE_DESTROYABLE) retval = MOVE_DESTROYABLE; - } else { - return(MOVE_NO); - } - break; - - default: - if (retval < MOVE_DESTROYABLE) retval = MOVE_DESTROYABLE; - break; - } - } else { - crushable = true; - } - } else { - if (retval < MOVE_CLOAK) retval = MOVE_CLOAK; - } - } - } - - /* - ** Move to next object in chain. - */ - obj = obj->Next; - } - - /* - ** If some allied object has reserved the cell, then consider the cell - ** as blocked by a moving object. - */ - if (retval == MOVE_OK && !crushable && cellptr->Flag.Composite) { - - /* - ** If reserved by a vehicle, then consider this blocked terrain. - */ - if (cellptr->Flag.Occupy.Vehicle) { - retval = MOVE_MOVING_BLOCK; - } else { - if (cellptr->InfType != HOUSE_NONE && House->Is_Ally(cellptr->InfType)) { - retval = MOVE_MOVING_BLOCK; - } else { - - /* - ** Enemy infantry have reserved the cell. If this unit can crush - ** infantry, consider the cell passable. If not, then consider the - ** cell destroyable if it has a weapon. If neither case applies, then - ** this vehicle should avoid the cell altogether. - */ - if (!Class->IsCrusher) { - if (Class->Primary != WEAPON_NONE) { - retval = MOVE_DESTROYABLE; - } else { - return(MOVE_NO); - } - } - } - } - } - - /* - ** If its ok to move into the cell because we can crush whats in the cell, then - ** make sure no one else is already moving into the cell to crush something. - */ - if (retval == MOVE_OK && crushable && cellptr->Flag.Occupy.Vehicle) { - -#ifdef ADVANCED - /* - ** However, if the cell is occupied by a crushable vehicle, then we can - ** never be sure if some other friendly vehicle is also trying to crush - ** the cell at the same time. In the case of a crushable vehicle in the - ** cell, then allow entry. - */ - if (!cellptr->Cell_Unit() || !cellptr->Cell_Unit()->Class->IsCrushable) { - return(MOVE_MOVING_BLOCK); - } -#else - return(MOVE_MOVING_BLOCK); -#endif - } - - /* - ** Return with the most severe reason why this cell would be impassable. - */ - return(retval); -} - - -/*********************************************************************************************** - * UnitClass::Init -- Clears all units for scenario preparation. * - * * - * This routine will zero out the unit list and unit objects. This routine is typically * - * used in preparation for a new scenario load. All units are guaranteed to be eliminated * - * by this routine. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/15/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Init(void) -{ - UnitClass * ptr; - - Units.Free_All(); - - ptr = new UnitClass(); - VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; - delete ptr; -} - - -/*********************************************************************************************** - * UnitClass::Target_Coord -- The coordinate to use when targeting this unit. * - * * - * Sometimes the coordinate to use when targeting an object is not the same as its center * - * coordinate. This is especially true for boats since leading their movement is needed * - * in order have any chance of hitting. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the coordinate to fire upon when attacking the unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/19/1994 JLB : Created. * - *=============================================================================================*/ -COORDINATE UnitClass::Target_Coord(void) const -{ - Validate(); -// if (*this == UNIT_GUNBOAT) { -// return(Coord_Move(Coord, PrimaryFacing.Current(), 0x0080)); -// } - return(TarComClass::Center_Coord()); -} - - -/*********************************************************************************************** - * UnitClass::Scatter -- Causes the unit to travel to a nearby safe cell. * - * * - * This routine is called when the unit discovers that it should get out of the "hot seat" * - * and move to an adjacent cell. Since the safety of the adjacent cell is not determined * - * before the move begins, it will appear that the unit is just scattering (which it * - * should). * - * * - * INPUT: threat -- The coordinate of the source of the threat. The unit will try to move * - * roughly away from the threat. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/25/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Scatter(COORDINATE threat, bool forced, bool nokidding) -{ - Validate(); - if (*this != UNIT_GUNBOAT && *this != UNIT_HOVER) { - if (PrimaryFacing.Is_Rotating()) return; - if (Target_Legal(NavCom) && !nokidding) return; - if (threat == 0) { - Assign_Destination(::As_Target(Map.Nearby_Location(Coord_Cell(Coord)))); - } else if (((!Target_Legal(TarCom) && !Target_Legal(NavCom)) || forced || nokidding || Random_Pick(1, 4) == 1)) { - FacingType toface; - FacingType newface; - CELL newcell; - - if (threat) { - toface = Dir_Facing(Direction8(threat, Coord)); - toface = toface + (Random_Pick(0, 2)-1); - } else { - toface = Dir_Facing(PrimaryFacing.Current()); - } - - for (FacingType face = FACING_N; face < FACING_COUNT; face++) { - newface = toface + face; - newcell = Adjacent_Cell(Coord_Cell(Coord), newface); - - if (Map.In_Radar(newcell) && Can_Enter_Cell(newcell) == MOVE_OK) { - Assign_Destination(::As_Target(newcell)); - } - } - } - } -} - - -/*********************************************************************************************** - * UnitClass::Stop_Driver -- Handles removing occupation bits when driving stops. * - * * - * This routine will remove the "reservation" flag (if present) when the vehicle is * - * required to stop movement. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the vehicle stopped? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Stop_Driver(void) -{ - Validate(); - - /* - ** We only need to do something if the vehicle is actually going - ** somewhere. - */ - if (Head_To_Coord()) { - - /* - ** Safe off whether the vehicle is down or not so we know whether - ** we have to put it back down. - */ - int temp = IsDown; - - /* - ** If the vehicle is down, pick it up so it doesnt interfere with - ** our flags. - */ - if (temp) { - Mark(MARK_UP); - } - - /* - ** Call the drive class function which will let us release the - ** reserved track. - */ - Mark_Track(Head_To_Coord(), MARK_UP); - - /* - ** If it was down it should be down when we are done. - */ - if (temp) { - Mark(MARK_DOWN); - } - } - return(TarComClass::Stop_Driver()); -} - - -/*********************************************************************************************** - * UnitClass::Start_Driver -- Starts driving and reserves destination cell. * - * * - * This routine will start the vehicle moving by marking the destination cell as * - * reserved. Cells must be reserved in this fashion or else they might become occupied as * - * the vehicle is proceeding toward it. * - * * - * INPUT: headto -- The location where the vehicle will be heading. * - * * - * OUTPUT: bool; Was the vehicle started to move? Failure could be the result of the cell * - * being occupied. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Start_Driver(COORDINATE & headto) -{ - Validate(); - if (TarComClass::Start_Driver(headto)) { - Mark_Track(headto, MARK_DOWN); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Limbo -- Prepares vehicle and then limbos it. * - * * - * This routine removes the occupation bits for the vehicle and also handles cleaning up * - * any vehicle reservation bits. After this, it then proceeds with limboing the unit. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Was the vehicle limboed? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/22/1994 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Limbo(void) -{ - Validate(); - if (!IsInLimbo) { - Stop_Driver(); - } - if (TarComClass::Limbo()) { - if (Flagged != HOUSE_NONE) { - HouseClass::As_Pointer(Flagged)->Flag_Attach(Coord_Cell(Coord)); - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Response_Select -- Voice feedback when selecting the unit. * - * * - * This is the voice to play when the unit is selected. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/30/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Response_Select(void) -{ - Validate(); - static VocType _response[] = { - VOC_VEHIC, - VOC_UNIT, - VOC_YESSIR, - VOC_YESSIR, - VOC_YESSIR, - VOC_AWAIT - }; - VocType response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - - if (*this == UNIT_TRIC || *this == UNIT_TREX || *this == UNIT_RAPT || *this == UNIT_STEG) { - response = VOC_DINOYES; - } - - if (AllowVoice) { - Sound_Effect(response, 0, -(Units.ID(this)+1)); - } -} - - -/*********************************************************************************************** - * UnitClass::Response_Move -- Voice feedback when ordering the unit to move. * - * * - * This plays the audio feedback when ordering this unit to move to a new destination. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/30/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Response_Move(void) -{ - Validate(); - static VocType _response[] = { - VOC_MOVEOUT, - VOC_MOVEOUT, - VOC_MOVEOUT, - VOC_ACKNOWL, - VOC_AFFIRM, - VOC_AFFIRM - }; - VocType response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - - if (*this == UNIT_TRIC || *this == UNIT_TREX || *this == UNIT_RAPT || *this == UNIT_STEG) { - response = VOC_DINOMOUT; - } - - if (AllowVoice) { - Sound_Effect(response, 0, -(Units.ID(this)+1)); - } -} - - -/*********************************************************************************************** - * UnitClass::Response_Attack -- Voice feedback when ordering the unit to attack a target. * - * * - * This plays the audio feedback when ordering this unit to attack. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 12/30/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Response_Attack(void) -{ - Validate(); - static VocType _response[] = { - VOC_AFFIRM, - VOC_ACKNOWL, - VOC_YESSIR, - VOC_YESSIR, - VOC_YESSIR - }; - VocType response = _response[Sim_Random_Pick(0, (int)(sizeof(_response) / sizeof(_response[0]))-1)]; - - if (*this == UNIT_TRIC || *this == UNIT_TREX || *this == UNIT_RAPT || *this == UNIT_STEG) { - response = VOC_DINOMOUT; - } - - if (AllowVoice) { - Sound_Effect(response, 0, -(Units.ID(this)+1)); - } -} - - -/*********************************************************************************************** - * UnitClass::What_Action -- Determines what action would occur if clicked on object. * - * * - * Use this function to determine what action would likely occur if the specified object * - * were clicked on while this unit was selected as current. This function controls, not * - * only the action to perform, but indirectly controls the cursor shape to use as well. * - * * - * INPUT: object -- The object that to check for against "this" object. * - * * - * OUTPUT: Returns with the default action to perform. If no clear action can be determined, * - * then ACTION_NONE is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/11/1995 JLB : Created. * - *=============================================================================================*/ -ActionType UnitClass::What_Action(ObjectClass * object) const -{ - Validate(); - ActionType action = TarComClass::What_Action(object); - - /* - ** If the unit doesn't have a weapon, but can crush the object, then consider - ** the object as a movable location. - */ - if (action == ACTION_ATTACK && !Can_Player_Fire()) { - if (Class->IsCrusher && object->Class_Of().IsCrushable) { - action = ACTION_MOVE; - } else { - action = ACTION_SELECT; - } - } - - /* - ** Don't allow special deploy action unless there is something to deploy. - */ - if (action == ACTION_SELF) { - if (*this != UNIT_MCV) { - if (!Class->IsTransporter || !How_Many()) { - action = ACTION_NONE; - } - } else { - ((ObjectClass &)(*this)).Mark(MARK_UP); - if (!BuildingTypeClass::As_Reference(STRUCT_CONST).Legal_Placement(Coord_Cell(Adjacent_Cell(Center_Coord(), FACING_NW)))) { - action = ACTION_NO_DEPLOY; - } - ((ObjectClass &)(*this)).Mark(MARK_DOWN); - } - } - - /* - ** Special return to friendly refinery action. - */ - if (Is_Owned_By_Player() && House->Class->House == object->Owner() && object->What_Am_I() == RTTI_BUILDING && ((UnitClass *)this)->Transmit_Message(RADIO_CAN_LOAD, (TechnoClass*)object) == RADIO_ROGER) { - action = ACTION_ENTER; - } - - /* - ** Special return to friendly repair factory action. - */ - if (Is_Owned_By_Player() && House->Class->House == object->Owner() && action == ACTION_SELECT && object->What_Am_I() == RTTI_BUILDING) { - BuildingClass * building = (BuildingClass *)object; - if (building->Class->Type == STRUCT_REPAIR && !building->In_Radio_Contact() && !building->Is_Something_Attached()) { - action = ACTION_MOVE; - } - } - - return(action); -} - - -ActionType UnitClass::What_Action(CELL cell) const -{ - Validate(); - ActionType action = TarComClass::What_Action(cell); - if (action == ACTION_MOVE && Map[cell].Land_Type() == LAND_TIBERIUM && Class->IsToHarvest) { - return(ACTION_HARVEST); - } - return(action); -} - - -/*********************************************************************************************** - * UnitClass::Can_Player_Move -- Determines if the player is legally allowed to move it. * - * * - * Use this routine to see if the player can move this object. If the player can move the * - * object, even only in theory, then this function returns true. In all other cases, such * - * as for enemy units, gunboats, or hovercraft, it returns false. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Can the player give this object a movement order? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 01/19/1995 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Can_Player_Move(void) const -{ - Validate(); - return(TarComClass::Can_Player_Move() && *this != UNIT_GUNBOAT && *this != UNIT_HOVER); -} - - -/*********************************************************************************************** - * UnitClass::Read_INI -- Reads units from scenario INI file. * - * * - * This routine is used to read all the starting units from the * - * scenario control INI file. The units are created and placed on the * - * map by this routine. * - * * - * INI entry format: * - * Housename, Typename, Strength, Coord, Facingnum, Missionname, Triggername * - * * - * INPUT: buffer -- Pointer to the loaded scenario INI file. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/24/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Read_INI(char *buffer) -{ - UnitClass *unit; // Working unit pointer. - char *tbuffer; // Accumulation buffer of unit IDs. - HousesType inhouse; // Unit house. - UnitType classid; // Unit class. - int len; // Length of data in buffer. - char buf[128]; - - len = strlen(buffer) + 2; - tbuffer = buffer + len; - - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); - while (*tbuffer != '\0') { - - WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); - inhouse = HouseTypeClass::From_Name(strtok(buf, ",")); - if (inhouse != HOUSE_NONE) { - classid = UnitTypeClass::From_Name(strtok(NULL, ",")); - - if (classid != UNIT_NONE) { - - if (HouseClass::As_Pointer(inhouse) != NULL) { - unit = new UnitClass(classid, inhouse); - if (unit) { - - /* - ** Read the raw data. - */ - int strength = atoi(strtok(NULL, ",\r\n")); - COORDINATE coord = Cell_Coord((CELL)atoi(strtok(NULL, ",\r\n"))); - DirType dir = (DirType)atoi(strtok(NULL, ",\r\n")); - MissionType mission = MissionClass::Mission_From_Name(strtok(NULL, ",\n\r")); - unit->Trigger = TriggerClass::As_Pointer(strtok(NULL,",\r\n")); - if (unit->Trigger) { - unit->Trigger->AttachCount++; - } - - if (unit->Unlimbo(coord, dir)) { - unit->Strength = Fixed_To_Cardinal(unit->Class->MaxStrength, strength); - if (GameToPlay == GAME_NORMAL || unit->House->IsHuman) { - unit->Assign_Mission(mission); - unit->Commence(); - } else { - unit->Enter_Idle_Mode(); - } - - /* - ** The gunboat is a special case: It must "drive" off the edge of the map. - ** Just pick the map edge that it is facing and set that as the destination - ** of the drive. - */ - if (*unit == UNIT_GUNBOAT) { - unit->PrimaryFacing.Set_Desired(DIR_W); - unit->PrimaryFacing.Set_Current(DIR_W); - unit->Assign_Mission(MISSION_HUNT); - unit->Commence(); - unit->Assign_Destination( ::As_Target(XY_Cell(Map.MapCellX-1, Cell_Y(Coord_Cell(unit->Coord))))); - } - - } else { - - /* - ** If the unit could not be unlimboed, then this is a catastrophic error - ** condition. Delete the unit. - */ - delete unit; - } - } - } - } - } - tbuffer += strlen(tbuffer)+1; - } -} - - -/*********************************************************************************************** - * UnitClass::Write_INI -- Writes all the units out to an INI file. * - * * - * This routine writes all of the units in the game out to an INI file. This is used * - * in the scenario editor when the game needs to be saved. * - * * - * INI entry format: * - * Housename, Typename, Strength, Coord, Facingnum, Missionname, Triggername * - * * - * INPUT: buffer -- A pointer to the loaded INI file staging area. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1994 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Write_INI(char *buffer) -{ - int index; - char uname[10]; - char buf[128]; - char *tbuffer; // Accumulation buffer of unit IDs. - - /* - ** First, clear out all existing unit data from the ini file. - */ - tbuffer = buffer + strlen(buffer) + 2; - WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); - while (*tbuffer != '\0') { - WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); - tbuffer += strlen(tbuffer)+1; - } - - /* - ** Write the unit data out. - */ - for (index = 0; index < Units.Count(); index++) { - UnitClass * unit; - - unit = Units.Ptr(index); - if (!unit->IsInLimbo && unit->IsActive) { - - sprintf(uname, "%03d", index); - sprintf(buf, "%s,%s,%d,%u,%d,%s,%s", - unit->House->Class->IniName, - unit->Class->IniName, - unit->Health_Ratio(), - Coord_Cell(unit->Coord), - unit->PrimaryFacing.Current(), - MissionClass::Mission_Name(unit->Mission), - unit->Trigger ? unit->Trigger->Get_Name() : "None" - ); - WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); - } - } -} - - -/*********************************************************************************************** - * UnitClass::Exit_Repair -- Drive the unit off the repair facility. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 04/03/1995 BWG : Created. * - *=============================================================================================*/ -#define XYCELL(x,y) (y*MAP_CELL_W+x) -void UnitClass::Exit_Repair(void) -{ - Validate(); - int i; - CELL cell; - bool found = false; - static short const ExitRepair[] = { - XYCELL(0,-2), - XYCELL(1,-1), - XYCELL(2, 0), - XYCELL(1, 1), - XYCELL(0, 2), - XYCELL(-1,1), - XYCELL(-2,0), - XYCELL(-1,-1) - }; - - cell = Coord_Cell(Coord) + ExitRepair[Dir_Facing(PrimaryFacing.Current())]; - if (Can_Enter_Cell(cell) == MOVE_OK) found = true; - - if (!found) for (i=0; i<8; i++) { - cell = Coord_Cell(Coord) + ExitRepair[i]; - if (Can_Enter_Cell(cell) == MOVE_OK) { - found = true; - break; - } - } - if (found) { - DirType dir = Direction(cell); - - Assign_Mission(MISSION_MOVE); - Assign_Destination(::As_Target(cell)); - } -} - - -/*********************************************************************************************** - * UnitClass::Mission_Guard -- Special guard mission override processor. * - * * - * This routine will intercept the guard mission and if it is for a hovercraft, assign * - * it the unload mission instead. This prevents the hovercraft from being stuck in the * - * water if something unexpected causes it to drop into guard mode. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the time delay before this command is executed again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/08/1995 JLB : Created. * - * 05/08/1995 JLB : Fixes gunboat problems. * - *=============================================================================================*/ -int UnitClass::Mission_Guard(void) -{ - Validate(); - if (*this == UNIT_HOVER) { - if (Is_Something_Attached()) { - Assign_Mission(MISSION_UNLOAD); - Find_LZ(); - } else { - Exit_Map(); - } - return(TICKS_PER_SECOND); - } - - if (*this == UNIT_GUNBOAT) { - Assign_Mission(MISSION_HUNT); - return(TICKS_PER_SECOND); - } - - if (*this == UNIT_HARVESTER && !House->IsHuman) { - Assign_Mission(MISSION_HARVEST); - return(TICKS_PER_SECOND); - } - -#ifdef USE_RA_AI - /* - ** Copied functionality from RA for AI. ST - 7/25/2019 3:11PM - */ - if (GameToPlay != GAME_NORMAL) { - if (*this == UNIT_MCV && House->IsBaseBuilding && House->IsHuman == false) { - Assign_Mission(MISSION_UNLOAD); - return(TICKS_PER_SECOND + Random_Pick(0, 2)); - } - } -#endif // USE_RA_AI - - return(TarComClass::Mission_Guard()); -} - - -/*********************************************************************************************** - * UnitClass::Mission_Move -- Handles special move mission overrides. * - * * - * This routine intercepts the normal move mission and if a gunboat is being processed, * - * changes its mission to hunt. This is an attempt to keep the gunboat on the hunt mission * - * regardless of what the player did. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the number of ticks before this routine should be called again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/09/1995 JLB : Created. * - *=============================================================================================*/ -int UnitClass::Mission_Move(void) -{ - Validate(); - IsHarvesting = false; - - /* - ** Always make sure that that transport door is closed if the vehcile is moving. - */ - if (!Is_Door_Closed()) { - APC_Close_Door(); - } - - /* - ** Gunboats must always have the hunt mission. - */ - if (*this == UNIT_GUNBOAT) { - Assign_Mission(MISSION_HUNT); - return(TICKS_PER_SECOND); - } - return(TarComClass::Mission_Move()); -} - - -/*********************************************************************************************** - * UnitClass::Desired_Load_Dir -- Determines the best cell and facing for loading. * - * * - * This routine examines the unit and adjacent cells in order to find the best facing * - * for the transport and best staging cell for the potential passengers. This location is * - * modified by adjacent cell passability and direction of the potential passenger. * - * * - * INPUT: passenger -- Pointer to the potential passenger. * - * * - * moveto -- Reference to the cell number that specifies where the potential * - * passenger should move to first. * - * * - * OUTPUT: Returns with the direction the transport should face before opening the transport * - * door. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -DirType UnitClass::Desired_Load_Dir(ObjectClass * passenger, CELL & moveto) const -{ - Validate(); - /* - ** Determine the ideal facing that provides the least resistance. This would be the direction - ** of the potential passenger or the current transport facing if it is going to unload. - */ - DirType faceto; - if (passenger) { - faceto = Direction(passenger); - } else { - faceto = PrimaryFacing.Current() + DIR_S; - } - - /* - ** Sweep through the adjacent cells in order to find the best candidate. - */ - FacingType bestdir; - int bestval = -1; - for (FacingType face = FACING_N; face < FACING_COUNT; face++) { - int value = 0; - CELL cellnum = Adjacent_Cell(Coord_Cell(Coord), face); - - /* - ** Base the initial value of the potential cell according to whether the passenger is - ** allowed to enter the cell. If it can't, then give such a negative value to the - ** cell so that it is prevented from ever choosing that cell for load/unload. - */ - if (passenger) { - value = (passenger->Can_Enter_Cell(cellnum) == MOVE_OK || Coord_Cell(passenger->Coord) == cellnum) ? 128 : -128; - } else { - CellClass * cell = &Map[cellnum]; - if (Ground[cell->Land_Type()].Cost[SPEED_FOOT] == 0 || cell->Flag.Occupy.Building || cell->Flag.Occupy.Vehicle || cell->Flag.Occupy.Monolith || (cell->Flag.Composite & 0x01F) == 0x01F) { - value = -128; - } else { - if (cell->Cell_Techno() && !House->Is_Ally(cell->Cell_Techno())) { - value = -128; - } else { - value = 128; - } - } - } - - /* - ** Give more weight to the cells that require the least rotation of the transport or the - ** least roundabout movement for the potential passenger. - */ - value -= (int)ABS(Dir_Diff(Facing_Dir(face), faceto)); - if (face == FACING_S) { - value -= 100; - } - if (face == FACING_SW || face == FACING_SE) value += 64; - - /* - ** If the value for the potiential cell is greater than the last recorded potential - ** value, then record this cell as the best candidate. - */ - if (bestval == -1 || value > bestval) { - bestval = value; - bestdir = face; - } - } - - /* - ** If a suitable direction was found, then return with the direction value. - */ - moveto = 0; - if (bestval > 0) { - static DirType _desired_to_actual[FACING_COUNT] = {DIR_S, DIR_SW, DIR_NW, DIR_NW, DIR_NE, DIR_NE, DIR_NE, DIR_SE}; - - moveto = Adjacent_Cell(Coord_Cell(Coord), bestdir); - return(_desired_to_actual[bestdir]); - } - return(DIR_S); -} - - -/*********************************************************************************************** - * UnitClass::Mission_Attack -- Handles the mission attack logic. * - * * - * This routine intercepts the normal mission attack logic. If a gunboat is assigned the * - * attack mission then it must be converted back to a hunt mission. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the time before calling this routine again. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -int UnitClass::Mission_Attack(void) -{ - Validate(); - if (*this == UNIT_GUNBOAT) { - Assign_Mission(MISSION_HUNT); - return(TICKS_PER_SECOND); - } - return(TarComClass::Mission_Attack()); -} - - -/*********************************************************************************************** - * UnitClass::Flag_Attach -- Attaches a house flag to this unit. * - * * - * This routine will attach a house flag to this unit. * - * * - * INPUT: house -- The house that is having its flag attached to it. * - * * - * OUTPUT: Was the house flag successfully attached to this unit? * - * * - * WARNINGS: A unit can only carry one flag at a time. This might be a reason for failure * - * of this routine. * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Flag_Attach(HousesType house) -{ - Validate(); - if (house != HOUSE_NONE && Flagged == HOUSE_NONE) { - Flagged = house; - Mark(MARK_CHANGE); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Flag_Remove -- Removes the house flag from this unit. * - * * - * This routine will remove the house flag that is attached to this unit. * - * * - * INPUT: none * - * * - * OUTPUT: Was the flag successfully removed? * - * * - * WARNINGS: This routine doesn't put the flag into a new location. That operation must * - * be performed or else the house flag will cease to exist. * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -bool UnitClass::Flag_Remove(void) -{ - Validate(); - if (Flagged != HOUSE_NONE) { - Flagged = HOUSE_NONE; - Mark(MARK_CHANGE); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * UnitClass::Stun -- Stuns the unit in preparation for unit removal. * - * * - * This routine intercepts the stun operation for the unit and if there is a house flag * - * attached, it will drop it to the ground. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/23/1995 JLB : Created. * - *=============================================================================================*/ -void UnitClass::Stun(void) -{ - Validate(); - if (Flagged != HOUSE_NONE) { - HouseClass::As_Pointer(Flagged)->Flag_Attach(Coord_Cell(Coord)); - } - TarComClass::Stun(); -} - - -/*********************************************************************************************** - * UnitClass::Pip_Count -- Fetchs the number of pips to display on unit. * - * * - * This routine is used to fetch the number of "fullness" pips to display on the unit. * - * This will either be the number of passengers or the percentage full (in 1/5ths) of * - * a harvester. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the number of pips to draw on this unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -int UnitClass::Pip_Count(void) const -{ - Validate(); - if (Class->IsTransporter) { - return(How_Many()); - } - if (Class->IsToHarvest) { - return(Fixed_To_Cardinal(UnitTypeClass::FULL_LOAD_CREDITS/100, Tiberium_Load())); - } - return(0); -} - - -/*********************************************************************************************** - * UnitClass::APC_Close_Door -- Closes an APC door. * - * * - * This routine will initiate closing of the APC door. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -void UnitClass::APC_Close_Door(void) -{ - Validate(); - Close_Door(10, 2); -} - - -/*********************************************************************************************** - * UnitClass::APC_Open_Door -- Opens an APC door. * - * * - * This routine will initiate opening of the APC door. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/25/1995 JLB : Created. * - *=============================================================================================*/ -void UnitClass::APC_Open_Door(void) -{ - Validate(); - if (!IsDriving && !IsRotating) { - if (PrimaryFacing == DIR_NW || PrimaryFacing == DIR_NE) { - Open_Door(10, 2); - } else { - Open_Door(1, 2); - } - } -} - - -/*********************************************************************************************** - * UnitClass::Remap_Table -- Fetches the remap table to use for this object. * - * * - * Use this routine to determine the rendering remap table to use for this object. The * - * remap table is normally the unit remap table, except for the MCV and the Harvestor. * - * These units use the building remap table since these units become part of the building * - * animation. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the remap table to use for this unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/08/1995 JLB : Created. * - *=============================================================================================*/ -void const * UnitClass::Remap_Table(void) -{ - Validate(); - if (*this == UNIT_MCV || *this == UNIT_HARVESTER) { - return(House->Remap_Table(IsBlushing, false)); - } - return(TarComClass::Remap_Table()); -} - - -/*********************************************************************************************** - * UnitClass::Crew_Type -- Fetches the kind of crew that this object produces. * - * * - * When a unit is destroyed, a crew member might be generated. This routine will return * - * with the infantry type to produce for this unit. This routine will be called for every * - * survivor that is generated. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a suggested infantry type to generate as a survivor from this unit. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -InfantryType UnitClass::Crew_Type(void) const -{ - Validate(); - if (Class->Primary == WEAPON_NONE) { - if (Random_Pick(0, 1) == 0) { - return(INFANTRY_C1); - } else { - return(INFANTRY_C7); - } - } - return(TarComClass::Crew_Type()); -} - - -/*********************************************************************************************** - * UnitClass::What_Am_I -- Returns with the RTTI type this object is. * - * * - * This will return that this is a normal vehicle unit type. Each object class overrides * - * this function in order to provide run time type identification support. * - * * - * INPUT: none * - * * - * OUTPUT: Returns the RTTI type that this object is (i.e., RTTI_UNIT). * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1995 JLB : Created. * - *=============================================================================================*/ -RTTIType UnitClass::What_Am_I(void) const -{ - Validate(); - return(RTTI_UNIT); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/UNIT.H b/code/TIBERIANDAWN/UNIT.H deleted file mode 100644 index e16e56e..0000000 --- a/code/TIBERIANDAWN/UNIT.H +++ /dev/null @@ -1,213 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\unit.h_v 2.19 16 Oct 1995 16:45:56 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : UNIT.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 14, 1994 * - * * - * Last Update : April 14, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef UNIT_H -#define UNIT_H - -#include "tarcom.h" -#include "radio.h" -#include "cargo.h" -#include "mission.h" -#include "target.h" - - -/**************************************************************************** -** For each instance of a unit (vehicle) in the game, there is one of -** these structures. This structure holds information that is specific -** and dynamic for a particular unit. -*/ -class UnitClass : public TarComClass -{ - public: - - /* - ** This records the house flag that this object is currently carrying. - */ - HousesType Flagged; - - /*--------------------------------------------------------------------- - ** Constructors, Destructors, and overloaded operators. - */ - static void * operator new(size_t size); - static void operator delete(void *ptr); - UnitClass(void) {}; - UnitClass(UnitType classid, HousesType house); - operator UnitType(void) const {return Class->Type;}; - virtual ~UnitClass(void); - virtual RTTIType What_Am_I(void) const; - - /*--------------------------------------------------------------------- - ** Member function prototypes. - */ - static void Init(void); - - bool Goto_Clear_Spot(void); - bool Try_To_Deploy(void); - - int Tiberium_Check(CELL ¢er, int x, int y); - bool Flag_Attach(HousesType house); - bool Flag_Remove(void); - void Find_LZ(void); - bool Unload_Hovercraft_Process(void); - bool Goto_Tiberium(void); - bool Harvesting(void); - void APC_Close_Door(void); - void APC_Open_Door(void); - - /* - ** Query functions. - */ - virtual bool Can_Player_Move(void) const; - virtual int Pip_Count(void) const; - virtual InfantryType Crew_Type(void) const; - - /* - ** Coordinate inquiry functions. These are used for both display and - ** combat purposes. - */ - virtual COORDINATE Sort_Y(void) const; - - /* - ** Object entry and exit from the game system. - */ - virtual bool Unlimbo(COORDINATE , DirType facing=DIR_N); - virtual bool Limbo(void); - - /* - ** Display and rendering support functionality. Supports imagery and how - ** object interacts with the map and thus indirectly controls rendering. - */ - virtual void const * Remap_Table(void); - virtual void Look(bool incremental=false); - virtual short const * Overlap_List(void) const; - virtual void Draw_It(int x, int y, WindowNumberType window); - - /* - ** ST Added 1/15/2019 2:44PM - */ - //virtual bool Get_Draw_Parameters(void); - - /* - ** User I/O. - */ - virtual ActionType What_Action(CELL cell) const; - virtual ActionType What_Action(ObjectClass * object) const; - virtual void Active_Click_With(ActionType action, ObjectClass * object); - virtual void Active_Click_With(ActionType action, CELL cell); - virtual void Player_Assign_Mission(MissionType mission, TARGET target=TARGET_NONE, TARGET destination=TARGET_NONE); - virtual void Response_Select(void); - virtual void Response_Move(void); - virtual void Response_Attack(void); - - /* - ** Combat related. - */ - virtual COORDINATE Target_Coord(void) const; - virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source=0); - virtual TARGET As_Target(void) const; - virtual void Stun(void); - - /* - ** Driver control support functions. These are used to control cell - ** occupation flags and driver instructions. - */ - virtual bool Stop_Driver(void); - virtual bool Start_Driver(COORDINATE & coord); - - /* - ** AI. - */ - virtual DirType Desired_Load_Dir(ObjectClass * passenger, CELL & moveto) const; - virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param); - virtual void AI(void); - virtual int Mission_Attack(void); - virtual int Mission_Unload(void); - virtual int Mission_Guard(void); - virtual int Mission_Harvest(void); - virtual int Mission_Hunt(void); - virtual int UnitClass::Mission_Move(void); - virtual FireErrorType Can_Fire(TARGET, int which) const; - - /* - ** Scenario and debug support. - */ - #ifdef CHEAT_KEYS - virtual void Debug_Dump(MonoClass *mono) const; - #endif - - /* - ** Movement and animation. - */ - virtual void Enter_Idle_Mode(bool initial=false); - virtual MoveType Can_Enter_Cell(CELL cell, FacingType facing=FACING_NONE) const; - virtual void Per_Cell_Process(bool center); - virtual void Scatter(COORDINATE threat, bool forced=false, bool nokidding=false); - void Exit_Repair(void); -// MoveType Blocking_Object(TechnoClass const *techno, CELL cell) const; - - /* - ** File I/O. - */ - static void Read_INI(char *buffer); - static void Write_INI(char *buffer); - static char *INI_Name(void) {return "UNITS";}; - bool Load(FileClass & file); - bool Save(FileClass & file); - virtual void Code_Pointers(void); - virtual void Decode_Pointers(void); - - /* - ** Dee-buggin' support. - */ - int Validate(void) const; - - private: - - /* - ** Timer to prevent Harvesters from collecting too often - */ - TCountDownTimerClass HarvestTimer; - - /* - ** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load - */ - unsigned char SaveLoadPadding[32]; - - /* - ** This contains the value of the Virtual Function Table Pointer - */ - static void * VTable; -}; - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/UTRACKER.CPP b/code/TIBERIANDAWN/UTRACKER.CPP deleted file mode 100644 index 38b8211..0000000 --- a/code/TIBERIANDAWN/UTRACKER.CPP +++ /dev/null @@ -1,239 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : UTRACKER.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : June 3rd, 1996 * - * * - * Last Update : June 7th, 1996 [ST] * - * * - *-------------------------------------------------------------------------* - * The UnitTracker class exists to track the various statistics * - * required for internet games. * - * * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - * * - * Functions: * - * * - * * - * * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - -#include "function.h" - - -/*********************************************************************************************** - * UTC::UnitTrackerClass -- Class constructor * - * * - * * - * * - * INPUT: Number of unit types to reserve space for * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:10AM ST : Created * - *=============================================================================================*/ -UnitTrackerClass::UnitTrackerClass (int unit_count) -{ - UnitTotals = new long [unit_count]; // Allocate memory for the unit totals - UnitCount = unit_count; // Keep a record of how many unit entries there are - InNetworkFormat = 0; // The unit entries are in host format - Clear_Unit_Total(); // Clear each entry -} - - -/*********************************************************************************************** - * UTC::~UnitTrackerClass -- Class destructor * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:10AM ST : Created * - *=============================================================================================*/ -UnitTrackerClass::~UnitTrackerClass (void) -{ - delete UnitTotals; -} - - - -/*********************************************************************************************** - * UTC::Increment_Unit_Total -- Increment the total for the specefied unit * - * * - * * - * * - * INPUT: Unit number * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:12AM ST : Created * - *=============================================================================================*/ -void UnitTrackerClass::Increment_Unit_Total(int unit_type) -{ - UnitTotals[unit_type]++; -} - - -/*********************************************************************************************** - * UTC::Decrement_Unit_Total -- Decrement the total for the specefied unit * - * * - * * - * * - * INPUT: Unit number * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:13AM ST : Created * - *=============================================================================================*/ -void UnitTrackerClass::Decrement_Unit_Total(int unit_type) -{ - UnitTotals[unit_type]--; -} - - -/*********************************************************************************************** - * UTC::Get_All_Totals -- Returns a pointer to the start of the unit totals list * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Ptr to unit totals list * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:13AM ST : Created * - *=============================================================================================*/ -long *UnitTrackerClass::Get_All_Totals (void) -{ - return (UnitTotals); -} - - -/*********************************************************************************************** - * UTC::Clear_Unit_Total -- Clear out all the unit totals * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:14AM ST : Created * - *=============================================================================================*/ -void UnitTrackerClass::Clear_Unit_Total (void) -{ - memset (UnitTotals, 0, UnitCount * sizeof(long) ); -} - - - -/*********************************************************************************************** - * UTC::To_Network_Format -- Changes all unit totals to network format for the internet * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 0:15AM ST : Created * - *=============================================================================================*/ -void UnitTrackerClass::To_Network_Format (void) -{ - if (!InNetworkFormat){ - for (int i=0 ; i= 0 && unit_type < UnitCount) - { - return UnitTotals[unit_type]; - } - return 0; -} - - diff --git a/code/TIBERIANDAWN/UTRACKER.H b/code/TIBERIANDAWN/UTRACKER.H deleted file mode 100644 index 35c216b..0000000 --- a/code/TIBERIANDAWN/UTRACKER.H +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : UTRACKER.H * - * * - * Programmer : Steve Tall * - * * - * Start Date : June 3rd, 1996 * - * * - * Last Update : June 7th, 1996 [ST] * - * * - *-------------------------------------------------------------------------* - * The UnitTracker class exists to track the various statistics * - * required for internet games. * - * * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - -/* -** UnitTracker Class -*/ - -class UnitTrackerClass { - - public: - - UnitTrackerClass(int unit_count); - ~UnitTrackerClass(void); - - void Increment_Unit_Total (int unit_type); - void Decrement_Unit_Total (int unit_type); - void Clear_Unit_Total(void); - - int Get_Unit_Total (int unit_type); - long *Get_All_Totals (void); - int Get_Unit_Count (void){return (UnitCount);}; - - void To_Network_Format(void); - void To_PC_Format(void); - - private: - - long *UnitTotals; - int UnitCount; - int InNetworkFormat; - -}; - - - - - - - - - - - - - - - - diff --git a/code/TIBERIANDAWN/VECTOR.CPP b/code/TIBERIANDAWN/VECTOR.CPP deleted file mode 100644 index 2c71426..0000000 --- a/code/TIBERIANDAWN/VECTOR.CPP +++ /dev/null @@ -1,898 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\vector.cpv 2.17 16 Oct 1995 16:49:26 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : VECTOR.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 02/19/95 * - * * - * Last Update : July 18, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * BooleanVectorClass::BooleanVectorClass -- Copy constructor fo boolean array. * - * BooleanVectorClass::BooleanVectorClass -- Explicit data buffer constructor. * - * BooleanVectorClass::Clear -- Resets boolean vector to empty state. * - * BooleanVectorClass::Fixup -- Updates the boolean vector to a known state. * - * BooleanVectorClass::Reset -- Clear all boolean values in array. * - * BooleanVectorClass::Resize -- Resizes a boolean vector object. * - * BooleanVectorClass::Set -- Forces all boolean elements to true. * - * BooleanVectorClass::operator = -- Assignment operator. * - * BooleanVectorClass::operator == -- Comparison operator for boolean vector. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "vector.h" -//#include -#include - -/* -** The following template function can be located here ONLY if all the instatiations are -** declared in a header file this module includes. By placing the template functions here, -** it speeds up compiler operation and reduces object module size. -*/ -#if (0) // Moved to header - -/*********************************************************************************************** - * VectorClass::VectorClass -- Constructor for vector class. * - * * - * This constructor for the vector class is passed the initial size of the vector and an * - * optional pointer to a preallocated block of memory that the vector will be placed in. * - * If this optional pointer is NULL (or not provided), then the vector is allocated out * - * of free store (with the "new" operator). * - * * - * INPUT: size -- The number of elements to initialize this vector to. * - * * - * array -- Optional pointer to a previously allocated memory block to hold the * - * vector. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass::VectorClass(unsigned size, T const * array) -{ - Vector = 0; - VectorMax = size; - IsAllocated = false; - - /* - ** Allocate the vector. The default constructor will be called for every - ** object in this vector. - */ - if (size) { - if (array) { - Vector = new((void*)array) T[size]; - } else { - Vector = new T[size]; - IsAllocated = true; - } - } -} - - -/*********************************************************************************************** - * VectorClass::~VectorClass -- Default destructor for vector class. * - * * - * This is the default destructor for the vector class. It will deallocate any memory * - * that it may have allocated. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass::~VectorClass(void) -{ - VectorClass::Clear(); -} - - -/*********************************************************************************************** - * VectorClass::VectorClass -- Copy constructor for vector object. * - * * - * This is the copy constructor for the vector class. It will duplicate the provided * - * vector into the new vector being created. * - * * - * INPUT: vector -- Reference to the vector to use as a copy. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass::VectorClass(VectorClass const & vector) -{ - VectorMax = 0; - IsAllocated = false; - Vector = 0; - *this = vector; -} - - -/*********************************************************************************************** - * VectorClass::operator = -- The assignment operator. * - * * - * This the the assignment operator for vector objects. It will alter the existing lvalue * - * vector to duplicate the rvalue one. * - * * - * INPUT: vector -- The rvalue vector to copy into the lvalue one. * - * * - * OUTPUT: Returns with reference to the newly copied vector. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass & VectorClass::operator =(VectorClass const & vector) -{ - Clear(); - VectorMax = vector.Length(); - if (VectorMax) { - Vector = new T[VectorMax]; - if (Vector) { - IsAllocated = true; - for (int index = 0; index < (int)VectorMax; index++) { - Vector[index] = vector[index]; - } - } - } else { - Vector = 0; - IsAllocated = false; - } - return(*this); -} - - -/*********************************************************************************************** - * VectorClass::operator == -- Equality operator for vector objects. * - * * - * This operator compares two vectors for equality. It does this by performing an object * - * by object comparison between the two vectors. * - * * - * INPUT: vector -- The right vector expression. * - * * - * OUTPUT: bool; Are the two vectors essentially equal? (do they contain comparable elements * - * in the same order?) * - * * - * WARNINGS: The equality operator must exist for the objects that this vector contains. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int VectorClass::operator == (VectorClass const & vector) const -{ - if (VectorMax == vector.Length()) { - for (int index = 0; index < (int)VectorMax; index++) { - if (Vector[index] != vector[index]) { - return(false); - } - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * VectorClass::ID -- Pointer based conversion to index number. * - * * - * Use this routine to convert a pointer to an element in the vector back into the index * - * number of that object. This routine ONLY works with actual pointers to object within * - * the vector. For "equivalent" object index number (such as with similar integral values) * - * then use the "by value" index number ID function. * - * * - * INPUT: pointer -- Pointer to an actual object in the vector. * - * * - * OUTPUT: Returns with the index number for the object pointed to by the parameter. * - * * - * WARNINGS: This routine is only valid for actual pointers to object that exist within * - * the vector. All other object pointers will yield undefined results. * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -template -inline int VectorClass::ID(T const * ptr) -{ - return(((unsigned long)ptr - (unsigned long)&(*this)[0]) / sizeof(T)); -} - - -/*********************************************************************************************** - * VectorClass::ID -- Finds object ID based on value. * - * * - * Use this routine to find the index value of an object with equivalent value in the * - * vector. Typical use of this would be for integral types. * - * * - * INPUT: object -- Reference to the object that is to be looked up in the vector. * - * * - * OUTPUT: Returns with the index number of the object that is equivalent to the one * - * specified. If no matching value could be found then -1 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -template -int VectorClass::ID(T const & object) -{ - for (int index = 0; index < (int)VectorMax; index++) { - if ((*this)[index] == object) { - return(index); - } - } - return(-1); -} - - -/*********************************************************************************************** - * VectorClass::Clear -- Frees and clears the vector. * - * * - * Use this routine to reset the vector to an empty (non-allocated) state. A vector will * - * free all allocated memory when this routine is called. In order for the vector to be * - * useful after this point, the Resize function must be called to give it element space. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -void VectorClass::Clear(void) -{ - if (Vector && IsAllocated) { - delete[] Vector; - Vector = 0; - } - IsAllocated = false; - VectorMax = 0; -} - - -/*********************************************************************************************** - * VectorClass::Resize -- Changes the size of the vector. * - * * - * This routine is used to change the size (usually to increase) the size of a vector. This * - * is the only way to increase the vector's working room (number of elements). * - * * - * INPUT: newsize -- The desired size of the vector. * - * * - * array -- Optional pointer to a previously allocated memory block that the * - * array will be located in. If this parameter is not supplied, then * - * the array will be allocated from free store. * - * * - * OUTPUT: bool; Was the array resized successfully? * - * * - * WARNINGS: Failure to succeed could be the result of running out of memory. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int VectorClass::Resize(unsigned newsize, T const * array) -{ - if (newsize) { - - /* - ** Allocate a new vector of the size specified. The default constructor - ** will be called for every object in this vector. - */ - T * newptr; - if (!array) { - newptr = new T[newsize]; - } else { - newptr = new((void*)array) T[newsize]; - } - if (!newptr) { - return(false); - } - - /* - ** If there is an old vector, then it must be copied (as much as is feasable) - ** to the new vector. - */ - if (Vector) { - - /* - ** Copy as much of the old vector into the new vector as possible. This - ** presumes that there is a functional assignment operator for each - ** of the objects in the vector. - */ - int copycount = (newsize < VectorMax) ? newsize : VectorMax; - for (int index = 0; index < copycount; index++) { - newptr[index] = Vector[index]; - } - - /* - ** Delete the old vector. This might cause the destructors to be called - ** for all of the old elements. This makes the implementation of suitable - ** assignment operator very important. The default assigment operator will - ** only work for the simplist of objects. - */ - if (IsAllocated) { - delete[] Vector; - Vector = 0; - } - } - - /* - ** Assign the new vector data to this class. - */ - Vector = newptr; - VectorMax = newsize; - IsAllocated = (Vector && !array); - - } else { - - /* - ** Resizing to zero is the same as clearing the vector. - */ - Clear(); - } - return(true); -} - - -/*********************************************************************************************** - * DynamicVectorClass::DynamicVectorClass -- Constructor for dynamic vector. * - * * - * This is the normal constructor for the dynamic vector class. It is similar to the normal * - * vector class constructor. The vector is initialized to contain the number of elements * - * specified in the "size" parameter. The memory is allocated from free store unless the * - * optional array parameter is provided. In this case it will place the vector at the * - * memory location specified. * - * * - * INPUT: size -- The maximum number of objects allowed in this vector. * - * * - * array -- Optional pointer to the memory area to place the vector at. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -DynamicVectorClass::DynamicVectorClass(unsigned size, T const * array) - : VectorClass(size, array) -{ - GrowthStep = 10; - ActiveCount = 0; -} - - -/*********************************************************************************************** - * DynamicVectorClass::Resize -- Changes the size of a dynamic vector. * - * * - * Use this routine to change the size of the vector. The size changed is the maximum * - * number of allocated objects within this vector. If a memory buffer is provided, then * - * the vector will be located there. Otherwise, the memory will be allocated out of free * - * store. * - * * - * INPUT: newsize -- The desired maximum size of this vector. * - * * - * array -- Optional pointer to a previosly allocated memory array. * - * * - * OUTPUT: bool; Was vector successfully resized according to specifications? * - * * - * WARNINGS: Failure to resize the vector could be the result of lack of free store. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Resize(unsigned newsize, T const * array) -{ - if (VectorClass::Resize(newsize, array)) { - if (Length() < (unsigned)ActiveCount) ActiveCount = Length(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * DynamicVectorClass::ID -- Find matching value in the dynamic vector. * - * * - * Use this routine to find a matching object (by value) in the vector. Unlike the base * - * class ID function of similar name, this one restricts the scan to the current number * - * of valid objects. * - * * - * INPUT: object -- A reference to the object that a match is to be found in the * - * vector. * - * * - * OUTPUT: Returns with the index number of the object that is equivalent to the one * - * specified. If no equivalent object could be found then -1 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::ID(T const & object) -{ - for (int index = 0; index < Count(); index++) { - if ((*this)[index] == object) return(index); - } - return(-1); -} - - -/*********************************************************************************************** - * DynamicVectorClass::Add -- Add an element to the vector. * - * * - * Use this routine to add an element to the vector. The vector will automatically be * - * resized to accomodate the new element IF the vector was allocated previosly and the * - * growth rate is not zero. * - * * - * INPUT: object -- Reference to the object that will be added to the vector. * - * * - * OUTPUT: bool; Was the object added successfully? If so, the object is added to the end * - * of the vector. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Add(T const & object) -{ - if ((unsigned)ActiveCount >= Length()) { - if ((IsAllocated || !VectorMax) && GrowthStep > 0) { - if (!Resize(Length() + GrowthStep)) { - - /* - ** Failure to increase the size of the vector is an error condition. - ** Return with the error flag. - */ - return(false); - } - } else { - - /* - ** Increasing the size of this vector is not allowed! Bail this - ** routine with the error code. - */ - return(false); - } - } - - /* - ** There is room for the new object now. Add it to the end of the object vector. - */ - (*this)[ActiveCount++] = object; - return(true); -} - - -template -int DynamicVectorClass::Add_Head(T const & object) -{ - if (ActiveCount >= Length()) { - if ((IsAllocated || !VectorMax) && GrowthStep > 0) { - if (!Resize(Length() + GrowthStep)) { - - /* - ** Failure to increase the size of the vector is an error condition. - ** Return with the error flag. - */ - return(false); - } - } else { - - /* - ** Increasing the size of this vector is not allowed! Bail this - ** routine with the error code. - */ - return(false); - } - } - - /* - ** There is room for the new object now. Add it to the end of the object vector. - */ - if (ActiveCount) { - memmove(&(*this)[1], &(*this)[0], ActiveCount * sizeof(T)); - } - (*this)[0] = object; - ActiveCount++; -// (*this)[ActiveCount++] = object; - return(true); -} - - -/*********************************************************************************************** - * DynamicVectorClass::Delete -- Remove the specified object from the vector. * - * * - * This routine will delete the object referenced from the vector. All objects in the * - * vector that follow the one deleted will be moved "down" to fill the hole. * - * * - * INPUT: object -- Reference to the object in this vector that is to be deleted. * - * * - * OUTPUT: bool; Was the object deleted successfully? This should always be true. * - * * - * WARNINGS: Do no pass a reference to an object that is NOT part of this vector. The * - * results of this are undefined and probably catastrophic. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Delete(T const & object) -{ - int index = ID(object); - if (index != -1){ - return(Delete(index)); - }else{ - return (false); - } -} - - -/*********************************************************************************************** - * DynamicVectorClass::Delete -- Deletes the specified index from the vector. * - * * - * Use this routine to delete the object at the specified index from the objects in the * - * vector. This routine will move all the remaining objects "down" in order to fill the * - * hole. * - * * - * INPUT: index -- The index number of the object in the vector that is to be deleted. * - * * - * OUTPUT: bool; Was the object index deleted successfully? Failure might mean that the index * - * specified was out of bounds. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Delete(int index) -{ - if ((unsigned)index < ActiveCount) { - ActiveCount--; - - /* - ** If there are any objects past the index that was deleted, copy those - ** objects down in order to fill the hole. A simple memory copy is - ** not sufficient since the vector could contain class objects that - ** need to use the assignment operator for movement. - */ - for (int i = index; i < ActiveCount; i++) { - (*this)[i] = (*this)[i+1]; - } - return(true); - } - return(false); -} - -#endif //Moved to header - - -//---------------------------------------------------------------------------------------------- - -/*********************************************************************************************** - * BooleanVectorClass::BooleanVectorClass -- Explicit data buffer constructor. * - * * - * This is the constructor for a boolean array. This constructor takes the memory pointer * - * provided as assigns that as the array data pointer. * - * * - * INPUT: size -- The size of the array (in bits). * - * * - * array -- Pointer to the memory that the array is to use. * - * * - * OUTPUT: none * - * * - * WARNINGS: You must make sure that the memory specified is large enough to contain the * - * bits specified. * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -BooleanVectorClass::BooleanVectorClass(unsigned size, unsigned char * array) -{ - BitArray.Resize(((size + (8-1)) / 8), array); - LastIndex = -1; - BitCount = size; -} - - -/*********************************************************************************************** - * BooleanVectorClass::BooleanVectorClass -- Copy constructor fo boolean array. * - * * - * This is the copy constructor for a boolean array. It is used to make a duplicate of the * - * boolean array. * - * * - * INPUT: vector -- Reference to the vector to be duplicated. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -BooleanVectorClass::BooleanVectorClass(BooleanVectorClass const & vector) -{ - LastIndex = -1; - *this = vector; -} - - -/*********************************************************************************************** - * BooleanVectorClass::operator = -- Assignment operator. * - * * - * This routine will make a copy of the specifed boolean vector array. The vector is * - * copied into an already constructed existing vector. The values from the existing vector * - * are destroyed by this copy. * - * * - * INPUT: vector -- Reference to the vector to make a copy of. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -BooleanVectorClass & BooleanVectorClass::operator =(BooleanVectorClass const & vector) -{ - Fixup(); - Copy = vector.Copy; - LastIndex = vector.LastIndex; - BitArray = vector.BitArray; - BitCount = vector.BitCount; - return(*this); -} - - -/*********************************************************************************************** - * BooleanVectorClass::operator == -- Comparison operator for boolean vector. * - * * - * This is the comparison operator for a boolean vector class. Boolean vectors are equal * - * if the bit count and bit values are identical. * - * * - * INPUT: vector -- Reference to the vector to compare to. * - * * - * OUTPUT: Are the boolean vectors identical? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -int BooleanVectorClass::operator == (const BooleanVectorClass & vector) -{ - Fixup(LastIndex); - return(BitCount == vector.BitCount && BitArray == vector.BitArray); -} - - -/*********************************************************************************************** - * BooleanVectorClass::Resize -- Resizes a boolean vector object. * - * * - * This routine will resize the boolean vector object. An index value used with a boolean * - * vector must be less than the value specified in as the new size. * - * * - * INPUT: size -- The new maximum size of this boolean vector. * - * * - * OUTPUT: Was the boolean vector sized successfully? * - * * - * WARNINGS: The boolean array might be reallocated or even deleted by this routine. * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -int BooleanVectorClass::Resize(unsigned size) -{ - Fixup(); - - if (size) { - - /* - ** Record the previous bit count of the boolean vector. This is used - ** to determine if the array has grown in size and thus clearing is - ** necessary. - */ - int oldsize = BitCount; - - /* - ** Actually resize the bit array. Since this is a bit packed array, - ** there are 8 elements per byte (rounded up). - */ - int success = BitArray.Resize(((size + (8-1)) / 8)); - - /* - ** Since there is no default constructor for bit packed integers, a manual - ** clearing of the bits is required. - */ - BitCount = size; - if (success && oldsize < (int)size) { - for (int index = oldsize; index < (int)size; index++) { - (*this)[index] = 0; - } - } - - return(success); - } - - /* - ** Resizing to zero is the same as clearing and deallocating the array. - ** This is always successful. - */ - Clear(); - return(true); -} - - -/*********************************************************************************************** - * BooleanVectorClass::Clear -- Resets boolean vector to empty state. * - * * - * This routine will clear out the boolean array. This will free any allocated memory and * - * result in the boolean vector being unusable until the Resize function is subsiquently * - * called. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: The boolean vector cannot be used until it is resized to a non null condition. * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -void BooleanVectorClass::Clear(void) -{ - Fixup(); - BitCount = 0; - BitArray.Clear(); -} - - -/*********************************************************************************************** - * BooleanVectorClass::Reset -- Clear all boolean values in array. * - * * - * This is the preferred (and quick) method to clear the boolean array to a false condition.* - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -void BooleanVectorClass::Reset(void) -{ - LastIndex = -1; - if (BitArray.Length()) { - memset(&BitArray[0], '\0', BitArray.Length()); - } -} - - -/*********************************************************************************************** - * BooleanVectorClass::Set -- Forces all boolean elements to true. * - * * - * This is the preferred (and fast) way to set all boolean elements to true. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -void BooleanVectorClass::Set(void) -{ - LastIndex = -1; - if (BitArray.Length()) { - memset(&BitArray[0], '\xFF', BitArray.Length()); - } -} - - -/*********************************************************************************************** - * BooleanVectorClass::Fixup -- Updates the boolean vector to a known state. * - * * - * Use this routine to set the boolean value copy to match the appropriate bit in the * - * boolean array. The boolean array will be updated with any changes from the last time * - * a value was fetched from the boolean vector. By using this update method, the boolean * - * array can be treated as a normal array even though the elements are composed of * - * otherwise inaccessable bits. * - * * - * INPUT: index -- The index to set the new copy value to. If the index is -1, then the * - * previous value will be updated into the vector array, but no new value * - * will be fetched from it. * - * * - * OUTPUT: none * - * * - * WARNINGS: Always call this routine with "-1" if any direct manipulation of the bit * - * array is to occur. This ensures that the bit array is accurate. * - * * - * HISTORY: * - * 07/18/1995 JLB : Created. * - *=============================================================================================*/ -void BooleanVectorClass::Fixup(int index) const -{ - /* - ** If the requested index value is illegal, then force the index - ** to be -1. This is the default non-index value. - */ - if (index >= BitCount) { - index = -1; - } - - /* - ** If the new index is different than the previous index, there might - ** be some fixing up required. - */ - if (index != LastIndex) { - - /* - ** If the previously fetched boolean value was changed, then update - ** the boolean array accordingly. - */ - if (LastIndex != -1) { - Set_Bit((void*)&BitArray[0], LastIndex, Copy); - } - - /* - ** If this new current index is valid, then fill in the reference boolean - ** value with the approriate data from the bit array. - */ - if (index != -1) { - ((unsigned char&)Copy) = Get_Bit(&BitArray[0], index); - } - - ((int &)LastIndex) = index; - } -} - diff --git a/code/TIBERIANDAWN/VECTOR.H b/code/TIBERIANDAWN/VECTOR.H deleted file mode 100644 index 9268299..0000000 --- a/code/TIBERIANDAWN/VECTOR.H +++ /dev/null @@ -1,988 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\vector.h_v 2.15 16 Oct 1995 16:47:38 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : VECTOR.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 02/19/95 * - * * - * Last Update : March 13, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * VectorClass::VectorClass -- Constructor for vector class. * - * VectorClass::~VectorClass -- Default destructor for vector class. * - * VectorClass::VectorClass -- Copy constructor for vector object. * - * VectorClass::operator = -- The assignment operator. * - * VectorClass::operator == -- Equality operator for vector objects. * - * VectorClass::Clear -- Frees and clears the vector. * - * VectorClass::Resize -- Changes the size of the vector. * - * DynamicVectorClass::DynamicVectorClass -- Constructor for dynamic vector. * - * DynamicVectorClass::Resize -- Changes the size of a dynamic vector. * - * DynamicVectorClass::Add -- Add an element to the vector. * - * DynamicVectorClass::Delete -- Remove the specified object from the vector. * - * DynamicVectorClass::Delete -- Deletes the specified index from the vector. * - * VectorClass::ID -- Pointer based conversion to index number. * - * VectorClass::ID -- Finds object ID based on value. * - * DynamicVectorClass::ID -- Find matching value in the dynamic vector. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef VECTOR_H -#define VECTOR_H - -#ifndef false -#define false 0 -#endif -#ifndef true -#define true 1 -#endif - -#include -#include - -inline void * operator new(size_t , void * pointer) {return(pointer);} -inline void * operator new[](size_t , void * pointer) {return(pointer);} - - -/************************************************************************** -** This is a general purpose vector class. A vector is defined by this -** class, as an array of arbitrary objects where the array can be dynamically -** sized. Because is deals with arbitrary object types, it can handle everything. -** As a result of this, it is not terribly efficient for integral objects (such -** as char or int). It will function correctly, but the copy constructor and -** equality operator could be highly optimized if the integral type were known. -** This efficiency can be implemented by deriving an integral vector template -** from this one in order to supply more efficient routines. -*/ -template -class VectorClass -{ - public: - VectorClass(unsigned size=0, T const * array=0); - VectorClass(VectorClass const &); // Copy constructor. - virtual ~VectorClass(void); - - T & operator[](unsigned index) {return(Vector[index]);}; - T const & operator[](unsigned index) const {return(Vector[index]);}; - virtual VectorClass & operator =(VectorClass const &); // Assignment operator. - virtual int operator == (VectorClass const &) const; // Equality operator. - virtual int Resize(unsigned newsize, T const * array=0); - virtual void Clear(void); - unsigned Length(void) const {return VectorMax;}; - virtual int ID(T const * ptr); // Pointer based identification. - virtual int ID(T const & ptr); // Value based identification. - - protected: - - /* - ** This is a pointer to the allocated vector array of elements. - */ - T * Vector; - - /* - ** This is the maximum number of elements allowed in this vector. - */ - unsigned VectorMax; - - /* - ** Does the vector data pointer refer to memory that this class has manually - ** allocated? If so, then this class is responsible for deleting it. - */ - unsigned IsAllocated:1; -}; - - -/************************************************************************** -** This derivative vector class adds the concept of adding and deleting -** objects. The objects are packed to the beginning of the vector array. -** If this is instantiated for a class object, then the assignment operator -** and the equality operator must be supported. If the vector allocates its -** own memory, then the vector can grow if it runs out of room adding items. -** The growth rate is controlled by setting the growth step rate. A growth -** step rate of zero disallows growing. -*/ -template -class DynamicVectorClass : public VectorClass -{ - public: - DynamicVectorClass(unsigned size=0, T const * array=0); - - // Change maximum size of vector. - virtual int Resize(unsigned newsize, T const * array=0); - - // Resets and frees the vector array. - virtual void Clear(void) {ActiveCount = 0;VectorClass::Clear();}; - - // Fetch number of "allocated" vector objects. - int Count(void) const {return(ActiveCount);}; - - // Add object to vector (growing as necessary). - int Add(T const & object); - int Add_Head(T const & object); - - // Delete object just like this from vector. - int Delete(T const & object); - - // Delete object at this vector index. - int Delete(int index); - - // Deletes all objects in the vector. - void Delete_All(void) {ActiveCount = 0;}; - - // Set amount that vector grows by. - int Set_Growth_Step(int step) {return(GrowthStep = step);}; - - // Fetch current growth step rate. - int Growth_Step(void) {return GrowthStep;}; - - virtual int ID(T const * ptr) {return(VectorClass::ID(ptr));}; - virtual int ID(T const & ptr); - - protected: - - /* - ** This is a count of the number of active objects in this - ** vector. The memory array often times is bigger than this - ** value. - */ - int ActiveCount; - - /* - ** If there is insufficient room in the vector array for a new - ** object to be added, then the vector will grow by the number - ** of objects specified by this value. This is controlled by - ** the Set_Growth_Step() function. - */ - int GrowthStep; -}; - - -/************************************************************************** -** A fixed-size array of dynamic vectors. -*/ -template -class DynamicVectorArrayClass -{ -public: - static const int COUNT = COUNT; - - DynamicVectorArrayClass() : Active(DEFAULT) {} - - void Set_Active_Context(int active) - { - Active = active; - } - - void Clear_All() - { - for (int i = FIRST; i < COUNT; ++i) - { - Clear(i); - } - } - - void Clear() - { - Clear(Active); - } - - int Count() const - { - return Count(Active); - } - - int Add(T const & object) - { - return Add(Active, object); - } - - int Add_Head(T const & object) - { - return Add_Head(Active, object); - } - - int Delete(T const & object) - { - return Delete(Active, object); - } - - int Delete_All(T const & object) - { - int count = 0; - for (int i = FIRST; i < COUNT; ++i) - { - count += Delete(i, object); - } - return count; - } - - int Delete_All_Except(T const & object, int except) - { - int count = 0; - for (int i = FIRST; i < COUNT; ++i) - { - if (except != i) - { - count += Delete(i, object); - } - } - return count; - } - - int Delete(int index) - { - return Delete(Active, index); - } - - T & operator[](unsigned index) - { - return Collection[Active][index]; - } - - T const & operator[](unsigned index) const - { - return Collection[Active][index]; - } - - void Clear(int context) - { - Collection[context].Clear(); - } - - int Count(int context) const - { - return Collection[context].Count(); - } - - int Add(int context, T const & object) - { - return Collection[context].Add(object); - } - - int Add_Head(int context, T const & object) - { - return Collection[context].Add(object); - } - - int Delete(int context, T const & object) - { - return Collection[context].Delete(object); - } - - int Delete(int context, int index) - { - return Collection[context].Delete(index); - } - - int Raw_Count() const - { - return COUNT; - } - - DynamicVectorClass & Raw() - { - return Collection[Active]; - } - - DynamicVectorClass & Raw(int context) - { - return Collection[context]; - } - -private: - DynamicVectorClass Collection[COUNT]; - int Active; -}; - - -/************************************************************************** -** This is a derivative of a vector class that supports boolean flags. Since -** a boolean flag can be represented by a single bit, this class packs the -** array of boolean flags into an array of bytes containing 8 boolean values -** each. For large boolean arrays, this results in an 87.5% savings. Although -** the indexing "[]" operator is supported, DO NOT pass pointers to sub elements -** of this bit vector class. A pointer derived from the indexing operator is -** only valid until the next call. Because of this, only simple -** direct use of the "[]" operator is allowed. -*/ -class BooleanVectorClass -{ - public: - BooleanVectorClass(unsigned size=0, unsigned char * array=0); - BooleanVectorClass(BooleanVectorClass const & vector); - - // Assignment operator. - BooleanVectorClass & operator =(BooleanVectorClass const & vector); - - // Equivalency operator. - int operator == (BooleanVectorClass const & vector); - - // Fetch number of boolean objects in vector. - int Length(void) {return BitCount;}; - - // Set all boolean values to false; - void Reset(void); - - // Set all boolean values to true. - void Set(void); - - // Resets vector to zero length (frees memory). - void Clear(void); - - // Change size of this boolean vector. - int Resize(unsigned size); - - // Fetch reference to specified index. - bool const & operator[](int index) const { - if (LastIndex != index) Fixup(index); - return(Copy); - }; - bool & operator[](int index) { - if (LastIndex != index) Fixup(index); - return(Copy); - }; - - // Quick check on boolean state. - bool Is_True(int index) const { - if (index == LastIndex) return(Copy); - return(Get_Bit(&BitArray[0], index) ? true : false); - }; - - // Find first index that is false. - int First_False(void) const { - if (LastIndex != -1) Fixup(-1); - - int retval = First_False_Bit(&BitArray[0], BitArray.Length()); - if (retval < BitCount) return(retval); - - /* - ** Failure to find a false boolean value in the vector. Return this - ** fact in the form of an invalid index number. - */ - return(-1); - } - - // Find first index that is true. - int First_True(void) const { - if (LastIndex != -1) Fixup(-1); - - int retval = First_True_Bit(&BitArray[0], BitArray.Length()); - if (retval < BitCount) return(retval); - - /* - ** Failure to find a true boolean value in the vector. Return this - ** fact in the form of an invalid index number. - */ - return(-1); - } - - private: - void Fixup(int index=-1) const; - - /* - ** This is the number of boolean values in the vector. This value is - ** not necessarily a multiple of 8, even though the underlying character - ** vector contains a multiple of 8 bits. - */ - int BitCount; - - /* - ** This is a referential copy of an element in the bit vector. The - ** purpose of this copy is to allow normal reference access to this - ** object (for speed reasons). This hides the bit packing scheme from - ** the user of this class. - */ - bool Copy; - - /* - ** This records the index of the value last fetched into the reference - ** boolean variable. This index is used to properly restore the value - ** when the reference copy needs updating. - */ - int LastIndex; - - /* - ** This points to the allocated bitfield array. - */ - VectorClass BitArray; -}; - - -/*********************************************************************************************** - * VectorClass::VectorClass -- Constructor for vector class. * - * * - * This constructor for the vector class is passed the initial size of the vector and an * - * optional pointer to a preallocated block of memory that the vector will be placed in. * - * If this optional pointer is NULL (or not provided), then the vector is allocated out * - * of free store (with the "new" operator). * - * * - * INPUT: size -- The number of elements to initialize this vector to. * - * * - * array -- Optional pointer to a previously allocated memory block to hold the * - * vector. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass::VectorClass(unsigned size, T const * array) -{ - Vector = 0; - VectorMax = size; - IsAllocated = false; - - /* - ** Allocate the vector. The default constructor will be called for every - ** object in this vector. - */ - if (size) { - if (array) { - Vector = new((void*)array) T[size]; - } else { - Vector = new T[size]; - IsAllocated = true; - } - } -} - - -/*********************************************************************************************** - * VectorClass::~VectorClass -- Default destructor for vector class. * - * * - * This is the default destructor for the vector class. It will deallocate any memory * - * that it may have allocated. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass::~VectorClass(void) -{ - VectorClass::Clear(); -} - - -/*********************************************************************************************** - * VectorClass::VectorClass -- Copy constructor for vector object. * - * * - * This is the copy constructor for the vector class. It will duplicate the provided * - * vector into the new vector being created. * - * * - * INPUT: vector -- Reference to the vector to use as a copy. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass::VectorClass(VectorClass const & vector) -{ - VectorMax = 0; - IsAllocated = false; - Vector = 0; - *this = vector; -} - - -/*********************************************************************************************** - * VectorClass::operator = -- The assignment operator. * - * * - * This the the assignment operator for vector objects. It will alter the existing lvalue * - * vector to duplicate the rvalue one. * - * * - * INPUT: vector -- The rvalue vector to copy into the lvalue one. * - * * - * OUTPUT: Returns with reference to the newly copied vector. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -VectorClass & VectorClass::operator =(VectorClass const & vector) -{ - Clear(); - VectorMax = vector.Length(); - if (VectorMax) { - Vector = new T[VectorMax]; - if (Vector) { - IsAllocated = true; - for (int index = 0; index < (int)VectorMax; index++) { - Vector[index] = vector[index]; - } - } - } else { - Vector = 0; - IsAllocated = false; - } - return(*this); -} - - -/*********************************************************************************************** - * VectorClass::operator == -- Equality operator for vector objects. * - * * - * This operator compares two vectors for equality. It does this by performing an object * - * by object comparison between the two vectors. * - * * - * INPUT: vector -- The right vector expression. * - * * - * OUTPUT: bool; Are the two vectors essentially equal? (do they contain comparable elements * - * in the same order?) * - * * - * WARNINGS: The equality operator must exist for the objects that this vector contains. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int VectorClass::operator == (VectorClass const & vector) const -{ - if (VectorMax == vector.Length()) { - for (int index = 0; index < (int)VectorMax; index++) { - if (Vector[index] != vector[index]) { - return(false); - } - } - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * VectorClass::ID -- Pointer based conversion to index number. * - * * - * Use this routine to convert a pointer to an element in the vector back into the index * - * number of that object. This routine ONLY works with actual pointers to object within * - * the vector. For "equivalent" object index number (such as with similar integral values) * - * then use the "by value" index number ID function. * - * * - * INPUT: pointer -- Pointer to an actual object in the vector. * - * * - * OUTPUT: Returns with the index number for the object pointed to by the parameter. * - * * - * WARNINGS: This routine is only valid for actual pointers to object that exist within * - * the vector. All other object pointers will yield undefined results. * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -template -inline int VectorClass::ID(T const * ptr) -{ - return(((unsigned long)ptr - (unsigned long)&(*this)[0]) / sizeof(T)); -} - - -/*********************************************************************************************** - * VectorClass::ID -- Finds object ID based on value. * - * * - * Use this routine to find the index value of an object with equivalent value in the * - * vector. Typical use of this would be for integral types. * - * * - * INPUT: object -- Reference to the object that is to be looked up in the vector. * - * * - * OUTPUT: Returns with the index number of the object that is equivalent to the one * - * specified. If no matching value could be found then -1 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -template -int VectorClass::ID(T const & object) -{ - for (int index = 0; index < (int)VectorMax; index++) { - if ((*this)[index] == object) { - return(index); - } - } - return(-1); -} - - -/*********************************************************************************************** - * VectorClass::Clear -- Frees and clears the vector. * - * * - * Use this routine to reset the vector to an empty (non-allocated) state. A vector will * - * free all allocated memory when this routine is called. In order for the vector to be * - * useful after this point, the Resize function must be called to give it element space. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -void VectorClass::Clear(void) -{ - if (Vector && IsAllocated) { - delete[] Vector; - Vector = 0; - } - IsAllocated = false; - VectorMax = 0; -} - - -/*********************************************************************************************** - * VectorClass::Resize -- Changes the size of the vector. * - * * - * This routine is used to change the size (usually to increase) the size of a vector. This * - * is the only way to increase the vector's working room (number of elements). * - * * - * INPUT: newsize -- The desired size of the vector. * - * * - * array -- Optional pointer to a previously allocated memory block that the * - * array will be located in. If this parameter is not supplied, then * - * the array will be allocated from free store. * - * * - * OUTPUT: bool; Was the array resized successfully? * - * * - * WARNINGS: Failure to succeed could be the result of running out of memory. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int VectorClass::Resize(unsigned newsize, T const * array) -{ - if (newsize) { - - /* - ** Allocate a new vector of the size specified. The default constructor - ** will be called for every object in this vector. - */ - T * newptr; - if (!array) { - newptr = new T[newsize]; - } else { - newptr = new((void*)array) T[newsize]; - } - if (!newptr) { - return(false); - } - - /* - ** If there is an old vector, then it must be copied (as much as is feasable) - ** to the new vector. - */ - if (Vector) { - - /* - ** Copy as much of the old vector into the new vector as possible. This - ** presumes that there is a functional assignment operator for each - ** of the objects in the vector. - */ - int copycount = (newsize < VectorMax) ? newsize : VectorMax; - for (int index = 0; index < copycount; index++) { - newptr[index] = Vector[index]; - } - - /* - ** Delete the old vector. This might cause the destructors to be called - ** for all of the old elements. This makes the implementation of suitable - ** assignment operator very important. The default assigment operator will - ** only work for the simplist of objects. - */ - if (IsAllocated) { - delete[] Vector; - Vector = 0; - } - } - - /* - ** Assign the new vector data to this class. - */ - Vector = newptr; - VectorMax = newsize; - IsAllocated = (Vector && !array); - - } else { - - /* - ** Resizing to zero is the same as clearing the vector. - */ - Clear(); - } - return(true); -} - - -/*********************************************************************************************** - * DynamicVectorClass::DynamicVectorClass -- Constructor for dynamic vector. * - * * - * This is the normal constructor for the dynamic vector class. It is similar to the normal * - * vector class constructor. The vector is initialized to contain the number of elements * - * specified in the "size" parameter. The memory is allocated from free store unless the * - * optional array parameter is provided. In this case it will place the vector at the * - * memory location specified. * - * * - * INPUT: size -- The maximum number of objects allowed in this vector. * - * * - * array -- Optional pointer to the memory area to place the vector at. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -DynamicVectorClass::DynamicVectorClass(unsigned size, T const * array) - : VectorClass(size, array) -{ - GrowthStep = 10; - ActiveCount = 0; -} - - -/*********************************************************************************************** - * DynamicVectorClass::Resize -- Changes the size of a dynamic vector. * - * * - * Use this routine to change the size of the vector. The size changed is the maximum * - * number of allocated objects within this vector. If a memory buffer is provided, then * - * the vector will be located there. Otherwise, the memory will be allocated out of free * - * store. * - * * - * INPUT: newsize -- The desired maximum size of this vector. * - * * - * array -- Optional pointer to a previosly allocated memory array. * - * * - * OUTPUT: bool; Was vector successfully resized according to specifications? * - * * - * WARNINGS: Failure to resize the vector could be the result of lack of free store. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Resize(unsigned newsize, T const * array) -{ - if (VectorClass::Resize(newsize, array)) { - if (Length() < (unsigned)ActiveCount) ActiveCount = Length(); - return(true); - } - return(false); -} - - -/*********************************************************************************************** - * DynamicVectorClass::ID -- Find matching value in the dynamic vector. * - * * - * Use this routine to find a matching object (by value) in the vector. Unlike the base * - * class ID function of similar name, this one restricts the scan to the current number * - * of valid objects. * - * * - * INPUT: object -- A reference to the object that a match is to be found in the * - * vector. * - * * - * OUTPUT: Returns with the index number of the object that is equivalent to the one * - * specified. If no equivalent object could be found then -1 is returned. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/13/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::ID(T const & object) -{ - for (int index = 0; index < Count(); index++) { - if ((*this)[index] == object) return(index); - } - return(-1); -} - - -/*********************************************************************************************** - * DynamicVectorClass::Add -- Add an element to the vector. * - * * - * Use this routine to add an element to the vector. The vector will automatically be * - * resized to accomodate the new element IF the vector was allocated previosly and the * - * growth rate is not zero. * - * * - * INPUT: object -- Reference to the object that will be added to the vector. * - * * - * OUTPUT: bool; Was the object added successfully? If so, the object is added to the end * - * of the vector. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Add(T const & object) -{ - if ((unsigned)ActiveCount >= Length()) { - if ((IsAllocated || !VectorMax) && GrowthStep > 0) { - if (!Resize(Length() + GrowthStep)) { - - /* - ** Failure to increase the size of the vector is an error condition. - ** Return with the error flag. - */ - return(false); - } - } else { - - /* - ** Increasing the size of this vector is not allowed! Bail this - ** routine with the error code. - */ - return(false); - } - } - - /* - ** There is room for the new object now. Add it to the end of the object vector. - */ - (*this)[ActiveCount++] = object; - return(true); -} - - -template -int DynamicVectorClass::Add_Head(T const & object) -{ - if ((unsigned)ActiveCount >= Length()) { - if ((IsAllocated || !VectorMax) && GrowthStep > 0) { - if (!Resize(Length() + GrowthStep)) { - - /* - ** Failure to increase the size of the vector is an error condition. - ** Return with the error flag. - */ - return(false); - } - } else { - - /* - ** Increasing the size of this vector is not allowed! Bail this - ** routine with the error code. - */ - return(false); - } - } - - /* - ** There is room for the new object now. Add it to the end of the object vector. - */ - if (ActiveCount) { - memmove(&(*this)[1], &(*this)[0], ActiveCount * sizeof(T)); - } - (*this)[0] = object; - ActiveCount++; -// (*this)[ActiveCount++] = object; - return(true); -} - - -/*********************************************************************************************** - * DynamicVectorClass::Delete -- Remove the specified object from the vector. * - * * - * This routine will delete the object referenced from the vector. All objects in the * - * vector that follow the one deleted will be moved "down" to fill the hole. * - * * - * INPUT: object -- Reference to the object in this vector that is to be deleted. * - * * - * OUTPUT: bool; Was the object deleted successfully? This should always be true. * - * * - * WARNINGS: Do no pass a reference to an object that is NOT part of this vector. The * - * results of this are undefined and probably catastrophic. * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Delete(T const & object) -{ - int index = ID(object); - if (index != -1){ - return(Delete(index)); - }else{ - return (false); - } -} - - -/*********************************************************************************************** - * DynamicVectorClass::Delete -- Deletes the specified index from the vector. * - * * - * Use this routine to delete the object at the specified index from the objects in the * - * vector. This routine will move all the remaining objects "down" in order to fill the * - * hole. * - * * - * INPUT: index -- The index number of the object in the vector that is to be deleted. * - * * - * OUTPUT: bool; Was the object index deleted successfully? Failure might mean that the index * - * specified was out of bounds. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/10/1995 JLB : Created. * - *=============================================================================================*/ -template -int DynamicVectorClass::Delete(int index) -{ - if (index < ActiveCount) { - ActiveCount--; - - /* - ** If there are any objects past the index that was deleted, copy those - ** objects down in order to fill the hole. A simple memory copy is - ** not sufficient since the vector could contain class objects that - ** need to use the assignment operator for movement. - */ - for (int i = index; i < ActiveCount; i++) { - (*this)[i] = (*this)[i+1]; - } - return(true); - } - return(false); -} - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/VISUDLG.CPP b/code/TIBERIANDAWN/VISUDLG.CPP deleted file mode 100644 index 2c52bed..0000000 --- a/code/TIBERIANDAWN/VISUDLG.CPP +++ /dev/null @@ -1,421 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\visudlg.cpv 2.17 16 Oct 1995 16:51:40 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : VISUDLG.CPP * - * * - * Programmer : Maria del Mar McCready Legg * - * Joe L. Bostic * - * * - * Start Date : Jan 8, 1995 * - * * - * Last Update : June 18, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * VisualControlsClass::Process -- Process the visual control dialog box. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "visudlg.h" -int VisualControlsClass::Init(void) -{ - int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; - Option_Width = 216 * factor; - Option_Height = 122 * factor; - Option_X = (((SeenBuff.Get_Width() - Option_Width) / 2)); - Option_Y = ((SeenBuff.Get_Height() - Option_Height) / 2); - Text_X = Option_X + (28 * factor); - Text_Y = Option_Y + (30 * factor); - Slider_X = Option_X + (105 * factor); - Slider_Y = Option_Y + (30 * factor); - Slider_Width = 70 * factor; - Slider_Height = 5 * factor; - Slider_Y_Spacing = 11 * factor; - Button_X = Option_X + (63 * factor); - Button_Y = Option_Y + (102 * factor); - return(factor); -} -/*********************************************************************************************** - * VisualControlsClass::Process -- Process the visual control dialog box. * - * * - * This routine displays and processes the visual controls dialog box. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/18/1995 JLB : Created. * - *=============================================================================================*/ -void VisualControlsClass::Process(void) -{ - static int _titles[4] = { - TXT_BRIGHTNESS, - TXT_COLOR, - TXT_CONTRAST, - TXT_TINT - }; - - enum { - NUM_OF_BUTTONS = 6, - }; - - /* - ** Variables. - */ - int selection; - int factor; - bool pressed; - int curbutton; - TextButtonClass *buttons[NUM_OF_BUTTONS]; - SliderClass *buttonsliders[NUM_OF_BUTTONS]; - - factor = Init(); - Set_Logic_Page(SeenBuff); - - /* - ** Create Buttons. Button coords are in pixels, but are window-relative. - */ - TextButtonClass optionsbtn( - BUTTON_OPTIONS, - TXT_GAME_CONTROLS, - TPF_6PT_GRAD | TPF_NOSHADOW, - 0, - Button_Y ); - - TextButtonClass resetbtn( - BUTTON_RESET, - TXT_RESET_MENU, - TPF_6PT_GRAD | TPF_NOSHADOW, - 0, - Button_Y); - - /* - ** Centers options button. - */ - optionsbtn.X = Option_X + (Option_Width - optionsbtn.Width - (15 * factor)); - resetbtn.X = Option_X + (15 *factor); - - resetbtn.Add_Tail(optionsbtn); - - /* - ** Brightness (value) control. - */ - SliderClass brightness(BUTTON_BRIGHTNESS, Slider_X, Slider_Y + (Slider_Y_Spacing*0), Slider_Width, Slider_Height); - brightness.Set_Thumb_Size(20); - brightness.Set_Value(Options.Get_Brightness()); - brightness.Add_Tail(optionsbtn); - - /* - ** Color (saturation) control. - */ - SliderClass color(BUTTON_COLOR, Slider_X, Slider_Y + (Slider_Y_Spacing*1), Slider_Width, Slider_Height); - color.Set_Thumb_Size(20); - color.Set_Value(Options.Get_Color()); - color.Add_Tail(optionsbtn); - - /* - ** Contrast control. - */ - SliderClass contrast(BUTTON_CONTRAST, Slider_X, Slider_Y + (Slider_Y_Spacing*2), Slider_Width, Slider_Height); - contrast.Set_Thumb_Size(20); - contrast.Set_Value(Options.Get_Contrast()); - contrast.Add_Tail(optionsbtn); - - /* - ** Tint (hue) control. - */ - SliderClass tint(BUTTON_TINT, Slider_X, Slider_Y + (Slider_Y_Spacing*3), Slider_Width, Slider_Height); - tint.Set_Thumb_Size(20); - tint.Set_Value(Options.Get_Tint()); - tint.Add_Tail(optionsbtn); - - /* - ** This causes left mouse button clicking within the confines of the dialog to - ** be ignored if it wasn't recognized by any other button or slider. - */ - GadgetClass dialog(Option_X, Option_Y, Option_Width, Option_Height, GadgetClass::LEFTPRESS); - dialog.Add_Tail(optionsbtn); - - /* - ** This causes a right click anywhere or a left click outside the dialog region - ** to be equivalent to clicking on the return to options dialog. - */ - ControlClass background(BUTTON_OPTIONS, 0, 0, SeenBuff.Get_Width(), SeenBuff.Get_Height(), GadgetClass::LEFTPRESS|GadgetClass::RIGHTPRESS); - background.Add_Tail(optionsbtn); - - curbutton = 0; - buttons[0] = NULL; - buttons[1] = NULL; - buttons[2] = NULL; - buttons[3] = NULL; - buttons[4] = &resetbtn; - buttons[5] = &optionsbtn; - - buttonsliders[0] = &brightness; - buttonsliders[1] = &color; - buttonsliders[2] = &contrast; - buttonsliders[3] = ∭ - buttonsliders[4] = NULL; - buttonsliders[5] = NULL; - - /* - ** Main Processing Loop. - */ - bool display = true; - bool process = true; - bool partial = true; - pressed = false; - while (process) { - - /* - ** Invoke game callback. - */ - if (GameToPlay == GAME_NORMAL) { - Call_Back(); - } else { - if (Main_Loop()) { - process = false; - } - } - - /* - ** If we have just received input focus again after running in the background then - ** we need to redraw. - */ - if (AllSurfaces.SurfacesRestored){ - AllSurfaces.SurfacesRestored=FALSE; - display=TRUE; - } - - /* - ** Refresh display if needed. - */ - if (display) { - Hide_Mouse(); - Dialog_Box(Option_X, Option_Y, Option_Width, Option_Height); - Draw_Caption(TXT_VISUAL_CONTROLS, Option_X, Option_Y, Option_Width); - Show_Mouse(); - display = false; - partial = true; - } - - /* - ** If just the buttons and captions need to be redrawn, then do so now. - */ - if (partial) { - Hide_Mouse(); - - /* - ** Draw the titles. - */ - for (int i = 0; i < (sizeof(_titles)/sizeof(_titles[0])); i++) { - Fancy_Text_Print(_titles[i], Slider_X-8, Text_Y + (i*Slider_Y_Spacing), - CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_RIGHT|TPF_NOSHADOW| ((curbutton == i) ? TPF_BRIGHT_COLOR : TPF_USE_GRAD_PAL)); - } - optionsbtn.Draw_All(); - Show_Mouse(); - partial = false; - } - - /* - ** Get and process player input. - */ - KeyNumType input = optionsbtn.Input(); - switch (input) { - case (BUTTON_BRIGHTNESS | KN_BUTTON): - Options.Set_Brightness(brightness.Get_Value()); - break; - - case (BUTTON_COLOR | KN_BUTTON): - Options.Set_Color(color.Get_Value()); - break; - - case (BUTTON_CONTRAST | KN_BUTTON): - Options.Set_Contrast(contrast.Get_Value()); - break; - - case (BUTTON_TINT | KN_BUTTON): - Options.Set_Tint(tint.Get_Value()); - break; - - case (BUTTON_RESET | KN_BUTTON): - selection = BUTTON_RESET; - pressed = true; - break; - - case KN_ESC: - case BUTTON_OPTIONS|KN_BUTTON: - selection = BUTTON_OPTIONS; - pressed = true; - break; - - case (KN_LEFT): - if (curbutton <= (BUTTON_TINT - BUTTON_BRIGHTNESS)) { - buttonsliders[curbutton]->Bump(1); - switch (curbutton) { - case (BUTTON_BRIGHTNESS - BUTTON_BRIGHTNESS): - Options.Set_Brightness(brightness.Get_Value()); - break; - - case (BUTTON_COLOR - BUTTON_BRIGHTNESS): - Options.Set_Color(color.Get_Value()); - break; - - case (BUTTON_CONTRAST - BUTTON_BRIGHTNESS): - Options.Set_Contrast(contrast.Get_Value()); - break; - - case (BUTTON_TINT - BUTTON_BRIGHTNESS): - Options.Set_Tint(tint.Get_Value()); - break; - } - } else { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - - curbutton--; - if (curbutton < (BUTTON_RESET - BUTTON_BRIGHTNESS) ) { - curbutton = (BUTTON_OPTIONS - BUTTON_BRIGHTNESS); - } - - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - break; - - case (KN_RIGHT): - if (curbutton <= (BUTTON_TINT - BUTTON_BRIGHTNESS)) { - buttonsliders[curbutton]->Bump(0); - switch (curbutton) { - case (BUTTON_BRIGHTNESS - BUTTON_BRIGHTNESS): - Options.Set_Brightness(brightness.Get_Value()); - break; - - case (BUTTON_COLOR - BUTTON_BRIGHTNESS): - Options.Set_Color(color.Get_Value()); - break; - - case (BUTTON_CONTRAST - BUTTON_BRIGHTNESS): - Options.Set_Contrast(contrast.Get_Value()); - break; - - case (BUTTON_TINT - BUTTON_BRIGHTNESS): - Options.Set_Tint(tint.Get_Value()); - break; - } - } else { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - - curbutton++; - if (curbutton > (BUTTON_OPTIONS - BUTTON_BRIGHTNESS) ) { - curbutton = (BUTTON_RESET - BUTTON_BRIGHTNESS); - } - - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - break; - - case (KN_UP): - if (curbutton <= (BUTTON_TINT - BUTTON_BRIGHTNESS) ) { - partial = true; - } else { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - } - - curbutton--; - if (curbutton == (BUTTON_RESET - BUTTON_BRIGHTNESS) ) { - curbutton--; - } - - if (curbutton < 0) { - curbutton = (BUTTON_RESET - BUTTON_BRIGHTNESS); - } - - if (curbutton <= (BUTTON_TINT - BUTTON_BRIGHTNESS) ) { - partial = true; - } else { - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - break; - - case (KN_DOWN): - if (curbutton <= (BUTTON_TINT - BUTTON_BRIGHTNESS) ) { - partial = true; - } else { - buttons[curbutton]->Turn_Off(); - buttons[curbutton]->Flag_To_Redraw(); - } - - curbutton++; - if (curbutton > (BUTTON_RESET - BUTTON_BRIGHTNESS) ) { - curbutton = 0; - } - - if (curbutton <= (BUTTON_TINT - BUTTON_BRIGHTNESS) ) { - partial = true; - } else { - buttons[curbutton]->Turn_On(); - buttons[curbutton]->Flag_To_Redraw(); - } - break; - - case (KN_RETURN): - selection = curbutton + BUTTON_BRIGHTNESS; - pressed = true; - break; - - default: - break; - } - - - if (pressed) { - switch (selection) { - case (BUTTON_RESET): - brightness.Set_Value(128); - contrast.Set_Value(128); - color.Set_Value(128); - tint.Set_Value(128); - - Options.Set_Brightness(128); - Options.Set_Contrast(128); - Options.Set_Color(128); - Options.Set_Tint(128); - break; - - case (BUTTON_OPTIONS): - process = false; - break; - } - - pressed = false; - } - } -} - diff --git a/code/TIBERIANDAWN/VISUDLG.H b/code/TIBERIANDAWN/VISUDLG.H deleted file mode 100644 index 43ed91b..0000000 --- a/code/TIBERIANDAWN/VISUDLG.H +++ /dev/null @@ -1,89 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\visudlg.h_v 2.15 16 Oct 1995 16:47:46 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : VISUDLG.H * - * * - * Programmer : Maria del Mar McCready Legg * - * Joe L. Bostic * - * * - * Start Date : Jan 8, 1995 * - * * - * Last Update : Jan 18, 1995 [MML] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - *---------------------------------------------------------------------------------------------*/ - -#ifndef VISUDLG_H -#define VISUDLG_H - -#include "gadget.h" - -class VisualControlsClass -{ - private: - - enum VisualControlEnums { - BUTTON_BRIGHTNESS=1, - BUTTON_COLOR, - BUTTON_CONTRAST, - BUTTON_TINT, - BUTTON_RESET, - BUTTON_OPTIONS, // Button number for "Options menu" - OPTION_WIDTH=216, // Width of dialog box. - OPTION_HEIGHT=122, // Height of dialog box. - OPTION_X=(((320 - OPTION_WIDTH) / 2)), - OPTION_Y=((200 - OPTION_HEIGHT) / 2), - TEXT_X=OPTION_X+28, // Title's x pos - TEXT_Y=OPTION_Y+30, // Add 11 for each following line - SLIDER_X=OPTION_X+105, // Slider's x pos - SLIDER_Y=OPTION_Y+30, // Add 11 for each following line - SLIDER_WIDTH=70, // Width of each control slider. - SLIDER_HEIGHT=5, // Height of each control slider. - SLIDER_Y_SPACING=11, // Vertical spacing between sliders. - BUTTON_X=OPTION_X+63, // Options button x pos - BUTTON_Y=OPTION_Y+102, // Options button y pos - }; - - public: - - VisualControlsClass(void) {}; - void Process(void); - int Init(void); - - int Option_Width; // Width of dialog box. - int Option_Height; // Height of dialog box. - int Option_X; - int Option_Y; - int Text_X; // Title's x pos - int Text_Y; // Add 11 for each following line - int Slider_X; // Slider's x pos - int Slider_Y; // Add 11 for each following line - int Slider_Width; // Width of each control slider. - int Slider_Height; // Height of each control slider. - int Slider_Y_Spacing; // Vertical spacing between sliders. - int Button_X; // Options button x pos - int Button_Y; // Options button y pos - -}; - -#endif diff --git a/code/TIBERIANDAWN/WATCOM.H b/code/TIBERIANDAWN/WATCOM.H deleted file mode 100644 index 107fab1..0000000 --- a/code/TIBERIANDAWN/WATCOM.H +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\watcom.h_v 2.13 16 Oct 1995 16:45:58 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : WATCOM.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : 03/12/95 * - * * - * Last Update : March 12, 1995 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WATCOM_H -#define WATCOM_H -#if (0) -// Turn all warnings into errors. -#pragma warning * 0 - -// Disables warning when "sizeof" is used on an object with virtual functions. -#pragma warning 549 9 - -// Disable the "Integral value may be truncated during assignment or initialization". -#pragma warning 389 9 - -// Allow constructing a temporary to be used as a parameter. -#pragma warning 604 9 - -// Disable the construct resolved as an expression warning. -#pragma warning 595 9 - -// Disable the strange "construct resolved as a declaration/type" warning. -#pragma warning 594 9 - -// Disable the "pre-compiled header file cannot be used" warning. -#pragma warning 698 9 - -// Disable the "temporary object used to initialize a non-constant reference" warning. -#pragma warning 665 9 - -// Disable the "pointer or reference truncated by cast. Cast is supposed to REMOVE warnings, not create them. -#pragma warning 579 9 - -// Disable the warning about moving empty constructors/destructors to the class declaration. -#pragma warning 657 9 - -// Turns off unreferenced function parameter warning. -//#pragma off(unreferenced) - -// Turns off "expression with side effect in sizeof()". This is needed if memchecker is used. -#pragma warning 472 9 -#endif -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/ALLOC.CPP b/code/TIBERIANDAWN/WIN32LIB/ALLOC.CPP deleted file mode 100644 index cd3f15f..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/ALLOC.CPP +++ /dev/null @@ -1,509 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : ALLOC.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : February 1, 1992 * - * * - * Last Update : March 9, 1995 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Alloc -- Allocates system RAM. * - * Ram_Free -- Determines the largest free chunk of RAM. * - * Free -- Free an Alloc'ed block of RAM. * - * Resize_Alloc -- Change the size of an allocated block. * - * Heap_Size -- Size of the heap we have. * - * Total_Ram_Free -- Total amount of free RAM. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include -#include -//#include -//#include - - -#ifndef WWMEM_H -#include "wwmem.h" -#endif - - -extern "C" unsigned long Largest_Mem_Block ( void ) ; - -/* -** Define the equates necessary to call a DPMI interrupt. -*/ -#define DPMI_INT 0x0031 -#define DPMI_LOCK_MEM 0x0600 -#define DPMI_UNLOCK_MEM 0x0601 - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -unsigned long MinRam=0L; // Record of least memory at worst case. -unsigned long MaxRam=0L; // Record of total allocated at worst case. -static unsigned long TotalRam = 0L; -static unsigned long Memory_Calls = 0L; - -void (*Memory_Error)(void) = NULL; -extern void (*Memory_Error_Exit)(char *string)=NULL; - - -//#define MEM_CHECK - -#ifdef MEM_CHECK -extern "C"{ - extern void __cdecl Int3(void); -} -#endif //MEM_CHECK - -/*************************************************************************** - * DPMI_LOCK -- handles locking a block of DPMI memory * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/23/1995 PWG : Created. * - *=========================================================================*/ -#include"mono.h" -void DPMI_Lock(VOID const *, long const ) -{ -} - -/*************************************************************************** - * DPMI_UNLOCK -- Handles unlocking a locked block of DPMI * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/23/1995 PWG : Created. * - *=========================================================================*/ -void DPMI_Unlock(void const *, long const ) -{ -} - -/*************************************************************************** - * Alloc -- Allocates system RAM. * - * * - * This is the basic RAM allocation function. It is used for all * - * memory allocations needed by the system or the main program. * - * * - * INPUT: bytes_to_alloc -- LONG value of the number of bytes to alloc. * - * * - * flags -- Memory allocation control flags. * - * MEM_NORMAL: No special flags. * - * MEM_CLEAR: Zero out memory block. * - * MEM_NEW: Called by a new. * - * * - * OUTPUT: Returns with pointer to allocated block. If NULL was returned * - * it indicates a failure to allocate. Note: NULL will never be * - * returned if the standard library allocation error routine is * - * used. * - * * - * WARNINGS: If you replace the standard memory allocation error routine * - * and make it so that Alloc CAN return with a NULL, be sure * - * and check for this in your code. * - * * - * HISTORY: * - * 09/03/1991 JLB : Documented. * - * 08/09/1993 JLB : Updated with EMS memory support. * - * 04/28/1994 JAW : Updated to 32bit Protected mode. * - * 03/09/1995 JLB : Fixed * - * 09/28/1995 ST : Simplified for win95 * - *=========================================================================*/ -void *Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags) -{ - -#ifdef WIN32 - - void *mem_ptr; - -#ifdef MEM_CHECK - bytes_to_alloc += 32; -#endif //MEM_CHECK - - mem_ptr = malloc ( bytes_to_alloc ); - - if ( !mem_ptr && Memory_Error ){ - Memory_Error(); - } - - if ( mem_ptr && ( flags & MEM_CLEAR ) ){ - memset ( mem_ptr , 0 , bytes_to_alloc ); - } - -#ifdef MEM_CHECK - mem_ptr = (void*)((char*)mem_ptr + 16); - unsigned long *magic_ptr =(unsigned long*) ( ((char *)mem_ptr) - 16 ); - *magic_ptr++ = (unsigned long)mem_ptr; - *magic_ptr++ = (unsigned long)mem_ptr; - *magic_ptr++ = (unsigned long)mem_ptr; - *magic_ptr = bytes_to_alloc - 32; - magic_ptr = (unsigned long*) ( ((char*)mem_ptr) + bytes_to_alloc - 32 ); - *magic_ptr++ = (unsigned long)mem_ptr; - *magic_ptr++ = (unsigned long)mem_ptr; - *magic_ptr++ = (unsigned long)mem_ptr; - *magic_ptr = (unsigned long)mem_ptr; -#endif //MEM_CHECK - - Memory_Calls++; - return ( mem_ptr ); - -#else - - - - union REGS regs ; - struct SREGS sregs ; - unsigned char *retval=NULL; // Pointer to allocated block. - unsigned long original_size; // Original allocation size. - unsigned long bytesfree; // Number of free bytes. - long *longptr=NULL; // Pointer used to store selector - - /* - ** Save the original allocated space size so that we can clear the - ** exact amount of RAM if they specified MEM_CLEAR. - */ - original_size = bytes_to_alloc; - - /* - ** Reserve one byte for the header of the memory we allocated. - ** We will store the flags variable there for later use. - */ - bytes_to_alloc += (flags & MEM_LOCK) ? 5 : 1; - - /* - ** Initialize the total ram available value. - */ - if (!TotalRam) { - TotalRam = Total_Ram_Free(MEM_NORMAL); - } - - - // Try to allocate the memory out of the protected mode memory - // chain if we did not require a real mode allocation. If this - // fails we will have to try to allocate it out of real mode memory. - // Real mode memory is a last resort because some types of applications - // require real mode memory. - if (!(flags & MEM_REAL)) { - retval = (unsigned char*)malloc(bytes_to_alloc); - } - - // Try to allocate the memory out of the real mode memory using DPMI - // service 0x100. Note that retval will be null if we are requesting - // real mode memory so that we do not have to explicitly check for the - // real mode flag. Remember we need to reserve room for the dos - // selector value at the beginning of our allocated block so rather than - // adding fifteen and rounding, we need to add 19 and round. - if (!retval) { - flags = (MemoryFlagType)(flags | MEM_REAL); - regs.x.eax = 0x100; - regs.x.ebx = (bytes_to_alloc + 19) >> 4; - if (regs.x.ebx & 0xFFFF0000) { - retval = NULL; - } else { - segread ( & sregs ) ; - int386x ( 0x31 , & regs, & regs , & sregs ) ; - if (regs.x.cflag) - retval = NULL; - else { - longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 1); - *longptr++ = regs.x.edx & 0xFFFF; - retval = (unsigned char *)longptr; - } - } - } - - // If the alloc failed then we need to signify a memory error. - if (retval == NULL) { - if(Memory_Error != NULL) - Memory_Error(); - return NULL; - } - - // If the memory needs to be DPMI locked then we should store the - // original size in the header before we store the flags. - if (flags & MEM_LOCK) { - longptr = (long *)retval; - *longptr++ = original_size; - retval = (unsigned char *)longptr; - } - - - // Now that we know the alloc was sucessful (and for an extra byte - // more than the user wanted) we need to stick in the memory flags. - *retval++ = flags; - - // If the memory needed to be DPMI locked then set it up so it - // is locked. - if (flags & MEM_LOCK) { - DPMI_Lock(retval, original_size); - - } - - - /* Clear the space if they wanted it clear */ - - if (flags & MEM_CLEAR) { - unsigned char *ptr; // Working memory block pointer. - - ptr = retval; - memset(ptr, '\0', original_size); - } - - bytesfree = Total_Ram_Free(MEM_NORMAL); - if (bytesfree < MinRam) { - MinRam = bytesfree; - } - if (TotalRam-bytesfree > MaxRam) { - MaxRam = TotalRam-bytesfree; - } - - Memory_Calls++; - - return(retval); - -#endif -} - - -/*************************************************************************** - * Free -- Free an Alloc'ed block of RAM. * - * * - * FUNCTION: * - * * - * INPUT: A pointer to a block of RAM from Alloc. * - * * - * OUTPUT: None. * - * * - * WARNINGS: Don't use this for an Alloc_Block'ed RAM block. * - * * - * HISTORY: * - * 05/25/1990 : Created. * - ***************************************************************************/ -#ifdef WIN32 - -void Free(void const *pointer) -{ - - if ( pointer ){ - -#ifdef MEM_CHECK - - unsigned long *magic_ptr = (unsigned long*) ( ((char*)pointer) - 16 ); - - if (*magic_ptr++ != (unsigned long)pointer || - *magic_ptr++ != (unsigned long)pointer || - *magic_ptr++ != (unsigned long)pointer ){ - Int3(); - } - - magic_ptr = (unsigned long*) ( ((char*)pointer) + *magic_ptr ); - - if (*magic_ptr++ != (unsigned long)pointer || - *magic_ptr++ != (unsigned long)pointer || - *magic_ptr++ != (unsigned long)pointer || - *magic_ptr++ != (unsigned long)pointer ){ - Int3(); - } - - pointer = (void*) (((char*)pointer)-16); -#endif //MEM_CHECK - - free ( (void*)pointer ); - Memory_Calls--; - } - -#else - -void Free(void const *pointer) -{ - - union REGS regs ; - struct SREGS sregs ; - - - if (pointer) { - /* - ** Get a pointer to the flags that we stored off. - */ - char *byteptr = ((char *)pointer) - 1; - - /* - ** Check to see if this was locked me and if it was unlock it. - */ - if (*byteptr & MEM_LOCK) { - long *longptr = ((long *)byteptr) - 1; - DPMI_Unlock(pointer, *longptr); - pointer = (void *)longptr; - } else - pointer = (void *)byteptr; - - - // If the pointer is a real mode pointer than it will point to the - // first megabyte of system memory. If it does than we need to - // use DPMI to free it. - if (*byteptr & MEM_REAL) { - regs.x.eax = 0x101; - regs.x.edx = *(((long *)pointer) - 1); - segread ( & sregs ) ; - int386x(0x31, ®s, ®s, &sregs); - } else { - free((void *)pointer); - } - Memory_Calls--; - } - -#endif -} - - - -/*************************************************************************** - * Resize_Alloc -- Change the size of an allocated block. * - * * - * This routine will take a previously allocated block and change its * - * size without unnecessarily altering its contents. * - * * - * INPUT: pointer -- Pointer to the original memory allocation. * - * * - * new_size -- Size in bytes that it will be converted to. * - * * - * OUTPUT: Returns with a pointer to the new allocation. * - * * - * WARNINGS: ??? * - * * - * HISTORY: * - * 02/01/1992 JLB : Commented. * - *=========================================================================*/ -void *Resize_Alloc(void *original_ptr, unsigned long new_size_in_bytes) -{ - - unsigned long *temp; - - temp = (unsigned long*)original_ptr; - - /* ReAlloc the space */ - temp = (unsigned long *)realloc(temp, new_size_in_bytes); - if (temp == NULL) { - if(Memory_Error != NULL) - Memory_Error(); - return NULL; - } - - return(temp); -} - - -/*************************************************************************** - * Ram_Free -- Determines the largest free chunk of RAM. * - * * - * Use this routine to determine the largest free chunk of available * - * RAM for allocation. It also performs a check of the memory chain. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with the size of the largest free chunk of RAM. * - * * - * WARNINGS: This does not return the TOTAL memory free, only the * - * largest free chunk. * - * * - * HISTORY: * - * 09/03/1991 JLB : Commented. * - *=========================================================================*/ -long Ram_Free(MemoryFlagType) -{ -// return(_memmax()); -#if(0) - MEMORYSTATUS mem_info; - mem_info.dwLength=sizeof(mem_info); - GlobalMemoryStatus(&mem_info); - return ( mem_info.dwAvailPhys ); -#endif - return ( 64*1024*1024 ); -} - - -/*************************************************************************** - * Heap_Size -- Size of the heap we have. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - *=========================================================================*/ -long Heap_Size(MemoryFlagType ) -{ - if (!TotalRam) { - TotalRam = Total_Ram_Free(MEM_NORMAL); - } - return(TotalRam); -} - - -/*************************************************************************** - * Total_Ram_Free -- Total amount of free RAM. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - * 03/09/1995 JLB : Uses prerecorded heap size maximum. * - *=========================================================================*/ -long Total_Ram_Free(MemoryFlagType ) -{ -#if(0) - MEMORYSTATUS mem_info; - mem_info.dwLength=sizeof(mem_info); - GlobalMemoryStatus(&mem_info); - return ( mem_info.dwAvailPhys ); -#endif - - return ( 64*1024*1024 ); -} - diff --git a/code/TIBERIANDAWN/WIN32LIB/AUDIO.H b/code/TIBERIANDAWN/WIN32LIB/AUDIO.H deleted file mode 100644 index d84c697..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/AUDIO.H +++ /dev/null @@ -1,158 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Westwood 32 bit Library * - * * - * File Name : AUDIO.H * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : March 10, 1995 * - * * - * Last Update : March 10, 1995 [PWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "wwstd.h" - -/*=========================================================================*/ -/* AUD file header type */ -/*=========================================================================*/ -#define AUD_FLAG_STEREO 1 -#define AUD_FLAG_16BIT 2 - -// PWG 3-14-95: This structure used to have bit fields defined for Stereo -// and Bits. These were removed because watcom packs them into a 32 bit -// flag entry even though they could have fit in a 8 bit entry. -//#pragma pack(1); -#pragma pack(push,1) -typedef struct { - unsigned short int Rate; // Playback rate (hertz). - long Size; // Size of data (bytes). - long UncompSize; // Size of data (bytes). - unsigned char Flags; // Holds flags for info - // 1: Is the sample stereo? - // 2: Is the sample 16 bits? - unsigned char Compression; // What kind of compression for this sample? -} AUDHeaderType; -#pragma pack(pop) - -/*=========================================================================*/ -/* There can be a different sound driver for sound effects, digitized */ -/* samples, and musical scores. Each one must be of these specified */ -/* types. */ -/*=========================================================================*/ -typedef enum { - SAMPLE_NONE, // No digitized sounds will be played. - SAMPLE_SB, // Sound Blaster digitized driver. - SAMPLE_SBPRO, // Sound Blaster Pro digitized driver. - SAMPLE_PAS, // Pro-Audio Spectrum digitized driver. - SAMPLE_ADLIBG, // Adlib-Gold digitized driver. - SAMPLE_TANDY, // Tandy 'compatible' driver. - SAMPLE_PCSPKR, // PC speaker digitized driver (The Audio Solution driver). - SAMPLE_ADLIB, // Adlib digitized driver (The Audio Solution driver). - SAMPLE_TEMP=0x1000, - SAMPLE_LAST -} Sample_Type; - -typedef enum { - SCORE_NONE, // No scores will be played. - SCORE_ALFX, // Westwood's ALFX adlib compatable driver. - SCORE_WWPCSPKR, // Westwood's PC-speaker driver (obsolete). - SCORE_WWTANDY, // Westwood's PC-speaker driver with Tandy mod (obsolete). - SCORE_PCSPKR, // PC speaker XMIDI driver. - SCORE_TANDY, // Tandy XMIDI driver. - SCORE_MT32, // MT-32 / LAPC-1 Roland XMIDI driver. - SCORE_CANVAS, // Sound Canvas SC-55. - SCORE_ADLIB, // Adlib XMIDI driver. - SCORE_ADLIBG, // Adlib Gold XMIDI driver. - SCORE_PASFM, // Pro Audio Spectrum XMIDI driver. - SCORE_SBFM, // Sound Blaster XMIDI driver. - SCORE_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver. - SCORE_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver (Can't use with SFX_ALFX). - SCORE_TEMP=0x1000, - SCORE_LAST -} Score_Type; - -typedef enum { - SFX_NONE, // No sound effects will be played. - SFX_ALFX, // Westwood's ALFX adlib compatable driver. - SFX_WWPCSPKR, // Westwood's PC-speaker driver. - SFX_WWTANDY, // Westwood's PC-speaker driver with Tandy mod. - SFX_PCSPKR, // PC speaker XMIDI driver. - SFX_TANDY, // Tandy XMIDI driver. - SFX_MT32, // MT-32 / LAPC-1 Roland XMIDI driver. - SFX_CANVAS, // Sound Canvas SC-55. - SFX_ADLIB, // Adlib XMIDI driver. - SFX_ADLIBG, // Adlib Gold XMIDI driver. - SFX_PASFM, // Pro Audio Spectrum XMIDI driver. - SFX_SBFM, // Sound Blaster XMIDI driver. - SFX_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver. - SFX_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver. - SFX_TEMP=0x1000, - SFX_LAST -} SFX_Type; - - - -/*=========================================================================*/ -/* The following prototypes are for the file: SOUNDIO.CPP */ -/*=========================================================================*/ -int File_Stream_Sample(char const *filename, BOOL real_time_start = FALSE); -int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start = FALSE); -void __cdecl Sound_Callback(void); -void __cdecl far maintenance_callback(void); -void *Load_Sample(char const *filename); -long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size); -long Sample_Read(int fh, void *buffer, long size); -void Free_Sample(void const *sample); -BOOL Audio_Init( HWND window , int bits_per_sample, BOOL stereo , int rate , int reverse_channels); -void Sound_End(void); -void Stop_Sample(int handle); -BOOL Sample_Status(int handle); -BOOL Is_Sample_Playing(void const * sample); -void Stop_Sample_Playing(void const * sample); -int Play_Sample(void const *sample, int priority=0xFF, int volume=0xFF, signed short panloc = 0x0); -int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id); -int Set_Sound_Vol(int volume); -int Set_Score_Vol(int volume); -void Fade_Sample(int handle, int ticks); -int Get_Free_Sample_Handle(int priority); -int Get_Digi_Handle(void); -long Sample_Length(void const *sample); -void Restore_Sound_Buffers (void); -BOOL Set_Primary_Buffer_Format(void); -BOOL Start_Primary_Sound_Buffer (BOOL forced); -void Stop_Primary_Sound_Buffer (void); - -/* -** Function to call if we detect focus loss -*/ -extern void (*Audio_Focus_Loss_Function)(void); - - -extern int Misc; -extern SFX_Type SoundType; -extern Sample_Type SampleType; - -extern CRITICAL_SECTION GlobalAudioCriticalSection; - -extern int StreamLowImpact; diff --git a/code/TIBERIANDAWN/WIN32LIB/BUFFER.CPP b/code/TIBERIANDAWN/WIN32LIB/BUFFER.CPP deleted file mode 100644 index 7affb08..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/BUFFER.CPP +++ /dev/null @@ -1,128 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood 32 Bit Library * - * * - * File Name : BUFFER.CPP * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : May 18, 1994 * - * * - * Last Update : June 1, 1994 [PWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * BC::BufferClass -- The default (void) constructor for a buffer class * - * BC::~BufferClass -- The destructor for the buffer class * - * BC::BufferClass -- The standard constructor for a buffer class * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef BUFFER_H -#include "buffer.h" -#endif - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -/*************************************************************************** - * BC::BufferClass -- The standard constructor for a buffer class * - * * - * INPUT: VOID * buffer to which should be included in buffer class * - * LONG size of the buffer which we included * - * * - * OUTPUT: NONE * - * * - * WARNINGS: If the buffer passed to this function is equal to NULL, * - * the buffer will be allocated using new. * - * * - * HISTORY: * - * 06/01/1994 PWG : Created. * - *=========================================================================*/ -BufferClass::BufferClass(VOID *buffer, LONG size) -{ - Size = size; // find size of physical buffer - - if (buffer) { // if buffer is specified - Buffer = (BYTE *)buffer; // point to it and mark - Allocated = FALSE; // it as user allocated - } else { - Buffer = new BYTE[Size]; // otherwise allocate it and - Allocated = TRUE; // mark it system alloced - } -} - -/*************************************************************************** - * BC::BufferClass -- constructor for BufferClass with size only * - * * - * INPUT: LONG the size of the buffer that needs to be allocated * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 06/01/1994 PWG : Created. * - *=========================================================================*/ -BufferClass::BufferClass(LONG size) -{ - Size = size; - Buffer = new BYTE[Size]; // otherwise allocate it and - Allocated = TRUE; // mark it system alloced -} - -/*************************************************************************** - * BC::BufferClass -- The default (void) constructor for a buffer class * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * NOTES: The primary function of this class is to be called by a * - * derived class which will fill in the values after the * - * fact. * - * * - * HISTORY: * - * 06/01/1994 PWG : Created. * - *=========================================================================*/ -BufferClass::BufferClass(VOID) -{ - Buffer = NULL; - Size = 0; - Allocated = FALSE; -} - -/*************************************************************************** - * BC::~BUFFERCLASS -- The destructor for the buffer class * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 06/01/1994 PWG : Created. * - *=========================================================================*/ -BufferClass::~BufferClass(VOID) -{ - if (Allocated) { - delete[] Buffer; - } -} diff --git a/code/TIBERIANDAWN/WIN32LIB/BUFFER.H b/code/TIBERIANDAWN/WIN32LIB/BUFFER.H deleted file mode 100644 index 39ce894..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/BUFFER.H +++ /dev/null @@ -1,121 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood 32 Bit Library * - * * - * File Name : GBUFFER.H * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : May 26, 1994 * - * * - * Last Update : July 5, 1994 [PWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * BC::Get_Size -- Returns the buffer size of the BufferClass instance * - * BC::Get_Buffer -- Returns pointer to buffer inherent to BufferClass * - * BC::BufferClass -- inline constructor for BufferClass with size only * - * BC::To_Page -- Copys a buffer class to a page with definable x, y, w, h* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef BUFFER_H -#define BUFFER_H - - -/*=========================================================================*/ -/* If we have not already loaded the standard library header, than we can */ -/* load it. */ -/*=========================================================================*/ -#ifndef WWSTD_H -#include "wwstd.h" -#endif - -class GraphicViewPortClass; - -/*=========================================================================*/ -/* BufferClass - A base class which holds buffer information including a */ -/* pointer and the size of the buffer. */ -/*=========================================================================*/ -class BufferClass { - public: - /*===================================================================*/ - /* Define the base constructor and destructors for the class */ - /*===================================================================*/ - BufferClass(void *ptr, long size); - BufferClass(long size); - BufferClass(); - ~BufferClass(); - /*===================================================================*/ - /* Define functions which work with the buffer class. */ - /*===================================================================*/ - long To_Page(GraphicViewPortClass &view); - long To_Page(int w, int h, GraphicViewPortClass &view); - long To_Page(int x, int y, int w, int h, GraphicViewPortClass &view); - - /*===================================================================*/ - /* define functions to get at the protected data members */ - /*===================================================================*/ - void *Get_Buffer(void); - long Get_Size(void); - - private: - /*===================================================================*/ - /* Define the operators we do not want to happen which are the copy */ - /* and equal constructors. These are bad because the Allocated flag */ - /* could be copied and the associated buffer freed. If this were to */ - /* gappen it could cause weird general protection fault. */ - /*===================================================================*/ - BufferClass(BufferClass const &); - BufferClass &operator=(BufferClass const &); - - protected: - void *Buffer; - long Size; - BOOL Allocated; -}; -/*************************************************************************** - * BC::GET_SIZE -- Returns the buffer size of the BufferClass instance * - * * - * INPUT: none * - * * - * OUTPUT: long the size of the buffer * - * * - * HISTORY: * - * 06/01/1994 PWG : Created. * - *=========================================================================*/ -inline long BufferClass::Get_Size(void) -{ - return(Size); -} -/*************************************************************************** - * BC::GET_BUFFER -- Returns pointer to buffer inherent to BufferClass * - * * - * INPUT: none * - * * - * OUTPUT: void * to the inherent buffer. * - * * - * HISTORY: * - * 06/01/1994 PWG : Created. * - *=========================================================================*/ -inline void *BufferClass::Get_Buffer(void) -{ - return(Buffer); -} -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/BUFFGLBL.CPP b/code/TIBERIANDAWN/WIN32LIB/BUFFGLBL.CPP deleted file mode 100644 index 6c16b9d..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/BUFFGLBL.CPP +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Westwood 32 bit Library * - * * - * File Name : BUFFGLBL.CPP * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : January 10, 1995 * - * * - * Last Update : January 10, 1995 [PWG] * - * * - * This module holds the global fixup tables for the MCGA buffer class. * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include "gbuffer.h" - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -/*=========================================================================*/ -/* Globals required by GraphicBufferClass for function pointers. These */ -/* pointers will be set to the proper function when set mode is called. */ -/*=========================================================================*/ -BOOL (*GVPC_Blit_to_VVPC_Func)(void *, void *, int, int, int, int, int, int, BOOL); -BOOL (*GVPC_Scale_To_VVPC)( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *); - -#ifdef not_any_more_it_doesnt -/*=========================================================================*/ -/* Globals required by VideoBufferClass for function pointers. These */ -/* pointers will be set to the proper function when set mode is called. */ -/*=========================================================================*/ -void (*VVPC_Clear_Func)(void *, unsigned char); -long (*VVPC_To_Buffer_Func)(void *,int x, int y, int w, int h, void *buff, long size); -void (*VVPC_Put_Pixel_Func)(void *,int x, int y, unsigned char color); -int (*VVPC_Get_Pixel_Func)(void *, int x, int y); -long (*VVPC_Buffer_To_Page)(int x, int y, int w, int h, void *Buffer, void *view); -BOOL (*VVPC_Blit_to_GVPC_Func)(void *, void *, int, int, int, int, int, int, BOOL); -BOOL (*VVPC_Blit_to_VVPC_Func)(void *, void *, int, int, int, int, int, int, BOOL); -BOOL (*VVPC_Scale_To_GVPC)( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *); -BOOL (*VVPC_Scale_To_VVPC)( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *); -LONG (*VVPC_Print_Func)( void *, const char *, int, int, int, int); -void (*VVPC_Draw_Stamp)(void *, void *, int, int, int, void *); -long (*VVPC_Size_Of_Region)(void *, int, int); - -#endif //not_any_more_it_doesnt - -/*=========================================================================*/ -/* We need to keep a pointer to the logic page hanging around somewhere */ -/*=========================================================================*/ -GraphicViewPortClass *LogicPage; - -BOOL IconCacheAllowed = TRUE; - -/* -** Pointer to a function we will call if we detect loss of focus -*/ -void (*Gbuffer_Focus_Loss_Function)(void) = NULL; diff --git a/code/TIBERIANDAWN/WIN32LIB/DDRAW.CPP b/code/TIBERIANDAWN/WIN32LIB/DDRAW.CPP deleted file mode 100644 index fb84677..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DDRAW.CPP +++ /dev/null @@ -1,1002 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Win32 Library * - * * - * File Name : DDRAW.CPP * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : October 10, 1995 * - * * - * Last Update : October 10, 1995 [] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - - -#include "misc.h" -#include -#include -#include "stdio.h" - -LPDIRECTDRAW DirectDrawObject=NULL; // Pointer to the direct draw object -LPDIRECTDRAW2 DirectDraw2Interface = NULL; // Pointer to direct draw 2 interface - -HWND MainWindow; // Handle to programs main window - // this is passed to SetCooperativeLevel - // so DirectDraw knows which window is ours - - -PALETTEENTRY PaletteEntries[256]; // 256 windows palette entries -LPDIRECTDRAWPALETTE PalettePtr; // Pointer to direct draw palette object -BOOL FirstPaletteSet=FALSE; // Is this the first time 'Set_Palette' has been called? -LPDIRECTDRAWSURFACE PaletteSurface=NULL; -SurfaceMonitorClass AllSurfaces; //List of all direct draw surfaces -BOOL CanVblankSync = TRUE; - -BOOL SystemToVideoBlits =FALSE; // Does hardware support system mem to video mem blits? -BOOL VideoToSystemBlits =FALSE; // Does hardware support video mem to system mem blits? -BOOL SystemToSystemBlits = FALSE; // Does hardware support system mem to system mem blits? -BOOL OverlappedVideoBlits = TRUE; // Can video driver blit overlapped regions? - -/* -** Function to call if we detect focus loss -*/ -extern void (*Misc_Focus_Loss_Function)(void) = NULL; -extern void (*Misc_Focus_Restore_Function)(void) = NULL; - - -/*********************************************************************************************** - * Process_DD_Result -- Does a message box based on the result of a DD command * - * * - * INPUT: HRESULT result - the result returned from the direct draw command * - * int display_ok_msg - should a message be displayed if command ok * * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 09/27/1995 PWG : Created. * - *=============================================================================================*/ -void Process_DD_Result(HRESULT result, int display_ok_msg) -{ - switch (result) { - case DD_OK: - if (display_ok_msg) { - MessageBox(MainWindow, "Direct Draw request went ok.", "Note", MB_ICONEXCLAMATION|MB_OK); - } - break; - case DDERR_ALREADYINITIALIZED: - MessageBox(MainWindow, "This object is already initialized ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_BLTFASTCANTCLIP: - MessageBox(MainWindow, "Return if a clipper object is attached to the source surface passed into a BltFast call.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CANNOTATTACHSURFACE: - MessageBox(MainWindow, "This surface can not be attached to the requested surface. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CANNOTDETACHSURFACE: - MessageBox(MainWindow, "This surface can not be detached from the requested surface. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CANTCREATEDC: - MessageBox(MainWindow, "Windows can not create any more DCs","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CANTDUPLICATE: - MessageBox(MainWindow, "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CANTLOCKSURFACE: - MessageBox(MainWindow, "Unable to lock surface because no driver exists which can supply a pointer to the surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CLIPPERISUSINGHWND: - MessageBox(MainWindow, "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_COLORKEYNOTSET: - MessageBox(MainWindow, "No src color key specified for this operation.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_CURRENTLYNOTAVAIL: - MessageBox(MainWindow, "Support is currently not available. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_DIRECTDRAWALREADYCREATED: - MessageBox(MainWindow, "A DirectDraw object representing this driver has already been created for this process. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_EXCEPTION: - MessageBox(MainWindow, "An exception was encountered while performing the requested operation. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_EXCLUSIVEMODEALREADYSET: - MessageBox(MainWindow, "An attempt was made to set the cooperative level when it was already set to exclusive.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_GENERIC: - MessageBox(MainWindow, "Generic failure.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_HEIGHTALIGN: - MessageBox(MainWindow, "Height of rectangle provided is not a multiple of reqd alignment.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_HWNDALREADYSET: - MessageBox(MainWindow, "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_HWNDSUBCLASSED: - MessageBox(MainWindow, "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_IMPLICITLYCREATED: - MessageBox(MainWindow, "This surface can not be restored because it is an implicitly created surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INCOMPATIBLEPRIMARY: - MessageBox(MainWindow, "Unable to match primary surface creation request with existing primary surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDCAPS: - MessageBox(MainWindow, "One or more of the caps bits passed to the callback are incorrect.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDCLIPLIST: - MessageBox(MainWindow, "DirectDraw does not support the provided cliplist.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDDIRECTDRAWGUID: - MessageBox(MainWindow, "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDMODE: - MessageBox(MainWindow, "DirectDraw does not support the requested mode.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDOBJECT: - MessageBox(MainWindow, "DirectDraw received a pointer that was an invalid DIRECTDRAW object.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDPARAMS: - MessageBox(MainWindow, "One or more of the parameters passed to the function are incorrect.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDPIXELFORMAT: - MessageBox(MainWindow, "The pixel format was invalid as specified.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDPOSITION: - MessageBox(MainWindow, "Returned when the position of the overlay on the destination is no longer legal for that destination.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_INVALIDRECT: - MessageBox(MainWindow, "Rectangle provided was invalid.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - - case DDERR_INVALIDSURFACETYPE: - MessageBox(MainWindow, "The requested action could not be performed because the surface was of the wrong type.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_LOCKEDSURFACES: - MessageBox(MainWindow, "Operation could not be carried out because one or more surfaces are locked.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NO3D: - MessageBox(MainWindow, "There is no 3D present.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOALPHAHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no alpha accleration hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; -#if(0) - case DDERR_NOANTITEARHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware support for synchronizing blts to avoid tearing. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; -#endif - case DDERR_NOBLTHW: - MessageBox(MainWindow, "No blter hardware present.","Note", MB_ICONEXCLAMATION|MB_OK); - break; -#if(0) - case DDERR_NOBLTQUEUEHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware support for asynchronous blting. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; -#endif - case DDERR_NOCLIPLIST: - MessageBox(MainWindow, "No cliplist available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOCLIPPERATTACHED: - MessageBox(MainWindow, "No clipper object attached to surface object.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOCOLORCONVHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no color conversion hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOCOLORKEY: - MessageBox(MainWindow, "Surface doesn't currently have a color key","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOCOLORKEYHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware support of the destination color key.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOCOOPERATIVELEVELSET: - MessageBox(MainWindow, "Create function called without DirectDraw object method SetCooperativeLevel being called.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NODC: - MessageBox(MainWindow, "No DC was ever created for this surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NODDROPSHW: - MessageBox(MainWindow, "No DirectDraw ROP hardware.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NODIRECTDRAWHW: - MessageBox(MainWindow, "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NODIRECTDRAWSUPPORT: - MessageBox(MainWindow, "No DirectDraw support possible with current display driver.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOEMULATION: - MessageBox(MainWindow, "Software emulation not available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOEXCLUSIVEMODE: - MessageBox(MainWindow, "Operation requires the application to have exclusive mode but the application does not have exclusive mode.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOFLIPHW: - MessageBox(MainWindow, "Flipping visible surfaces is not supported.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOGDI: - MessageBox(MainWindow, "There is no GDI present.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOHWND: - MessageBox(MainWindow, "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOMIRRORHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOOVERLAYDEST: - MessageBox(MainWindow, "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOOVERLAYHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no overlay hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOPALETTEATTACHED: - MessageBox(MainWindow, "No palette object attached to this surface. ","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOPALETTEHW: - MessageBox(MainWindow, "No hardware support for 16 or 256 color palettes.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NORASTEROPHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no appropriate raster op hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOROTATIONHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no rotation hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOSTRETCHHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware support for stretching.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOT4BITCOLOR: - MessageBox(MainWindow, "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOT4BITCOLORINDEX: - MessageBox(MainWindow, "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOT8BITCOLOR: - MessageBox(MainWindow, "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOTAOVERLAYSURFACE: - MessageBox(MainWindow, "Returned when an overlay member is called for a non-overlay surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOTEXTUREHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no texture mapping hardware present or available.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOTFLIPPABLE: - MessageBox(MainWindow, "An attempt has been made to flip a surface that is not flippable.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOTFOUND: - MessageBox(MainWindow, "Requested item was not found.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOTLOCKED: - MessageBox(MainWindow, "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this process, has been attempted.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOTPALETTIZED: - MessageBox(MainWindow, "The surface being used is not a palette-based surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOVSYNCHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOZBUFFERHW: - MessageBox(MainWindow, "Operation could not be carried out because there is no hardware support for zbuffer blting.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_NOZOVERLAYHW: - MessageBox(MainWindow, "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_OUTOFCAPS: - MessageBox(MainWindow, "The hardware needed for the requested operation has already been allocated.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_OUTOFMEMORY: - MessageBox(MainWindow, "DirectDraw does not have enough memory to perform the operation.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_OUTOFVIDEOMEMORY: - MessageBox(MainWindow, "DirectDraw does not have enough memory to perform the operation.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_OVERLAYCANTCLIP: - MessageBox(MainWindow, "The hardware does not support clipped overlays.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: - MessageBox(MainWindow, "Can only have ony color key active at one time for overlays.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_OVERLAYNOTVISIBLE: - MessageBox(MainWindow, "Returned when GetOverlayPosition is called on a hidden overlay.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_PALETTEBUSY: - MessageBox(MainWindow, "Access to this palette is being refused because the palette is already locked by another thread.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_PRIMARYSURFACEALREADYEXISTS: - MessageBox(MainWindow, "This process already has created a primary surface.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_REGIONTOOSMALL: - MessageBox(MainWindow, "Region passed to Clipper::GetClipList is too small.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_SURFACEALREADYATTACHED: - MessageBox(MainWindow, "This surface is already attached to the surface it is being attached to.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_SURFACEALREADYDEPENDENT: - MessageBox(MainWindow, "This surface is already a dependency of the surface it is being made a dependency of.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_SURFACEBUSY: - MessageBox(MainWindow, "Access to this surface is being refused because the surface is already locked by another thread.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_SURFACEISOBSCURED: - MessageBox(MainWindow, "Access to surface refused because the surface is obscured.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_SURFACELOST: - MessageBox(MainWindow, "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_SURFACENOTATTACHED: - MessageBox(MainWindow, "The requested surface is not attached.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_TOOBIGHEIGHT: - MessageBox(MainWindow, "Height requested by DirectDraw is too large.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_TOOBIGSIZE: - MessageBox(MainWindow, "Size requested by DirectDraw is too large -- the individual height and width are OK.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_TOOBIGWIDTH: - MessageBox(MainWindow, "Width requested by DirectDraw is too large.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_UNSUPPORTED: - MessageBox(MainWindow, "Action not supported.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_UNSUPPORTEDFORMAT: - MessageBox(MainWindow, "FOURCC format requested is unsupported by DirectDraw.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_UNSUPPORTEDMASK: - MessageBox(MainWindow, "Bitmask in the pixel format requested is unsupported by DirectDraw.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_VERTICALBLANKINPROGRESS: - MessageBox(MainWindow, "Vertical blank is in progress.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_WASSTILLDRAWING: - MessageBox(MainWindow, "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_WRONGMODE: - MessageBox(MainWindow, "This surface can not be restored because it was created in a different mode.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - case DDERR_XALIGN: - MessageBox(MainWindow, "Rectangle provided was not horizontally aligned on required boundary.","Note", MB_ICONEXCLAMATION|MB_OK); - break; - default: - char string[256]; - sprintf (string, "Unrecognised Direct Draw result code: %d", result & 0xffff); - MessageBox(MainWindow, string,"Note", MB_ICONEXCLAMATION|MB_OK); - break; - } -} - - - -/*********************************************************************************************** - * Check_Overlapped_Blit_Capability -- See if video driver supports blitting overlapped regions* - * * - * We will check for this by drawing something to a video page and blitting it over itself. * - * If we end up with the top line repeating then overlapped region blits dont work. * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/7/96 5:06PM ST : Created * - *=============================================================================================*/ -void Check_Overlapped_Blit_Capability(void) -{ - - /* - ** Assume we can until we find out otherwise - */ - OverlappedVideoBlits = TRUE; - - GraphicBufferClass test_buffer; - - test_buffer.Init (64, 64, NULL, 0, (GBC_Enum)GBC_VIDEOMEM); - - test_buffer.Clear(); - - /* - ** Plot a pixel in the top left corner of the buffer. - */ - test_buffer.Put_Pixel(0, 0, 255); - - /* - ** Blit the buffer down by one line. If we end up with a vertical strip of pixel 255's then - ** overlapped blits dont work - */ - - test_buffer.Blit(test_buffer, 0, 0, 0, 1, test_buffer.Get_Width(), test_buffer.Get_Height()-1); - - if (test_buffer.Get_Pixel (0 ,5) == 255) OverlappedVideoBlits = FALSE; -} - - - -/*********************************************************************************************** - * Set_Video_Mode -- Initializes Direct Draw and sets the required Video Mode * - * * - * INPUT: int width - the width of the video mode in pixels * - * int height - the height of the video mode in pixels * - * int bits_per_pixel - the number of bits per pixel the video mode supports * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 09/26/1995 PWG : Created. * - *=============================================================================================*/ -BOOL Set_Video_Mode(HWND hwnd, int w, int h, int bits_per_pixel) -{ -// ST - 1/3/2019 10:41AM - return TRUE; -#if (0) - HRESULT result; - // - // If there is not currently a direct draw object then we need to define one. - // - if ( DirectDrawObject == NULL ){ - //MessageBox(MainWindow, "In Set_Video_Mode. About to call DirectDrawCreate.","Note", MB_ICONEXCLAMATION|MB_OK); - result = DirectDrawCreate(NULL, &DirectDrawObject, NULL); - Process_DD_Result(result, FALSE); - if (result == DD_OK){ - if (w==320){ - result = DirectDrawObject->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX); - } else { - //MessageBox(MainWindow, "In Set_Video_Mode. About to call SetCooperativeLevel.","Note", MB_ICONEXCLAMATION|MB_OK); - result = DirectDrawObject->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); - } - Process_DD_Result(result, FALSE); - }else{ - return (FALSE); - } - } - - // - // Set the required display mode with 8 bits per pixel - // - //MessageBox(MainWindow, "In Set_Video_Mode. About to call call SetDisplayMode.","Note", MB_ICONEXCLAMATION|MB_OK); - result = DirectDrawObject->SetDisplayMode ( w , h , bits_per_pixel ); - if (result != DD_OK){ -// Process_DD_Result(result, FALSE); - DirectDrawObject->Release(); - DirectDrawObject = NULL; - return(FALSE); - } - - // - // Create a direct draw palette object - // - //MessageBox(MainWindow, "In Set_Video_Mode. About to call CreatePalette.","Note", MB_ICONEXCLAMATION|MB_OK); - result = DirectDrawObject->CreatePalette( DDPCAPS_8BIT | DDPCAPS_ALLOW256, &PaletteEntries[0] , &PalettePtr ,NULL); - Process_DD_Result(result, FALSE); - if (result != DD_OK){ - return (FALSE); - } - - Check_Overlapped_Blit_Capability(); - - //MessageBox(MainWindow, "In Set_Video_Mode. About to return success.","Note", MB_ICONEXCLAMATION|MB_OK); -#if (0) - /* - ** Find out if DirectX 2 extensions are available - */ - result = DirectDrawObject->QueryInterface (IID_IDirectDraw2, (LPVOID*)&DirectDraw2Interface); - SystemToVideoBlits = FALSE; - VideoToSystemBlits = FALSE; - SystemToSystemBlits= FALSE; - if (result != DD_OK){ - DirectDraw2Interface = NULL; - }else{ - DDCAPS capabilities; - DDCAPS emulated_capabilities; - - memset ((char*)&capabilities, 0, sizeof(capabilities)); - memset ((char*)&emulated_capabilities, 0, sizeof(emulated_capabilities)); - capabilities.dwSize = sizeof (capabilities); - emulated_capabilities.dwSize = sizeof (emulated_capabilities); - - DirectDrawObject->GetCaps (&capabilities, &emulated_capabilities); - - if (capabilities.dwCaps & DDCAPS_CANBLTSYSMEM){ - SystemToVideoBlits = (capabilities.dwSVBCaps & DDCAPS_BLT) ? TRUE : FALSE; - VideoToSystemBlits = (capabilities.dwVSBCaps & DDCAPS_BLT) ? TRUE : FALSE; - SystemToSystemBlits = (capabilities.dwSSBCaps & DDCAPS_BLT) ? TRUE : FALSE; - } - } -#endif //(0) - - //MessageBox(MainWindow, "In Set_Video_Mode. About to return success.","Note", MB_ICONEXCLAMATION|MB_OK); - - return (TRUE); -#endif -} - -/*********************************************************************************************** - * Reset_Video_Mode -- Resets video mode and deletes Direct Draw Object * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 09/26/1995 PWG : Created. * - *=============================================================================================*/ -void Reset_Video_Mode(void) -{ - HRESULT result; - - // - // If a direct draw object has been declared and a video mode has been set - // then reset the video mode and release the direct draw object. - // - if ( DirectDrawObject ) { - result = DirectDrawObject->RestoreDisplayMode(); - Process_DD_Result(result, FALSE); - result = DirectDrawObject->Release(); - Process_DD_Result(result, FALSE); - - DirectDrawObject = NULL; - } -} - - - - -/*********************************************************************************************** - * Get_Free_Video_Memory -- returns amount of free video memory * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: bytes of available video RAM * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/29/95 12:52PM ST : Created * - *=============================================================================================*/ -unsigned int Get_Free_Video_Memory(void) -{ - - DDCAPS video_capabilities; - - if (DirectDrawObject){ - - video_capabilities.dwSize = sizeof (video_capabilities); - - //MessageBox(MainWindow, "In Get_Free_Video_Memory. About to call GetCaps","Note", MB_ICONEXCLAMATION|MB_OK); - if (DD_OK == DirectDrawObject->GetCaps (&video_capabilities , NULL)){ - char string [256]; - sprintf (string, "In Get_Free_Video_Memory. About to return %d bytes",video_capabilities.dwVidMemFree); - //MessageBox(MainWindow, string,"Note", MB_ICONEXCLAMATION|MB_OK); - return (video_capabilities.dwVidMemFree); - } - } - - //MessageBox(MainWindow, "In Get_Free_Video_Memory. About to return failure","Note", MB_ICONEXCLAMATION|MB_OK); - return (0); -} - - - - -/*********************************************************************************************** - * Get_Video_Hardware_Caps -- returns bitmask of direct draw video hardware support * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: hardware flags * - * * - * WARNINGS: Must call Set_Video_Mode 1st to create the direct draw object * - * * - * HISTORY: * - * 1/12/96 9:14AM ST : Created * - *=============================================================================================*/ -unsigned Get_Video_Hardware_Capabilities(void) -{ - DDCAPS video_capabilities; - unsigned video; - - /* - ** Fail if the direct draw object has not been initialised - */ - if (!DirectDrawObject) return (0); - - /* - ** Get the capabilities of the direct draw object - */ - video_capabilities.dwSize = sizeof(video_capabilities); - //MessageBox(MainWindow, "In Get_Video_Hardware_Capabilities. About to call GetCaps","Note", MB_ICONEXCLAMATION|MB_OK); - HRESULT result = DirectDrawObject->GetCaps (&video_capabilities, NULL); - if (result != DD_OK){ - Process_DD_Result(result, FALSE); - return (0); - } - - /* - ** Set flags to indicate the presence of the features we are interested in - */ - video = 0; - - /* Hardware blits supported? */ - if (video_capabilities.dwCaps & DDCAPS_BLT) video |= VIDEO_BLITTER; - - /* Hardware blits asyncronous? */ - if (video_capabilities.dwCaps & DDCAPS_BLTQUEUE) video |= VIDEO_BLITTER_ASYNC; - - /* Can palette changes be synced to vertical refresh? */ - if (video_capabilities.dwCaps & DDCAPS_PALETTEVSYNC) video |= VIDEO_SYNC_PALETTE; - - /* Is the video cards memory bank switched? */ - if (video_capabilities.dwCaps & DDCAPS_BANKSWITCHED) video |= VIDEO_BANK_SWITCHED; - - /* Can the blitter do filled rectangles? */ - if (video_capabilities.dwCaps & DDCAPS_BLTCOLORFILL) video |= VIDEO_COLOR_FILL; - - /* Is there no hardware assistance avaailable at all? */ - if (video_capabilities.dwCaps & DDCAPS_NOHARDWARE) video |= VIDEO_NO_HARDWARE_ASSIST; - - //MessageBox(MainWindow, "In Get_Video_Hardware_Capabilities. About to return success.","Note", MB_ICONEXCLAMATION|MB_OK); - return (video); -} - - - - -/*********************************************************************************************** - * Wait_Vert_Blank -- Waits for the start (leading edge) of a vertical blank * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - *=============================================================================================*/ -extern int ScreenWidth; -void Wait_Vert_Blank(void) -{ - if (DirectDrawObject == NULL) { - return; - } - if( ScreenWidth!=320 && CanVblankSync){ - HRESULT result = DirectDrawObject->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); - if (result == E_NOTIMPL){ - CanVblankSync = FALSE; - return; - } - Process_DD_Result(result, FALSE); - } -} - - - - - -/*********************************************************************************************** - * Set_Palette -- set a direct draw palette * - * * - * * - * * - * INPUT: ptr to 768 rgb palette bytes * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/11/95 3:33PM ST : Created * - *=============================================================================================*/ -void Set_DD_Palette ( void *palette ) -{ - - /* - ** Trap null ptr - */ - if (!palette) return; - - int j; - int k; - char *palette_get; - - if ( DirectDrawObject && PaletteSurface ){ - - k=0; - - palette_get = (char*)palette; - - for( j=0 ; j<768 ; j+=3 ) - { - PaletteEntries[k].peRed = (unsigned char)((*palette_get++)<<2); - PaletteEntries[k].peGreen = (unsigned char)((*palette_get++)<<2); - PaletteEntries[k].peBlue = (unsigned char)((*palette_get++)<<2); - k++; - } - - if ( !FirstPaletteSet ){ - //MessageBox(MainWindow, "In Set_DD_Palette. About to call SetPalette","Note", MB_ICONEXCLAMATION|MB_OK); - PaletteSurface->SetPalette( PalettePtr ); - FirstPaletteSet=TRUE; - } - - //MessageBox(MainWindow, "In Set_DD_Palette. About to call SetEntries","Note", MB_ICONEXCLAMATION|MB_OK); - PalettePtr->SetEntries( 0 , 0 , 256 , &PaletteEntries[0] ); - } - //MessageBox(MainWindow, "Leaving Set_DD_Palette","Note", MB_ICONEXCLAMATION|MB_OK); - -} - - - - - -/*********************************************************************************************** - * Wait_Blit -- waits for the DirectDraw blitter to become idle * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 07-25-95 03:53pm ST : Created * - *=============================================================================================*/ - -void Wait_Blit (void) -{ - HRESULT return_code; - - do { - return_code=PaletteSurface->GetBltStatus (DDGBS_ISBLTDONE); - } while (return_code != DD_OK && return_code != DDERR_SURFACELOST); - -} - - - -/*********************************************************************************************** - * SMC::SurfaceMonitorClass -- constructor for surface monitor class * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/3/95 3:23PM ST : Created * - *=============================================================================================*/ - -SurfaceMonitorClass::SurfaceMonitorClass(void) -{ - for (int i=0 ; iRestore() != DD_OK){ - if (Misc_Focus_Loss_Function){ - Misc_Focus_Loss_Function(); - } - return; - } - } - } - - /* - ** PWG/ST: Now that we know all the surfaces are restored call - ** the function pointer to notify the program that it has - ** happened. This function pointer is used to clear the pages, - ** etc. - */ - if (Misc_Focus_Restore_Function){ - Misc_Focus_Restore_Function(); - } - - SurfacesRestored = TRUE; - - /* - ** Restore the palette - */ - Set_DD_Palette (CurrentPalette); - } -} - - -/*********************************************************************************************** - * SMC::Set_Surface_Focus -- set the InFocus flag to the given state * - * * - * The InFocus flag is used to keep track of whether our application is currently in focus. * - * We dont want to be restoring video surfaces when we are supposed to be running in the * - * background. * - * * - * INPUT: bool in focus * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/6/95 12:21PM ST : Created * - *=============================================================================================*/ - -void SurfaceMonitorClass::Set_Surface_Focus ( BOOL in_focus ) -{ - InFocus=in_focus; -} - - - - -/*********************************************************************************************** - * SMC::Release -- releases all direct draw surfaces * - * * - * Call this at the end of the game before called RestoreDisplayMode * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/6/96 12:23PM ST : Created * - *=============================================================================================*/ - -void SurfaceMonitorClass::Release(void) -{ - /* - ** Call release for each Direct Draw surface - */ - for (int i=0 ; iRelease(); - Surface[i] = 0; - } - } - -} diff --git a/code/TIBERIANDAWN/WIN32LIB/DDRAW.H b/code/TIBERIANDAWN/WIN32LIB/DDRAW.H deleted file mode 100644 index d1af82f..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DDRAW.H +++ /dev/null @@ -1,3117 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*==========================================================================; - * - * Copyright (C) 1994-1996 Microsoft Corporation. All Rights Reserved. - * - * File: ddraw.h - * Content: DirectDraw include file - * - ***************************************************************************/ - -#ifndef __DDRAW_INCLUDED__ -#define __DDRAW_INCLUDED__ -#if defined( _WIN32 ) && !defined( _NO_COM ) -#define COM_NO_WINDOWS_H -#include -#else -#define IUnknown void -#define CO_E_NOTINITIALIZED 0x800401F0L -#endif - -#define _FACDD 0x876 -#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * GUIDS used by DirectDraw objects - */ -#if defined( _WIN32 ) && !defined( _NO_COM ) -DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); -DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); -DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); -DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); - -DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); - -#endif - -/*============================================================================ - * - * DirectDraw Structures - * - * Various structures used to invoke DirectDraw. - * - *==========================================================================*/ - -struct IDirectDraw; -struct IDirectDrawSurface; -struct IDirectDrawPalette; -struct IDirectDrawClipper; - -typedef struct IDirectDraw FAR *LPDIRECTDRAW; -typedef struct IDirectDraw2 FAR *LPDIRECTDRAW2; -typedef struct IDirectDrawSurface FAR *LPDIRECTDRAWSURFACE; -typedef struct IDirectDrawSurface2 FAR *LPDIRECTDRAWSURFACE2; - -typedef struct IDirectDrawPalette FAR *LPDIRECTDRAWPALETTE; -typedef struct IDirectDrawClipper FAR *LPDIRECTDRAWCLIPPER; - -typedef struct _DDFXROP FAR *LPDDFXROP; -typedef struct _DDSURFACEDESC FAR *LPDDSURFACEDESC; - -/* - * API's - */ -#if (defined (WIN32) || defined( _WIN32 ) ) && !defined( _NO_COM ) -//#if defined( _WIN32 ) && !defined( _NO_ENUM ) - typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKA)(GUID FAR *, LPSTR, LPSTR, LPVOID); - typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKW)(GUID FAR *, LPWSTR, LPWSTR, LPVOID); - extern HRESULT WINAPI DirectDrawEnumerateW( LPDDENUMCALLBACKW lpCallback, LPVOID lpContext ); - extern HRESULT WINAPI DirectDrawEnumerateA( LPDDENUMCALLBACKA lpCallback, LPVOID lpContext ); - #ifdef UNICODE - typedef LPDDENUMCALLBACKW LPDDENUMCALLBACK; - #define DirectDrawEnumerate DirectDrawEnumerateW - #else - typedef LPDDENUMCALLBACKA LPDDENUMCALLBACK; - #define DirectDrawEnumerate DirectDrawEnumerateA - #endif - extern HRESULT WINAPI DirectDrawCreate( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter ); - extern HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter ); - #ifdef WINNT - //This is the user-mode entry stub to the kernel mode procedure. - extern HRESULT NtDirectDrawCreate( GUID FAR *lpGUID, HANDLE *lplpDD, IUnknown FAR *pUnkOuter ); - #endif -#endif - -#define REGSTR_KEY_DDHW_DESCRIPTION "Description" -#define REGSTR_KEY_DDHW_DRIVERNAME "DriverName" -#define REGSTR_PATH_DDHW "Hardware\\DirectDrawDrivers" - -#define DDCREATE_HARDWAREONLY 0x00000001l -#define DDCREATE_EMULATIONONLY 0x00000002l - -#ifdef WINNT -typedef long HRESULT; -#endif - -//#ifndef WINNT -typedef HRESULT (FAR PASCAL * LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); -typedef HRESULT (FAR PASCAL * LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); -//#endif -/* - * DDCOLORKEY - */ -typedef struct _DDCOLORKEY -{ - DWORD dwColorSpaceLowValue; // low boundary of color space that is to - // be treated as Color Key, inclusive - DWORD dwColorSpaceHighValue; // high boundary of color space that is - // to be treated as Color Key, inclusive -} DDCOLORKEY; - -typedef DDCOLORKEY FAR* LPDDCOLORKEY; - -/* - * DDBLTFX - * Used to pass override information to the DIRECTDRAWSURFACE callback Blt. - */ -typedef struct _DDBLTFX -{ - DWORD dwSize; // size of structure - DWORD dwDDFX; // FX operations - DWORD dwROP; // Win32 raster operations - DWORD dwDDROP; // Raster operations new for DirectDraw - DWORD dwRotationAngle; // Rotation angle for blt - DWORD dwZBufferOpCode; // ZBuffer compares - DWORD dwZBufferLow; // Low limit of Z buffer - DWORD dwZBufferHigh; // High limit of Z buffer - DWORD dwZBufferBaseDest; // Destination base value - DWORD dwZDestConstBitDepth; // Bit depth used to specify Z constant for destination - union - { - DWORD dwZDestConst; // Constant to use as Z buffer for dest - LPDIRECTDRAWSURFACE lpDDSZBufferDest; // Surface to use as Z buffer for dest - }; - DWORD dwZSrcConstBitDepth; // Bit depth used to specify Z constant for source - union - { - DWORD dwZSrcConst; // Constant to use as Z buffer for src - LPDIRECTDRAWSURFACE lpDDSZBufferSrc; // Surface to use as Z buffer for src - }; - DWORD dwAlphaEdgeBlendBitDepth; // Bit depth used to specify constant for alpha edge blend - DWORD dwAlphaEdgeBlend; // Alpha for edge blending - DWORD dwReserved; - DWORD dwAlphaDestConstBitDepth; // Bit depth used to specify alpha constant for destination - union - { - DWORD dwAlphaDestConst; // Constant to use as Alpha Channel - LPDIRECTDRAWSURFACE lpDDSAlphaDest; // Surface to use as Alpha Channel - }; - DWORD dwAlphaSrcConstBitDepth; // Bit depth used to specify alpha constant for source - union - { - DWORD dwAlphaSrcConst; // Constant to use as Alpha Channel - LPDIRECTDRAWSURFACE lpDDSAlphaSrc; // Surface to use as Alpha Channel - }; - union - { - DWORD dwFillColor; // color in RGB or Palettized - DWORD dwFillDepth; // depth value for z-buffer - LPDIRECTDRAWSURFACE lpDDSPattern; // Surface to use as pattern - }; - DDCOLORKEY ddckDestColorkey; // DestColorkey override - DDCOLORKEY ddckSrcColorkey; // SrcColorkey override -} DDBLTFX; - -typedef DDBLTFX FAR* LPDDBLTFX; - - -/* - * DDSCAPS - */ -typedef struct _DDSCAPS -{ - DWORD dwCaps; // capabilities of surface wanted -} DDSCAPS; - -typedef DDSCAPS FAR* LPDDSCAPS; - -/* - * DDCAPS - */ -#define DD_ROP_SPACE (256/32) // space required to store ROP array - -typedef struct _DDCAPS -{ - DWORD dwSize; // size of the DDDRIVERCAPS structure - DWORD dwCaps; // driver specific capabilities - DWORD dwCaps2; // more driver specific capabilites - DWORD dwCKeyCaps; // color key capabilities of the surface - DWORD dwFXCaps; // driver specific stretching and effects capabilites - DWORD dwFXAlphaCaps; // alpha driver specific capabilities - DWORD dwPalCaps; // palette capabilities - DWORD dwSVCaps; // stereo vision capabilities - DWORD dwAlphaBltConstBitDepths; // DDBD_2,4,8 - DWORD dwAlphaBltPixelBitDepths; // DDBD_1,2,4,8 - DWORD dwAlphaBltSurfaceBitDepths; // DDBD_1,2,4,8 - DWORD dwAlphaOverlayConstBitDepths; // DDBD_2,4,8 - DWORD dwAlphaOverlayPixelBitDepths; // DDBD_1,2,4,8 - DWORD dwAlphaOverlaySurfaceBitDepths; // DDBD_1,2,4,8 - DWORD dwZBufferBitDepths; // DDBD_8,16,24,32 - DWORD dwVidMemTotal; // total amount of video memory - DWORD dwVidMemFree; // amount of free video memory - DWORD dwMaxVisibleOverlays; // maximum number of visible overlays - DWORD dwCurrVisibleOverlays; // current number of visible overlays - DWORD dwNumFourCCCodes; // number of four cc codes - DWORD dwAlignBoundarySrc; // source rectangle alignment - DWORD dwAlignSizeSrc; // source rectangle byte size - DWORD dwAlignBoundaryDest; // dest rectangle alignment - DWORD dwAlignSizeDest; // dest rectangle byte size - DWORD dwAlignStrideAlign; // stride alignment - DWORD dwRops[DD_ROP_SPACE]; // ROPS supported - DDSCAPS ddsCaps; // DDSCAPS structure has all the general capabilities - DWORD dwMinOverlayStretch; // minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 - DWORD dwMaxOverlayStretch; // maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 - DWORD dwMinLiveVideoStretch; // minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 - DWORD dwMaxLiveVideoStretch; // maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 - DWORD dwMinHwCodecStretch; // minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 - DWORD dwMaxHwCodecStretch; // maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 - DWORD dwReserved1; // reserved - DWORD dwReserved2; // reserved - DWORD dwReserved3; // reserved - DWORD dwSVBCaps; // driver specific capabilities for System->Vmem blts - DWORD dwSVBCKeyCaps; // driver color key capabilities for System->Vmem blts - DWORD dwSVBFXCaps; // driver FX capabilities for System->Vmem blts - DWORD dwSVBRops[DD_ROP_SPACE];// ROPS supported for System->Vmem blts - DWORD dwVSBCaps; // driver specific capabilities for Vmem->System blts - DWORD dwVSBCKeyCaps; // driver color key capabilities for Vmem->System blts - DWORD dwVSBFXCaps; // driver FX capabilities for Vmem->System blts - DWORD dwVSBRops[DD_ROP_SPACE];// ROPS supported for Vmem->System blts - DWORD dwSSBCaps; // driver specific capabilities for System->System blts - DWORD dwSSBCKeyCaps; // driver color key capabilities for System->System blts - DWORD dwSSBFXCaps; // driver FX capabilities for System->System blts - DWORD dwSSBRops[DD_ROP_SPACE];// ROPS supported for System->System blts - DWORD dwReserved4; // reserved - DWORD dwReserved5; // reserved - DWORD dwReserved6; // reserved -} DDCAPS; - -typedef DDCAPS FAR* LPDDCAPS; - - - -/* - * DDPIXELFORMAT - */ -typedef struct _DDPIXELFORMAT -{ - DWORD dwSize; // size of structure - DWORD dwFlags; // pixel format flags - DWORD dwFourCC; // (FOURCC code) - union - { - DWORD dwRGBBitCount; // how many bits per pixel (BD_4,8,16,24,32) - DWORD dwYUVBitCount; // how many bits per pixel (BD_4,8,16,24,32) - DWORD dwZBufferBitDepth; // how many bits for z buffers (BD_8,16,24,32) - DWORD dwAlphaBitDepth; // how many bits for alpha channels (BD_1,2,4,8) - }; - union - { - DWORD dwRBitMask; // mask for red bit - DWORD dwYBitMask; // mask for Y bits - }; - union - { - DWORD dwGBitMask; // mask for green bits - DWORD dwUBitMask; // mask for U bits - }; - union - { - DWORD dwBBitMask; // mask for blue bits - DWORD dwVBitMask; // mask for V bits - }; - union - { - DWORD dwRGBAlphaBitMask; // mask for alpha channel - DWORD dwYUVAlphaBitMask; // mask for alpha channel - }; -} DDPIXELFORMAT; - -typedef DDPIXELFORMAT FAR* LPDDPIXELFORMAT; - -/* - * DDOVERLAYFX - */ -typedef struct _DDOVERLAYFX -{ - DWORD dwSize; // size of structure - DWORD dwAlphaEdgeBlendBitDepth; // Bit depth used to specify constant for alpha edge blend - DWORD dwAlphaEdgeBlend; // Constant to use as alpha for edge blend - DWORD dwReserved; - DWORD dwAlphaDestConstBitDepth; // Bit depth used to specify alpha constant for destination - union - { - DWORD dwAlphaDestConst; // Constant to use as alpha channel for dest - LPDIRECTDRAWSURFACE lpDDSAlphaDest; // Surface to use as alpha channel for dest - }; - DWORD dwAlphaSrcConstBitDepth; // Bit depth used to specify alpha constant for source - union - { - DWORD dwAlphaSrcConst; // Constant to use as alpha channel for src - LPDIRECTDRAWSURFACE lpDDSAlphaSrc; // Surface to use as alpha channel for src - }; - DDCOLORKEY dckDestColorkey; // DestColorkey override - DDCOLORKEY dckSrcColorkey; // DestColorkey override - DWORD dwDDFX; // Overlay FX - DWORD dwFlags; // flags -} DDOVERLAYFX; - -typedef DDOVERLAYFX FAR *LPDDOVERLAYFX; - -/* - * DDBLTBATCH: BltBatch entry structure - */ -typedef struct _DDBLTBATCH -{ - LPRECT lprDest; - LPDIRECTDRAWSURFACE lpDDSSrc; - LPRECT lprSrc; - DWORD dwFlags; - LPDDBLTFX lpDDBltFx; -} DDBLTBATCH; - -typedef DDBLTBATCH FAR * LPDDBLTBATCH; - -/* - * callbacks - */ -typedef DWORD (FAR PASCAL *LPCLIPPERCALLBACK)(LPDIRECTDRAWCLIPPER lpDDClipper, HWND hWnd, DWORD code, LPVOID lpContext ); -#ifdef STREAMING -typedef DWORD (FAR PASCAL *LPSURFACESTREAMINGCALLBACK)(DWORD); -#endif - - -/* - * INTERACES FOLLOW: - * IDirectDraw - * IDirectDrawClipper - * IDirectDrawPalette - * IDirectDrawSurface - */ - -/* - * IDirectDraw - */ -#if defined( _WIN32 ) && !defined( _NO_COM ) -#undef INTERFACE -#define INTERFACE IDirectDraw -DECLARE_INTERFACE_( IDirectDraw, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectDraw methods ***/ - STDMETHOD(Compact)(THIS) PURE; - STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; - STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; - STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE; - STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE; - STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; - STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; - STDMETHOD(FlipToGDISurface)(THIS) PURE; - STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; - STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; - STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; - STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; - STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; - STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; - STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; - STDMETHOD(RestoreDisplayMode)(THIS) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; - STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD) PURE; - STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectDraw_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) -#define IDirectDraw_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectDraw_Release(p) (p)->lpVtbl->Release(p) -#define IDirectDraw_Compact(p) (p)->lpVtbl->Compact(p) -#define IDirectDraw_CreateClipper(p, a, b, c) (p)->lpVtbl->CreateClipper(p, a, b, c) -#define IDirectDraw_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) -#define IDirectDraw_CreateSurface(p, a, b, c) (p)->lpVtbl->CreateSurface(p, a, b, c) -#define IDirectDraw_DuplicateSurface(p, a, b) (p)->lpVtbl->DuplicateSurface(p, a, b) -#define IDirectDraw_EnumDisplayModes(p, a, b, c, d) (p)->lpVtbl->EnumDisplayModes(p, a, b, c, d) -#define IDirectDraw_EnumSurfaces(p, a, b, c, d) (p)->lpVtbl->EnumSurfaces(p, a, b, c, d) -#define IDirectDraw_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p) -#define IDirectDraw_GetCaps(p, a, b) (p)->lpVtbl->GetCaps(p, a, b) -#define IDirectDraw_GetDisplayMode(p, a) (p)->lpVtbl->GetDisplayMode(p, a) -#define IDirectDraw_GetFourCCCodes(p, a, b) (p)->lpVtbl->GetFourCCCodes(p, a, b) -#define IDirectDraw_GetGDISurface(p, a) (p)->lpVtbl->GetGDISurface(p, a) -#define IDirectDraw_GetMonitorFrequency(p, a) (p)->lpVtbl->GetMonitorFrequency(p, a) -#define IDirectDraw_GetScanLine(p, a) (p)->lpVtbl->GetScanLine(p, a) -#define IDirectDraw_GetVerticalBlankStatus(p, a) (p)->lpVtbl->GetVerticalBlankStatus(p, a) -#define IDirectDraw_Initialize(p, a) (p)->lpVtbl->Initialize(p, a) -#define IDirectDraw_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p) -#define IDirectDraw_SetCooperativeLevel(p, a, b) (p)->lpVtbl->SetCooperativeLevel(p, a, b) -#define IDirectDraw_SetDisplayMode(p, a, b, c) (p)->lpVtbl->SetDisplayMode(p, a, b, c) -#define IDirectDraw_WaitForVerticalBlank(p, a, b) (p)->lpVtbl->WaitForVerticalBlank(p, a, b) -#endif - -#endif - -#if defined( _WIN32 ) && !defined( _NO_COM ) -#undef INTERFACE -#define INTERFACE IDirectDraw2 -DECLARE_INTERFACE_( IDirectDraw2, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectDraw methods ***/ - STDMETHOD(Compact)(THIS) PURE; - STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; - STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; - STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE; - STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE; - STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; - STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; - STDMETHOD(FlipToGDISurface)(THIS) PURE; - STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; - STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; - STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; - STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; - STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; - STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; - STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; - STDMETHOD(RestoreDisplayMode)(THIS) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; - STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; - STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; - /*** Added in the v2 interface ***/ - STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS, LPDWORD, LPDWORD) PURE; -}; -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectDraw2_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) -#define IDirectDraw2_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectDraw2_Release(p) (p)->lpVtbl->Release(p) -#define IDirectDraw2_Compact(p) (p)->lpVtbl->Compact(p) -#define IDirectDraw2_CreateClipper(p, a, b, c) (p)->lpVtbl->CreateClipper(p, a, b, c) -#define IDirectDraw2_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) -#define IDirectDraw2_CreateSurface(p, a, b, c) (p)->lpVtbl->CreateSurface(p, a, b, c) -#define IDirectDraw2_DuplicateSurface(p, a, b) (p)->lpVtbl->DuplicateSurface(p, a, b) -#define IDirectDraw2_EnumDisplayModes(p, a, b, c, d) (p)->lpVtbl->EnumDisplayModes(p, a, b, c, d) -#define IDirectDraw2_EnumSurfaces(p, a, b, c, d) (p)->lpVtbl->EnumSurfaces(p, a, b, c, d) -#define IDirectDraw2_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p) -#define IDirectDraw2_GetCaps(p, a, b) (p)->lpVtbl->GetCaps(p, a, b) -#define IDirectDraw2_GetDisplayMode(p, a) (p)->lpVtbl->GetDisplayMode(p, a) -#define IDirectDraw2_GetFourCCCodes(p, a, b) (p)->lpVtbl->GetFourCCCodes(p, a, b) -#define IDirectDraw2_GetGDISurface(p, a) (p)->lpVtbl->GetGDISurface(p, a) -#define IDirectDraw2_GetMonitorFrequency(p, a) (p)->lpVtbl->GetMonitorFrequency(p, a) -#define IDirectDraw2_GetScanLine(p, a) (p)->lpVtbl->GetScanLine(p, a) -#define IDirectDraw2_GetVerticalBlankStatus(p, a) (p)->lpVtbl->GetVerticalBlankStatus(p, a) -#define IDirectDraw2_Initialize(p, a) (p)->lpVtbl->Initialize(p, a) -#define IDirectDraw2_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p) -#define IDirectDraw2_SetCooperativeLevel(p, a, b) (p)->lpVtbl->SetCooperativeLevel(p, a, b) -#define IDirectDraw2_SetDisplayMode(p, a, b, c, d) (p)->lpVtbl->SetDisplayMode(p, a, b, c, d) -#define IDirectDraw2_WaitForVerticalBlank(p, a, b) (p)->lpVtbl->WaitForVerticalBlank(p, a, b) -#define IDirectDraw2_GetAvailableVidMem(p, a, b, c) (p)->lpVtbl->GetAvailableVidMem(p, a, b, c) -#endif - -#endif - -/* - * IDirectDrawPalette - */ -#if defined( _WIN32 ) && !defined( _NO_COM ) -#undef INTERFACE -#define INTERFACE IDirectDrawPalette -DECLARE_INTERFACE_( IDirectDrawPalette, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectDrawPalette methods ***/ - STDMETHOD(GetCaps)(THIS_ LPDWORD) PURE; - STDMETHOD(GetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE; - STDMETHOD(SetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectDrawPalette_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) -#define IDirectDrawPalette_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectDrawPalette_Release(p) (p)->lpVtbl->Release(p) -#define IDirectDrawPalette_GetCaps(p, a) (p)->lpVtbl->GetCaps(p, a) -#define IDirectDrawPalette_GetEntries(p, a, b, c, d) (p)->lpVtbl->GetEntries(p, a, b, c, d) -#define IDirectDrawPalette_Initialize(p, a, b, c) (p)->lpVtbl->Initialize(p, a, b, c) -#define IDirectDrawPalette_SetEntries(p, a, b, c, d) (p)->lpVtbl->SetEntries(p, a, b, c, d) -#endif - -#endif - -/* - * IDirectDrawClipper - */ -#if defined( _WIN32 ) && !defined( _NO_COM ) -#undef INTERFACE -#define INTERFACE IDirectDrawClipper -DECLARE_INTERFACE_( IDirectDrawClipper, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectDrawClipper methods ***/ - STDMETHOD(GetClipList)(THIS_ LPRECT, LPRGNDATA, LPDWORD) PURE; - STDMETHOD(GetHWnd)(THIS_ HWND FAR *) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD) PURE; - STDMETHOD(IsClipListChanged)(THIS_ BOOL FAR *) PURE; - STDMETHOD(SetClipList)(THIS_ LPRGNDATA,DWORD) PURE; - STDMETHOD(SetHWnd)(THIS_ DWORD, HWND ) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectDrawClipper_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) -#define IDirectDrawClipper_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectDrawClipper_Release(p) (p)->lpVtbl->Release(p) -#define IDirectDrawClipper_GetClipList(p, a, b, c) (p)->lpVtbl->GetClipList(p, a, b, c) -#define IDirectDrawClipper_GetHWnd(p, a) (p)->lpVtbl->GetHWnd(p, a) -#define IDirectDrawClipper_Initialize(p, a, b) (p)->lpVtbl->Initialize(p, a, b) -#define IDirectDrawClipper_IsClipListChanged(p, a) (p)->lpVtbl->IsClipListChanged(p, a) -#define IDirectDrawClipper_SetClipList(p, a, b) (p)->lpVtbl->SetClipList(p, a, b) -#define IDirectDrawClipper_SetHWnd(p, a, b) (p)->lpVtbl->SetHWnd(p, a, b) -#endif - -#endif - -/* - * IDirectDrawSurface and related interfaces - */ -#if defined( _WIN32 ) && !defined( _NO_COM ) -#undef INTERFACE -#define INTERFACE IDirectDrawSurface -DECLARE_INTERFACE_( IDirectDrawSurface, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectDrawSurface methods ***/ - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; - STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE, LPRECT,DWORD, LPDDBLTFX) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; - STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE, LPRECT,DWORD) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE FAR *) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; - STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; - STDMETHOD(Unlock)(THIS_ LPVOID) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE,LPRECT,DWORD, LPDDOVERLAYFX) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectDrawSurface_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectDrawSurface_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectDrawSurface_Release(p) (p)->lpVtbl->Release(p) -#define IDirectDrawSurface_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a) -#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a) -#define IDirectDrawSurface_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e) -#define IDirectDrawSurface_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c) -#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e) -#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b) -#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b) -#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c) -#define IDirectDrawSurface_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b) -#define IDirectDrawSurface_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b) -#define IDirectDrawSurface_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a) -#define IDirectDrawSurface_GetCaps(p,b) (p)->lpVtbl->GetCaps(p,b) -#define IDirectDrawSurface_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a) -#define IDirectDrawSurface_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b) -#define IDirectDrawSurface_GetDC(p,a) (p)->lpVtbl->GetDC(p,a) -#define IDirectDrawSurface_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a) -#define IDirectDrawSurface_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b) -#define IDirectDrawSurface_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a) -#define IDirectDrawSurface_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a) -#define IDirectDrawSurface_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a) -#define IDirectDrawSurface_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -#define IDirectDrawSurface_IsLost(p) (p)->lpVtbl->IsLost(p) -#define IDirectDrawSurface_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) -#define IDirectDrawSurface_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a) -#define IDirectDrawSurface_Restore(p) (p)->lpVtbl->Restore(p) -#define IDirectDrawSurface_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a) -#define IDirectDrawSurface_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b) -#define IDirectDrawSurface_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b) -#define IDirectDrawSurface_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a) -#define IDirectDrawSurface_Unlock(p,b) (p)->lpVtbl->Unlock(p,b) -#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e) -#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a) -#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b) -#endif - -/* - * IDirectDrawSurface2 and related interfaces - */ -#undef INTERFACE -#define INTERFACE IDirectDrawSurface2 -DECLARE_INTERFACE_( IDirectDrawSurface2, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectDrawSurface methods ***/ - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; - STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE2, LPRECT,DWORD, LPDDBLTFX) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; - STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE2, LPRECT,DWORD) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE2) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2, DWORD) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE2 FAR *) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; - STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; - STDMETHOD(Unlock)(THIS_ LPVOID) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE2) PURE; - /*** Added in the v2 interface ***/ - STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; - STDMETHOD(PageLock)(THIS_ DWORD) PURE; - STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectDrawSurface2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectDrawSurface2_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectDrawSurface2_Release(p) (p)->lpVtbl->Release(p) -#define IDirectDrawSurface2_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a) -#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a) -#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e) -#define IDirectDrawSurface2_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c) -#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e) -#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b) -#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b) -#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c) -#define IDirectDrawSurface2_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b) -#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b) -#define IDirectDrawSurface2_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a) -#define IDirectDrawSurface2_GetCaps(p,b) (p)->lpVtbl->GetCaps(p,b) -#define IDirectDrawSurface2_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a) -#define IDirectDrawSurface2_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b) -#define IDirectDrawSurface2_GetDC(p,a) (p)->lpVtbl->GetDC(p,a) -#define IDirectDrawSurface2_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a) -#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b) -#define IDirectDrawSurface2_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a) -#define IDirectDrawSurface2_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a) -#define IDirectDrawSurface2_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a) -#define IDirectDrawSurface2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -#define IDirectDrawSurface2_IsLost(p) (p)->lpVtbl->IsLost(p) -#define IDirectDrawSurface2_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) -#define IDirectDrawSurface2_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a) -#define IDirectDrawSurface2_Restore(p) (p)->lpVtbl->Restore(p) -#define IDirectDrawSurface2_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a) -#define IDirectDrawSurface2_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b) -#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b) -#define IDirectDrawSurface2_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a) -#define IDirectDrawSurface2_Unlock(p,b) (p)->lpVtbl->Unlock(p,b) -#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e) -#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a) -#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b) -#define IDirectDrawSurface2_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a) -#define IDirectDrawSurface2_PageLock(p,a) (p)->lpVtbl->PageLock(p,a) -#define IDirectDrawSurface2_PageUnlock(p,a) (p)->lpVtbl->PageUnlock(p,a) -#endif - - -#endif - - -/* - * DDSURFACEDESC - */ -typedef struct _DDSURFACEDESC -{ - DWORD dwSize; // size of the DDSURFACEDESC structure - DWORD dwFlags; // determines what fields are valid - DWORD dwHeight; // height of surface to be created - DWORD dwWidth; // width of input surface - LONG lPitch; // distance to start of next line (return value only) - DWORD dwBackBufferCount; // number of back buffers requested - union - { - DWORD dwMipMapCount; // number of mip-map levels requested - DWORD dwZBufferBitDepth; // depth of Z buffer requested - DWORD dwRefreshRate; // refresh rate (used when display mode is described) - }; - DWORD dwAlphaBitDepth; // depth of alpha buffer requested - DWORD dwReserved; // reserved - LPVOID lpSurface; // pointer to the associated surface memory - DDCOLORKEY ddckCKDestOverlay; // color key for destination overlay use - DDCOLORKEY ddckCKDestBlt; // color key for destination blt use - DDCOLORKEY ddckCKSrcOverlay; // color key for source overlay use - DDCOLORKEY ddckCKSrcBlt; // color key for source blt use - DDPIXELFORMAT ddpfPixelFormat; // pixel format description of the surface - DDSCAPS ddsCaps; // direct draw surface capabilities -} DDSURFACEDESC; - -/* - * ddsCaps field is valid. - */ -#define DDSD_CAPS 0x00000001l // default - -/* - * dwHeight field is valid. - */ -#define DDSD_HEIGHT 0x00000002l - -/* - * dwWidth field is valid. - */ -#define DDSD_WIDTH 0x00000004l - -/* - * lPitch is valid. - */ -#define DDSD_PITCH 0x00000008l - -/* - * dwBackBufferCount is valid. - */ -#define DDSD_BACKBUFFERCOUNT 0x00000020l - -/* - * dwZBufferBitDepth is valid. - */ -#define DDSD_ZBUFFERBITDEPTH 0x00000040l - -/* - * dwAlphaBitDepth is valid. - */ -#define DDSD_ALPHABITDEPTH 0x00000080l - - - -/* - * ddpfPixelFormat is valid. - */ -#define DDSD_PIXELFORMAT 0x00001000l - -/* - * ddckCKDestOverlay is valid. - */ -#define DDSD_CKDESTOVERLAY 0x00002000l - -/* - * ddckCKDestBlt is valid. - */ -#define DDSD_CKDESTBLT 0x00004000l - -/* - * ddckCKSrcOverlay is valid. - */ -#define DDSD_CKSRCOVERLAY 0x00008000l - -/* - * ddckCKSrcBlt is valid. - */ -#define DDSD_CKSRCBLT 0x00010000l - -/* - * dwMipMapCount is valid. - */ -#define DDSD_MIPMAPCOUNT 0x00020000l - - /* - * dwRefreshRate is valid - */ -#define DDSD_REFRESHRATE 0x00040000l - - -/* - * All input fields are valid. - */ -#define DDSD_ALL 0x0007f9eel - - -/*============================================================================ - * - * Direct Draw Capability Flags - * - * These flags are used to describe the capabilities of a given Surface. - * All flags are bit flags. - * - *==========================================================================*/ - -/**************************************************************************** - * - * DIRECTDRAWSURFACE CAPABILITY FLAGS - * - ****************************************************************************/ -/* - * This bit currently has no meaning. - */ -#define DDSCAPS_3D 0x00000001l - -/* - * Indicates that this surface contains alpha information. The pixel - * format must be interrogated to determine whether this surface - * contains only alpha information or alpha information interlaced - * with pixel color data (e.g. RGBA or YUVA). - */ -#define DDSCAPS_ALPHA 0x00000002l - -/* - * Indicates that this surface is a backbuffer. It is generally - * set by CreateSurface when the DDSCAPS_FLIP capability bit is set. - * It indicates that this surface is THE back buffer of a surface - * flipping structure. DirectDraw supports N surfaces in a - * surface flipping structure. Only the surface that immediately - * precedeces the DDSCAPS_FRONTBUFFER has this capability bit set. - * The other surfaces are identified as back buffers by the presence - * of the DDSCAPS_FLIP capability, their attachment order, and the - * absence of the DDSCAPS_FRONTBUFFER and DDSCAPS_BACKBUFFER - * capabilities. The bit is sent to CreateSurface when a standalone - * back buffer is being created. This surface could be attached to - * a front buffer and/or back buffers to form a flipping surface - * structure after the CreateSurface call. See AddAttachments for - * a detailed description of the behaviors in this case. - */ -#define DDSCAPS_BACKBUFFER 0x00000004l - -/* - * Indicates a complex surface structure is being described. A - * complex surface structure results in the creation of more than - * one surface. The additional surfaces are attached to the root - * surface. The complex structure can only be destroyed by - * destroying the root. - */ -#define DDSCAPS_COMPLEX 0x00000008l - -/* - * Indicates that this surface is a part of a surface flipping structure. - * When it is passed to CreateSurface the DDSCAPS_FRONTBUFFER and - * DDSCAP_BACKBUFFER bits are not set. They are set by CreateSurface - * on the resulting creations. The dwBackBufferCount field in the - * DDSURFACEDESC structure must be set to at least 1 in order for - * the CreateSurface call to succeed. The DDSCAPS_COMPLEX capability - * must always be set with creating multiple surfaces through CreateSurface. - */ -#define DDSCAPS_FLIP 0x00000010l - -/* - * Indicates that this surface is THE front buffer of a surface flipping - * structure. It is generally set by CreateSurface when the DDSCAPS_FLIP - * capability bit is set. - * If this capability is sent to CreateSurface then a standalonw front buffer - * is created. This surface will not have the DDSCAPS_FLIP capability. - * It can be attached to other back buffers to form a flipping structure. - * See AddAttachments for a detailed description of the behaviors in this - * case. - */ -#define DDSCAPS_FRONTBUFFER 0x00000020l - -/* - * Indicates that this surface is any offscreen surface that is not an overlay, - * texture, zbuffer, front buffer, back buffer, or alpha surface. It is used - * to identify plain vanilla surfaces. - */ -#define DDSCAPS_OFFSCREENPLAIN 0x00000040l - -/* - * Indicates that this surface is an overlay. It may or may not be directly visible - * depending on whether or not it is currently being overlayed onto the primary - * surface. DDSCAPS_VISIBLE can be used to determine whether or not it is being - * overlayed at the moment. - */ -#define DDSCAPS_OVERLAY 0x00000080l - -/* - * Indicates that unique DirectDrawPalette objects can be created and - * attached to this surface. - */ -#define DDSCAPS_PALETTE 0x00000100l - -/* - * Indicates that this surface is the primary surface. The primary - * surface represents what the user is seeing at the moment. - */ -#define DDSCAPS_PRIMARYSURFACE 0x00000200l - -/* - * Indicates that this surface is the primary surface for the left eye. - * The primary surface for the left eye represents what the user is seeing - * at the moment with the users left eye. When this surface is created the - * DDSCAPS_PRIMARYSURFACE represents what the user is seeing with the users - * right eye. - */ -#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400l - -/* - * Indicates that this surface memory was allocated in system memory - */ -#define DDSCAPS_SYSTEMMEMORY 0x00000800l - -/* - * Indicates that this surface can be used as a 3D texture. It does not - * indicate whether or not the surface is being used for that purpose. - */ -#define DDSCAPS_TEXTURE 0x00001000l - -/* - * Indicates that a surface may be a destination for 3D rendering. This - * bit must be set in order to query for a Direct3D Device Interface - * from this surface. - */ -#define DDSCAPS_3DDEVICE 0x00002000l - -/* - * Indicates that this surface exists in video memory. - */ -#define DDSCAPS_VIDEOMEMORY 0x00004000l - -/* - * Indicates that changes made to this surface are immediately visible. - * It is always set for the primary surface and is set for overlays while - * they are being overlayed and texture maps while they are being textured. - */ -#define DDSCAPS_VISIBLE 0x00008000l - -/* - * Indicates that only writes are permitted to the surface. Read accesses - * from the surface may or may not generate a protection fault, but the - * results of a read from this surface will not be meaningful. READ ONLY. - */ -#define DDSCAPS_WRITEONLY 0x00010000l - -/* - * Indicates that this surface is a z buffer. A z buffer does not contain - * displayable information. Instead it contains bit depth information that is - * used to determine which pixels are visible and which are obscured. - */ -#define DDSCAPS_ZBUFFER 0x00020000l - -/* - * Indicates surface will have a DC associated long term - */ -#define DDSCAPS_OWNDC 0x00040000l - -/* - * Indicates surface should be able to receive live video - */ -#define DDSCAPS_LIVEVIDEO 0x00080000l - -/* - * Indicates surface should be able to have a stream decompressed - * to it by the hardware. - */ -#define DDSCAPS_HWCODEC 0x00100000l - -/* - * Surface is a 320x200 or 320x240 ModeX surface - */ -#define DDSCAPS_MODEX 0x00200000l - -/* - * Indicates surface is one level of a mip-map. This surface will - * be attached to other DDSCAPS_MIPMAP surfaces to form the mip-map. - * This can be done explicitly, by creating a number of surfaces and - * attaching them with AddAttachedSurface or by implicitly by CreateSurface. - * If this bit is set then DDSCAPS_TEXTURE must also be set. - */ -#define DDSCAPS_MIPMAP 0x00400000l - - - -/* - * Indicates that memory for the surface is not allocated until the surface - * is loaded (via the Direct3D texture Load() function). - */ -#define DDSCAPS_ALLOCONLOAD 0x04000000l - - - - /**************************************************************************** - * - * DIRECTDRAW DRIVER CAPABILITY FLAGS - * - ****************************************************************************/ - -/* - * Display hardware has 3D acceleration. - */ -#define DDCAPS_3D 0x00000001l - -/* - * Indicates that DirectDraw will support only dest rectangles that are aligned - * on DIRECTDRAWCAPS.dwAlignBoundaryDest boundaries of the surface, respectively. - * READ ONLY. - */ -#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002l - -/* - * Indicates that DirectDraw will support only source rectangles whose sizes in - * BYTEs are DIRECTDRAWCAPS.dwAlignSizeDest multiples, respectively. READ ONLY. - */ -#define DDCAPS_ALIGNSIZEDEST 0x00000004l -/* - * Indicates that DirectDraw will support only source rectangles that are aligned - * on DIRECTDRAWCAPS.dwAlignBoundarySrc boundaries of the surface, respectively. - * READ ONLY. - */ -#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008l - -/* - * Indicates that DirectDraw will support only source rectangles whose sizes in - * BYTEs are DIRECTDRAWCAPS.dwAlignSizeSrc multiples, respectively. READ ONLY. - */ -#define DDCAPS_ALIGNSIZESRC 0x00000010l - -/* - * Indicates that DirectDraw will create video memory surfaces that have a stride - * alignment equal to DIRECTDRAWCAPS.dwAlignStride. READ ONLY. - */ -#define DDCAPS_ALIGNSTRIDE 0x00000020l - -/* - * Display hardware is capable of blt operations. - */ -#define DDCAPS_BLT 0x00000040l - -/* - * Display hardware is capable of asynchronous blt operations. - */ -#define DDCAPS_BLTQUEUE 0x00000080l - -/* - * Display hardware is capable of color space conversions during the blt operation. - */ -#define DDCAPS_BLTFOURCC 0x00000100l - -/* - * Display hardware is capable of stretching during blt operations. - */ -#define DDCAPS_BLTSTRETCH 0x00000200l - -/* - * Display hardware is shared with GDI. - */ -#define DDCAPS_GDI 0x00000400l - -/* - * Display hardware can overlay. - */ -#define DDCAPS_OVERLAY 0x00000800l - -/* - * Set if display hardware supports overlays but can not clip them. - */ -#define DDCAPS_OVERLAYCANTCLIP 0x00001000l - -/* - * Indicates that overlay hardware is capable of color space conversions during - * the overlay operation. - */ -#define DDCAPS_OVERLAYFOURCC 0x00002000l - -/* - * Indicates that stretching can be done by the overlay hardware. - */ -#define DDCAPS_OVERLAYSTRETCH 0x00004000l - -/* - * Indicates that unique DirectDrawPalettes can be created for DirectDrawSurfaces - * other than the primary surface. - */ -#define DDCAPS_PALETTE 0x00008000l - -/* - * Indicates that palette changes can be syncd with the veritcal refresh. - */ -#define DDCAPS_PALETTEVSYNC 0x00010000l - -/* - * Display hardware can return the current scan line. - */ -#define DDCAPS_READSCANLINE 0x00020000l - -/* - * Display hardware has stereo vision capabilities. DDSCAPS_PRIMARYSURFACELEFT - * can be created. - */ -#define DDCAPS_STEREOVIEW 0x00040000l - -/* - * Display hardware is capable of generating a vertical blank interrupt. - */ -#define DDCAPS_VBI 0x00080000l - -/* - * Supports the use of z buffers with blt operations. - */ -#define DDCAPS_ZBLTS 0x00100000l - -/* - * Supports Z Ordering of overlays. - */ -#define DDCAPS_ZOVERLAYS 0x00200000l - -/* - * Supports color key - */ -#define DDCAPS_COLORKEY 0x00400000l - -/* - * Supports alpha surfaces - */ -#define DDCAPS_ALPHA 0x00800000l - -/* - * colorkey is hardware assisted(DDCAPS_COLORKEY will also be set) - */ -#define DDCAPS_COLORKEYHWASSIST 0x01000000l - -/* - * no hardware support at all - */ -#define DDCAPS_NOHARDWARE 0x02000000l - -/* - * Display hardware is capable of color fill with bltter - */ -#define DDCAPS_BLTCOLORFILL 0x04000000l - -/* - * Display hardware is bank switched, and potentially very slow at - * random access to VRAM. - */ -#define DDCAPS_BANKSWITCHED 0x08000000l - -/* - * Display hardware is capable of depth filling Z-buffers with bltter - */ -#define DDCAPS_BLTDEPTHFILL 0x10000000l - -/* - * Display hardware is capable of clipping while bltting. - */ -#define DDCAPS_CANCLIP 0x20000000l - -/* - * Display hardware is capable of clipping while stretch bltting. - */ -#define DDCAPS_CANCLIPSTRETCHED 0x40000000l - -/* - * Display hardware is capable of bltting to or from system memory - */ -#define DDCAPS_CANBLTSYSMEM 0x80000000l - - - /**************************************************************************** - * - * MORE DIRECTDRAW DRIVER CAPABILITY FLAGS (dwCaps2) - * - ****************************************************************************/ - -/* - * Display hardware is certified - */ -#define DDCAPS2_CERTIFIED 0x00000001l - -/* - * Driver cannot interleave 2D operations (lock and blt) to surfaces with - * Direct3D rendering operations between calls to BeginScene() and EndScene() - */ -#define DDCAPS2_NO2DDURING3DSCENE 0x00000002l - -/**************************************************************************** - * - * DIRECTDRAW FX ALPHA CAPABILITY FLAGS - * - ****************************************************************************/ - -/* - * Supports alpha blending around the edge of a source color keyed surface. - * For Blt. - */ -#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001l - -/* - * Supports alpha information in the pixel format. The bit depth of alpha - * information in the pixel format can be 1,2,4, or 8. The alpha value becomes - * more opaque as the alpha value increases. (0 is transparent.) - * For Blt. - */ -#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002l - -/* - * Supports alpha information in the pixel format. The bit depth of alpha - * information in the pixel format can be 1,2,4, or 8. The alpha value - * becomes more transparent as the alpha value increases. (0 is opaque.) - * This flag can only be set if DDCAPS_ALPHA is set. - * For Blt. - */ -#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004l - -/* - * Supports alpha only surfaces. The bit depth of an alpha only surface can be - * 1,2,4, or 8. The alpha value becomes more opaque as the alpha value increases. - * (0 is transparent.) - * For Blt. - */ -#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008l - -/* - * The depth of the alpha channel data can range can be 1,2,4, or 8. - * The NEG suffix indicates that this alpha channel becomes more transparent - * as the alpha value increases. (0 is opaque.) This flag can only be set if - * DDCAPS_ALPHA is set. - * For Blt. - */ -#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010l - -/* - * Supports alpha blending around the edge of a source color keyed surface. - * For Overlays. - */ -#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020l - -/* - * Supports alpha information in the pixel format. The bit depth of alpha - * information in the pixel format can be 1,2,4, or 8. The alpha value becomes - * more opaque as the alpha value increases. (0 is transparent.) - * For Overlays. - */ -#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040l - -/* - * Supports alpha information in the pixel format. The bit depth of alpha - * information in the pixel format can be 1,2,4, or 8. The alpha value - * becomes more transparent as the alpha value increases. (0 is opaque.) - * This flag can only be set if DDCAPS_ALPHA is set. - * For Overlays. - */ -#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080l - -/* - * Supports alpha only surfaces. The bit depth of an alpha only surface can be - * 1,2,4, or 8. The alpha value becomes more opaque as the alpha value increases. - * (0 is transparent.) - * For Overlays. - */ -#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100l - -/* - * The depth of the alpha channel data can range can be 1,2,4, or 8. - * The NEG suffix indicates that this alpha channel becomes more transparent - * as the alpha value increases. (0 is opaque.) This flag can only be set if - * DDCAPS_ALPHA is set. - * For Overlays. - */ -#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200l - -/**************************************************************************** - * - * DIRECTDRAW FX CAPABILITY FLAGS - * - ****************************************************************************/ - -/* - * Uses arithmetic operations to stretch and shrink surfaces during blt - * rather than pixel doubling techniques. Along the Y axis. - */ -#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020l - -/* - * Uses arithmetic operations to stretch during blt - * rather than pixel doubling techniques. Along the Y axis. Only - * works for x1, x2, etc. - */ -#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010l - -/* - * Supports mirroring left to right in blt. - */ -#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040l - -/* - * Supports mirroring top to bottom in blt. - */ -#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080l - -/* - * Supports arbitrary rotation for blts. - */ -#define DDFXCAPS_BLTROTATION 0x00000100l - -/* - * Supports 90 degree rotations for blts. - */ -#define DDFXCAPS_BLTROTATION90 0x00000200l - -/* - * DirectDraw supports arbitrary shrinking of a surface along the - * x axis (horizontal direction) for blts. - */ -#define DDFXCAPS_BLTSHRINKX 0x00000400l - -/* - * DirectDraw supports integer shrinking (1x,2x,) of a surface - * along the x axis (horizontal direction) for blts. - */ -#define DDFXCAPS_BLTSHRINKXN 0x00000800l - -/* - * DirectDraw supports arbitrary shrinking of a surface along the - * y axis (horizontal direction) for blts. - */ -#define DDFXCAPS_BLTSHRINKY 0x00001000l - -/* - * DirectDraw supports integer shrinking (1x,2x,) of a surface - * along the y axis (vertical direction) for blts. - */ -#define DDFXCAPS_BLTSHRINKYN 0x00002000l - -/* - * DirectDraw supports arbitrary stretching of a surface along the - * x axis (horizontal direction) for blts. - */ -#define DDFXCAPS_BLTSTRETCHX 0x00004000l - -/* - * DirectDraw supports integer stretching (1x,2x,) of a surface - * along the x axis (horizontal direction) for blts. - */ -#define DDFXCAPS_BLTSTRETCHXN 0x00008000l - -/* - * DirectDraw supports arbitrary stretching of a surface along the - * y axis (horizontal direction) for blts. - */ -#define DDFXCAPS_BLTSTRETCHY 0x00010000l - -/* - * DirectDraw supports integer stretching (1x,2x,) of a surface - * along the y axis (vertical direction) for blts. - */ -#define DDFXCAPS_BLTSTRETCHYN 0x00020000l - -/* - * Uses arithmetic operations to stretch and shrink surfaces during - * overlay rather than pixel doubling techniques. Along the Y axis - * for overlays. - */ -#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000l - -/* - * Uses arithmetic operations to stretch surfaces during - * overlay rather than pixel doubling techniques. Along the Y axis - * for overlays. Only works for x1, x2, etc. - */ -#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008l - -/* - * DirectDraw supports arbitrary shrinking of a surface along the - * x axis (horizontal direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSHRINKX 0x00080000l - -/* - * DirectDraw supports integer shrinking (1x,2x,) of a surface - * along the x axis (horizontal direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000l - -/* - * DirectDraw supports arbitrary shrinking of a surface along the - * y axis (horizontal direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSHRINKY 0x00200000l - -/* - * DirectDraw supports integer shrinking (1x,2x,) of a surface - * along the y axis (vertical direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000l - -/* - * DirectDraw supports arbitrary stretching of a surface along the - * x axis (horizontal direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000l - -/* - * DirectDraw supports integer stretching (1x,2x,) of a surface - * along the x axis (horizontal direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000l - -/* - * DirectDraw supports arbitrary stretching of a surface along the - * y axis (horizontal direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000l - -/* - * DirectDraw supports integer stretching (1x,2x,) of a surface - * along the y axis (vertical direction) for overlays. - */ -#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000l - -/* - * DirectDraw supports mirroring of overlays across the vertical axis - */ -#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000l - -/* - * DirectDraw supports mirroring of overlays across the horizontal axis - */ -#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000l - -/**************************************************************************** - * - * DIRECTDRAW STEREO VIEW CAPABILITIES - * - ****************************************************************************/ - -/* - * The stereo view is accomplished via enigma encoding. - */ -#define DDSVCAPS_ENIGMA 0x00000001l - -/* - * The stereo view is accomplished via high frequency flickering. - */ -#define DDSVCAPS_FLICKER 0x00000002l - -/* - * The stereo view is accomplished via red and blue filters applied - * to the left and right eyes. All images must adapt their colorspaces - * for this process. - */ -#define DDSVCAPS_REDBLUE 0x00000004l - -/* - * The stereo view is accomplished with split screen technology. - */ -#define DDSVCAPS_SPLIT 0x00000008l - -/**************************************************************************** - * - * DIRECTDRAWPALETTE CAPABILITIES - * - ****************************************************************************/ - -/* - * Index is 4 bits. There are sixteen color entries in the palette table. - */ -#define DDPCAPS_4BIT 0x00000001l - -/* - * Index is onto a 8 bit color index. This field is only valid with the - * DDPCAPS_1BIT, DDPCAPS_2BIT or DDPCAPS_4BIT capability and the target - * surface is in 8bpp. Each color entry is one byte long and is an index - * into destination surface's 8bpp palette. - */ -#define DDPCAPS_8BITENTRIES 0x00000002l - -/* - * Index is 8 bits. There are 256 color entries in the palette table. - */ -#define DDPCAPS_8BIT 0x00000004l - -/* - * Indicates that this DIRECTDRAWPALETTE should use the palette color array - * passed into the lpDDColorArray parameter to initialize the DIRECTDRAWPALETTE - * object. - */ -#define DDPCAPS_INITIALIZE 0x00000008l - -/* - * This palette is the one attached to the primary surface. Changing this - * table has immediate effect on the display unless DDPSETPAL_VSYNC is specified - * and supported. - */ -#define DDPCAPS_PRIMARYSURFACE 0x00000010l - -/* - * This palette is the one attached to the primary surface left. Changing - * this table has immediate effect on the display for the left eye unless - * DDPSETPAL_VSYNC is specified and supported. - */ -#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020l - -/* - * This palette can have all 256 entries defined - */ -#define DDPCAPS_ALLOW256 0x00000040l - -/* - * This palette can have modifications to it synced with the monitors - * refresh rate. - */ -#define DDPCAPS_VSYNC 0x00000080l - -/* - * Index is 1 bit. There are two color entries in the palette table. - */ -#define DDPCAPS_1BIT 0x00000100l - -/* - * Index is 2 bit. There are four color entries in the palette table. - */ -#define DDPCAPS_2BIT 0x00000200l - - -/**************************************************************************** - * - * DIRECTDRAWPALETTE SETENTRY CONSTANTS - * - ****************************************************************************/ - - -/**************************************************************************** - * - * DIRECTDRAWPALETTE GETENTRY CONSTANTS - * - ****************************************************************************/ - -/* 0 is the only legal value */ - -/**************************************************************************** - * - * DIRECTDRAWSURFACE SETPALETTE CONSTANTS - * - ****************************************************************************/ - - -/**************************************************************************** - * - * DIRECTDRAW BITDEPTH CONSTANTS - * - * NOTE: These are only used to indicate supported bit depths. These - * are flags only, they are not to be used as an actual bit depth. The - * absolute numbers 1, 2, 4, 8, 16, 24 and 32 are used to indicate actual - * bit depths in a surface or for changing the display mode. - * - ****************************************************************************/ - -/* - * 1 bit per pixel. - */ -#define DDBD_1 0x00004000l - -/* - * 2 bits per pixel. - */ -#define DDBD_2 0x00002000l - -/* - * 4 bits per pixel. - */ -#define DDBD_4 0x00001000l - -/* - * 8 bits per pixel. - */ -#define DDBD_8 0x00000800l - -/* - * 16 bits per pixel. - */ -#define DDBD_16 0x00000400l - -/* - * 24 bits per pixel. - */ -#define DDBD_24 0X00000200l - -/* - * 32 bits per pixel. - */ -#define DDBD_32 0x00000100l - -/**************************************************************************** - * - * DIRECTDRAWSURFACE SET/GET COLOR KEY FLAGS - * - ****************************************************************************/ - -/* - * Set if the structure contains a color space. Not set if the structure - * contains a single color key. - */ -#define DDCKEY_COLORSPACE 0x00000001l - -/* - * Set if the structure specifies a color key or color space which is to be - * used as a destination color key for blt operations. - */ -#define DDCKEY_DESTBLT 0x00000002l - -/* - * Set if the structure specifies a color key or color space which is to be - * used as a destination color key for overlay operations. - */ -#define DDCKEY_DESTOVERLAY 0x00000004l - -/* - * Set if the structure specifies a color key or color space which is to be - * used as a source color key for blt operations. - */ -#define DDCKEY_SRCBLT 0x00000008l - -/* - * Set if the structure specifies a color key or color space which is to be - * used as a source color key for overlay operations. - */ -#define DDCKEY_SRCOVERLAY 0x00000010l - - -/**************************************************************************** - * - * DIRECTDRAW COLOR KEY CAPABILITY FLAGS - * - ****************************************************************************/ - -/* - * Supports transparent blting using a color key to identify the replaceable - * bits of the destination surface for RGB colors. - */ -#define DDCKEYCAPS_DESTBLT 0x00000001l - -/* - * Supports transparent blting using a color space to identify the replaceable - * bits of the destination surface for RGB colors. - */ -#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002l - -/* - * Supports transparent blting using a color space to identify the replaceable - * bits of the destination surface for YUV colors. - */ -#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004l - -/* - * Supports transparent blting using a color key to identify the replaceable - * bits of the destination surface for YUV colors. - */ -#define DDCKEYCAPS_DESTBLTYUV 0x00000008l - -/* - * Supports overlaying using colorkeying of the replaceable bits of the surface - * being overlayed for RGB colors. - */ -#define DDCKEYCAPS_DESTOVERLAY 0x00000010l - -/* - * Supports a color space as the color key for the destination for RGB colors. - */ -#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020l - -/* - * Supports a color space as the color key for the destination for YUV colors. - */ -#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040l - -/* - * Supports only one active destination color key value for visible overlay - * surfaces. - */ -#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080l - -/* - * Supports overlaying using colorkeying of the replaceable bits of the - * surface being overlayed for YUV colors. - */ -#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100l - -/* - * Supports transparent blting using the color key for the source with - * this surface for RGB colors. - */ -#define DDCKEYCAPS_SRCBLT 0x00000200l - -/* - * Supports transparent blting using a color space for the source with - * this surface for RGB colors. - */ -#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400l - -/* - * Supports transparent blting using a color space for the source with - * this surface for YUV colors. - */ -#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800l - -/* - * Supports transparent blting using the color key for the source with - * this surface for YUV colors. - */ -#define DDCKEYCAPS_SRCBLTYUV 0x00001000l - -/* - * Supports overlays using the color key for the source with this - * overlay surface for RGB colors. - */ -#define DDCKEYCAPS_SRCOVERLAY 0x00002000l - -/* - * Supports overlays using a color space as the source color key for - * the overlay surface for RGB colors. - */ -#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000l - -/* - * Supports overlays using a color space as the source color key for - * the overlay surface for YUV colors. - */ -#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000l - -/* - * Supports only one active source color key value for visible - * overlay surfaces. - */ -#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000l - -/* - * Supports overlays using the color key for the source with this - * overlay surface for YUV colors. - */ -#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000l - -/* - * there are no bandwidth trade-offs for using colorkey with an overlay - */ -#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000l - - -/**************************************************************************** - * - * DIRECTDRAW PIXELFORMAT FLAGS - * - ****************************************************************************/ - -/* - * The surface has alpha channel information in the pixel format. - */ -#define DDPF_ALPHAPIXELS 0x00000001l - -/* - * The pixel format contains alpha only information - */ -#define DDPF_ALPHA 0x00000002l - -/* - * The FourCC code is valid. - */ -#define DDPF_FOURCC 0x00000004l - -/* - * The surface is 4-bit color indexed. - */ -#define DDPF_PALETTEINDEXED4 0x00000008l - -/* - * The surface is indexed into a palette which stores indices - * into the destination surface's 8-bit palette. - */ -#define DDPF_PALETTEINDEXEDTO8 0x00000010l - -/* - * The surface is 8-bit color indexed. - */ -#define DDPF_PALETTEINDEXED8 0x00000020l - -/* - * The RGB data in the pixel format structure is valid. - */ -#define DDPF_RGB 0x00000040l - -/* - * The surface will accept pixel data in the format specified - * and compress it during the write. - */ -#define DDPF_COMPRESSED 0x00000080l - -/* - * The surface will accept RGB data and translate it during - * the write to YUV data. The format of the data to be written - * will be contained in the pixel format structure. The DDPF_RGB - * flag will be set. - */ -#define DDPF_RGBTOYUV 0x00000100l - -/* - * pixel format is YUV - YUV data in pixel format struct is valid - */ -#define DDPF_YUV 0x00000200l - -/* - * pixel format is a z buffer only surface - */ -#define DDPF_ZBUFFER 0x00000400l - -/* - * The surface is 1-bit color indexed. - */ -#define DDPF_PALETTEINDEXED1 0x00000800l - -/* - * The surface is 2-bit color indexed. - */ -#define DDPF_PALETTEINDEXED2 0x00001000l - -/*=========================================================================== - * - * - * DIRECTDRAW CALLBACK FLAGS - * - * - *==========================================================================*/ - -/**************************************************************************** - * - * DIRECTDRAW ENUMSURFACES FLAGS - * - ****************************************************************************/ - -/* - * Enumerate all of the surfaces that meet the search criterion. - */ -#define DDENUMSURFACES_ALL 0x00000001l - -/* - * A search hit is a surface that matches the surface description. - */ -#define DDENUMSURFACES_MATCH 0x00000002l - -/* - * A search hit is a surface that does not match the surface description. - */ -#define DDENUMSURFACES_NOMATCH 0x00000004l - -/* - * Enumerate the first surface that can be created which meets the search criterion. - */ -#define DDENUMSURFACES_CANBECREATED 0x00000008l - -/* - * Enumerate the surfaces that already exist that meet the search criterion. - */ -#define DDENUMSURFACES_DOESEXIST 0x00000010l - - -/**************************************************************************** - * - * DIRECTDRAW ENUMDISPLAYMODES FLAGS - * - ****************************************************************************/ - -/* - * Enumerate Modes with different refresh rates. EnumDisplayModes guarantees - * that a particular mode will be enumerated only once. This flag specifies whether - * the refresh rate is taken into account when determining if a mode is unique. - */ -#define DDEDM_REFRESHRATES 0x00000001l - - -/**************************************************************************** - * - * DIRECTDRAW SETCOOPERATIVELEVEL FLAGS - * - ****************************************************************************/ - -/* - * Exclusive mode owner will be responsible for the entire primary surface. - * GDI can be ignored. used with DD - */ -#define DDSCL_FULLSCREEN 0x00000001l - -/* - * allow CTRL_ALT_DEL to work while in fullscreen exclusive mode - */ -#define DDSCL_ALLOWREBOOT 0x00000002l - -/* - * prevents DDRAW from modifying the application window. - * prevents DDRAW from minimize/restore the application window on activation. - */ -#define DDSCL_NOWINDOWCHANGES 0x00000004l - -/* - * app wants to work as a regular Windows application - */ -#define DDSCL_NORMAL 0x00000008l - -/* - * app wants exclusive access - */ -#define DDSCL_EXCLUSIVE 0x00000010l - - -/* - * app can deal with non-windows display modes - */ -#define DDSCL_ALLOWMODEX 0x00000040l - - -/**************************************************************************** - * - * DIRECTDRAW BLT FLAGS - * - ****************************************************************************/ - -/* - * Use the alpha information in the pixel format or the alpha channel surface - * attached to the destination surface as the alpha channel for this blt. - */ -#define DDBLT_ALPHADEST 0x00000001l - -/* - * Use the dwConstAlphaDest field in the DDBLTFX structure as the alpha channel - * for the destination surface for this blt. - */ -#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002l - -/* - * The NEG suffix indicates that the destination surface becomes more - * transparent as the alpha value increases. (0 is opaque) - */ -#define DDBLT_ALPHADESTNEG 0x00000004l - -/* - * Use the lpDDSAlphaDest field in the DDBLTFX structure as the alpha - * channel for the destination for this blt. - */ -#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008l - -/* - * Use the dwAlphaEdgeBlend field in the DDBLTFX structure as the alpha channel - * for the edges of the image that border the color key colors. - */ -#define DDBLT_ALPHAEDGEBLEND 0x00000010l - -/* - * Use the alpha information in the pixel format or the alpha channel surface - * attached to the source surface as the alpha channel for this blt. - */ -#define DDBLT_ALPHASRC 0x00000020l - -/* - * Use the dwConstAlphaSrc field in the DDBLTFX structure as the alpha channel - * for the source for this blt. - */ -#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040l - -/* - * The NEG suffix indicates that the source surface becomes more transparent - * as the alpha value increases. (0 is opaque) - */ -#define DDBLT_ALPHASRCNEG 0x00000080l - -/* - * Use the lpDDSAlphaSrc field in the DDBLTFX structure as the alpha channel - * for the source for this blt. - */ -#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100l - -/* - * Do this blt asynchronously through the FIFO in the order received. If - * there is no room in the hardware FIFO fail the call. - */ -#define DDBLT_ASYNC 0x00000200l - -/* - * Uses the dwFillColor field in the DDBLTFX structure as the RGB color - * to fill the destination rectangle on the destination surface with. - */ -#define DDBLT_COLORFILL 0x00000400l - -/* - * Uses the dwDDFX field in the DDBLTFX structure to specify the effects - * to use for the blt. - */ -#define DDBLT_DDFX 0x00000800l - -/* - * Uses the dwDDROPS field in the DDBLTFX structure to specify the ROPS - * that are not part of the Win32 API. - */ -#define DDBLT_DDROPS 0x00001000l - -/* - * Use the color key associated with the destination surface. - */ -#define DDBLT_KEYDEST 0x00002000l - -/* - * Use the dckDestColorkey field in the DDBLTFX structure as the color key - * for the destination surface. - */ -#define DDBLT_KEYDESTOVERRIDE 0x00004000l - -/* - * Use the color key associated with the source surface. - */ -#define DDBLT_KEYSRC 0x00008000l - -/* - * Use the dckSrcColorkey field in the DDBLTFX structure as the color key - * for the source surface. - */ -#define DDBLT_KEYSRCOVERRIDE 0x00010000l - -/* - * Use the dwROP field in the DDBLTFX structure for the raster operation - * for this blt. These ROPs are the same as the ones defined in the Win32 API. - */ -#define DDBLT_ROP 0x00020000l - -/* - * Use the dwRotationAngle field in the DDBLTFX structure as the angle - * (specified in 1/100th of a degree) to rotate the surface. - */ -#define DDBLT_ROTATIONANGLE 0x00040000l - -/* - * Z-buffered blt using the z-buffers attached to the source and destination - * surfaces and the dwZBufferOpCode field in the DDBLTFX structure as the - * z-buffer opcode. - */ -#define DDBLT_ZBUFFER 0x00080000l - -/* - * Z-buffered blt using the dwConstDest Zfield and the dwZBufferOpCode field - * in the DDBLTFX structure as the z-buffer and z-buffer opcode respectively - * for the destination. - */ -#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000l - -/* - * Z-buffered blt using the lpDDSDestZBuffer field and the dwZBufferOpCode - * field in the DDBLTFX structure as the z-buffer and z-buffer opcode - * respectively for the destination. - */ -#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000l - -/* - * Z-buffered blt using the dwConstSrcZ field and the dwZBufferOpCode field - * in the DDBLTFX structure as the z-buffer and z-buffer opcode respectively - * for the source. - */ -#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000l - -/* - * Z-buffered blt using the lpDDSSrcZBuffer field and the dwZBufferOpCode - * field in the DDBLTFX structure as the z-buffer and z-buffer opcode - * respectively for the source. - */ -#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000l - -/* - * wait until the device is ready to handle the blt - * this will cause blt to not return DDERR_WASSTILLDRAWING - */ -#define DDBLT_WAIT 0x01000000l - -/* - * Uses the dwFillDepth field in the DDBLTFX structure as the depth value - * to fill the destination rectangle on the destination Z-buffer surface - * with. - */ -#define DDBLT_DEPTHFILL 0x02000000l - - -/**************************************************************************** - * - * BLTFAST FLAGS - * - ****************************************************************************/ - -#define DDBLTFAST_NOCOLORKEY 0x00000000 -#define DDBLTFAST_SRCCOLORKEY 0x00000001 -#define DDBLTFAST_DESTCOLORKEY 0x00000002 -#define DDBLTFAST_WAIT 0x00000010 - -/**************************************************************************** - * - * FLIP FLAGS - * - ****************************************************************************/ - -#define DDFLIP_WAIT 0x00000001l - - -/**************************************************************************** - * - * DIRECTDRAW SURFACE OVERLAY FLAGS - * - ****************************************************************************/ - -/* - * Use the alpha information in the pixel format or the alpha channel surface - * attached to the destination surface as the alpha channel for the - * destination overlay. - */ -#define DDOVER_ALPHADEST 0x00000001l - -/* - * Use the dwConstAlphaDest field in the DDOVERLAYFX structure as the - * destination alpha channel for this overlay. - */ -#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002l - -/* - * The NEG suffix indicates that the destination surface becomes more - * transparent as the alpha value increases. - */ -#define DDOVER_ALPHADESTNEG 0x00000004l - -/* - * Use the lpDDSAlphaDest field in the DDOVERLAYFX structure as the alpha - * channel destination for this overlay. - */ -#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008l - -/* - * Use the dwAlphaEdgeBlend field in the DDOVERLAYFX structure as the alpha - * channel for the edges of the image that border the color key colors. - */ -#define DDOVER_ALPHAEDGEBLEND 0x00000010l - -/* - * Use the alpha information in the pixel format or the alpha channel surface - * attached to the source surface as the source alpha channel for this overlay. - */ -#define DDOVER_ALPHASRC 0x00000020l - -/* - * Use the dwConstAlphaSrc field in the DDOVERLAYFX structure as the source - * alpha channel for this overlay. - */ -#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040l - -/* - * The NEG suffix indicates that the source surface becomes more transparent - * as the alpha value increases. - */ -#define DDOVER_ALPHASRCNEG 0x00000080l - -/* - * Use the lpDDSAlphaSrc field in the DDOVERLAYFX structure as the alpha channel - * source for this overlay. - */ -#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100l - -/* - * Turn this overlay off. - */ -#define DDOVER_HIDE 0x00000200l - -/* - * Use the color key associated with the destination surface. - */ -#define DDOVER_KEYDEST 0x00000400l - -/* - * Use the dckDestColorkey field in the DDOVERLAYFX structure as the color key - * for the destination surface - */ -#define DDOVER_KEYDESTOVERRIDE 0x00000800l - -/* - * Use the color key associated with the source surface. - */ -#define DDOVER_KEYSRC 0x00001000l - -/* - * Use the dckSrcColorkey field in the DDOVERLAYFX structure as the color key - * for the source surface. - */ -#define DDOVER_KEYSRCOVERRIDE 0x00002000l - -/* - * Turn this overlay on. - */ -#define DDOVER_SHOW 0x00004000l - -/* - * Add a dirty rect to an emulated overlayed surface. - */ -#define DDOVER_ADDDIRTYRECT 0x00008000l - -/* - * Redraw all dirty rects on an emulated overlayed surface. - */ -#define DDOVER_REFRESHDIRTYRECTS 0x00010000l - -/* - * Redraw the entire surface on an emulated overlayed surface. - */ -#define DDOVER_REFRESHALL 0x00020000l - - -/* - * Use the overlay FX flags to define special overlay FX - */ -#define DDOVER_DDFX 0x00080000l - - -/**************************************************************************** - * - * DIRECTDRAWSURFACE LOCK FLAGS - * - ****************************************************************************/ - -/* - * The default. Set to indicate that Lock should return a valid memory pointer - * to the top of the specified rectangle. If no rectangle is specified then a - * pointer to the top of the surface is returned. - */ -#define DDLOCK_SURFACEMEMORYPTR 0x00000000L // default - -/* - * Set to indicate that Lock should wait until it can obtain a valid memory - * pointer before returning. If this bit is set, Lock will never return - * DDERR_WASSTILLDRAWING. - */ -#define DDLOCK_WAIT 0x00000001L - -/* - * Set if an event handle is being passed to Lock. Lock will trigger the event - * when it can return the surface memory pointer requested. - */ -#define DDLOCK_EVENT 0x00000002L - -/* - * Indicates that the surface being locked will only be read from. - */ -#define DDLOCK_READONLY 0x00000010L - -/* - * Indicates that the surface being locked will only be written to - */ -#define DDLOCK_WRITEONLY 0x00000020L - - -/**************************************************************************** - * - * DIRECTDRAWSURFACE PAGELOCK FLAGS - * - ****************************************************************************/ - -/* - * No flags defined at present - */ - - -/**************************************************************************** - * - * DIRECTDRAWSURFACE PAGEUNLOCK FLAGS - * - ****************************************************************************/ - -/* - * No flags defined at present - */ - - -/**************************************************************************** - * - * DIRECTDRAWSURFACE BLT FX FLAGS - * - ****************************************************************************/ - -/* - * If stretching, use arithmetic stretching along the Y axis for this blt. - */ -#define DDBLTFX_ARITHSTRETCHY 0x00000001l - -/* - * Do this blt mirroring the surface left to right. Spin the - * surface around its y-axis. - */ -#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002l - -/* - * Do this blt mirroring the surface up and down. Spin the surface - * around its x-axis. - */ -#define DDBLTFX_MIRRORUPDOWN 0x00000004l - -/* - * Schedule this blt to avoid tearing. - */ -#define DDBLTFX_NOTEARING 0x00000008l - -/* - * Do this blt rotating the surface one hundred and eighty degrees. - */ -#define DDBLTFX_ROTATE180 0x00000010l - -/* - * Do this blt rotating the surface two hundred and seventy degrees. - */ -#define DDBLTFX_ROTATE270 0x00000020l - -/* - * Do this blt rotating the surface ninety degrees. - */ -#define DDBLTFX_ROTATE90 0x00000040l - -/* - * Do this z blt using dwZBufferLow and dwZBufferHigh as range values - * specified to limit the bits copied from the source surface. - */ -#define DDBLTFX_ZBUFFERRANGE 0x00000080l - -/* - * Do this z blt adding the dwZBufferBaseDest to each of the sources z values - * before comparing it with the desting z values. - */ -#define DDBLTFX_ZBUFFERBASEDEST 0x00000100l - -/**************************************************************************** - * - * DIRECTDRAWSURFACE OVERLAY FX FLAGS - * - ****************************************************************************/ - -/* - * If stretching, use arithmetic stretching along the Y axis for this overlay. - */ -#define DDOVERFX_ARITHSTRETCHY 0x00000001l - -/* - * Mirror the overlay across the vertical axis - */ -#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002l - -/* - * Mirror the overlay across the horizontal axis - */ -#define DDOVERFX_MIRRORUPDOWN 0x00000004l - -/**************************************************************************** - * - * DIRECTDRAW WAITFORVERTICALBLANK FLAGS - * - ****************************************************************************/ - -/* - * return when the vertical blank interval begins - */ -#define DDWAITVB_BLOCKBEGIN 0x00000001l - -/* - * set up an event to trigger when the vertical blank begins - */ -#define DDWAITVB_BLOCKBEGINEVENT 0x00000002l - -/* - * return when the vertical blank interval ends and display begins - */ -#define DDWAITVB_BLOCKEND 0x00000004l - -/**************************************************************************** - * - * DIRECTDRAW GETFLIPSTATUS FLAGS - * - ****************************************************************************/ - -/* - * is it OK to flip now? - */ -#define DDGFS_CANFLIP 0x00000001l - -/* - * is the last flip finished? - */ -#define DDGFS_ISFLIPDONE 0x00000002l - -/**************************************************************************** - * - * DIRECTDRAW GETBLTSTATUS FLAGS - * - ****************************************************************************/ - -/* - * is it OK to blt now? - */ -#define DDGBS_CANBLT 0x00000001l - -/* - * is the blt to the surface finished? - */ -#define DDGBS_ISBLTDONE 0x00000002l - - -/**************************************************************************** - * - * DIRECTDRAW ENUMOVERLAYZORDER FLAGS - * - ****************************************************************************/ - -/* - * Enumerate overlays back to front. - */ -#define DDENUMOVERLAYZ_BACKTOFRONT 0x00000000l - -/* - * Enumerate overlays front to back - */ -#define DDENUMOVERLAYZ_FRONTTOBACK 0x00000001l - -/**************************************************************************** - * - * DIRECTDRAW UPDATEOVERLAYZORDER FLAGS - * - ****************************************************************************/ - -/* - * Send overlay to front - */ -#define DDOVERZ_SENDTOFRONT 0x00000000l - -/* - * Send overlay to back - */ -#define DDOVERZ_SENDTOBACK 0x00000001l - -/* - * Move Overlay forward - */ -#define DDOVERZ_MOVEFORWARD 0x00000002l - -/* - * Move Overlay backward - */ -#define DDOVERZ_MOVEBACKWARD 0x00000003l - -/* - * Move Overlay in front of relative surface - */ -#define DDOVERZ_INSERTINFRONTOF 0x00000004l - -/* - * Move Overlay in back of relative surface - */ -#define DDOVERZ_INSERTINBACKOF 0x00000005l - -/*=========================================================================== - * - * - * DIRECTDRAW RETURN CODES - * - * The return values from DirectDraw Commands and Surface that return an HRESULT - * are codes from DirectDraw concerning the results of the action - * requested by DirectDraw. - * - *==========================================================================*/ - -/* - * Status is OK - * - * Issued by: DirectDraw Commands and all callbacks - */ -#define DD_OK 0 - -/**************************************************************************** - * - * DIRECTDRAW ENUMCALLBACK RETURN VALUES - * - * EnumCallback returns are used to control the flow of the DIRECTDRAW and - * DIRECTDRAWSURFACE object enumerations. They can only be returned by - * enumeration callback routines. - * - ****************************************************************************/ - -/* - * stop the enumeration - */ -#define DDENUMRET_CANCEL 0 - -/* - * continue the enumeration - */ -#define DDENUMRET_OK 1 - -/**************************************************************************** - * - * DIRECTDRAW ERRORS - * - * Errors are represented by negative values and cannot be combined. - * - ****************************************************************************/ - -/* - * This object is already initialized - */ -#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 ) - -/* - * This surface can not be attached to the requested surface. - */ -#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 ) - -/* - * This surface can not be detached from the requested surface. - */ -#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 ) - -/* - * Support is currently not available. - */ -#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 ) - -/* - * An exception was encountered while performing the requested operation - */ -#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 ) - -/* - * Generic failure. - */ -#define DDERR_GENERIC E_FAIL - -/* - * Height of rectangle provided is not a multiple of reqd alignment - */ -#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 ) - -/* - * Unable to match primary surface creation request with existing - * primary surface. - */ -#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 ) - -/* - * One or more of the caps bits passed to the callback are incorrect. - */ -#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 ) - -/* - * DirectDraw does not support provided Cliplist. - */ -#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 ) - -/* - * DirectDraw does not support the requested mode - */ -#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 ) - -/* - * DirectDraw received a pointer that was an invalid DIRECTDRAW object. - */ -#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 ) - -/* - * One or more of the parameters passed to the callback function are - * incorrect. - */ -#define DDERR_INVALIDPARAMS E_INVALIDARG - -/* - * pixel format was invalid as specified - */ -#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 ) - -/* - * Rectangle provided was invalid. - */ -#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 ) - -/* - * Operation could not be carried out because one or more surfaces are locked - */ -#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 ) - -/* - * There is no 3D present. - */ -#define DDERR_NO3D MAKE_DDHRESULT( 170 ) - -/* - * Operation could not be carried out because there is no alpha accleration - * hardware present or available. - */ -#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 ) - - -/* - * no clip list available - */ -#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 ) - -/* - * Operation could not be carried out because there is no color conversion - * hardware present or available. - */ -#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 ) - -/* - * Create function called without DirectDraw object method SetCooperativeLevel - * being called. - */ -#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 ) - -/* - * Surface doesn't currently have a color key - */ -#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 ) - -/* - * Operation could not be carried out because there is no hardware support - * of the dest color key. - */ -#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 ) - -/* - * No DirectDraw support possible with current display driver - */ -#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 ) - -/* - * Operation requires the application to have exclusive mode but the - * application does not have exclusive mode. - */ -#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 ) - -/* - * Flipping visible surfaces is not supported. - */ -#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 ) - -/* - * There is no GDI present. - */ -#define DDERR_NOGDI MAKE_DDHRESULT( 240 ) - -/* - * Operation could not be carried out because there is no hardware present - * or available. - */ -#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 ) - -/* - * Requested item was not found - */ -#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 ) - -/* - * Operation could not be carried out because there is no overlay hardware - * present or available. - */ -#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 ) - -/* - * Operation could not be carried out because there is no appropriate raster - * op hardware present or available. - */ -#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 ) - -/* - * Operation could not be carried out because there is no rotation hardware - * present or available. - */ -#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 ) - -/* - * Operation could not be carried out because there is no hardware support - * for stretching - */ -#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 ) - -/* - * DirectDrawSurface is not in 4 bit color palette and the requested operation - * requires 4 bit color palette. - */ -#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 ) - -/* - * DirectDrawSurface is not in 4 bit color index palette and the requested - * operation requires 4 bit color index palette. - */ -#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 ) - -/* - * DirectDraw Surface is not in 8 bit color mode and the requested operation - * requires 8 bit color. - */ -#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 ) - -/* - * Operation could not be carried out because there is no texture mapping - * hardware present or available. - */ -#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 ) - -/* - * Operation could not be carried out because there is no hardware support - * for vertical blank synchronized operations. - */ -#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 ) - -/* - * Operation could not be carried out because there is no hardware support - * for zbuffer blting. - */ -#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 ) - -/* - * Overlay surfaces could not be z layered based on their BltOrder because - * the hardware does not support z layering of overlays. - */ -#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 ) - -/* - * The hardware needed for the requested operation has already been - * allocated. - */ -#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 ) - -/* - * DirectDraw does not have enough memory to perform the operation. - */ -#define DDERR_OUTOFMEMORY E_OUTOFMEMORY - -/* - * DirectDraw does not have enough memory to perform the operation. - */ -#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 ) - -/* - * hardware does not support clipped overlays - */ -#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 ) - -/* - * Can only have ony color key active at one time for overlays - */ -#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 ) - -/* - * Access to this palette is being refused because the palette is already - * locked by another thread. - */ -#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 ) - -/* - * No src color key specified for this operation. - */ -#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 ) - -/* - * This surface is already attached to the surface it is being attached to. - */ -#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 ) - -/* - * This surface is already a dependency of the surface it is being made a - * dependency of. - */ -#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 ) - -/* - * Access to this surface is being refused because the surface is already - * locked by another thread. - */ -#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 ) - -/* - * Access to this surface is being refused because no driver exists - * which can supply a pointer to the surface. - * This is most likely to happen when attempting to lock the primary - * surface when no DCI provider is present. - */ -#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 ) - -/* - * Access to Surface refused because Surface is obscured. - */ -#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 ) - -/* - * Access to this surface is being refused because the surface is gone. - * The DIRECTDRAWSURFACE object representing this surface should - * have Restore called on it. - */ -#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 ) - -/* - * The requested surface is not attached. - */ -#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 ) - -/* - * Height requested by DirectDraw is too large. - */ -#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 ) - -/* - * Size requested by DirectDraw is too large -- The individual height and - * width are OK. - */ -#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 ) - -/* - * Width requested by DirectDraw is too large. - */ -#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 ) - -/* - * Action not supported. - */ -#define DDERR_UNSUPPORTED E_NOTIMPL - -/* - * FOURCC format requested is unsupported by DirectDraw - */ -#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 ) - -/* - * Bitmask in the pixel format requested is unsupported by DirectDraw - */ -#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 ) - -/* - * vertical blank is in progress - */ -#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 ) - -/* - * Informs DirectDraw that the previous Blt which is transfering information - * to or from this Surface is incomplete. - */ -#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 ) - -/* - * Rectangle provided was not horizontally aligned on reqd. boundary - */ -#define DDERR_XALIGN MAKE_DDHRESULT( 560 ) - -/* - * The GUID passed to DirectDrawCreate is not a valid DirectDraw driver - * identifier. - */ -#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 ) - -/* - * A DirectDraw object representing this driver has already been created - * for this process. - */ -#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 ) - -/* - * A hardware only DirectDraw object creation was attempted but the driver - * did not support any hardware. - */ -#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 ) - -/* - * this process already has created a primary surface - */ -#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 ) - -/* - * software emulation not available. - */ -#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 ) - -/* - * region passed to Clipper::GetClipList is too small. - */ -#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 ) - -/* - * an attempt was made to set a clip list for a clipper objec that - * is already monitoring an hwnd. - */ -#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 ) - -/* - * No clipper object attached to surface object - */ -#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 ) - -/* - * Clipper notification requires an HWND or - * no HWND has previously been set as the CooperativeLevel HWND. - */ -#define DDERR_NOHWND MAKE_DDHRESULT( 569 ) - -/* - * HWND used by DirectDraw CooperativeLevel has been subclassed, - * this prevents DirectDraw from restoring state. - */ -#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 ) - -/* - * The CooperativeLevel HWND has already been set. - * It can not be reset while the process has surfaces or palettes created. - */ -#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 ) - -/* - * No palette object attached to this surface. - */ -#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 ) - -/* - * No hardware support for 16 or 256 color palettes. - */ -#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 ) - -/* - * If a clipper object is attached to the source surface passed into a - * BltFast call. - */ -#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 ) - -/* - * No blter. - */ -#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 ) - -/* - * No DirectDraw ROP hardware. - */ -#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 ) - -/* - * returned when GetOverlayPosition is called on a hidden overlay - */ -#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 ) - -/* - * returned when GetOverlayPosition is called on a overlay that UpdateOverlay - * has never been called on to establish a destionation. - */ -#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 ) - -/* - * returned when the position of the overlay on the destionation is no longer - * legal for that destionation. - */ -#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 ) - -/* - * returned when an overlay member is called for a non-overlay surface - */ -#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 ) - -/* - * An attempt was made to set the cooperative level when it was already - * set to exclusive. - */ -#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 ) - -/* - * An attempt has been made to flip a surface that is not flippable. - */ -#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 ) - -/* - * Can't duplicate primary & 3D surfaces, or surfaces that are implicitly - * created. - */ -#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 ) - -/* - * Surface was not locked. An attempt to unlock a surface that was not - * locked at all, or by this process, has been attempted. - */ -#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 ) - -/* - * Windows can not create any more DCs - */ -#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 ) - -/* - * No DC was ever created for this surface. - */ -#define DDERR_NODC MAKE_DDHRESULT( 586 ) - -/* - * This surface can not be restored because it was created in a different - * mode. - */ -#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 ) - -/* - * This surface can not be restored because it is an implicitly created - * surface. - */ -#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 ) - -/* - * The surface being used is not a palette-based surface - */ -#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 ) - - -/* - * The display is currently in an unsupported mode - */ -#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 ) - -/* - * Operation could not be carried out because there is no mip-map - * texture mapping hardware present or available. - */ -#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 ) - -/* - * The requested action could not be performed because the surface was of - * the wrong type. - */ -#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 ) - - - -/* - * A DC has already been returned for this surface. Only one DC can be - * retrieved per surface. - */ -#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 ) - -/* - * The attempt to page lock a surface failed. - */ -#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 ) - -/* - * The attempt to page unlock a surface failed. - */ -#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 ) - -/* - * An attempt was made to page unlock a surface with no outstanding page locks. - */ -#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 ) - -/* - * An attempt was made to invoke an interface member of a DirectDraw object - * created by CoCreateInstance() before it was initialized. - */ -#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED - -/* Alpha bit depth constants */ - - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/DEFINES.H b/code/TIBERIANDAWN/WIN32LIB/DEFINES.H deleted file mode 100644 index 954e91d..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DEFINES.H +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB32 Example * - * * - * File Name : DEFINES.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - -#define USER_TIMER_FREQ 60 diff --git a/code/TIBERIANDAWN/WIN32LIB/DESCMGMT.H b/code/TIBERIANDAWN/WIN32LIB/DESCMGMT.H deleted file mode 100644 index f810255..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DESCMGMT.H +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB32 library * - * * - * File Name : DESCMGMT.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef DESCMGMT_H -#define DESCMGMT_H - - -#ifndef WWSTD_H -#include "wwstd.h" -#endif - -//===================================================================== -// C type include files -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#ifdef __cplusplus -} -#endif - -// ==================================================================== - - -// types -// These where taken from dos.h -//========================================== - -// external functions -// =================================================== -extern ULONG Map_Segment_To_Address(ULONG address, ULONG length); - -extern "C" { - // Assemble functions - extern UWORD FixSelector(UWORD sel); - extern UWORD GetDs(void); - extern UWORD GetCs(void); - extern VOID GetDefaultSelectors(VOID); - extern UWORD Get_Standard_Selector(void); - - - // Assembly data variables - extern UWORD CodeSelector; - extern UWORD DataSelector; - extern UWORD ScreenSelector; - extern UWORD GraphicsSelector; - extern UWORD PspSelector; - extern UWORD EnvSelector; - extern UWORD DosMemSelector; - extern UWORD Fp1167Selector; - extern UWORD FpWeitekSelector; - extern UWORD FpCyrixSelector; -} - -#endif // DESCMGMT_H - - diff --git a/code/TIBERIANDAWN/WIN32LIB/DIFFTB.INC b/code/TIBERIANDAWN/WIN32LIB/DIFFTB.INC deleted file mode 100644 index 0c345aa..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DIFFTB.INC +++ /dev/null @@ -1,1445 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;**************************************************************************** -;* dwDiffTable - ADPCM Lookup table for sample differences -;**************************************************************************** - - align 4 - -dwDiffTable DD 0 ; Index = 0 Token = 0 - DD 1 ; Index = 0 Token = 1 - DD 3 ; Index = 0 Token = 2 - DD 4 ; Index = 0 Token = 3 - DD 7 ; Index = 0 Token = 4 - DD 8 ; Index = 0 Token = 5 - DD 10 ; Index = 0 Token = 6 - DD 11 ; Index = 0 Token = 7 - DD 0 ; Index = 0 Token = 8 - DD -1 ; Index = 0 Token = 9 - DD -3 ; Index = 0 Token = 10 - DD -4 ; Index = 0 Token = 11 - DD -7 ; Index = 0 Token = 12 - DD -8 ; Index = 0 Token = 13 - DD -10 ; Index = 0 Token = 14 - DD -11 ; Index = 0 Token = 15 - DD 1 ; Index = 1 Token = 0 - DD 3 ; Index = 1 Token = 1 - DD 5 ; Index = 1 Token = 2 - DD 7 ; Index = 1 Token = 3 - DD 9 ; Index = 1 Token = 4 - DD 11 ; Index = 1 Token = 5 - DD 13 ; Index = 1 Token = 6 - DD 15 ; Index = 1 Token = 7 - DD -1 ; Index = 1 Token = 8 - DD -3 ; Index = 1 Token = 9 - DD -5 ; Index = 1 Token = 10 - DD -7 ; Index = 1 Token = 11 - DD -9 ; Index = 1 Token = 12 - DD -11 ; Index = 1 Token = 13 - DD -13 ; Index = 1 Token = 14 - DD -15 ; Index = 1 Token = 15 - DD 1 ; Index = 2 Token = 0 - DD 3 ; Index = 2 Token = 1 - DD 5 ; Index = 2 Token = 2 - DD 7 ; Index = 2 Token = 3 - DD 10 ; Index = 2 Token = 4 - DD 12 ; Index = 2 Token = 5 - DD 14 ; Index = 2 Token = 6 - DD 16 ; Index = 2 Token = 7 - DD -1 ; Index = 2 Token = 8 - DD -3 ; Index = 2 Token = 9 - DD -5 ; Index = 2 Token = 10 - DD -7 ; Index = 2 Token = 11 - DD -10 ; Index = 2 Token = 12 - DD -12 ; Index = 2 Token = 13 - DD -14 ; Index = 2 Token = 14 - DD -16 ; Index = 2 Token = 15 - DD 1 ; Index = 3 Token = 0 - DD 3 ; Index = 3 Token = 1 - DD 6 ; Index = 3 Token = 2 - DD 8 ; Index = 3 Token = 3 - DD 11 ; Index = 3 Token = 4 - DD 13 ; Index = 3 Token = 5 - DD 16 ; Index = 3 Token = 6 - DD 18 ; Index = 3 Token = 7 - DD -1 ; Index = 3 Token = 8 - DD -3 ; Index = 3 Token = 9 - DD -6 ; Index = 3 Token = 10 - DD -8 ; Index = 3 Token = 11 - DD -11 ; Index = 3 Token = 12 - DD -13 ; Index = 3 Token = 13 - DD -16 ; Index = 3 Token = 14 - DD -18 ; Index = 3 Token = 15 - DD 1 ; Index = 4 Token = 0 - DD 3 ; Index = 4 Token = 1 - DD 6 ; Index = 4 Token = 2 - DD 8 ; Index = 4 Token = 3 - DD 12 ; Index = 4 Token = 4 - DD 14 ; Index = 4 Token = 5 - DD 17 ; Index = 4 Token = 6 - DD 19 ; Index = 4 Token = 7 - DD -1 ; Index = 4 Token = 8 - DD -3 ; Index = 4 Token = 9 - DD -6 ; Index = 4 Token = 10 - DD -8 ; Index = 4 Token = 11 - DD -12 ; Index = 4 Token = 12 - DD -14 ; Index = 4 Token = 13 - DD -17 ; Index = 4 Token = 14 - DD -19 ; Index = 4 Token = 15 - DD 1 ; Index = 5 Token = 0 - DD 4 ; Index = 5 Token = 1 - DD 7 ; Index = 5 Token = 2 - DD 10 ; Index = 5 Token = 3 - DD 13 ; Index = 5 Token = 4 - DD 16 ; Index = 5 Token = 5 - DD 19 ; Index = 5 Token = 6 - DD 22 ; Index = 5 Token = 7 - DD -1 ; Index = 5 Token = 8 - DD -4 ; Index = 5 Token = 9 - DD -7 ; Index = 5 Token = 10 - DD -10 ; Index = 5 Token = 11 - DD -13 ; Index = 5 Token = 12 - DD -16 ; Index = 5 Token = 13 - DD -19 ; Index = 5 Token = 14 - DD -22 ; Index = 5 Token = 15 - DD 1 ; Index = 6 Token = 0 - DD 4 ; Index = 6 Token = 1 - DD 7 ; Index = 6 Token = 2 - DD 10 ; Index = 6 Token = 3 - DD 14 ; Index = 6 Token = 4 - DD 17 ; Index = 6 Token = 5 - DD 20 ; Index = 6 Token = 6 - DD 23 ; Index = 6 Token = 7 - DD -1 ; Index = 6 Token = 8 - DD -4 ; Index = 6 Token = 9 - DD -7 ; Index = 6 Token = 10 - DD -10 ; Index = 6 Token = 11 - DD -14 ; Index = 6 Token = 12 - DD -17 ; Index = 6 Token = 13 - DD -20 ; Index = 6 Token = 14 - DD -23 ; Index = 6 Token = 15 - DD 1 ; Index = 7 Token = 0 - DD 4 ; Index = 7 Token = 1 - DD 8 ; Index = 7 Token = 2 - DD 11 ; Index = 7 Token = 3 - DD 15 ; Index = 7 Token = 4 - DD 18 ; Index = 7 Token = 5 - DD 22 ; Index = 7 Token = 6 - DD 25 ; Index = 7 Token = 7 - DD -1 ; Index = 7 Token = 8 - DD -4 ; Index = 7 Token = 9 - DD -8 ; Index = 7 Token = 10 - DD -11 ; Index = 7 Token = 11 - DD -15 ; Index = 7 Token = 12 - DD -18 ; Index = 7 Token = 13 - DD -22 ; Index = 7 Token = 14 - DD -25 ; Index = 7 Token = 15 - DD 2 ; Index = 8 Token = 0 - DD 6 ; Index = 8 Token = 1 - DD 10 ; Index = 8 Token = 2 - DD 14 ; Index = 8 Token = 3 - DD 18 ; Index = 8 Token = 4 - DD 22 ; Index = 8 Token = 5 - DD 26 ; Index = 8 Token = 6 - DD 30 ; Index = 8 Token = 7 - DD -2 ; Index = 8 Token = 8 - DD -6 ; Index = 8 Token = 9 - DD -10 ; Index = 8 Token = 10 - DD -14 ; Index = 8 Token = 11 - DD -18 ; Index = 8 Token = 12 - DD -22 ; Index = 8 Token = 13 - DD -26 ; Index = 8 Token = 14 - DD -30 ; Index = 8 Token = 15 - DD 2 ; Index = 9 Token = 0 - DD 6 ; Index = 9 Token = 1 - DD 10 ; Index = 9 Token = 2 - DD 14 ; Index = 9 Token = 3 - DD 19 ; Index = 9 Token = 4 - DD 23 ; Index = 9 Token = 5 - DD 27 ; Index = 9 Token = 6 - DD 31 ; Index = 9 Token = 7 - DD -2 ; Index = 9 Token = 8 - DD -6 ; Index = 9 Token = 9 - DD -10 ; Index = 9 Token = 10 - DD -14 ; Index = 9 Token = 11 - DD -19 ; Index = 9 Token = 12 - DD -23 ; Index = 9 Token = 13 - DD -27 ; Index = 9 Token = 14 - DD -31 ; Index = 9 Token = 15 - DD 2 ; Index = 10 Token = 0 - DD 6 ; Index = 10 Token = 1 - DD 11 ; Index = 10 Token = 2 - DD 15 ; Index = 10 Token = 3 - DD 21 ; Index = 10 Token = 4 - DD 25 ; Index = 10 Token = 5 - DD 30 ; Index = 10 Token = 6 - DD 34 ; Index = 10 Token = 7 - DD -2 ; Index = 10 Token = 8 - DD -6 ; Index = 10 Token = 9 - DD -11 ; Index = 10 Token = 10 - DD -15 ; Index = 10 Token = 11 - DD -21 ; Index = 10 Token = 12 - DD -25 ; Index = 10 Token = 13 - DD -30 ; Index = 10 Token = 14 - DD -34 ; Index = 10 Token = 15 - DD 2 ; Index = 11 Token = 0 - DD 7 ; Index = 11 Token = 1 - DD 12 ; Index = 11 Token = 2 - DD 17 ; Index = 11 Token = 3 - DD 23 ; Index = 11 Token = 4 - DD 28 ; Index = 11 Token = 5 - DD 33 ; Index = 11 Token = 6 - DD 38 ; Index = 11 Token = 7 - DD -2 ; Index = 11 Token = 8 - DD -7 ; Index = 11 Token = 9 - DD -12 ; Index = 11 Token = 10 - DD -17 ; Index = 11 Token = 11 - DD -23 ; Index = 11 Token = 12 - DD -28 ; Index = 11 Token = 13 - DD -33 ; Index = 11 Token = 14 - DD -38 ; Index = 11 Token = 15 - DD 2 ; Index = 12 Token = 0 - DD 7 ; Index = 12 Token = 1 - DD 13 ; Index = 12 Token = 2 - DD 18 ; Index = 12 Token = 3 - DD 25 ; Index = 12 Token = 4 - DD 30 ; Index = 12 Token = 5 - DD 36 ; Index = 12 Token = 6 - DD 41 ; Index = 12 Token = 7 - DD -2 ; Index = 12 Token = 8 - DD -7 ; Index = 12 Token = 9 - DD -13 ; Index = 12 Token = 10 - DD -18 ; Index = 12 Token = 11 - DD -25 ; Index = 12 Token = 12 - DD -30 ; Index = 12 Token = 13 - DD -36 ; Index = 12 Token = 14 - DD -41 ; Index = 12 Token = 15 - DD 3 ; Index = 13 Token = 0 - DD 9 ; Index = 13 Token = 1 - DD 15 ; Index = 13 Token = 2 - DD 21 ; Index = 13 Token = 3 - DD 28 ; Index = 13 Token = 4 - DD 34 ; Index = 13 Token = 5 - DD 40 ; Index = 13 Token = 6 - DD 46 ; Index = 13 Token = 7 - DD -3 ; Index = 13 Token = 8 - DD -9 ; Index = 13 Token = 9 - DD -15 ; Index = 13 Token = 10 - DD -21 ; Index = 13 Token = 11 - DD -28 ; Index = 13 Token = 12 - DD -34 ; Index = 13 Token = 13 - DD -40 ; Index = 13 Token = 14 - DD -46 ; Index = 13 Token = 15 - DD 3 ; Index = 14 Token = 0 - DD 10 ; Index = 14 Token = 1 - DD 17 ; Index = 14 Token = 2 - DD 24 ; Index = 14 Token = 3 - DD 31 ; Index = 14 Token = 4 - DD 38 ; Index = 14 Token = 5 - DD 45 ; Index = 14 Token = 6 - DD 52 ; Index = 14 Token = 7 - DD -3 ; Index = 14 Token = 8 - DD -10 ; Index = 14 Token = 9 - DD -17 ; Index = 14 Token = 10 - DD -24 ; Index = 14 Token = 11 - DD -31 ; Index = 14 Token = 12 - DD -38 ; Index = 14 Token = 13 - DD -45 ; Index = 14 Token = 14 - DD -52 ; Index = 14 Token = 15 - DD 3 ; Index = 15 Token = 0 - DD 10 ; Index = 15 Token = 1 - DD 18 ; Index = 15 Token = 2 - DD 25 ; Index = 15 Token = 3 - DD 34 ; Index = 15 Token = 4 - DD 41 ; Index = 15 Token = 5 - DD 49 ; Index = 15 Token = 6 - DD 56 ; Index = 15 Token = 7 - DD -3 ; Index = 15 Token = 8 - DD -10 ; Index = 15 Token = 9 - DD -18 ; Index = 15 Token = 10 - DD -25 ; Index = 15 Token = 11 - DD -34 ; Index = 15 Token = 12 - DD -41 ; Index = 15 Token = 13 - DD -49 ; Index = 15 Token = 14 - DD -56 ; Index = 15 Token = 15 - DD 4 ; Index = 16 Token = 0 - DD 12 ; Index = 16 Token = 1 - DD 21 ; Index = 16 Token = 2 - DD 29 ; Index = 16 Token = 3 - DD 38 ; Index = 16 Token = 4 - DD 46 ; Index = 16 Token = 5 - DD 55 ; Index = 16 Token = 6 - DD 63 ; Index = 16 Token = 7 - DD -4 ; Index = 16 Token = 8 - DD -12 ; Index = 16 Token = 9 - DD -21 ; Index = 16 Token = 10 - DD -29 ; Index = 16 Token = 11 - DD -38 ; Index = 16 Token = 12 - DD -46 ; Index = 16 Token = 13 - DD -55 ; Index = 16 Token = 14 - DD -63 ; Index = 16 Token = 15 - DD 4 ; Index = 17 Token = 0 - DD 13 ; Index = 17 Token = 1 - DD 22 ; Index = 17 Token = 2 - DD 31 ; Index = 17 Token = 3 - DD 41 ; Index = 17 Token = 4 - DD 50 ; Index = 17 Token = 5 - DD 59 ; Index = 17 Token = 6 - DD 68 ; Index = 17 Token = 7 - DD -4 ; Index = 17 Token = 8 - DD -13 ; Index = 17 Token = 9 - DD -22 ; Index = 17 Token = 10 - DD -31 ; Index = 17 Token = 11 - DD -41 ; Index = 17 Token = 12 - DD -50 ; Index = 17 Token = 13 - DD -59 ; Index = 17 Token = 14 - DD -68 ; Index = 17 Token = 15 - DD 5 ; Index = 18 Token = 0 - DD 15 ; Index = 18 Token = 1 - DD 25 ; Index = 18 Token = 2 - DD 35 ; Index = 18 Token = 3 - DD 46 ; Index = 18 Token = 4 - DD 56 ; Index = 18 Token = 5 - DD 66 ; Index = 18 Token = 6 - DD 76 ; Index = 18 Token = 7 - DD -5 ; Index = 18 Token = 8 - DD -15 ; Index = 18 Token = 9 - DD -25 ; Index = 18 Token = 10 - DD -35 ; Index = 18 Token = 11 - DD -46 ; Index = 18 Token = 12 - DD -56 ; Index = 18 Token = 13 - DD -66 ; Index = 18 Token = 14 - DD -76 ; Index = 18 Token = 15 - DD 5 ; Index = 19 Token = 0 - DD 16 ; Index = 19 Token = 1 - DD 27 ; Index = 19 Token = 2 - DD 38 ; Index = 19 Token = 3 - DD 50 ; Index = 19 Token = 4 - DD 61 ; Index = 19 Token = 5 - DD 72 ; Index = 19 Token = 6 - DD 83 ; Index = 19 Token = 7 - DD -5 ; Index = 19 Token = 8 - DD -16 ; Index = 19 Token = 9 - DD -27 ; Index = 19 Token = 10 - DD -38 ; Index = 19 Token = 11 - DD -50 ; Index = 19 Token = 12 - DD -61 ; Index = 19 Token = 13 - DD -72 ; Index = 19 Token = 14 - DD -83 ; Index = 19 Token = 15 - DD 6 ; Index = 20 Token = 0 - DD 18 ; Index = 20 Token = 1 - DD 31 ; Index = 20 Token = 2 - DD 43 ; Index = 20 Token = 3 - DD 56 ; Index = 20 Token = 4 - DD 68 ; Index = 20 Token = 5 - DD 81 ; Index = 20 Token = 6 - DD 93 ; Index = 20 Token = 7 - DD -6 ; Index = 20 Token = 8 - DD -18 ; Index = 20 Token = 9 - DD -31 ; Index = 20 Token = 10 - DD -43 ; Index = 20 Token = 11 - DD -56 ; Index = 20 Token = 12 - DD -68 ; Index = 20 Token = 13 - DD -81 ; Index = 20 Token = 14 - DD -93 ; Index = 20 Token = 15 - DD 6 ; Index = 21 Token = 0 - DD 19 ; Index = 21 Token = 1 - DD 33 ; Index = 21 Token = 2 - DD 46 ; Index = 21 Token = 3 - DD 61 ; Index = 21 Token = 4 - DD 74 ; Index = 21 Token = 5 - DD 88 ; Index = 21 Token = 6 - DD 101 ; Index = 21 Token = 7 - DD -6 ; Index = 21 Token = 8 - DD -19 ; Index = 21 Token = 9 - DD -33 ; Index = 21 Token = 10 - DD -46 ; Index = 21 Token = 11 - DD -61 ; Index = 21 Token = 12 - DD -74 ; Index = 21 Token = 13 - DD -88 ; Index = 21 Token = 14 - DD -101 ; Index = 21 Token = 15 - DD 7 ; Index = 22 Token = 0 - DD 22 ; Index = 22 Token = 1 - DD 37 ; Index = 22 Token = 2 - DD 52 ; Index = 22 Token = 3 - DD 67 ; Index = 22 Token = 4 - DD 82 ; Index = 22 Token = 5 - DD 97 ; Index = 22 Token = 6 - DD 112 ; Index = 22 Token = 7 - DD -7 ; Index = 22 Token = 8 - DD -22 ; Index = 22 Token = 9 - DD -37 ; Index = 22 Token = 10 - DD -52 ; Index = 22 Token = 11 - DD -67 ; Index = 22 Token = 12 - DD -82 ; Index = 22 Token = 13 - DD -97 ; Index = 22 Token = 14 - DD -112 ; Index = 22 Token = 15 - DD 8 ; Index = 23 Token = 0 - DD 24 ; Index = 23 Token = 1 - DD 41 ; Index = 23 Token = 2 - DD 57 ; Index = 23 Token = 3 - DD 74 ; Index = 23 Token = 4 - DD 90 ; Index = 23 Token = 5 - DD 107 ; Index = 23 Token = 6 - DD 123 ; Index = 23 Token = 7 - DD -8 ; Index = 23 Token = 8 - DD -24 ; Index = 23 Token = 9 - DD -41 ; Index = 23 Token = 10 - DD -57 ; Index = 23 Token = 11 - DD -74 ; Index = 23 Token = 12 - DD -90 ; Index = 23 Token = 13 - DD -107 ; Index = 23 Token = 14 - DD -123 ; Index = 23 Token = 15 - DD 9 ; Index = 24 Token = 0 - DD 27 ; Index = 24 Token = 1 - DD 45 ; Index = 24 Token = 2 - DD 63 ; Index = 24 Token = 3 - DD 82 ; Index = 24 Token = 4 - DD 100 ; Index = 24 Token = 5 - DD 118 ; Index = 24 Token = 6 - DD 136 ; Index = 24 Token = 7 - DD -9 ; Index = 24 Token = 8 - DD -27 ; Index = 24 Token = 9 - DD -45 ; Index = 24 Token = 10 - DD -63 ; Index = 24 Token = 11 - DD -82 ; Index = 24 Token = 12 - DD -100 ; Index = 24 Token = 13 - DD -118 ; Index = 24 Token = 14 - DD -136 ; Index = 24 Token = 15 - DD 10 ; Index = 25 Token = 0 - DD 30 ; Index = 25 Token = 1 - DD 50 ; Index = 25 Token = 2 - DD 70 ; Index = 25 Token = 3 - DD 90 ; Index = 25 Token = 4 - DD 110 ; Index = 25 Token = 5 - DD 130 ; Index = 25 Token = 6 - DD 150 ; Index = 25 Token = 7 - DD -10 ; Index = 25 Token = 8 - DD -30 ; Index = 25 Token = 9 - DD -50 ; Index = 25 Token = 10 - DD -70 ; Index = 25 Token = 11 - DD -90 ; Index = 25 Token = 12 - DD -110 ; Index = 25 Token = 13 - DD -130 ; Index = 25 Token = 14 - DD -150 ; Index = 25 Token = 15 - DD 11 ; Index = 26 Token = 0 - DD 33 ; Index = 26 Token = 1 - DD 55 ; Index = 26 Token = 2 - DD 77 ; Index = 26 Token = 3 - DD 99 ; Index = 26 Token = 4 - DD 121 ; Index = 26 Token = 5 - DD 143 ; Index = 26 Token = 6 - DD 165 ; Index = 26 Token = 7 - DD -11 ; Index = 26 Token = 8 - DD -33 ; Index = 26 Token = 9 - DD -55 ; Index = 26 Token = 10 - DD -77 ; Index = 26 Token = 11 - DD -99 ; Index = 26 Token = 12 - DD -121 ; Index = 26 Token = 13 - DD -143 ; Index = 26 Token = 14 - DD -165 ; Index = 26 Token = 15 - DD 12 ; Index = 27 Token = 0 - DD 36 ; Index = 27 Token = 1 - DD 60 ; Index = 27 Token = 2 - DD 84 ; Index = 27 Token = 3 - DD 109 ; Index = 27 Token = 4 - DD 133 ; Index = 27 Token = 5 - DD 157 ; Index = 27 Token = 6 - DD 181 ; Index = 27 Token = 7 - DD -12 ; Index = 27 Token = 8 - DD -36 ; Index = 27 Token = 9 - DD -60 ; Index = 27 Token = 10 - DD -84 ; Index = 27 Token = 11 - DD -109 ; Index = 27 Token = 12 - DD -133 ; Index = 27 Token = 13 - DD -157 ; Index = 27 Token = 14 - DD -181 ; Index = 27 Token = 15 - DD 13 ; Index = 28 Token = 0 - DD 39 ; Index = 28 Token = 1 - DD 66 ; Index = 28 Token = 2 - DD 92 ; Index = 28 Token = 3 - DD 120 ; Index = 28 Token = 4 - DD 146 ; Index = 28 Token = 5 - DD 173 ; Index = 28 Token = 6 - DD 199 ; Index = 28 Token = 7 - DD -13 ; Index = 28 Token = 8 - DD -39 ; Index = 28 Token = 9 - DD -66 ; Index = 28 Token = 10 - DD -92 ; Index = 28 Token = 11 - DD -120 ; Index = 28 Token = 12 - DD -146 ; Index = 28 Token = 13 - DD -173 ; Index = 28 Token = 14 - DD -199 ; Index = 28 Token = 15 - DD 14 ; Index = 29 Token = 0 - DD 43 ; Index = 29 Token = 1 - DD 73 ; Index = 29 Token = 2 - DD 102 ; Index = 29 Token = 3 - DD 132 ; Index = 29 Token = 4 - DD 161 ; Index = 29 Token = 5 - DD 191 ; Index = 29 Token = 6 - DD 220 ; Index = 29 Token = 7 - DD -14 ; Index = 29 Token = 8 - DD -43 ; Index = 29 Token = 9 - DD -73 ; Index = 29 Token = 10 - DD -102 ; Index = 29 Token = 11 - DD -132 ; Index = 29 Token = 12 - DD -161 ; Index = 29 Token = 13 - DD -191 ; Index = 29 Token = 14 - DD -220 ; Index = 29 Token = 15 - DD 16 ; Index = 30 Token = 0 - DD 48 ; Index = 30 Token = 1 - DD 81 ; Index = 30 Token = 2 - DD 113 ; Index = 30 Token = 3 - DD 146 ; Index = 30 Token = 4 - DD 178 ; Index = 30 Token = 5 - DD 211 ; Index = 30 Token = 6 - DD 243 ; Index = 30 Token = 7 - DD -16 ; Index = 30 Token = 8 - DD -48 ; Index = 30 Token = 9 - DD -81 ; Index = 30 Token = 10 - DD -113 ; Index = 30 Token = 11 - DD -146 ; Index = 30 Token = 12 - DD -178 ; Index = 30 Token = 13 - DD -211 ; Index = 30 Token = 14 - DD -243 ; Index = 30 Token = 15 - DD 17 ; Index = 31 Token = 0 - DD 52 ; Index = 31 Token = 1 - DD 88 ; Index = 31 Token = 2 - DD 123 ; Index = 31 Token = 3 - DD 160 ; Index = 31 Token = 4 - DD 195 ; Index = 31 Token = 5 - DD 231 ; Index = 31 Token = 6 - DD 266 ; Index = 31 Token = 7 - DD -17 ; Index = 31 Token = 8 - DD -52 ; Index = 31 Token = 9 - DD -88 ; Index = 31 Token = 10 - DD -123 ; Index = 31 Token = 11 - DD -160 ; Index = 31 Token = 12 - DD -195 ; Index = 31 Token = 13 - DD -231 ; Index = 31 Token = 14 - DD -266 ; Index = 31 Token = 15 - DD 19 ; Index = 32 Token = 0 - DD 58 ; Index = 32 Token = 1 - DD 97 ; Index = 32 Token = 2 - DD 136 ; Index = 32 Token = 3 - DD 176 ; Index = 32 Token = 4 - DD 215 ; Index = 32 Token = 5 - DD 254 ; Index = 32 Token = 6 - DD 293 ; Index = 32 Token = 7 - DD -19 ; Index = 32 Token = 8 - DD -58 ; Index = 32 Token = 9 - DD -97 ; Index = 32 Token = 10 - DD -136 ; Index = 32 Token = 11 - DD -176 ; Index = 32 Token = 12 - DD -215 ; Index = 32 Token = 13 - DD -254 ; Index = 32 Token = 14 - DD -293 ; Index = 32 Token = 15 - DD 21 ; Index = 33 Token = 0 - DD 64 ; Index = 33 Token = 1 - DD 107 ; Index = 33 Token = 2 - DD 150 ; Index = 33 Token = 3 - DD 194 ; Index = 33 Token = 4 - DD 237 ; Index = 33 Token = 5 - DD 280 ; Index = 33 Token = 6 - DD 323 ; Index = 33 Token = 7 - DD -21 ; Index = 33 Token = 8 - DD -64 ; Index = 33 Token = 9 - DD -107 ; Index = 33 Token = 10 - DD -150 ; Index = 33 Token = 11 - DD -194 ; Index = 33 Token = 12 - DD -237 ; Index = 33 Token = 13 - DD -280 ; Index = 33 Token = 14 - DD -323 ; Index = 33 Token = 15 - DD 23 ; Index = 34 Token = 0 - DD 70 ; Index = 34 Token = 1 - DD 118 ; Index = 34 Token = 2 - DD 165 ; Index = 34 Token = 3 - DD 213 ; Index = 34 Token = 4 - DD 260 ; Index = 34 Token = 5 - DD 308 ; Index = 34 Token = 6 - DD 355 ; Index = 34 Token = 7 - DD -23 ; Index = 34 Token = 8 - DD -70 ; Index = 34 Token = 9 - DD -118 ; Index = 34 Token = 10 - DD -165 ; Index = 34 Token = 11 - DD -213 ; Index = 34 Token = 12 - DD -260 ; Index = 34 Token = 13 - DD -308 ; Index = 34 Token = 14 - DD -355 ; Index = 34 Token = 15 - DD 26 ; Index = 35 Token = 0 - DD 78 ; Index = 35 Token = 1 - DD 130 ; Index = 35 Token = 2 - DD 182 ; Index = 35 Token = 3 - DD 235 ; Index = 35 Token = 4 - DD 287 ; Index = 35 Token = 5 - DD 339 ; Index = 35 Token = 6 - DD 391 ; Index = 35 Token = 7 - DD -26 ; Index = 35 Token = 8 - DD -78 ; Index = 35 Token = 9 - DD -130 ; Index = 35 Token = 10 - DD -182 ; Index = 35 Token = 11 - DD -235 ; Index = 35 Token = 12 - DD -287 ; Index = 35 Token = 13 - DD -339 ; Index = 35 Token = 14 - DD -391 ; Index = 35 Token = 15 - DD 28 ; Index = 36 Token = 0 - DD 85 ; Index = 36 Token = 1 - DD 143 ; Index = 36 Token = 2 - DD 200 ; Index = 36 Token = 3 - DD 258 ; Index = 36 Token = 4 - DD 315 ; Index = 36 Token = 5 - DD 373 ; Index = 36 Token = 6 - DD 430 ; Index = 36 Token = 7 - DD -28 ; Index = 36 Token = 8 - DD -85 ; Index = 36 Token = 9 - DD -143 ; Index = 36 Token = 10 - DD -200 ; Index = 36 Token = 11 - DD -258 ; Index = 36 Token = 12 - DD -315 ; Index = 36 Token = 13 - DD -373 ; Index = 36 Token = 14 - DD -430 ; Index = 36 Token = 15 - DD 31 ; Index = 37 Token = 0 - DD 94 ; Index = 37 Token = 1 - DD 157 ; Index = 37 Token = 2 - DD 220 ; Index = 37 Token = 3 - DD 284 ; Index = 37 Token = 4 - DD 347 ; Index = 37 Token = 5 - DD 410 ; Index = 37 Token = 6 - DD 473 ; Index = 37 Token = 7 - DD -31 ; Index = 37 Token = 8 - DD -94 ; Index = 37 Token = 9 - DD -157 ; Index = 37 Token = 10 - DD -220 ; Index = 37 Token = 11 - DD -284 ; Index = 37 Token = 12 - DD -347 ; Index = 37 Token = 13 - DD -410 ; Index = 37 Token = 14 - DD -473 ; Index = 37 Token = 15 - DD 34 ; Index = 38 Token = 0 - DD 103 ; Index = 38 Token = 1 - DD 173 ; Index = 38 Token = 2 - DD 242 ; Index = 38 Token = 3 - DD 313 ; Index = 38 Token = 4 - DD 382 ; Index = 38 Token = 5 - DD 452 ; Index = 38 Token = 6 - DD 521 ; Index = 38 Token = 7 - DD -34 ; Index = 38 Token = 8 - DD -103 ; Index = 38 Token = 9 - DD -173 ; Index = 38 Token = 10 - DD -242 ; Index = 38 Token = 11 - DD -313 ; Index = 38 Token = 12 - DD -382 ; Index = 38 Token = 13 - DD -452 ; Index = 38 Token = 14 - DD -521 ; Index = 38 Token = 15 - DD 38 ; Index = 39 Token = 0 - DD 114 ; Index = 39 Token = 1 - DD 191 ; Index = 39 Token = 2 - DD 267 ; Index = 39 Token = 3 - DD 345 ; Index = 39 Token = 4 - DD 421 ; Index = 39 Token = 5 - DD 498 ; Index = 39 Token = 6 - DD 574 ; Index = 39 Token = 7 - DD -38 ; Index = 39 Token = 8 - DD -114 ; Index = 39 Token = 9 - DD -191 ; Index = 39 Token = 10 - DD -267 ; Index = 39 Token = 11 - DD -345 ; Index = 39 Token = 12 - DD -421 ; Index = 39 Token = 13 - DD -498 ; Index = 39 Token = 14 - DD -574 ; Index = 39 Token = 15 - DD 42 ; Index = 40 Token = 0 - DD 126 ; Index = 40 Token = 1 - DD 210 ; Index = 40 Token = 2 - DD 294 ; Index = 40 Token = 3 - DD 379 ; Index = 40 Token = 4 - DD 463 ; Index = 40 Token = 5 - DD 547 ; Index = 40 Token = 6 - DD 631 ; Index = 40 Token = 7 - DD -42 ; Index = 40 Token = 8 - DD -126 ; Index = 40 Token = 9 - DD -210 ; Index = 40 Token = 10 - DD -294 ; Index = 40 Token = 11 - DD -379 ; Index = 40 Token = 12 - DD -463 ; Index = 40 Token = 13 - DD -547 ; Index = 40 Token = 14 - DD -631 ; Index = 40 Token = 15 - DD 46 ; Index = 41 Token = 0 - DD 138 ; Index = 41 Token = 1 - DD 231 ; Index = 41 Token = 2 - DD 323 ; Index = 41 Token = 3 - DD 417 ; Index = 41 Token = 4 - DD 509 ; Index = 41 Token = 5 - DD 602 ; Index = 41 Token = 6 - DD 694 ; Index = 41 Token = 7 - DD -46 ; Index = 41 Token = 8 - DD -138 ; Index = 41 Token = 9 - DD -231 ; Index = 41 Token = 10 - DD -323 ; Index = 41 Token = 11 - DD -417 ; Index = 41 Token = 12 - DD -509 ; Index = 41 Token = 13 - DD -602 ; Index = 41 Token = 14 - DD -694 ; Index = 41 Token = 15 - DD 51 ; Index = 42 Token = 0 - DD 153 ; Index = 42 Token = 1 - DD 255 ; Index = 42 Token = 2 - DD 357 ; Index = 42 Token = 3 - DD 459 ; Index = 42 Token = 4 - DD 561 ; Index = 42 Token = 5 - DD 663 ; Index = 42 Token = 6 - DD 765 ; Index = 42 Token = 7 - DD -51 ; Index = 42 Token = 8 - DD -153 ; Index = 42 Token = 9 - DD -255 ; Index = 42 Token = 10 - DD -357 ; Index = 42 Token = 11 - DD -459 ; Index = 42 Token = 12 - DD -561 ; Index = 42 Token = 13 - DD -663 ; Index = 42 Token = 14 - DD -765 ; Index = 42 Token = 15 - DD 56 ; Index = 43 Token = 0 - DD 168 ; Index = 43 Token = 1 - DD 280 ; Index = 43 Token = 2 - DD 392 ; Index = 43 Token = 3 - DD 505 ; Index = 43 Token = 4 - DD 617 ; Index = 43 Token = 5 - DD 729 ; Index = 43 Token = 6 - DD 841 ; Index = 43 Token = 7 - DD -56 ; Index = 43 Token = 8 - DD -168 ; Index = 43 Token = 9 - DD -280 ; Index = 43 Token = 10 - DD -392 ; Index = 43 Token = 11 - DD -505 ; Index = 43 Token = 12 - DD -617 ; Index = 43 Token = 13 - DD -729 ; Index = 43 Token = 14 - DD -841 ; Index = 43 Token = 15 - DD 61 ; Index = 44 Token = 0 - DD 184 ; Index = 44 Token = 1 - DD 308 ; Index = 44 Token = 2 - DD 431 ; Index = 44 Token = 3 - DD 555 ; Index = 44 Token = 4 - DD 678 ; Index = 44 Token = 5 - DD 802 ; Index = 44 Token = 6 - DD 925 ; Index = 44 Token = 7 - DD -61 ; Index = 44 Token = 8 - DD -184 ; Index = 44 Token = 9 - DD -308 ; Index = 44 Token = 10 - DD -431 ; Index = 44 Token = 11 - DD -555 ; Index = 44 Token = 12 - DD -678 ; Index = 44 Token = 13 - DD -802 ; Index = 44 Token = 14 - DD -925 ; Index = 44 Token = 15 - DD 68 ; Index = 45 Token = 0 - DD 204 ; Index = 45 Token = 1 - DD 340 ; Index = 45 Token = 2 - DD 476 ; Index = 45 Token = 3 - DD 612 ; Index = 45 Token = 4 - DD 748 ; Index = 45 Token = 5 - DD 884 ; Index = 45 Token = 6 - DD 1020 ; Index = 45 Token = 7 - DD -68 ; Index = 45 Token = 8 - DD -204 ; Index = 45 Token = 9 - DD -340 ; Index = 45 Token = 10 - DD -476 ; Index = 45 Token = 11 - DD -612 ; Index = 45 Token = 12 - DD -748 ; Index = 45 Token = 13 - DD -884 ; Index = 45 Token = 14 - DD -1020 ; Index = 45 Token = 15 - DD 74 ; Index = 46 Token = 0 - DD 223 ; Index = 46 Token = 1 - DD 373 ; Index = 46 Token = 2 - DD 522 ; Index = 46 Token = 3 - DD 672 ; Index = 46 Token = 4 - DD 821 ; Index = 46 Token = 5 - DD 971 ; Index = 46 Token = 6 - DD 1120 ; Index = 46 Token = 7 - DD -74 ; Index = 46 Token = 8 - DD -223 ; Index = 46 Token = 9 - DD -373 ; Index = 46 Token = 10 - DD -522 ; Index = 46 Token = 11 - DD -672 ; Index = 46 Token = 12 - DD -821 ; Index = 46 Token = 13 - DD -971 ; Index = 46 Token = 14 - DD -1120 ; Index = 46 Token = 15 - DD 82 ; Index = 47 Token = 0 - DD 246 ; Index = 47 Token = 1 - DD 411 ; Index = 47 Token = 2 - DD 575 ; Index = 47 Token = 3 - DD 740 ; Index = 47 Token = 4 - DD 904 ; Index = 47 Token = 5 - DD 1069 ; Index = 47 Token = 6 - DD 1233 ; Index = 47 Token = 7 - DD -82 ; Index = 47 Token = 8 - DD -246 ; Index = 47 Token = 9 - DD -411 ; Index = 47 Token = 10 - DD -575 ; Index = 47 Token = 11 - DD -740 ; Index = 47 Token = 12 - DD -904 ; Index = 47 Token = 13 - DD -1069 ; Index = 47 Token = 14 - DD -1233 ; Index = 47 Token = 15 - DD 90 ; Index = 48 Token = 0 - DD 271 ; Index = 48 Token = 1 - DD 452 ; Index = 48 Token = 2 - DD 633 ; Index = 48 Token = 3 - DD 814 ; Index = 48 Token = 4 - DD 995 ; Index = 48 Token = 5 - DD 1176 ; Index = 48 Token = 6 - DD 1357 ; Index = 48 Token = 7 - DD -90 ; Index = 48 Token = 8 - DD -271 ; Index = 48 Token = 9 - DD -452 ; Index = 48 Token = 10 - DD -633 ; Index = 48 Token = 11 - DD -814 ; Index = 48 Token = 12 - DD -995 ; Index = 48 Token = 13 - DD -1176 ; Index = 48 Token = 14 - DD -1357 ; Index = 48 Token = 15 - DD 99 ; Index = 49 Token = 0 - DD 298 ; Index = 49 Token = 1 - DD 497 ; Index = 49 Token = 2 - DD 696 ; Index = 49 Token = 3 - DD 895 ; Index = 49 Token = 4 - DD 1094 ; Index = 49 Token = 5 - DD 1293 ; Index = 49 Token = 6 - DD 1492 ; Index = 49 Token = 7 - DD -99 ; Index = 49 Token = 8 - DD -298 ; Index = 49 Token = 9 - DD -497 ; Index = 49 Token = 10 - DD -696 ; Index = 49 Token = 11 - DD -895 ; Index = 49 Token = 12 - DD -1094 ; Index = 49 Token = 13 - DD -1293 ; Index = 49 Token = 14 - DD -1492 ; Index = 49 Token = 15 - DD 109 ; Index = 50 Token = 0 - DD 328 ; Index = 50 Token = 1 - DD 547 ; Index = 50 Token = 2 - DD 766 ; Index = 50 Token = 3 - DD 985 ; Index = 50 Token = 4 - DD 1204 ; Index = 50 Token = 5 - DD 1423 ; Index = 50 Token = 6 - DD 1642 ; Index = 50 Token = 7 - DD -109 ; Index = 50 Token = 8 - DD -328 ; Index = 50 Token = 9 - DD -547 ; Index = 50 Token = 10 - DD -766 ; Index = 50 Token = 11 - DD -985 ; Index = 50 Token = 12 - DD -1204 ; Index = 50 Token = 13 - DD -1423 ; Index = 50 Token = 14 - DD -1642 ; Index = 50 Token = 15 - DD 120 ; Index = 51 Token = 0 - DD 360 ; Index = 51 Token = 1 - DD 601 ; Index = 51 Token = 2 - DD 841 ; Index = 51 Token = 3 - DD 1083 ; Index = 51 Token = 4 - DD 1323 ; Index = 51 Token = 5 - DD 1564 ; Index = 51 Token = 6 - DD 1804 ; Index = 51 Token = 7 - DD -120 ; Index = 51 Token = 8 - DD -360 ; Index = 51 Token = 9 - DD -601 ; Index = 51 Token = 10 - DD -841 ; Index = 51 Token = 11 - DD -1083 ; Index = 51 Token = 12 - DD -1323 ; Index = 51 Token = 13 - DD -1564 ; Index = 51 Token = 14 - DD -1804 ; Index = 51 Token = 15 - DD 132 ; Index = 52 Token = 0 - DD 397 ; Index = 52 Token = 1 - DD 662 ; Index = 52 Token = 2 - DD 927 ; Index = 52 Token = 3 - DD 1192 ; Index = 52 Token = 4 - DD 1457 ; Index = 52 Token = 5 - DD 1722 ; Index = 52 Token = 6 - DD 1987 ; Index = 52 Token = 7 - DD -132 ; Index = 52 Token = 8 - DD -397 ; Index = 52 Token = 9 - DD -662 ; Index = 52 Token = 10 - DD -927 ; Index = 52 Token = 11 - DD -1192 ; Index = 52 Token = 12 - DD -1457 ; Index = 52 Token = 13 - DD -1722 ; Index = 52 Token = 14 - DD -1987 ; Index = 52 Token = 15 - DD 145 ; Index = 53 Token = 0 - DD 436 ; Index = 53 Token = 1 - DD 728 ; Index = 53 Token = 2 - DD 1019 ; Index = 53 Token = 3 - DD 1311 ; Index = 53 Token = 4 - DD 1602 ; Index = 53 Token = 5 - DD 1894 ; Index = 53 Token = 6 - DD 2185 ; Index = 53 Token = 7 - DD -145 ; Index = 53 Token = 8 - DD -436 ; Index = 53 Token = 9 - DD -728 ; Index = 53 Token = 10 - DD -1019 ; Index = 53 Token = 11 - DD -1311 ; Index = 53 Token = 12 - DD -1602 ; Index = 53 Token = 13 - DD -1894 ; Index = 53 Token = 14 - DD -2185 ; Index = 53 Token = 15 - DD 160 ; Index = 54 Token = 0 - DD 480 ; Index = 54 Token = 1 - DD 801 ; Index = 54 Token = 2 - DD 1121 ; Index = 54 Token = 3 - DD 1442 ; Index = 54 Token = 4 - DD 1762 ; Index = 54 Token = 5 - DD 2083 ; Index = 54 Token = 6 - DD 2403 ; Index = 54 Token = 7 - DD -160 ; Index = 54 Token = 8 - DD -480 ; Index = 54 Token = 9 - DD -801 ; Index = 54 Token = 10 - DD -1121 ; Index = 54 Token = 11 - DD -1442 ; Index = 54 Token = 12 - DD -1762 ; Index = 54 Token = 13 - DD -2083 ; Index = 54 Token = 14 - DD -2403 ; Index = 54 Token = 15 - DD 176 ; Index = 55 Token = 0 - DD 528 ; Index = 55 Token = 1 - DD 881 ; Index = 55 Token = 2 - DD 1233 ; Index = 55 Token = 3 - DD 1587 ; Index = 55 Token = 4 - DD 1939 ; Index = 55 Token = 5 - DD 2292 ; Index = 55 Token = 6 - DD 2644 ; Index = 55 Token = 7 - DD -176 ; Index = 55 Token = 8 - DD -528 ; Index = 55 Token = 9 - DD -881 ; Index = 55 Token = 10 - DD -1233 ; Index = 55 Token = 11 - DD -1587 ; Index = 55 Token = 12 - DD -1939 ; Index = 55 Token = 13 - DD -2292 ; Index = 55 Token = 14 - DD -2644 ; Index = 55 Token = 15 - DD 194 ; Index = 56 Token = 0 - DD 582 ; Index = 56 Token = 1 - DD 970 ; Index = 56 Token = 2 - DD 1358 ; Index = 56 Token = 3 - DD 1746 ; Index = 56 Token = 4 - DD 2134 ; Index = 56 Token = 5 - DD 2522 ; Index = 56 Token = 6 - DD 2910 ; Index = 56 Token = 7 - DD -194 ; Index = 56 Token = 8 - DD -582 ; Index = 56 Token = 9 - DD -970 ; Index = 56 Token = 10 - DD -1358 ; Index = 56 Token = 11 - DD -1746 ; Index = 56 Token = 12 - DD -2134 ; Index = 56 Token = 13 - DD -2522 ; Index = 56 Token = 14 - DD -2910 ; Index = 56 Token = 15 - DD 213 ; Index = 57 Token = 0 - DD 639 ; Index = 57 Token = 1 - DD 1066 ; Index = 57 Token = 2 - DD 1492 ; Index = 57 Token = 3 - DD 1920 ; Index = 57 Token = 4 - DD 2346 ; Index = 57 Token = 5 - DD 2773 ; Index = 57 Token = 6 - DD 3199 ; Index = 57 Token = 7 - DD -213 ; Index = 57 Token = 8 - DD -639 ; Index = 57 Token = 9 - DD -1066 ; Index = 57 Token = 10 - DD -1492 ; Index = 57 Token = 11 - DD -1920 ; Index = 57 Token = 12 - DD -2346 ; Index = 57 Token = 13 - DD -2773 ; Index = 57 Token = 14 - DD -3199 ; Index = 57 Token = 15 - DD 234 ; Index = 58 Token = 0 - DD 703 ; Index = 58 Token = 1 - DD 1173 ; Index = 58 Token = 2 - DD 1642 ; Index = 58 Token = 3 - DD 2112 ; Index = 58 Token = 4 - DD 2581 ; Index = 58 Token = 5 - DD 3051 ; Index = 58 Token = 6 - DD 3520 ; Index = 58 Token = 7 - DD -234 ; Index = 58 Token = 8 - DD -703 ; Index = 58 Token = 9 - DD -1173 ; Index = 58 Token = 10 - DD -1642 ; Index = 58 Token = 11 - DD -2112 ; Index = 58 Token = 12 - DD -2581 ; Index = 58 Token = 13 - DD -3051 ; Index = 58 Token = 14 - DD -3520 ; Index = 58 Token = 15 - DD 258 ; Index = 59 Token = 0 - DD 774 ; Index = 59 Token = 1 - DD 1291 ; Index = 59 Token = 2 - DD 1807 ; Index = 59 Token = 3 - DD 2324 ; Index = 59 Token = 4 - DD 2840 ; Index = 59 Token = 5 - DD 3357 ; Index = 59 Token = 6 - DD 3873 ; Index = 59 Token = 7 - DD -258 ; Index = 59 Token = 8 - DD -774 ; Index = 59 Token = 9 - DD -1291 ; Index = 59 Token = 10 - DD -1807 ; Index = 59 Token = 11 - DD -2324 ; Index = 59 Token = 12 - DD -2840 ; Index = 59 Token = 13 - DD -3357 ; Index = 59 Token = 14 - DD -3873 ; Index = 59 Token = 15 - DD 284 ; Index = 60 Token = 0 - DD 852 ; Index = 60 Token = 1 - DD 1420 ; Index = 60 Token = 2 - DD 1988 ; Index = 60 Token = 3 - DD 2556 ; Index = 60 Token = 4 - DD 3124 ; Index = 60 Token = 5 - DD 3692 ; Index = 60 Token = 6 - DD 4260 ; Index = 60 Token = 7 - DD -284 ; Index = 60 Token = 8 - DD -852 ; Index = 60 Token = 9 - DD -1420 ; Index = 60 Token = 10 - DD -1988 ; Index = 60 Token = 11 - DD -2556 ; Index = 60 Token = 12 - DD -3124 ; Index = 60 Token = 13 - DD -3692 ; Index = 60 Token = 14 - DD -4260 ; Index = 60 Token = 15 - DD 312 ; Index = 61 Token = 0 - DD 936 ; Index = 61 Token = 1 - DD 1561 ; Index = 61 Token = 2 - DD 2185 ; Index = 61 Token = 3 - DD 2811 ; Index = 61 Token = 4 - DD 3435 ; Index = 61 Token = 5 - DD 4060 ; Index = 61 Token = 6 - DD 4684 ; Index = 61 Token = 7 - DD -312 ; Index = 61 Token = 8 - DD -936 ; Index = 61 Token = 9 - DD -1561 ; Index = 61 Token = 10 - DD -2185 ; Index = 61 Token = 11 - DD -2811 ; Index = 61 Token = 12 - DD -3435 ; Index = 61 Token = 13 - DD -4060 ; Index = 61 Token = 14 - DD -4684 ; Index = 61 Token = 15 - DD 343 ; Index = 62 Token = 0 - DD 1030 ; Index = 62 Token = 1 - DD 1717 ; Index = 62 Token = 2 - DD 2404 ; Index = 62 Token = 3 - DD 3092 ; Index = 62 Token = 4 - DD 3779 ; Index = 62 Token = 5 - DD 4466 ; Index = 62 Token = 6 - DD 5153 ; Index = 62 Token = 7 - DD -343 ; Index = 62 Token = 8 - DD -1030 ; Index = 62 Token = 9 - DD -1717 ; Index = 62 Token = 10 - DD -2404 ; Index = 62 Token = 11 - DD -3092 ; Index = 62 Token = 12 - DD -3779 ; Index = 62 Token = 13 - DD -4466 ; Index = 62 Token = 14 - DD -5153 ; Index = 62 Token = 15 - DD 378 ; Index = 63 Token = 0 - DD 1134 ; Index = 63 Token = 1 - DD 1890 ; Index = 63 Token = 2 - DD 2646 ; Index = 63 Token = 3 - DD 3402 ; Index = 63 Token = 4 - DD 4158 ; Index = 63 Token = 5 - DD 4914 ; Index = 63 Token = 6 - DD 5670 ; Index = 63 Token = 7 - DD -378 ; Index = 63 Token = 8 - DD -1134 ; Index = 63 Token = 9 - DD -1890 ; Index = 63 Token = 10 - DD -2646 ; Index = 63 Token = 11 - DD -3402 ; Index = 63 Token = 12 - DD -4158 ; Index = 63 Token = 13 - DD -4914 ; Index = 63 Token = 14 - DD -5670 ; Index = 63 Token = 15 - DD 415 ; Index = 64 Token = 0 - DD 1246 ; Index = 64 Token = 1 - DD 2078 ; Index = 64 Token = 2 - DD 2909 ; Index = 64 Token = 3 - DD 3742 ; Index = 64 Token = 4 - DD 4573 ; Index = 64 Token = 5 - DD 5405 ; Index = 64 Token = 6 - DD 6236 ; Index = 64 Token = 7 - DD -415 ; Index = 64 Token = 8 - DD -1246 ; Index = 64 Token = 9 - DD -2078 ; Index = 64 Token = 10 - DD -2909 ; Index = 64 Token = 11 - DD -3742 ; Index = 64 Token = 12 - DD -4573 ; Index = 64 Token = 13 - DD -5405 ; Index = 64 Token = 14 - DD -6236 ; Index = 64 Token = 15 - DD 457 ; Index = 65 Token = 0 - DD 1372 ; Index = 65 Token = 1 - DD 2287 ; Index = 65 Token = 2 - DD 3202 ; Index = 65 Token = 3 - DD 4117 ; Index = 65 Token = 4 - DD 5032 ; Index = 65 Token = 5 - DD 5947 ; Index = 65 Token = 6 - DD 6862 ; Index = 65 Token = 7 - DD -457 ; Index = 65 Token = 8 - DD -1372 ; Index = 65 Token = 9 - DD -2287 ; Index = 65 Token = 10 - DD -3202 ; Index = 65 Token = 11 - DD -4117 ; Index = 65 Token = 12 - DD -5032 ; Index = 65 Token = 13 - DD -5947 ; Index = 65 Token = 14 - DD -6862 ; Index = 65 Token = 15 - DD 503 ; Index = 66 Token = 0 - DD 1509 ; Index = 66 Token = 1 - DD 2516 ; Index = 66 Token = 2 - DD 3522 ; Index = 66 Token = 3 - DD 4529 ; Index = 66 Token = 4 - DD 5535 ; Index = 66 Token = 5 - DD 6542 ; Index = 66 Token = 6 - DD 7548 ; Index = 66 Token = 7 - DD -503 ; Index = 66 Token = 8 - DD -1509 ; Index = 66 Token = 9 - DD -2516 ; Index = 66 Token = 10 - DD -3522 ; Index = 66 Token = 11 - DD -4529 ; Index = 66 Token = 12 - DD -5535 ; Index = 66 Token = 13 - DD -6542 ; Index = 66 Token = 14 - DD -7548 ; Index = 66 Token = 15 - DD 553 ; Index = 67 Token = 0 - DD 1660 ; Index = 67 Token = 1 - DD 2767 ; Index = 67 Token = 2 - DD 3874 ; Index = 67 Token = 3 - DD 4981 ; Index = 67 Token = 4 - DD 6088 ; Index = 67 Token = 5 - DD 7195 ; Index = 67 Token = 6 - DD 8302 ; Index = 67 Token = 7 - DD -553 ; Index = 67 Token = 8 - DD -1660 ; Index = 67 Token = 9 - DD -2767 ; Index = 67 Token = 10 - DD -3874 ; Index = 67 Token = 11 - DD -4981 ; Index = 67 Token = 12 - DD -6088 ; Index = 67 Token = 13 - DD -7195 ; Index = 67 Token = 14 - DD -8302 ; Index = 67 Token = 15 - DD 608 ; Index = 68 Token = 0 - DD 1825 ; Index = 68 Token = 1 - DD 3043 ; Index = 68 Token = 2 - DD 4260 ; Index = 68 Token = 3 - DD 5479 ; Index = 68 Token = 4 - DD 6696 ; Index = 68 Token = 5 - DD 7914 ; Index = 68 Token = 6 - DD 9131 ; Index = 68 Token = 7 - DD -608 ; Index = 68 Token = 8 - DD -1825 ; Index = 68 Token = 9 - DD -3043 ; Index = 68 Token = 10 - DD -4260 ; Index = 68 Token = 11 - DD -5479 ; Index = 68 Token = 12 - DD -6696 ; Index = 68 Token = 13 - DD -7914 ; Index = 68 Token = 14 - DD -9131 ; Index = 68 Token = 15 - DD 669 ; Index = 69 Token = 0 - DD 2008 ; Index = 69 Token = 1 - DD 3348 ; Index = 69 Token = 2 - DD 4687 ; Index = 69 Token = 3 - DD 6027 ; Index = 69 Token = 4 - DD 7366 ; Index = 69 Token = 5 - DD 8706 ; Index = 69 Token = 6 - DD 10045 ; Index = 69 Token = 7 - DD -669 ; Index = 69 Token = 8 - DD -2008 ; Index = 69 Token = 9 - DD -3348 ; Index = 69 Token = 10 - DD -4687 ; Index = 69 Token = 11 - DD -6027 ; Index = 69 Token = 12 - DD -7366 ; Index = 69 Token = 13 - DD -8706 ; Index = 69 Token = 14 - DD -10045 ; Index = 69 Token = 15 - DD 736 ; Index = 70 Token = 0 - DD 2209 ; Index = 70 Token = 1 - DD 3683 ; Index = 70 Token = 2 - DD 5156 ; Index = 70 Token = 3 - DD 6630 ; Index = 70 Token = 4 - DD 8103 ; Index = 70 Token = 5 - DD 9577 ; Index = 70 Token = 6 - DD 11050 ; Index = 70 Token = 7 - DD -736 ; Index = 70 Token = 8 - DD -2209 ; Index = 70 Token = 9 - DD -3683 ; Index = 70 Token = 10 - DD -5156 ; Index = 70 Token = 11 - DD -6630 ; Index = 70 Token = 12 - DD -8103 ; Index = 70 Token = 13 - DD -9577 ; Index = 70 Token = 14 - DD -11050 ; Index = 70 Token = 15 - DD 810 ; Index = 71 Token = 0 - DD 2431 ; Index = 71 Token = 1 - DD 4052 ; Index = 71 Token = 2 - DD 5673 ; Index = 71 Token = 3 - DD 7294 ; Index = 71 Token = 4 - DD 8915 ; Index = 71 Token = 5 - DD 10536 ; Index = 71 Token = 6 - DD 12157 ; Index = 71 Token = 7 - DD -810 ; Index = 71 Token = 8 - DD -2431 ; Index = 71 Token = 9 - DD -4052 ; Index = 71 Token = 10 - DD -5673 ; Index = 71 Token = 11 - DD -7294 ; Index = 71 Token = 12 - DD -8915 ; Index = 71 Token = 13 - DD -10536 ; Index = 71 Token = 14 - DD -12157 ; Index = 71 Token = 15 - DD 891 ; Index = 72 Token = 0 - DD 2674 ; Index = 72 Token = 1 - DD 4457 ; Index = 72 Token = 2 - DD 6240 ; Index = 72 Token = 3 - DD 8023 ; Index = 72 Token = 4 - DD 9806 ; Index = 72 Token = 5 - DD 11589 ; Index = 72 Token = 6 - DD 13372 ; Index = 72 Token = 7 - DD -891 ; Index = 72 Token = 8 - DD -2674 ; Index = 72 Token = 9 - DD -4457 ; Index = 72 Token = 10 - DD -6240 ; Index = 72 Token = 11 - DD -8023 ; Index = 72 Token = 12 - DD -9806 ; Index = 72 Token = 13 - DD -11589 ; Index = 72 Token = 14 - DD -13372 ; Index = 72 Token = 15 - DD 980 ; Index = 73 Token = 0 - DD 2941 ; Index = 73 Token = 1 - DD 4902 ; Index = 73 Token = 2 - DD 6863 ; Index = 73 Token = 3 - DD 8825 ; Index = 73 Token = 4 - DD 10786 ; Index = 73 Token = 5 - DD 12747 ; Index = 73 Token = 6 - DD 14708 ; Index = 73 Token = 7 - DD -980 ; Index = 73 Token = 8 - DD -2941 ; Index = 73 Token = 9 - DD -4902 ; Index = 73 Token = 10 - DD -6863 ; Index = 73 Token = 11 - DD -8825 ; Index = 73 Token = 12 - DD -10786 ; Index = 73 Token = 13 - DD -12747 ; Index = 73 Token = 14 - DD -14708 ; Index = 73 Token = 15 - DD 1078 ; Index = 74 Token = 0 - DD 3235 ; Index = 74 Token = 1 - DD 5393 ; Index = 74 Token = 2 - DD 7550 ; Index = 74 Token = 3 - DD 9708 ; Index = 74 Token = 4 - DD 11865 ; Index = 74 Token = 5 - DD 14023 ; Index = 74 Token = 6 - DD 16180 ; Index = 74 Token = 7 - DD -1078 ; Index = 74 Token = 8 - DD -3235 ; Index = 74 Token = 9 - DD -5393 ; Index = 74 Token = 10 - DD -7550 ; Index = 74 Token = 11 - DD -9708 ; Index = 74 Token = 12 - DD -11865 ; Index = 74 Token = 13 - DD -14023 ; Index = 74 Token = 14 - DD -16180 ; Index = 74 Token = 15 - DD 1186 ; Index = 75 Token = 0 - DD 3559 ; Index = 75 Token = 1 - DD 5932 ; Index = 75 Token = 2 - DD 8305 ; Index = 75 Token = 3 - DD 10679 ; Index = 75 Token = 4 - DD 13052 ; Index = 75 Token = 5 - DD 15425 ; Index = 75 Token = 6 - DD 17798 ; Index = 75 Token = 7 - DD -1186 ; Index = 75 Token = 8 - DD -3559 ; Index = 75 Token = 9 - DD -5932 ; Index = 75 Token = 10 - DD -8305 ; Index = 75 Token = 11 - DD -10679 ; Index = 75 Token = 12 - DD -13052 ; Index = 75 Token = 13 - DD -15425 ; Index = 75 Token = 14 - DD -17798 ; Index = 75 Token = 15 - DD 1305 ; Index = 76 Token = 0 - DD 3915 ; Index = 76 Token = 1 - DD 6526 ; Index = 76 Token = 2 - DD 9136 ; Index = 76 Token = 3 - DD 11747 ; Index = 76 Token = 4 - DD 14357 ; Index = 76 Token = 5 - DD 16968 ; Index = 76 Token = 6 - DD 19578 ; Index = 76 Token = 7 - DD -1305 ; Index = 76 Token = 8 - DD -3915 ; Index = 76 Token = 9 - DD -6526 ; Index = 76 Token = 10 - DD -9136 ; Index = 76 Token = 11 - DD -11747 ; Index = 76 Token = 12 - DD -14357 ; Index = 76 Token = 13 - DD -16968 ; Index = 76 Token = 14 - DD -19578 ; Index = 76 Token = 15 - DD 1435 ; Index = 77 Token = 0 - DD 4306 ; Index = 77 Token = 1 - DD 7178 ; Index = 77 Token = 2 - DD 10049 ; Index = 77 Token = 3 - DD 12922 ; Index = 77 Token = 4 - DD 15793 ; Index = 77 Token = 5 - DD 18665 ; Index = 77 Token = 6 - DD 21536 ; Index = 77 Token = 7 - DD -1435 ; Index = 77 Token = 8 - DD -4306 ; Index = 77 Token = 9 - DD -7178 ; Index = 77 Token = 10 - DD -10049 ; Index = 77 Token = 11 - DD -12922 ; Index = 77 Token = 12 - DD -15793 ; Index = 77 Token = 13 - DD -18665 ; Index = 77 Token = 14 - DD -21536 ; Index = 77 Token = 15 - DD 1579 ; Index = 78 Token = 0 - DD 4737 ; Index = 78 Token = 1 - DD 7896 ; Index = 78 Token = 2 - DD 11054 ; Index = 78 Token = 3 - DD 14214 ; Index = 78 Token = 4 - DD 17372 ; Index = 78 Token = 5 - DD 20531 ; Index = 78 Token = 6 - DD 23689 ; Index = 78 Token = 7 - DD -1579 ; Index = 78 Token = 8 - DD -4737 ; Index = 78 Token = 9 - DD -7896 ; Index = 78 Token = 10 - DD -11054 ; Index = 78 Token = 11 - DD -14214 ; Index = 78 Token = 12 - DD -17372 ; Index = 78 Token = 13 - DD -20531 ; Index = 78 Token = 14 - DD -23689 ; Index = 78 Token = 15 - DD 1737 ; Index = 79 Token = 0 - DD 5211 ; Index = 79 Token = 1 - DD 8686 ; Index = 79 Token = 2 - DD 12160 ; Index = 79 Token = 3 - DD 15636 ; Index = 79 Token = 4 - DD 19110 ; Index = 79 Token = 5 - DD 22585 ; Index = 79 Token = 6 - DD 26059 ; Index = 79 Token = 7 - DD -1737 ; Index = 79 Token = 8 - DD -5211 ; Index = 79 Token = 9 - DD -8686 ; Index = 79 Token = 10 - DD -12160 ; Index = 79 Token = 11 - DD -15636 ; Index = 79 Token = 12 - DD -19110 ; Index = 79 Token = 13 - DD -22585 ; Index = 79 Token = 14 - DD -26059 ; Index = 79 Token = 15 - DD 1911 ; Index = 80 Token = 0 - DD 5733 ; Index = 80 Token = 1 - DD 9555 ; Index = 80 Token = 2 - DD 13377 ; Index = 80 Token = 3 - DD 17200 ; Index = 80 Token = 4 - DD 21022 ; Index = 80 Token = 5 - DD 24844 ; Index = 80 Token = 6 - DD 28666 ; Index = 80 Token = 7 - DD -1911 ; Index = 80 Token = 8 - DD -5733 ; Index = 80 Token = 9 - DD -9555 ; Index = 80 Token = 10 - DD -13377 ; Index = 80 Token = 11 - DD -17200 ; Index = 80 Token = 12 - DD -21022 ; Index = 80 Token = 13 - DD -24844 ; Index = 80 Token = 14 - DD -28666 ; Index = 80 Token = 15 - DD 2102 ; Index = 81 Token = 0 - DD 6306 ; Index = 81 Token = 1 - DD 10511 ; Index = 81 Token = 2 - DD 14715 ; Index = 81 Token = 3 - DD 18920 ; Index = 81 Token = 4 - DD 23124 ; Index = 81 Token = 5 - DD 27329 ; Index = 81 Token = 6 - DD 31533 ; Index = 81 Token = 7 - DD -2102 ; Index = 81 Token = 8 - DD -6306 ; Index = 81 Token = 9 - DD -10511 ; Index = 81 Token = 10 - DD -14715 ; Index = 81 Token = 11 - DD -18920 ; Index = 81 Token = 12 - DD -23124 ; Index = 81 Token = 13 - DD -27329 ; Index = 81 Token = 14 - DD -31533 ; Index = 81 Token = 15 - DD 2312 ; Index = 82 Token = 0 - DD 6937 ; Index = 82 Token = 1 - DD 11562 ; Index = 82 Token = 2 - DD 16187 ; Index = 82 Token = 3 - DD 20812 ; Index = 82 Token = 4 - DD 25437 ; Index = 82 Token = 5 - DD 30062 ; Index = 82 Token = 6 - DD 34687 ; Index = 82 Token = 7 - DD -2312 ; Index = 82 Token = 8 - DD -6937 ; Index = 82 Token = 9 - DD -11562 ; Index = 82 Token = 10 - DD -16187 ; Index = 82 Token = 11 - DD -20812 ; Index = 82 Token = 12 - DD -25437 ; Index = 82 Token = 13 - DD -30062 ; Index = 82 Token = 14 - DD -34687 ; Index = 82 Token = 15 - DD 2543 ; Index = 83 Token = 0 - DD 7630 ; Index = 83 Token = 1 - DD 12718 ; Index = 83 Token = 2 - DD 17805 ; Index = 83 Token = 3 - DD 22893 ; Index = 83 Token = 4 - DD 27980 ; Index = 83 Token = 5 - DD 33068 ; Index = 83 Token = 6 - DD 38155 ; Index = 83 Token = 7 - DD -2543 ; Index = 83 Token = 8 - DD -7630 ; Index = 83 Token = 9 - DD -12718 ; Index = 83 Token = 10 - DD -17805 ; Index = 83 Token = 11 - DD -22893 ; Index = 83 Token = 12 - DD -27980 ; Index = 83 Token = 13 - DD -33068 ; Index = 83 Token = 14 - DD -38155 ; Index = 83 Token = 15 - DD 2798 ; Index = 84 Token = 0 - DD 8394 ; Index = 84 Token = 1 - DD 13990 ; Index = 84 Token = 2 - DD 19586 ; Index = 84 Token = 3 - DD 25183 ; Index = 84 Token = 4 - DD 30779 ; Index = 84 Token = 5 - DD 36375 ; Index = 84 Token = 6 - DD 41971 ; Index = 84 Token = 7 - DD -2798 ; Index = 84 Token = 8 - DD -8394 ; Index = 84 Token = 9 - DD -13990 ; Index = 84 Token = 10 - DD -19586 ; Index = 84 Token = 11 - DD -25183 ; Index = 84 Token = 12 - DD -30779 ; Index = 84 Token = 13 - DD -36375 ; Index = 84 Token = 14 - DD -41971 ; Index = 84 Token = 15 - DD 3077 ; Index = 85 Token = 0 - DD 9232 ; Index = 85 Token = 1 - DD 15388 ; Index = 85 Token = 2 - DD 21543 ; Index = 85 Token = 3 - DD 27700 ; Index = 85 Token = 4 - DD 33855 ; Index = 85 Token = 5 - DD 40011 ; Index = 85 Token = 6 - DD 46166 ; Index = 85 Token = 7 - DD -3077 ; Index = 85 Token = 8 - DD -9232 ; Index = 85 Token = 9 - DD -15388 ; Index = 85 Token = 10 - DD -21543 ; Index = 85 Token = 11 - DD -27700 ; Index = 85 Token = 12 - DD -33855 ; Index = 85 Token = 13 - DD -40011 ; Index = 85 Token = 14 - DD -46166 ; Index = 85 Token = 15 - DD 3385 ; Index = 86 Token = 0 - DD 10156 ; Index = 86 Token = 1 - DD 16928 ; Index = 86 Token = 2 - DD 23699 ; Index = 86 Token = 3 - DD 30471 ; Index = 86 Token = 4 - DD 37242 ; Index = 86 Token = 5 - DD 44014 ; Index = 86 Token = 6 - DD 50785 ; Index = 86 Token = 7 - DD -3385 ; Index = 86 Token = 8 - DD -10156 ; Index = 86 Token = 9 - DD -16928 ; Index = 86 Token = 10 - DD -23699 ; Index = 86 Token = 11 - DD -30471 ; Index = 86 Token = 12 - DD -37242 ; Index = 86 Token = 13 - DD -44014 ; Index = 86 Token = 14 - DD -50785 ; Index = 86 Token = 15 - DD 3724 ; Index = 87 Token = 0 - DD 11172 ; Index = 87 Token = 1 - DD 18621 ; Index = 87 Token = 2 - DD 26069 ; Index = 87 Token = 3 - DD 33518 ; Index = 87 Token = 4 - DD 40966 ; Index = 87 Token = 5 - DD 48415 ; Index = 87 Token = 6 - DD 55863 ; Index = 87 Token = 7 - DD -3724 ; Index = 87 Token = 8 - DD -11172 ; Index = 87 Token = 9 - DD -18621 ; Index = 87 Token = 10 - DD -26069 ; Index = 87 Token = 11 - DD -33518 ; Index = 87 Token = 12 - DD -40966 ; Index = 87 Token = 13 - DD -48415 ; Index = 87 Token = 14 - DD -55863 ; Index = 87 Token = 15 - DD 4095 ; Index = 88 Token = 0 - DD 12286 ; Index = 88 Token = 1 - DD 20478 ; Index = 88 Token = 2 - DD 28669 ; Index = 88 Token = 3 - DD 36862 ; Index = 88 Token = 4 - DD 45053 ; Index = 88 Token = 5 - DD 53245 ; Index = 88 Token = 6 - DD 61436 ; Index = 88 Token = 7 - DD -4095 ; Index = 88 Token = 8 - DD -12286 ; Index = 88 Token = 9 - DD -20478 ; Index = 88 Token = 10 - DD -28669 ; Index = 88 Token = 11 - DD -36862 ; Index = 88 Token = 12 - DD -45053 ; Index = 88 Token = 13 - DD -53245 ; Index = 88 Token = 14 - DD -61436 ; Index = 88 Token = 15 diff --git a/code/TIBERIANDAWN/WIN32LIB/DIPTHONG.CPP b/code/TIBERIANDAWN/WIN32LIB/DIPTHONG.CPP deleted file mode 100644 index 7202f9b..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DIPTHONG.CPP +++ /dev/null @@ -1,325 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: g:/library/source/rcs/./dipthong.c 1.15 1994/05/20 15:35:17 joe_bostic Exp $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : DIPTHONG.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : February 23, 1992 * - * * - * Last Update : February 13, 1995 [BWG] * - * * - * DIGRAM or DIATOMIC encoding is the correct term for this method. * - * This is a fixed dictionary digram encoding optimized for English text. * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Extract_String -- Extracts a string pointer from a string data block. * - * UnDip_Text -- Undipthongs a text string into specified buffer. * - * Dip_Text -- Compresses text by using dipthonging. * - * Fixup_Text -- Converts dipthonged foreign text into normal text. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -//#include "function.h" -//#include "ems.h" -#include -#include "dipthong.h" - -/*************************************************************************** - * Fixup_Text -- Converts dipthonged foreign text into normal text. * - * * - * Takes text that has been processed (or undipped) to hold foriegn * - * language character pairs (needed for Window_Print) and converts it * - * so that Text_Print will print it properly. Typically this would be * - * used after text has been undipped but before it will be Text_Printed.* - * Text that is to be Window_Printed doesn't and mustn't have its text * - * processed by this routine. * - * * - * INPUT: source -- Pointer to the source string to process. * - * * - * dest -- Destination buffer to hold the processed string. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine will only reduce the size of the string if it * - * modifies it at all. Because of this it is quite legal to * - * pass the same pointers to this routine so that it will * - * modify the string "in place". * - * * - * HISTORY: * - * 08/13/1993 JLB : Created. * - * 10/06/1994 JLB : Handles source string in EMS. * - *=========================================================================*/ -void Fixup_Text(char const *source, char *dest) -{ - if (source && dest) { - char const *src; - char temp; - - src = source; - while (*src) { - if (*src == KA_EXTEND) { - src++; - temp = *src++; - temp += 127; - *dest++ = temp; - } else { - *dest++ = *src++; - } - } - *dest = '\0'; - - } -} - - -/*************************************************************************** - * Dip_Text -- Compresses text by using dipthonging. * - * * - * This routine is used to compress text by using dipthonging. Text * - * that is compressed in this fashion usually is reduced in size by * - * approximately 40%. * - * * - * INPUT: source -- Pointer to the source string to compress. * - * * - * dest -- Pointer to the buffer that will hold the dipthong * - * text output. * - * * - * OUTPUT: Returns the number of bytes output into the output buffer. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1993 JLB : Created. * - *=========================================================================*/ -int Dip_Text(char const *source, char *dest) -{ - unsigned char first, // First character in pair. - next; // Second character in pair. - int common, // Common character index. - dipthong; // Dipthong character index. - - unsigned long length=0; // Length of output string - - first = *source++; - next = *source; - while (first) { - - if (first > 127) { - - /* - ** Characters greater than 127 cannot be dipthonged. They must - ** be preceeded with an extended character code. - */ - *dest++ = (char)KA_EXTEND; - first -= 127; - length++; - - } else { - - /* - ** Normal characters can be dipthonged. First see if there is a - ** match in the Common table. - */ - for (common = 0; common < 16; common++) { - if (Common[common] == first) { - - /* - ** Common character found. See if there is a matching - ** Dipthong character. - */ - for (dipthong = 0; dipthong < 8; dipthong++) { - if (Dipthong[common][dipthong] == next) { - first = (unsigned char) (common << 3); - first |= (unsigned char)dipthong; - first |= (unsigned char)0x80; - source++; - } - } - } - } - } - - /* - ** Output the translated character to the destination buffer. - */ - *dest++ = first; - length++; - - first = *source++; - next = *source; - } - - *dest = '\0'; - - return(length); -} - - -/*************************************************************************** - * UnDip_Text -- Undipthongs a text string into specified buffer. * - * * - * This routine is used to undipthong a text string and place the * - * undipped text into the buffer specified. Since dipthonged text is * - * compressed, in order for the text to be used it must be undipped * - * first. * - * * - * INPUT: source -- Pointer to the dipped string. * - * * - * dest -- Pointer to the destination buffer. * - * * - * OUTPUT: Returns the number of bytes placed into the destination * - * buffer. * - * * - * WARNINGS: Be sure the destination buffer is big enough to hold the * - * undipped text. * - * * - * HISTORY: * - * 08/13/1993 JLB : Created. * - * 10/06/1994 JLB : Handles source string in EMS. * - *=========================================================================*/ -int UnDip_Text(char const *source, char *dest) -{ - int c; // Source input character. - int common; // Common character index. - int len; // Length of output string. - char const *src; - - len = 0; // Presume no translation. - - /* - ** Sweep through the source text and dipthong it. - */ - src = source; - c = *src++; - while (c) { - - /* - ** Convert a dipthong character into it's component - ** ASCII characters. - */ - if (c & 0x80) { - c &= 0x7F; - - common = (c & 0x78) >> 3; - - *dest++ = Common[common]; - len++; - - c = Dipthong[common][c & 0x07]; - } - - *dest++ = (unsigned char)c; - len++; - - c = *src++; - } - - /* - ** End the output text with a '\0'. - */ - *dest++ = '\0'; - - return(len); -} - - -/*************************************************************************** - * Extract_String -- Extracts a string pointer from a string data block. * - * * - * This routine is used to find a pointer to the specified string * - * inside a string block. String data blocks are created with the * - * TEXTMAKE utility. The data block my reside in XMS or EMS memory, * - * but of course the returned string pointer will also point to * - * such memory. In this case, the string must be placed in real * - * memory before it can be used. * - * * - * INPUT: data -- Pointer to the string data block. * - * * - * string -- The string number to extract (if < 0 then NULL * - * is returned). * - * * - * OUTPUT: Returns with pointer to the string number specified. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 08/13/1993 JLB : Created. * - * 08/13/1993 JLB : Handles EMS or XMS data pointer. * - *=========================================================================*/ - -#define TXT_GUEST 4567+3 -#define TXT_LOGIN 4567+4 -#define TXT_LOGIN_TO_INTERNET 4567+5 -#define TXT_YOUR_HANDLE 4567+6 -#define TXT_YOUR_PASSWORD 4567+7 -#define TXT_INTERNET_HOST 4567+8 -#define TXT_INTERNET_JOIN 4567+9 -#define TXT_INTERNET_GAME_TYPE 4567+10 -#define TXT_JOIN_INTERNET_GAME 4567+11 -#define TXT_ENTER_IP_ADDRESS 4567+12 -#define TXT_WINSOCK_CONNECTING 4567+13 -#define TXT_WINSOCK_NOT_CONNECTING 4567+14 -#define TXT_WINSOCK_UNABLE_TO_CONNECT_TO_SERVER 4567+15 -#define TXT_WINSOCK_CONTACTING_SERVER 4567+16 -#define TXT_WINSOCK_SERVER_ADDRESS_LOOKUP_FAILED 4567+17 -#define TXT_WINSOCK_UNABLE_TO_ACCEPT_CLIENT 4567+18 -#define TXT_WINSOCK_UNABLE_TO_CONNECT 4567+19 -#define TXT_WINSOCK_CONNECTION_LOST 4567+20 -#define TXT_WINSOCK_RESOLVING_HOST_ADDRESS 4567+21 - -static char InternetTxt[22][40]={ - "Internet H2H", - "Host Internet Game", - "Join Internet Game", - "Guest", - "Login", - "Login to Planet Westwood", - "Planet Westwood Handle", - "Planet Westwood Password", - "Host Game", - "Join Game", - "Choose Type of Internet Game", - "Join Internet Game", - "Address of Host", - "Connecting...", - "Connection Error!", - "Unable to connect to host!", - "Connecting to host...", - "Unable to resolve host address!", - "Unable to accept client connection", - "Unable to connect!", - "Connection lost!", - "Resolving address of host..." -}; - -char *Extract_String(void const *data, int string) -{ - unsigned short int const *ptr; - - if (!data || string < 0) return(NULL); - - if (string >= 4567) return (InternetTxt[string-4567]); - - ptr = (unsigned short int const *)data; - return (((char*)data) + ptr[string]); -} diff --git a/code/TIBERIANDAWN/WIN32LIB/DIPTHONG.H b/code/TIBERIANDAWN/WIN32LIB/DIPTHONG.H deleted file mode 100644 index c8ab804..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DIPTHONG.H +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -int Dip_Text(char const *source, char *dest); -int UnDip_Text(char const *source, char *dest); -char *Extract_String(void const *data, int string); -void Fixup_Text(char const *source, char *dest); -extern char Common[]; -extern char Dipthong[16][8]; diff --git a/code/TIBERIANDAWN/WIN32LIB/DPLAY.H b/code/TIBERIANDAWN/WIN32LIB/DPLAY.H deleted file mode 100644 index c8e703d..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DPLAY.H +++ /dev/null @@ -1,323 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*==========================================================================; - * - * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved. - * - * File: dplay.h - * Content: DirectPlay include file - * - ***************************************************************************/ - -#ifndef __DPLAY_INCLUDED__ -#define __DPLAY_INCLUDED__ -#ifdef _WIN32 -/* for DECLARE_INTERFACE and HRESULT. */ -#include -#endif - -#define _FACDP 0x877 -#define MAKE_DPHRESULT( code ) MAKE_HRESULT( 1, _FACDP, code ) - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push, 1) - - -/*============================================================================ - * - * DirectPlay Structures - * - * Various structures used to invoke DirectPlay. - * - *==========================================================================*/ - -#ifdef __cplusplus -/* 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined */ -struct IDirectPlay; -typedef struct IDirectPlay FAR *LPDIRECTPLAY; -#else -typedef struct IDirectPlay FAR *LPDIRECTPLAY; -#endif - -typedef DWORD DPID, FAR *LPDPID; - -typedef struct _DPCAPS -{ - DWORD dwSize; - DWORD dwFlags; - DWORD dwMaxBufferSize; - DWORD dwMaxQueueSize; // Function of DPlay, not SP. - DWORD dwMaxPlayers; - DWORD dwHundredBaud; // 24 is 2400, 96 is 9600, etc. - DWORD dwLatency; -} DPCAPS; - -typedef DPCAPS FAR *LPDPCAPS; - -#define DPLONGNAMELEN 52 -#define DPSHORTNAMELEN 20 -#define DPSESSIONNAMELEN 32 -#define DPPASSWORDLEN 16 -#define DPUSERRESERVED 16 - -typedef struct -{ - DWORD dwSize; - GUID guidSession; // Id for Game. Null is all games. - DWORD dwSession; // session identifier - DWORD dwMaxPlayers; // Maximum players allowed in game. - DWORD dwCurrentPlayers; // Current players in Game. - DWORD dwFlags; // DPOPEN_* flags - char szSessionName[DPSESSIONNAMELEN];// Human readable name for Game - char szUserField[DPUSERRESERVED]; - DWORD dwReserved1; // Reserved for future MS use. - char szPassword[DPPASSWORDLEN]; // Password to be allowed into game. - DWORD dwReserved2; // Reserved for future MS use. - DWORD dwUser1; - DWORD dwUser2; - DWORD dwUser3; - DWORD dwUser4; -} DPSESSIONDESC; -typedef DPSESSIONDESC FAR *LPDPSESSIONDESC; - - -/* - * Create API - */ -typedef BOOL (FAR PASCAL * LPDPENUMDPCALLBACK)( - LPGUID lpSPGuid, - LPSTR lpFriendlyName, - DWORD dwMajorVersion, - DWORD dwMinorVersion, - LPVOID lpContext); - -typedef BOOL (FAR PASCAL * LPDPENUMSESSIONSCALLBACK)( - LPDPSESSIONDESC lpDPSGameDesc, - LPVOID lpContext, - LPDWORD lpdwTimeOut, - DWORD dwFlags); - - - -extern HRESULT WINAPI DirectPlayCreate( LPGUID lpGUID, LPDIRECTPLAY FAR *lplpDP, IUnknown FAR *pUnk); -extern HRESULT WINAPI DirectPlayEnumerate( LPDPENUMDPCALLBACK, LPVOID ); - - -/* Player enumeration callback prototype */ -typedef BOOL (FAR PASCAL *LPDPENUMPLAYERSCALLBACK)( - DPID dpId, - LPSTR lpFriendlyName, - LPSTR lpFormalName, - DWORD dwFlags, - LPVOID lpContext ); - -/* - * IDirectPlay - */ -#undef INTERFACE -#define INTERFACE IDirectPlay -#ifdef _WIN32 -DECLARE_INTERFACE_( IDirectPlay, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectPlay methods ***/ - STDMETHOD(AddPlayerToGroup) (THIS_ DPID, DPID) PURE; - STDMETHOD(Close) (THIS) PURE; - STDMETHOD(CreatePlayer) (THIS_ LPDPID,LPSTR,LPSTR,LPHANDLE) PURE; - STDMETHOD(CreateGroup) (THIS_ LPDPID,LPSTR,LPSTR) PURE; - STDMETHOD(DeletePlayerFromGroup)(THIS_ DPID,DPID) PURE; - STDMETHOD(DestroyPlayer) (THIS_ DPID) PURE; - STDMETHOD(DestroyGroup) (THIS_ DPID) PURE; - STDMETHOD(EnableNewPlayers) (THIS_ BOOL) PURE; - STDMETHOD(EnumGroupPlayers) (THIS_ DPID, LPDPENUMPLAYERSCALLBACK,LPVOID,DWORD) PURE; - STDMETHOD(EnumGroups) (THIS_ DWORD, LPDPENUMPLAYERSCALLBACK,LPVOID,DWORD) PURE; - STDMETHOD(EnumPlayers) (THIS_ DWORD, LPDPENUMPLAYERSCALLBACK,LPVOID,DWORD) PURE; - STDMETHOD(EnumSessions) (THIS_ LPDPSESSIONDESC,DWORD,LPDPENUMSESSIONSCALLBACK,LPVOID,DWORD) PURE; - STDMETHOD(GetCaps) (THIS_ LPDPCAPS) PURE; - STDMETHOD(GetMessageCount) (THIS_ DPID, LPDWORD) PURE; - STDMETHOD(GetPlayerCaps) (THIS_ DPID, LPDPCAPS) PURE; - STDMETHOD(GetPlayerName) (THIS_ DPID,LPSTR,LPDWORD,LPSTR,LPDWORD) PURE; - STDMETHOD(Initialize) (THIS_ LPGUID) PURE; - STDMETHOD(Open) (THIS_ LPDPSESSIONDESC) PURE; - STDMETHOD(Receive) (THIS_ LPDPID,LPDPID,DWORD,LPVOID,LPDWORD) PURE; - STDMETHOD(SaveSession) (THIS_ LPSTR) PURE; - STDMETHOD(Send) (THIS_ DPID, DPID, DWORD, LPVOID, DWORD) PURE; - STDMETHOD(SetPlayerName) (THIS_ DPID,LPSTR,LPSTR) PURE; -}; -#endif - - - - -/**************************************************************************** - * - * DIRECTPLAY ERRORS - * - * Errors are represented by negative values and cannot be combined. - * - ****************************************************************************/ -#define DP_OK 0 -#define DPERR_ALREADYINITIALIZED MAKE_DPHRESULT( 5 ) -#define DPERR_ACCESSDENIED MAKE_DPHRESULT( 10 ) -#define DPERR_ACTIVEPLAYERS MAKE_DPHRESULT( 20 ) -#define DPERR_BUFFERTOOSMALL MAKE_DPHRESULT( 30 ) -#define DPERR_CANTADDPLAYER MAKE_DPHRESULT( 40 ) -#define DPERR_CANTCREATEGROUP MAKE_DPHRESULT( 50 ) -#define DPERR_CANTCREATEPLAYER MAKE_DPHRESULT( 60 ) -#define DPERR_CANTCREATESESSION MAKE_DPHRESULT( 70 ) -#define DPERR_CAPSNOTAVAILABLEYET MAKE_DPHRESULT( 80 ) -#define DPERR_EXCEPTION MAKE_DPHRESULT( 90 ) -#define DPERR_GENERIC E_FAIL - -#define DPERR_INVALIDFLAGS MAKE_DPHRESULT( 120 ) -#define DPERR_INVALIDOBJECT MAKE_DPHRESULT( 130 ) -#define DPERR_INVALIDPARAM E_INVALIDARG -#define DPERR_INVALIDPARAMS DPERR_INVALIDPARAM -#define DPERR_INVALIDPLAYER MAKE_DPHRESULT( 150 ) -#define DPERR_NOCAPS MAKE_DPHRESULT( 160 ) -#define DPERR_NOCONNECTION MAKE_DPHRESULT( 170 ) -#define DPERR_NOMEMORY E_OUTOFMEMORY -#define DPERR_OUTOFMEMORY DPERR_NOMEMORY -#define DPERR_NOMESSAGES MAKE_DPHRESULT( 190 ) -#define DPERR_NONAMESERVERFOUND MAKE_DPHRESULT( 200 ) -#define DPERR_NOPLAYERS MAKE_DPHRESULT( 210 ) -#define DPERR_NOSESSIONS MAKE_DPHRESULT( 220 ) -#define DPERR_SENDTOOBIG MAKE_DPHRESULT( 230 ) -#define DPERR_TIMEOUT MAKE_DPHRESULT( 240 ) -#define DPERR_UNAVAILABLE MAKE_DPHRESULT( 250 ) -#define DPERR_UNSUPPORTED E_NOTIMPL -#define DPERR_BUSY MAKE_DPHRESULT( 270 ) -#define DPERR_USERCANCEL MAKE_DPHRESULT( 280 ) - - -#define DPOPEN_OPENSESSION 0x00000001 -#define DPOPEN_CREATESESSION 0x00000002 - -#define DPSEND_GUARANTEE 0x00000001 -#define DPSEND_HIGHPRIORITY 0x00000002 -#define DPSEND_TRYONCE 0x00000004 - -#define DPRECEIVE_ALL 0x00000001 -#define DPRECEIVE_TOPLAYER 0x00000002 -#define DPRECEIVE_FROMPLAYER 0x00000004 -#define DPRECEIVE_PEEK 0x00000008 - -#define DPCAPS_NAMESERVICE 0x00000001 // A name server is supported. -#define DPCAPS_NAMESERVER 0x00000002 // You are the name server. -#define DPCAPS_GUARANTEED 0x00000004 // SP's don't have to implement guarantees. - -#define DPENUMSESSIONS_AVAILABLE 0x00000001 // All games that match password (if given) - // and have openings. -#define DPENUMSESSIONS_ALL 0x00000002 -#define DPENUMSESSIONS_PREVIOUS 0x00000004 - -#define DPENUMPLAYERS_ALL 0x00000000 -#define DPENUMPLAYERS_PREVIOUS 0x00000004 -#define DPENUMPLAYERS_LOCAL 0x00000008 -#define DPENUMPLAYERS_REMOTE 0x00000010 -#define DPENUMPLAYERS_GROUP 0x00000020 -#define DPENUMPLAYERS_SESSION 0x00000080 - -// -// This flag is set on the enumsessions callback when the time out has occured. -// This means that there is no session data for this callback. -// If lpdwTimeOut is set to a non-zero value and the EnumSessionsCallback returns -// TRUE then EnumSessions will continue until the next timeout occurs. -// Timeouts are in milliseconds. - -#define DPESC_TIMEDOUT 0x00000001 - - -// -// System message structures and types. -// -// System messages have a leading 4 byte type code to identify the message. -// an app knows it is a system message because it is addressed 'To' player 0. -// - - -#define DPSYS_ADDPLAYER 0x0003 // DPMSG_ADDPLAYER -#define DPSYS_DELETEPLAYER 0x0005 // DPMSG_DELETEPLAYER - -#define DPSYS_ADDPLAYERTOGROUP 0x0007 // DPMSG_GROUPADD - -#define DPSYS_INVITE 0x000e // DPMSG_INVITE, Net only. - -#define DPSYS_DELETEGROUP 0x0020 // DPMSG_DELETEPLAYER -#define DPSYS_DELETEPLAYERFROMGRP 0x0021 // DPMSG_GROUPDELETE -#define DPSYS_SESSIONLOST 0x0031 - -#define DPSYS_CONNECT 0x484b // DPMSG_GENERIC - - - -typedef struct -{ - DWORD dwType; - DWORD dwPlayerType; - DPID dpId; - char szLongName[DPLONGNAMELEN]; - char szShortName[DPSHORTNAMELEN]; - DWORD dwCurrentPlayers; -} DPMSG_ADDPLAYER; - -typedef DPMSG_ADDPLAYER DPMSG_ADDGROUP; - -typedef struct -{ - DWORD dwType; - DPID dpIdGroup; - DPID dpIdPlayer; -} DPMSG_GROUPADD; - -typedef DPMSG_GROUPADD DPMSG_GROUPDELETE; -typedef struct -{ - DWORD dwType; - DPID dpId; -} DPMSG_DELETEPLAYER; - -typedef struct -{ - DWORD dwType; - DPSESSIONDESC dpsDesc; -} DPMSG_INVITE; - - - -typedef struct -{ - DWORD dwType; -} DPMSG_GENERIC; - -#pragma pack(pop) - - -DEFINE_GUID( IID_IDirectPlay, 0x5454e9a0, 0xdb65, 0x11ce, 0x92, 0x1c, 0x00, 0xaa, 0x00, 0x6c, 0x49, 0x72); - - - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.H b/code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.H deleted file mode 100644 index 1b08216..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.H +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -#ifndef DRAWBUFF_H -#define DRAWBUFF_H - - -#ifndef WWSTD_H -#include "wwstd.h" -#endif - -class GraphicViewPortClass; -class GraphicBufferClass; -/*=========================================================================*/ -/* Define functions which have not under-gone name mangling */ -/*=========================================================================*/ - -extern "C" { - /*======================================================================*/ - /* Externs for all of the common functions between the video buffer */ - /* class and the graphic buffer class. */ - /*======================================================================*/ - long __cdecl Buffer_Size_Of_Region(void *thisptr, int w, int h); - - void __cdecl Buffer_Put_Pixel(void * thisptr, int x, int y, unsigned char color); - int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y); - void __cdecl Buffer_Clear(void *thisptr, unsigned char color); - long __cdecl Buffer_To_Buffer(void *thisptr, int x, int y, int w, int h, void *buff, long size); - long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view); - BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel, - int dy_pixel, int pixel_width, int pixel_height, BOOL trans); - BOOL __cdecl Linear_Scale_To_Linear( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *); - - LONG __cdecl Buffer_Print(void *thisptr, const char *str, int x, int y, int fcolor, int bcolor); - - /*======================================================================*/ - /* Externs for all of the graphic buffer class only functions */ - /*======================================================================*/ - VOID __cdecl Buffer_Draw_Line(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color); - VOID __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color); - VOID __cdecl Buffer_Remap(void * thisptr, int sx, int sy, int width, int height, void *remap); - VOID __cdecl Buffer_Fill_Quad(void * thisptr, VOID *span_buff, int x0, int y0, int x1, int y1, - int x2, int y2, int x3, int y3, int color); - void __cdecl Buffer_Draw_Stamp(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap); - void __cdecl Buffer_Draw_Stamp_Clip(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int ,int,int,int); - void * __cdecl Get_Font_Palette_Ptr ( void ); -} - -extern GraphicViewPortClass *LogicPage; -extern BOOL AllowHardwareBlitFills; -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.INC b/code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.INC deleted file mode 100644 index fcc061c..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DRAWBUFF.INC +++ /dev/null @@ -1,90 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : DRAWBUFF.INC * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : January 16, 1995 * -;* * -;* Last Update : January 16, 1995 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -; Externs from REGIONSZ.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Size_Of_Region :NEAR - -; Externs from GETPIX.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Get_Pixel :NEAR - -; Externs from PUTPIX.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Put_Pixel :NEAR - -; Externs from CLEAR.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Clear :NEAR - -; Externs from BITBLIT.ASM module of the DRAWBUFF library -GLOBAL C Linear_Blit_To_Linear :NEAR - -; Externs from TOBUFF.ASM module of the DRAWBUFF library -GLOBAL C Buffer_To_Buffer :NEAR - -; Externs from TOPAGE.ASM module of the DRAWBUFF library -GLOBAL C Buffer_To_Page :NEAR - -; Externs from SCALE.ASM module of the DRAWBUFF library -GLOBAL C Linear_Scale_To_Linear :NEAR - -; Externs from TXTPRNT.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Print :NEAR - - -;*-------------------------------------------------------------------------* -;* Define Buffer only assembly GLOBALS * -;*-------------------------------------------------------------------------* - -; Externs from DRAWLINE.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Draw_Line:NEAR - -; Externs from FILLQUAD.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Fill_Quad :NEAR - -; Externs from FILLRECT.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Fill_Rect :NEAR - -; Externs from REMAP.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Remap :NEAR - -; Externs from STAMP.ASM module of the DRAWBUFF library -GLOBAL C Buffer_Draw_Stamp :NEAR - -GLOBAL C get_clip : NEAR - -struc RECTANGLE - x0 dd ? - y0 dd ? - x1 dd ? - y1 dd ? -ends RECTANGLE - diff --git a/code/TIBERIANDAWN/WIN32LIB/DRAWRECT.CPP b/code/TIBERIANDAWN/WIN32LIB/DRAWRECT.CPP deleted file mode 100644 index beaaacd..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DRAWRECT.CPP +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood 32 Bit Library * - * * - * File Name : DRAWRECT.C * - * * - * Programmer : Christopher Yates * - * * - * Last Update : August 20, 1993 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Draw_Rect -- Draws a rectangle to the LogicPage. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GBUFFER_H -#include "gbuffer.h" -#include "misc.h" -#endif - -/*************************************************************************** - * Draw_Rect -- Draws a rectangle to the LogicPage. * - * * - * This routine will draw a rectangle to the LogicPage. The rectangle * - * doesn't have to be aligned on the vertical or horizontal axis. In * - * fact, it doesn't even have to be a rectangle. The "square" can be * - * skewed. * - * * - * INPUT: x1_pixel, y1_pixel -- One corner. * - * * - * x2_pixel, y2_pixel -- The other corner. * - * * - * color -- The color to draw the lines. * - * * - * OUTPUT: none * - * * - * WARNINGS: None, but the rectangle will be clipped to the current * - * draw line clipping rectangle. * - * * - * HISTORY: * - * 08/20/1993 JLB : Created. * - *=========================================================================*/ -VOID GraphicViewPortClass::Draw_Rect(int x1_pixel, int y1_pixel, int x2_pixel, int y2_pixel, unsigned char color) -{ - Lock(); - Draw_Line(x1_pixel, y1_pixel, x2_pixel, y1_pixel, color); - Draw_Line(x1_pixel, y2_pixel, x2_pixel, y2_pixel, color); - Draw_Line(x1_pixel, y1_pixel, x1_pixel, y2_pixel, color); - Draw_Line(x2_pixel, y1_pixel, x2_pixel, y2_pixel, color); - Unlock(); -} - diff --git a/code/TIBERIANDAWN/WIN32LIB/DSETUP.H b/code/TIBERIANDAWN/WIN32LIB/DSETUP.H deleted file mode 100644 index 54ea585..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DSETUP.H +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*========================================================================== - * - * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. - * - * File: dsetup.h - * Content: DirectXSetup, error codes and flags - ***************************************************************************/ - -#ifndef __DSETUP_H__ -#define __DSETUP_H__ - -#ifdef _WIN32 -#define COM_NO_WINDOWS_H -#include -#else -#define GUID void -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define DSETUPERR_BADWINDOWSVERSION -1 -#define DSETUPERR_SOURCEFILENOTFOUND -2 -#define DSETUPERR_BADSOURCESIZE -3 -#define DSETUPERR_BADSOURCETIME -4 -#define DSETUPERR_NOCOPY -5 -#define DSETUPERR_OUTOFDISKSPACE -6 -#define DSETUPERR_CANTFINDINF -7 -#define DSETUPERR_CANTFINDDIR -8 -#define DSETUPERR_INTERNAL -9 - - -#define MAX_INFLINE (16*1024) -#define MAX_DESCRIPTION 256 - -#define DSETUP_DDRAW 0x00000001 /* install DirectDraw */ -#define DSETUP_DSOUND 0x00000002 /* install DirectSound */ -#define DSETUP_DPLAY 0x00000004 /* install DirectPlay */ -#define DSETUP_DDRAWDRV 0x00000008 /* install DirectDraw Drivers */ -#define DSETUP_DSOUNDDRV 0x00000010 /* install DirectSound Drivers */ -#define DSETUP_DPLAYSP 0x00000020 /* install DirectPlay Providers */ -#define DSETUP_DIRECTX DSETUP_DDRAW | DSETUP_DSOUND | DSETUP_DPLAY | DSETUP_DDRAWDRV | DSETUP_DSOUNDDRV | DSETUP_DPLAYSP -#define DSETUP_REINSTALL 0x00000080 /* install DirectX even if existing components have the same version */ - -int WINAPI DirectXSetup( HWND hwnd, LPSTR root_path, DWORD flags ); -int WINAPI DirectXDeviceDriverSetup( HWND hwnd, LPSTR driver_class, LPSTR inf_path, LPSTR driver_path, DWORD flags ); - -typedef int (WINAPI * LPDIRECTXSETUP)( HWND, LPSTR, DWORD ); -typedef int (WINAPI * LPDIRECTXDEVICEDRIVERSETUP)( HWND, LPSTR, LPSTR, LPSTR, DWORD ); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/DSOUND.H b/code/TIBERIANDAWN/WIN32LIB/DSOUND.H deleted file mode 100644 index 5c31e9b..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DSOUND.H +++ /dev/null @@ -1,380 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*==========================================================================; - * - * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. - * - * File: dsound.h - * Content: DirectSound include file - * - ***************************************************************************/ - -#ifndef __DSOUND_INCLUDED__ -#define __DSOUND_INCLUDED__ - -#ifdef _WIN32 -#define COM_NO_WINDOWS_H -#include -#endif - -#define _FACDS 0x878 -#define MAKE_DSHRESULT( code ) MAKE_HRESULT( 1, _FACDS, code ) - -#ifdef __cplusplus -extern "C" { -#endif - -// Direct Sound Component GUID {47D4D946-62E8-11cf-93BC-444553540000} -DEFINE_GUID(CLSID_DirectSound, -0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); - -// DirectSound 279afa83-4981-11ce-a521-0020af0be560 -DEFINE_GUID(IID_IDirectSound,0x279AFA83,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); -// DirectSoundBuffer 279afa85-4981-11ce-a521-0020af0be560 -DEFINE_GUID(IID_IDirectSoundBuffer,0x279AFA85,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); - - - -//==========================================================================; -// -// Structures... -// -//==========================================================================; -#ifdef __cplusplus -/* 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined */ -struct IDirectSound; -struct IDirectSoundBuffer; -#endif - -typedef struct IDirectSound *LPDIRECTSOUND; -typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; -typedef struct IDirectSoundBuffer **LPLPDIRECTSOUNDBUFFER; - - -typedef struct _DSCAPS -{ - DWORD dwSize; - DWORD dwFlags; - DWORD dwMinSecondarySampleRate; - DWORD dwMaxSecondarySampleRate; - DWORD dwPrimaryBuffers; - DWORD dwMaxHwMixingAllBuffers; - DWORD dwMaxHwMixingStaticBuffers; - DWORD dwMaxHwMixingStreamingBuffers; - DWORD dwFreeHwMixingAllBuffers; - DWORD dwFreeHwMixingStaticBuffers; - DWORD dwFreeHwMixingStreamingBuffers; - DWORD dwMaxHw3DAllBuffers; - DWORD dwMaxHw3DStaticBuffers; - DWORD dwMaxHw3DStreamingBuffers; - DWORD dwFreeHw3DAllBuffers; - DWORD dwFreeHw3DStaticBuffers; - DWORD dwFreeHw3DStreamingBuffers; - DWORD dwTotalHwMemBytes; - DWORD dwFreeHwMemBytes; - DWORD dwMaxContigFreeHwMemBytes; - DWORD dwUnlockTransferRateHwBuffers; - DWORD dwPlayCpuOverheadSwBuffers; - DWORD dwReserved1; - DWORD dwReserved2; -} DSCAPS, *LPDSCAPS; - -typedef struct _DSBCAPS -{ - - DWORD dwSize; - DWORD dwFlags; - DWORD dwBufferBytes; - DWORD dwUnlockTransferRate; - DWORD dwPlayCpuOverhead; -} DSBCAPS, *LPDSBCAPS; - -typedef struct _DSBUFFERDESC -{ - DWORD dwSize; - DWORD dwFlags; - DWORD dwBufferBytes; - DWORD dwReserved; - LPWAVEFORMATEX lpwfxFormat; -} DSBUFFERDESC, *LPDSBUFFERDESC; - - - -typedef LPVOID* LPLPVOID; - - -typedef BOOL (FAR PASCAL * LPDSENUMCALLBACKW)(GUID FAR *, LPWSTR, LPWSTR, LPVOID); -typedef BOOL (FAR PASCAL * LPDSENUMCALLBACKA)(GUID FAR *, LPSTR, LPSTR, LPVOID); - -extern HRESULT WINAPI DirectSoundCreate(GUID FAR * lpGUID, LPDIRECTSOUND * ppDS, IUnknown FAR *pUnkOuter ); -extern HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW lpCallback, LPVOID lpContext ); -extern HRESULT WINAPI DirectSoundEnumerateA(LPDSENUMCALLBACKA lpCallback, LPVOID lpContext ); - -#ifdef UNICODE -#define LPDSENUMCALLBACK LPDSENUMCALLBACKW -#define DirectSoundEnumerate DirectSoundEnumerateW -#else -#define LPDSENUMCALLBACK LPDSENUMCALLBACKA -#define DirectSoundEnumerate DirectSoundEnumerateA -#endif - -// -// IDirectSound -// -#undef INTERFACE -#define INTERFACE IDirectSound -#ifdef _WIN32 -DECLARE_INTERFACE_( IDirectSound, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectSound methods ***/ - - STDMETHOD( CreateSoundBuffer)(THIS_ LPDSBUFFERDESC, LPLPDIRECTSOUNDBUFFER, IUnknown FAR *) PURE; - STDMETHOD( GetCaps)(THIS_ LPDSCAPS ) PURE; - STDMETHOD( DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER, LPLPDIRECTSOUNDBUFFER ) PURE; - STDMETHOD( SetCooperativeLevel)(THIS_ HWND, DWORD ) PURE; - STDMETHOD( Compact)(THIS ) PURE; - STDMETHOD( GetSpeakerConfig)(THIS_ LPDWORD ) PURE; - STDMETHOD( SetSpeakerConfig)(THIS_ DWORD ) PURE; - STDMETHOD( Initialize)(THIS_ GUID FAR * ) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectSound_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectSound_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectSound_Release(p) (p)->lpVtbl->Release(p) -#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c) -#define IDirectSound_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) -#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b) -#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) -#define IDirectSound_Compact(p) (p)->lpVtbl->Compact(p) -#define IDirectSound_GetSpeakerConfig(p,a) (p)->lpVtbl->GetSpeakerConfig(p,a) -#define IDirectSound_SetSpeakerConfig(p,b) (p)->lpVtbl->SetSpeakerConfig(p,b) -#define IDirectSound_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) -#endif - -#endif - -// -// IDirectSoundBuffer -// -#undef INTERFACE -#define INTERFACE IDirectSoundBuffer -#ifdef _WIN32 -DECLARE_INTERFACE_( IDirectSoundBuffer, IUnknown ) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - /*** IDirectSoundBuffer methods ***/ - - STDMETHOD( GetCaps)(THIS_ LPDSBCAPS ) PURE; - STDMETHOD(GetCurrentPosition)(THIS_ LPDWORD,LPDWORD ) PURE; - STDMETHOD( GetFormat)(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) PURE; - STDMETHOD( GetVolume)(THIS_ LPLONG ) PURE; - STDMETHOD( GetPan)(THIS_ LPLONG ) PURE; - STDMETHOD( GetFrequency)(THIS_ LPDWORD ) PURE; - STDMETHOD( GetStatus)(THIS_ LPDWORD ) PURE; - STDMETHOD( Initialize)(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) PURE; - STDMETHOD( Lock)(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) PURE; - STDMETHOD( Play)(THIS_ DWORD,DWORD,DWORD ) PURE; - STDMETHOD(SetCurrentPosition)(THIS_ DWORD ) PURE; - STDMETHOD( SetFormat)(THIS_ LPWAVEFORMATEX ) PURE; - STDMETHOD( SetVolume)(THIS_ LONG ) PURE; - STDMETHOD( SetPan)(THIS_ LONG ) PURE; - STDMETHOD( SetFrequency)(THIS_ DWORD ) PURE; - STDMETHOD( Stop)(THIS ) PURE; - STDMETHOD( Unlock)(THIS_ LPVOID,DWORD,LPVOID,DWORD ) PURE; - STDMETHOD( Restore)(THIS ) PURE; -}; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirectSoundBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirectSoundBuffer_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirectSoundBuffer_Release(p) (p)->lpVtbl->Release(p) -#define IDirectSoundBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) -#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) -#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) -#define IDirectSoundBuffer_GetVolume(p,a) (p)->lpVtbl->GetVolume(p,a) -#define IDirectSoundBuffer_GetPan(p,a) (p)->lpVtbl->GetPan(p,a) -#define IDirectSoundBuffer_GetFrequency(p,a) (p)->lpVtbl->GetFrequency(p,a) -#define IDirectSoundBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) -#define IDirectSoundBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) -#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) -#define IDirectSoundBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c) -#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->lpVtbl->SetCurrentPosition(p,a) -#define IDirectSoundBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) -#define IDirectSoundBuffer_SetVolume(p,a) (p)->lpVtbl->SetVolume(p,a) -#define IDirectSoundBuffer_SetPan(p,a) (p)->lpVtbl->SetPan(p,a) -#define IDirectSoundBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a) -#define IDirectSoundBuffer_Stop(p) (p)->lpVtbl->Stop(p) -#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) -#define IDirectSoundBuffer_Restore(p) (p)->lpVtbl->Restore(p) -#endif - -#endif - - - -/* - * Return Codes - */ - -#define DS_OK 0 - -/* - * The call failed because resources (such as a priority level) - * were already being used by another caller. - */ -#define DSERR_ALLOCATED MAKE_DSHRESULT( 10 ) -/* - * The control (vol,pan,etc.) requested by the caller is not available. - */ -#define DSERR_CONTROLUNAVAIL MAKE_DSHRESULT( 30 ) -/* - * An invalid parameter was passed to the returning function - */ -#define DSERR_INVALIDPARAM E_INVALIDARG -/* - * This call is not valid for the current state of this object - */ -#define DSERR_INVALIDCALL MAKE_DSHRESULT( 50 ) -/* - * An undetermined error occured inside the DSound subsystem - */ -#define DSERR_GENERIC E_FAIL -/* - * The caller does not have the priority level required for the function to - * succeed. - */ -#define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT( 70 ) -/* - * The DSound subsystem couldn't allocate sufficient memory to complete the - * caller's request. - */ -#define DSERR_OUTOFMEMORY E_OUTOFMEMORY -/* - * The specified WAVE format is not supported - */ -#define DSERR_BADFORMAT MAKE_DSHRESULT( 100 ) -/* - * The function called is not supported at this time - */ -#define DSERR_UNSUPPORTED E_NOTIMPL -/* - * No sound driver is available for use - */ -#define DSERR_NODRIVER MAKE_DSHRESULT( 120 ) -/* - * This object is already initialized - */ -#define DSERR_ALREADYINITIALIZED MAKE_DSHRESULT( 130 ) -/* - * This object does not support aggregation - */ -#define DSERR_NOAGGREGATION CLASS_E_NOAGGREGATION -/* - * The buffer memory has been lost, and must be Restored. - */ -#define DSERR_BUFFERLOST MAKE_DSHRESULT( 150 ) -/* - * Another app has a higher priority level, preventing this call from - * succeeding. - */ -#define DSERR_OTHERAPPHASPRIO MAKE_DSHRESULT( 160 ) -/* - * The Initialize() member on the Direct Sound Object has not been - * called or called successfully before calls to other members. - */ -#define DSERR_UNINITIALIZED MAKE_DSHRESULT( 170 ) - - - - -//==========================================================================; -// -// Flags... -// -//==========================================================================; - -#define DSCAPS_PRIMARYMONO 0x00000001 -#define DSCAPS_PRIMARYSTEREO 0x00000002 -#define DSCAPS_PRIMARY8BIT 0x00000004 -#define DSCAPS_PRIMARY16BIT 0x00000008 -#define DSCAPS_CONTINUOUSRATE 0x00000010 -#define DSCAPS_EMULDRIVER 0x00000020 -#define DSCAPS_CERTIFIED 0x00000040 -#define DSCAPS_SECONDARYMONO 0x00000100 -#define DSCAPS_SECONDARYSTEREO 0x00000200 -#define DSCAPS_SECONDARY8BIT 0x00000400 -#define DSCAPS_SECONDARY16BIT 0x00000800 - - - -#define DSBPLAY_LOOPING 0x00000001 - - - -#define DSBSTATUS_PLAYING 0x00000001 -#define DSBSTATUS_BUFFERLOST 0x00000002 -#define DSBSTATUS_LOOPING 0x00000004 - - -#define DSBLOCK_FROMWRITECURSOR 0x00000001 - - - -#define DSSCL_NORMAL 1 -#define DSSCL_PRIORITY 2 -#define DSSCL_EXCLUSIVE 3 -#define DSSCL_WRITEPRIMARY 4 - - - -#define DSBCAPS_PRIMARYBUFFER 0x00000001 -#define DSBCAPS_STATIC 0x00000002 -#define DSBCAPS_LOCHARDWARE 0x00000004 -#define DSBCAPS_LOCSOFTWARE 0x00000008 -#define DSBCAPS_CTRLFREQUENCY 0x00000020 -#define DSBCAPS_CTRLPAN 0x00000040 -#define DSBCAPS_CTRLVOLUME 0x00000080 -#define DSBCAPS_CTRLDEFAULT 0x000000E0 // Pan + volume + frequency. -#define DSBCAPS_CTRLALL 0x000000E0 // All control capabilities -#define DSBCAPS_STICKYFOCUS 0x00004000 - - - - -#define DSSPEAKER_HEADPHONE 1 -#define DSSPEAKER_MONO 2 -#define DSSPEAKER_QUAD 3 -#define DSSPEAKER_STEREO 4 -#define DSSPEAKER_SURROUND 5 - - - - - - -#ifdef __cplusplus -}; -#endif - -#endif /* __DSOUND_INCLUDED__ */ diff --git a/code/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp b/code/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp deleted file mode 100644 index 05f9a52..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp +++ /dev/null @@ -1,5508 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* -** -** -** Misc asm functions from ww lib -** ST - 12/19/2018 1:20PM -** -** -** -** -** -** -** -** -** -** -** -*/ - -#include "gbuffer.h" -#include "MISC.H" - -IconCacheClass::IconCacheClass (void) -{ - IsCached =FALSE; - SurfaceLost =FALSE; - DrawFrequency =0; - CacheSurface =NULL; - IconSource =NULL; -} - -IconCacheClass::~IconCacheClass (void) -{ -} - -IconCacheClass CachedIcons[MAX_CACHED_ICONS]; - -extern "C"{ -IconSetType IconSetList[MAX_ICON_SETS]; -short IconCacheLookup[MAX_LOOKUP_ENTRIES]; -} - -int CachedIconsDrawn=0; //Counter of number of cache hits -int UnCachedIconsDrawn=0; //Counter of number of cache misses -BOOL CacheMemoryExhausted; //Flag set if we have run out of video RAM - - -void Invalidate_Cached_Icons (void) {} -void Restore_Cached_Icons (void) {} -void Register_Icon_Set (void *icon_data , BOOL pre_cache) {}; - -// -// Prototypes for assembly language procedures in STMPCACH.ASM -// -extern "C" void __cdecl Clear_Icon_Pointers (void) {}; -extern "C" void __cdecl Cache_Copy_Icon (void const *icon_ptr ,void * , int) {}; -extern "C" int __cdecl Is_Icon_Cached (void const *icon_data , int icon) {return -1;}; -extern "C" int __cdecl Get_Icon_Index (void *icon_ptr) {return 0;}; -extern "C" int __cdecl Get_Free_Index (void) {return 0;}; -extern "C" BOOL __cdecl Cache_New_Icon (int icon_index, void *icon_ptr) {return -1;}; -extern "C" int __cdecl Get_Free_Cache_Slot(void) {return -1;} - -void IconCacheClass::Draw_It (LPDIRECTDRAWSURFACE dest_surface , int x_pixel, int y_pixel, int window_left , int window_top , int window_width , int window_height) {} - - - -extern int CachedIconsDrawn; -extern int UnCachedIconsDrawn; - - -extern "C" void __cdecl Set_Font_Palette_Range(void const *palette, INT start_idx, INT end_idx) -{ -} - - -/* -;*************************************************************************** -;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport * -;* * -;* INPUT: WORD sx_pixel - the starting x pixel position * -;* WORD sy_pixel - the starting y pixel position * -;* WORD dx_pixel - the destination x pixel position * -;* WORD dy_pixel - the destination y pixel position * -;* WORD color - the color of the line to draw * -;* * -;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel * -;* with the graphic viewport it has been assigned to. * -;* * -;* HISTORY: * -;* 06/16/1994 PWG : Created. * -;* 08/30/1994 IML : Fixed clipping bug. * -;*=========================================================================* - PROC Buffer_Draw_Line C NEAR - USES eax,ebx,ecx,edx,esi,edi -*/ - -void __cdecl Buffer_Draw_Line(void *this_object, int sx, int sy, int dx, int dy, unsigned char color) -{ - unsigned int clip_min_x; - unsigned int clip_max_x; - unsigned int clip_min_y; - unsigned int clip_max_y; - unsigned int clip_var; - unsigned int accum; - unsigned int bpr; - - static int _one_time_init = 0; - - //clip_tbl DD nada,a_up,a_dwn,nada - // DD a_lft,a_lft,a_dwn,nada - // DD a_rgt,a_up,a_rgt,nada - // DD nada,nada,nada,nada - - static void *_clip_table [4*4] = {0}; - - unsigned int int_color = color; - unsigned int x1_pixel = (unsigned int) sx; - unsigned int y1_pixel = (unsigned int) sy; - unsigned int x2_pixel = (unsigned int) dx; - unsigned int y2_pixel = (unsigned int) dy; - - __asm { - mov eax,_one_time_init - and eax,eax - jnz init_done - - call do_init - -init_done: - - //;*================================================================== - //;* Take care of find the clip minimum and maximums - //;*================================================================== - mov ebx,[this_object] - xor eax,eax - mov [clip_min_x],eax - mov [clip_min_y],eax - mov eax,[ebx]GraphicViewPortClass.Width - mov [clip_max_x],eax - add eax,[ebx]GraphicViewPortClass.XAdd - add eax,[ebx]GraphicViewPortClass.Pitch - mov [bpr],eax - mov eax,[ebx]GraphicViewPortClass.Height - mov [clip_max_y],eax - - //;*================================================================== - //;* Adjust max pixels as they are tested inclusively. - //;*================================================================== - dec [clip_max_x] - dec [clip_max_y] - - //;*================================================================== - //;* Set the registers with the data for drawing the line - //;*================================================================== - mov eax,[x1_pixel] //; eax = start x pixel position - mov ebx,[y1_pixel] //; ebx = start y pixel position - mov ecx,[x2_pixel] //; ecx = dest x pixel position - mov edx,[y2_pixel] //; edx = dest y pixel position - - //;*================================================================== - //;* This is the section that "pushes" the line into bounds. - //;* I have marked the section with PORTABLE start and end to signify - //;* how much of this routine is 100% portable between graphics modes. - //;* It was just as easy to have variables as it would be for constants - //;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used - //;* to clip the line (default is the screen) - //;* PORTABLE start - //;*================================================================== - - cmp eax,[clip_min_x] - jl short clip_it - cmp eax,[clip_max_x] - jg short clip_it - cmp ebx,[clip_min_y] - jl short clip_it - cmp ebx,[clip_max_y] - jg short clip_it - cmp ecx,[clip_min_x] - jl short clip_it - cmp ecx,[clip_max_x] - jg short clip_it - cmp edx,[clip_min_y] - jl short clip_it - cmp edx,[clip_max_y] - jle short on_screen - - //;*================================================================== - //;* Takes care off clipping the line. - //;*================================================================== - clip_it: - call set_bits - xchg eax,ecx - xchg ebx,edx - mov edi,esi - call set_bits - mov [clip_var],edi - or [clip_var],esi - jz short on_screen - test edi,esi - jne short off_screen - shl esi,2 - //call [clip_tbl+esi] - call [_clip_table+esi] - jc clip_it - xchg eax,ecx - xchg ebx,edx - shl edi,2 - //call [clip_tbl+edi] - call [_clip_table+edi] - jmp clip_it - - on_screen: - jmp draw_it - - off_screen: - jmp and_out - - //;*================================================================== - //;* Jump table for clipping conditions - //;*================================================================== - //clip_tbl DD nada,a_up,a_dwn,nada - // DD a_lft,a_lft,a_dwn,nada - // DD a_rgt,a_up,a_rgt,nada - // DD nada,nada,nada,nada - - nada: - clc - ret - - a_up: - mov esi,[clip_min_y] - call clip_vert - stc - ret - - a_dwn: - mov esi,[clip_max_y] - neg esi - neg ebx - neg edx - call clip_vert - neg ebx - neg edx - stc - ret - - //;*================================================================== - //;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)] - //;*================================================================== - clip_vert: - push edx - push eax - mov [clip_var],edx //; clip_var = yb - sub [clip_var],ebx //; clip_var = (yb-ya) - neg eax //; eax=-xa - add eax,ecx //; (ebx-xa) - mov edx,esi //; edx=miny - sub edx,ebx //; edx=(miny-ya) - imul edx - idiv [clip_var] - pop edx - add eax,edx - pop edx - mov ebx,esi - ret - - a_lft: - mov esi,[clip_min_x] - call clip_horiz - stc - ret - - a_rgt: - mov esi,[clip_max_x] - neg eax - neg ecx - neg esi - call clip_horiz - neg eax - neg ecx - stc - ret - - //;*================================================================== - //;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)] - //;*================================================================== - clip_horiz: - push edx - mov [clip_var],ecx //; clip_var = xb - sub [clip_var],eax //; clip_var = (xb-xa) - sub edx,ebx //; edx = (yb-ya) - neg eax //; eax = -xa - add eax,esi //; eax = (minx-xa) - imul edx //; eax = (minx-xa)(yb-ya) - idiv [clip_var] //; eax = (minx-xa)(yb-ya)/(xb-xa) - add ebx,eax //; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)] - pop edx - mov eax,esi - ret - - //;*================================================================== - //;* Sets the condition bits - //;*================================================================== - set_bits: - xor esi,esi - cmp ebx,[clip_min_y] //; if y >= top its not up - jge short a_not_up - or esi,1 - - a_not_up: - cmp ebx,[clip_max_y] //; if y <= bottom its not down - jle short a_not_down - or esi,2 - - a_not_down: - cmp eax,[clip_min_x] //; if x >= left its not left - jge short a_not_left - or esi,4 - - a_not_left: - cmp eax,[clip_max_x] //; if x <= right its not right - jle short a_not_right - or esi,8 - - a_not_right: - ret - - //;*================================================================== - //;* Draw the line to the screen. - //;* PORTABLE end - //;*================================================================== - draw_it: - sub edx,ebx //; see if line is being draw down - jnz short not_hline //; if not then its not a hline - jmp short hline //; do special case h line - - not_hline: - jg short down //; if so there is no need to rev it - neg edx //; negate for actual pixel length - xchg eax,ecx //; swap x's to rev line draw - sub ebx,edx //; get old edx - - down: - push edx - push eax - mov eax,[bpr] - mul ebx - mov ebx,eax - mov eax,[this_object] - add ebx,[eax]GraphicViewPortClass.Offset - pop eax - pop edx - - mov esi,1 //; assume a right mover - sub ecx,eax //; see if line is right - jnz short not_vline //; see if its a vertical line - jmp vline - - not_vline: - jg short right //; if so, the difference = length - - //left: - neg ecx //; else negate for actual pixel length - neg esi //; negate counter to move left - - right: - cmp ecx,edx //; is it a horiz or vert line - jge short horiz //; if ecx > edx then |x|>|y| or horiz - - //vert: - xchg ecx,edx //; make ecx greater and edx lesser - mov edi,ecx //; set greater - mov [accum],ecx //; set accumulator to 1/2 greater - shr [accum],1 - - //;*================================================================== - //;* at this point ... - //;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; - //;* esi=adder; accum=accumulator - //;* in a vertical loop the adder is conditional and the inc constant - //;*================================================================== - //vert_loop: - add ebx,eax - mov eax,[int_color] - - v_midloop: - mov [ebx],al - dec ecx - jl and_out - add ebx,[bpr] - sub [accum],edx //; sub the lesser - jge v_midloop //; any line could be new - add [accum],edi //; add greater for new accum - add ebx,esi //; next pixel over - jmp v_midloop - - horiz: - mov edi,ecx //; set greater - mov [accum],ecx //; set accumulator to 1/2 greater - shr [accum],1 - - //;*================================================================== - //;* at this point ... - //;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; - //;* esi=adder; accum=accumulator - //;* in a vertical loop the adder is conditional and the inc constant - //;*================================================================== - //horiz_loop: - add ebx,eax - mov eax,[int_color] - - h_midloop: - mov [ebx],al - dec ecx //; dec counter - jl and_out //; end of line - add ebx,esi - sub [accum],edx //; sub the lesser - jge h_midloop - add [accum],edi //; add greater for new accum - add ebx,[bpr] //; goto next line - jmp h_midloop - - //;*================================================================== - //;* Special case routine for horizontal line draws - //;*================================================================== - hline: - cmp eax,ecx //; make eax < ecx - jl short hl_ac - xchg eax,ecx - - hl_ac: - sub ecx,eax //; get len - inc ecx - - push edx - push eax - mov eax,[bpr] - mul ebx - mov ebx,eax - mov eax,[this_object] - add ebx,[eax]GraphicViewPortClass.Offset - pop eax - pop edx - add ebx,eax - mov edi,ebx - cmp ecx,15 - jg big_line - mov al,[color] - rep stosb //; write as many words as possible - jmp short and_out //; get outt - - - big_line: - mov al,[color] - mov ah,al - mov ebx,eax - shl eax,16 - mov ax,bx - test edi,3 - jz aligned - mov [edi],al - inc edi - dec ecx - test edi,3 - jz aligned - mov [edi],al - inc edi - dec ecx - test edi,3 - jz aligned - mov [edi],al - inc edi - dec ecx - - aligned: - mov ebx,ecx - shr ecx,2 - rep stosd - mov ecx,ebx - and ecx,3 - rep stosb - jmp and_out - - - //;*================================================================== - //;* a special case routine for vertical line draws - //;*================================================================== - vline: - mov ecx,edx //; get length of line to draw - inc ecx - add ebx,eax - mov eax,[int_color] - - vl_loop: - mov [ebx],al //; store bit - add ebx,[bpr] - dec ecx - jnz vl_loop - jmp and_out - - -do_init: - mov edi, offset _clip_table - - lea esi, nada - mov [edi], esi - mov [edi+12], esi - lea esi, a_up - mov [edi+4], esi - lea esi, a_dwn - mov [edi+8], esi - - add edi, 16 - - lea esi, a_lft - mov [edi], esi - mov [edi+4], esi - lea esi, a_dwn - mov [edi+8], esi - lea esi, nada - mov [edi+12], esi - - add edi, 16 - - lea esi, a_rgt - mov [edi], esi - mov [edi+8], esi - lea esi, a_up - mov [edi+4], esi - lea esi, nada - mov [edi+12], esi - - add edi, 16 - - lea esi, nada - mov [edi], esi - mov [edi+4], esi - mov [edi+8], esi - mov [edi+12], esi - - mov [_one_time_init], 1 - ret - - and_out: - } -} - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : DRAWLINE.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : June 16, 1994 * -;* * -;* Last Update : August 30, 1994 [IML] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* VVC::Scale -- Scales a virtual viewport to another virtual viewport * -;* Normal_Draw -- jump loc for drawing scaled line of normal pixel * -;* __DRAW_LINE -- Assembly routine to draw a line * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -INCLUDE ".\drawbuff.inc" -INCLUDE ".\gbuffer.inc" - - -CODESEG -*/ - - -/* -;*************************************************************************** -;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport * -;* * -;* INPUT: WORD sx_pixel - the starting x pixel position * -;* WORD sy_pixel - the starting y pixel position * -;* WORD dx_pixel - the destination x pixel position * -;* WORD dy_pixel - the destination y pixel position * -;* WORD color - the color of the line to draw * -;* * -;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel * -;* with the graphic viewport it has been assigned to. * -;* * -;* HISTORY: * -;* 06/16/1994 PWG : Created. * -;* 08/30/1994 IML : Fixed clipping bug. * -;*=========================================================================* - PROC Buffer_Draw_Line C NEAR - USES eax,ebx,ecx,edx,esi,edi - - ;*================================================================== - ;* Define the arguements that the function takes. - ;*================================================================== - ARG this_object:DWORD ; associated graphic view port - ARG x1_pixel:DWORD ; the start x pixel position - ARG y1_pixel:DWORD ; the start y pixel position - ARG x2_pixel:DWORD ; the dest x pixel position - ARG y2_pixel:DWORD ; the dest y pixel position - ARG color:DWORD ; the color we are drawing - - ;*================================================================== - ;* Define the local variables that we will use on the stack - ;*================================================================== - LOCAL clip_min_x:DWORD - LOCAL clip_max_x:DWORD - LOCAL clip_min_y:DWORD - LOCAL clip_max_y:DWORD - LOCAL clip_var:DWORD - LOCAL accum:DWORD - LOCAL bpr:DWORD - - ;*================================================================== - ;* Take care of find the clip minimum and maximums - ;*================================================================== - mov ebx,[this_object] - xor eax,eax - mov [clip_min_x],eax - mov [clip_min_y],eax - mov eax,[(GraphicViewPort ebx).GVPWidth] - mov [clip_max_x],eax - add eax,[(GraphicViewPort ebx).GVPXAdd] - add eax,[(GraphicViewPort ebx).GVPPitch] - mov [bpr],eax - mov eax,[(GraphicViewPort ebx).GVPHeight] - mov [clip_max_y],eax - - ;*================================================================== - ;* Adjust max pixels as they are tested inclusively. - ;*================================================================== - dec [clip_max_x] - dec [clip_max_y] - - ;*================================================================== - ;* Set the registers with the data for drawing the line - ;*================================================================== - mov eax,[x1_pixel] ; eax = start x pixel position - mov ebx,[y1_pixel] ; ebx = start y pixel position - mov ecx,[x2_pixel] ; ecx = dest x pixel position - mov edx,[y2_pixel] ; edx = dest y pixel position - - ;*================================================================== - ;* This is the section that "pushes" the line into bounds. - ;* I have marked the section with PORTABLE start and end to signify - ;* how much of this routine is 100% portable between graphics modes. - ;* It was just as easy to have variables as it would be for constants - ;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used - ;* to clip the line (default is the screen) - ;* PORTABLE start - ;*================================================================== - - cmp eax,[clip_min_x] - jl short ??clip_it - cmp eax,[clip_max_x] - jg short ??clip_it - cmp ebx,[clip_min_y] - jl short ??clip_it - cmp ebx,[clip_max_y] - jg short ??clip_it - cmp ecx,[clip_min_x] - jl short ??clip_it - cmp ecx,[clip_max_x] - jg short ??clip_it - cmp edx,[clip_min_y] - jl short ??clip_it - cmp edx,[clip_max_y] - jle short ??on_screen - - ;*================================================================== - ;* Takes care off clipping the line. - ;*================================================================== -??clip_it: - call NEAR PTR ??set_bits - xchg eax,ecx - xchg ebx,edx - mov edi,esi - call NEAR PTR ??set_bits - mov [clip_var],edi - or [clip_var],esi - jz short ??on_screen - test edi,esi - jne short ??off_screen - shl esi,2 - call [DWORD PTR cs:??clip_tbl+esi] - jc ??clip_it - xchg eax,ecx - xchg ebx,edx - shl edi,2 - call [DWORD PTR cs:??clip_tbl+edi] - jmp ??clip_it - -??on_screen: - jmp ??draw_it - -??off_screen: - jmp ??out - - ;*================================================================== - ;* Jump table for clipping conditions - ;*================================================================== -??clip_tbl DD ??nada,??a_up,??a_dwn,??nada - DD ??a_lft,??a_lft,??a_dwn,??nada - DD ??a_rgt,??a_up,??a_rgt,??nada - DD ??nada,??nada,??nada,??nada - -??nada: - clc - retn - -??a_up: - mov esi,[clip_min_y] - call NEAR PTR ??clip_vert - stc - retn - -??a_dwn: - mov esi,[clip_max_y] - neg esi - neg ebx - neg edx - call NEAR PTR ??clip_vert - neg ebx - neg edx - stc - retn - - ;*================================================================== - ;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)] - ;*================================================================== -??clip_vert: - push edx - push eax - mov [clip_var],edx ; clip_var = yb - sub [clip_var],ebx ; clip_var = (yb-ya) - neg eax ; eax=-xa - add eax,ecx ; (ebx-xa) - mov edx,esi ; edx=miny - sub edx,ebx ; edx=(miny-ya) - imul edx - idiv [clip_var] - pop edx - add eax,edx - pop edx - mov ebx,esi - retn - -??a_lft: - mov esi,[clip_min_x] - call NEAR PTR ??clip_horiz - stc - retn - -??a_rgt: - mov esi,[clip_max_x] - neg eax - neg ecx - neg esi - call NEAR PTR ??clip_horiz - neg eax - neg ecx - stc - retn - - ;*================================================================== - ;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)] - ;*================================================================== -??clip_horiz: - push edx - mov [clip_var],ecx ; clip_var = xb - sub [clip_var],eax ; clip_var = (xb-xa) - sub edx,ebx ; edx = (yb-ya) - neg eax ; eax = -xa - add eax,esi ; eax = (minx-xa) - imul edx ; eax = (minx-xa)(yb-ya) - idiv [clip_var] ; eax = (minx-xa)(yb-ya)/(xb-xa) - add ebx,eax ; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)] - pop edx - mov eax,esi - retn - - ;*================================================================== - ;* Sets the condition bits - ;*================================================================== -??set_bits: - xor esi,esi - cmp ebx,[clip_min_y] ; if y >= top its not up - jge short ??a_not_up - or esi,1 - -??a_not_up: - cmp ebx,[clip_max_y] ; if y <= bottom its not down - jle short ??a_not_down - or esi,2 - -??a_not_down: - cmp eax,[clip_min_x] ; if x >= left its not left - jge short ??a_not_left - or esi,4 - -??a_not_left: - cmp eax,[clip_max_x] ; if x <= right its not right - jle short ??a_not_right - or esi,8 - -??a_not_right: - retn - - ;*================================================================== - ;* Draw the line to the screen. - ;* PORTABLE end - ;*================================================================== -??draw_it: - sub edx,ebx ; see if line is being draw down - jnz short ??not_hline ; if not then its not a hline - jmp short ??hline ; do special case h line - -??not_hline: - jg short ??down ; if so there is no need to rev it - neg edx ; negate for actual pixel length - xchg eax,ecx ; swap x's to rev line draw - sub ebx,edx ; get old edx - -??down: - push edx - push eax - mov eax,[bpr] - mul ebx - mov ebx,eax - mov eax,[this_object] - add ebx,[(GraphicViewPort eax).GVPOffset] - pop eax - pop edx - - mov esi,1 ; assume a right mover - sub ecx,eax ; see if line is right - jnz short ??not_vline ; see if its a vertical line - jmp ??vline - -??not_vline: - jg short ??right ; if so, the difference = length - -??left: - neg ecx ; else negate for actual pixel length - neg esi ; negate counter to move left - -??right: - cmp ecx,edx ; is it a horiz or vert line - jge short ??horiz ; if ecx > edx then |x|>|y| or horiz - -??vert: - xchg ecx,edx ; make ecx greater and edx lesser - mov edi,ecx ; set greater - mov [accum],ecx ; set accumulator to 1/2 greater - shr [accum],1 - - ;*================================================================== - ;* at this point ... - ;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; - ;* esi=adder; accum=accumulator - ;* in a vertical loop the adder is conditional and the inc constant - ;*================================================================== -??vert_loop: - add ebx,eax - mov eax,[color] - -??v_midloop: - mov [ebx],al - dec ecx - jl ??out - add ebx,[bpr] - sub [accum],edx ; sub the lesser - jge ??v_midloop ; any line could be new - add [accum],edi ; add greater for new accum - add ebx,esi ; next pixel over - jmp ??v_midloop - -??horiz: - mov edi,ecx ; set greater - mov [accum],ecx ; set accumulator to 1/2 greater - shr [accum],1 - - ;*================================================================== - ;* at this point ... - ;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; - ;* esi=adder; accum=accumulator - ;* in a vertical loop the adder is conditional and the inc constant - ;*================================================================== -??horiz_loop: - add ebx,eax - mov eax,[color] - -??h_midloop: - mov [ebx],al - dec ecx ; dec counter - jl ??out ; end of line - add ebx,esi - sub [accum],edx ; sub the lesser - jge ??h_midloop - add [accum],edi ; add greater for new accum - add ebx,[bpr] ; goto next line - jmp ??h_midloop - - ;*================================================================== - ;* Special case routine for horizontal line draws - ;*================================================================== -??hline: - cmp eax,ecx ; make eax < ecx - jl short ??hl_ac - xchg eax,ecx - -??hl_ac: - sub ecx,eax ; get len - inc ecx - - push edx - push eax - mov eax,[bpr] - mul ebx - mov ebx,eax - mov eax,[this_object] - add ebx,[(GraphicViewPort eax).GVPOffset] - pop eax - pop edx - add ebx,eax - mov edi,ebx - cmp ecx,15 - jg ??big_line - mov al,[byte color] - rep stosb ; write as many words as possible - jmp short ??out ; get outt - - -??big_line: - mov al,[byte color] - mov ah,al - mov ebx,eax - shl eax,16 - mov ax,bx - test edi,3 - jz ??aligned - mov [edi],al - inc edi - dec ecx - test edi,3 - jz ??aligned - mov [edi],al - inc edi - dec ecx - test edi,3 - jz ??aligned - mov [edi],al - inc edi - dec ecx - -??aligned: - mov ebx,ecx - shr ecx,2 - rep stosd - mov ecx,ebx - and ecx,3 - rep stosb - jmp ??out - - - ;*================================================================== - ;* a special case routine for vertical line draws - ;*================================================================== -??vline: - mov ecx,edx ; get length of line to draw - inc ecx - add ebx,eax - mov eax,[color] - -??vl_loop: - mov [ebx],al ; store bit - add ebx,[bpr] - dec ecx - jnz ??vl_loop - -??out: - ret - ENDP Buffer_Draw_Line - - -*/ - - - - - - - - - - - - - - - -/* - -;*************************************************************************** -;* GVPC::FILL_RECT -- Fills a rectangular region of a graphic view port * -;* * -;* INPUT: WORD the left hand x pixel position of region * -;* WORD the upper x pixel position of region * -;* WORD the right hand x pixel position of region * -;* WORD the lower x pixel position of region * -;* UBYTE the color (optional) to clear the view port to * -;* * -;* OUTPUT: none * -;* * -;* NOTE: This function is optimized to handle viewport with no XAdd * -;* value. It also handles DWORD aligning the destination * -;* when speed can be gained by doing it. * -;* HISTORY: * -;* 06/07/1994 PWG : Created. * -;*=========================================================================* -*/ - -/* -;****************************************************************************** -; Much testing was done to determine that only when there are 14 or more bytes -; being copied does it speed the time it takes to do copies in this algorithm. -; For this reason and because 1 and 2 byte copies crash, is the special case -; used. SKB 4/21/94. Tested on 486 66mhz. Copied by PWG 6/7/04. -*/ -#define OPTIMAL_BYTE_COPY 14 - - -void __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color) -{ -/* - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ARG this_object:DWORD ; this is a member function - ARG x1_pixel:WORD - ARG y1_pixel:WORD - ARG x2_pixel:WORD - ARG y2_pixel:WORD - ARG color:BYTE ; what color should we clear to -*/ - - void *this_object = thisptr; - int x1_pixel = sx; - int y1_pixel = sy; - int x2_pixel = dx; - int y2_pixel = dy; - -/* - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL VPwidth:DWORD ; the width of the viewport - LOCAL VPheight:DWORD ; the height of the viewport - LOCAL VPxadd:DWORD ; the additional x offset of viewport - LOCAL VPbpr:DWORD ; the number of bytes per row of viewport -*/ - - int VPwidth; - int VPheight; - int VPxadd; - int VPbpr; - - int local_ebp; // Can't use ebp - - __asm { - - ;*=================================================================== - ;* save off the viewport characteristics on the stack - ;*=================================================================== - mov ebx,[this_object] ; get a pointer to viewport - mov eax,[ebx]GraphicViewPortClass.Width ; get width from viewport - mov ecx,[ebx]GraphicViewPortClass.Height ; get height from viewport - mov edx,[ebx]GraphicViewPortClass.XAdd ; get xadd from viewport - add edx,[ebx]GraphicViewPortClass.Pitch ; extra pitch of direct draw surface - mov [VPwidth],eax ; store the width of locally - mov [VPheight],ecx - mov [VPxadd],edx - add eax,edx - mov [VPbpr],eax - - ;*=================================================================== - ;* move the important parameters into local registers - ;*=================================================================== - mov eax,[x1_pixel] - mov ebx,[y1_pixel] - mov ecx,[x2_pixel] - mov edx,[y2_pixel] - - ;*=================================================================== - ;* Convert the x2 and y2 pixel to a width and height - ;*=================================================================== - cmp eax,ecx - jl no_swap_x - xchg eax,ecx - - no_swap_x: - sub ecx,eax - cmp ebx,edx - jl no_swap_y - xchg ebx,edx - no_swap_y: - sub edx,ebx - inc ecx - inc edx - - ;*=================================================================== - ;* Bounds check source X. - ;*=================================================================== - cmp eax, [VPwidth] ; compare with the max - jge done ; starts off screen, then later - jb short sx_done ; if it's not negative, it's ok - - ;------ Clip source X to left edge of screen. - add ecx, eax ; Reduce width (add in negative src X). - xor eax, eax ; Clip to left of screen. - sx_done: - - ;*=================================================================== - ;* Bounds check source Y. - ;*=================================================================== - cmp ebx, [VPheight] ; compare with the max - jge done ; starts off screen, then later - jb short sy_done ; if it's not negative, it's ok - - ;------ Clip source Y to top edge of screen. - add edx, ebx ; Reduce height (add in negative src Y). - xor ebx, ebx ; Clip to top of screen. - - sy_done: - ;*=================================================================== - ;* Bounds check width versus width of source and dest view ports - ;*=================================================================== - push ebx ; save off ebx for later use - mov ebx,[VPwidth] ; get the source width - sub ebx, eax ; Maximum allowed pixel width (given coordinates). - sub ebx, ecx ; Pixel width undershoot. - jns short width_ok ; if not signed no adjustment necessary - add ecx, ebx ; Reduce width to screen limits. - - width_ok: - pop ebx ; restore ebx to old value - - ;*=================================================================== - ;* Bounds check height versus height of source view port - ;*=================================================================== - push eax ; save of eax for later use - mov eax, [VPheight] ; get the source height - sub eax, ebx ; Maximum allowed pixel height (given coordinates). - sub eax, edx ; Pixel height undershoot. - jns short height_ok ; if not signed no adjustment necessary - add edx, eax ; Reduce height to screen limits. - height_ok: - pop eax ; restore eax to old value - - ;*=================================================================== - ;* Perform the last minute checks on the width and height - ;*=================================================================== - or ecx,ecx - jz done - - or edx,edx - jz done - - cmp ecx,[VPwidth] - ja done - cmp edx,[VPheight] - ja done - - ;*=================================================================== - ;* Get the offset into the virtual viewport. - ;*=================================================================== - xchg edi,eax ; save off the contents of eax - xchg esi,edx ; and edx for size test - mov eax,ebx ; move the y pixel into eax - mul [VPbpr] ; multiply by bytes per row - add edi,eax ; add the result into the x position - mov ebx,[this_object] - add edi,[ebx]GraphicViewPortClass.Offset - - mov edx,esi ; restore edx back to real value - mov eax,ecx ; store total width in ecx - sub eax,[VPwidth] ; modify xadd value to include clipped - sub [VPxadd],eax ; width bytes (subtract a negative number) - - ;*=================================================================== - ; Convert the color byte to a DWORD for fast storing - ;*=================================================================== - mov al,[color] ; get color to clear to - mov ah,al ; extend across WORD - mov ebx,eax ; extend across DWORD in - shl eax,16 ; several steps - mov ax,bx - - ;*=================================================================== - ; If there is no row offset then adjust the width to be the size of - ; the entire viewport and adjust the height to be 1 - ;*=================================================================== - mov esi,[VPxadd] - or esi,esi ; set the flags for esi - jnz row_by_row_aligned ; and act on them - - xchg eax,ecx ; switch bit pattern and width - mul edx ; multiply by edx to get size - xchg eax,ecx ; switch size and bit pattern - mov edx,1 ; only 1 line off view port size to do - - ;*=================================================================== - ; Find out if we should bother to align the row. - ;*=================================================================== - row_by_row_aligned: - mov [local_ebp],ecx ; width saved in ebp - cmp ecx,OPTIMAL_BYTE_COPY ; is it worth aligning them? - jl row_by_row ; if not then skip - - ;*=================================================================== - ; Figure out the alignment offset if there is any - ;*=================================================================== - mov ebx,edi ; get output position - and ebx,3 ; is there a remainder? - jz aligned_loop ; if not we are aligned - xor ebx,3 ; find number of align bytes - inc ebx ; this number is off by one - sub [local_ebp],ebx ; subtract from width - - ;*=================================================================== - ; Now that we have the alignment offset copy each row - ;*=================================================================== - aligned_loop: - mov ecx,ebx ; get number of bytes to align - rep stosb ; and move them over - mov ecx,[local_ebp] ; get number of aligned bytes - shr ecx,2 ; convert to DWORDS - rep stosd ; and move them over - mov ecx,[local_ebp] ; get number of aligned bytes - and ecx,3 ; find the remainder - rep stosb ; and move it over - add edi,esi ; fix the line offset - dec edx ; decrement the height - jnz aligned_loop ; if more to do than do it - jmp done ; we are all done - - ;*=================================================================== - ; If not enough bytes to bother aligning copy each line across a byte - ; at a time. - ;*=================================================================== - row_by_row: - mov ecx,[local_ebp] ; get total width in bytes - rep stosb ; store the width - add edi,esi ; handle the xadd - dec edx ; decrement the height - jnz row_by_row ; if any left then next line - done: - } -} - - - - -/* -;*************************************************************************** -;* VVPC::CLEAR -- Clears a virtual viewport instance * -;* * -;* INPUT: UBYTE the color (optional) to clear the view port to * -;* * -;* OUTPUT: none * -;* * -;* NOTE: This function is optimized to handle viewport with no XAdd * -;* value. It also handles DWORD aligning the destination * -;* when speed can be gained by doing it. * -;* HISTORY: * -;* 06/07/1994 PWG : Created. * -;* 08/23/1994 SKB : Clear the direction flag to always go forward. * -;*=========================================================================* -*/ -void __cdecl Buffer_Clear(void *this_object, unsigned char color) -{ - unsigned int local_color = color; - - __asm { - - cld ; always go forward - - mov ebx,[this_object] ; get a pointer to viewport - mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset - mov edx,[ebx]GraphicViewPortClass.Height ; get height from viewport - mov esi,[ebx]GraphicViewPortClass.Width ; get width from viewport - //push [dword (GraphicViewPort ebx).GVPPitch] ; extra pitch of direct draw surface - push [ebx]GraphicViewPortClass.Pitch - - mov ebx,[ebx]GraphicViewPortClass.XAdd ; esi = add for each line - add ebx,[esp] ; Yes, I know its nasty but - add esp,4 ; it works! - - ;*=================================================================== - ; Convert the color byte to a DWORD for fast storing - ;*=================================================================== - mov al,[color] ; get color to clear to - mov ah,al ; extend across WORD - mov ecx,eax ; extend across DWORD in - shl eax,16 ; several steps - mov ax,cx - - ;*=================================================================== - ; Find out if we should bother to align the row. - ;*=================================================================== - - cmp esi , OPTIMAL_BYTE_COPY ; is it worth aligning them? - jl byte_by_byte ; if not then skip - - ;*=================================================================== - ; Figure out the alignment offset if there is any - ;*=================================================================== - push ebx - - dword_aligned_loop: - mov ecx , edi - mov ebx , esi - neg ecx - and ecx , 3 - sub ebx , ecx - rep stosb - mov ecx , ebx - shr ecx , 2 - rep stosd - mov ecx , ebx - and ecx , 3 - rep stosb - add edi , [ esp ] - dec edx ; decrement the height - jnz dword_aligned_loop ; if more to do than do it - pop eax - jmp done - //ret - - ;*=================================================================== - ; If not enough bytes to bother aligning copy each line across a byte - ; at a time. - ;*=================================================================== - byte_by_byte: - mov ecx,esi ; get total width in bytes - rep stosb ; store the width - add edi,ebx ; handle the xadd - dec edx ; decrement the height - jnz byte_by_byte ; if any left then next line - done: - } -} - - - - - - - - - - - - - - -BOOL __cdecl Linear_Blit_To_Linear( void *this_object, void * dest, int x_pixel, int y_pixel, int dest_x0, int dest_y0, int pixel_width, int pixel_height, BOOL trans) -{ -/* - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ARG this_object :DWORD ; this is a member function - ARG dest :DWORD ; what are we blitting to - ARG x_pixel :DWORD ; x pixel position in source - ARG y_pixel :DWORD ; y pixel position in source - ARG dest_x0 :dword - ARG dest_y0 :dword - ARG pixel_width :DWORD ; width of rectangle to blit - ARG pixel_height:DWORD ; height of rectangle to blit - ARG trans :DWORD ; do we deal with transparents? - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL x1_pixel :dword - LOCAL y1_pixel :dword - LOCAL dest_x1 : dword - LOCAL dest_y1 : dword - LOCAL scr_ajust_width:DWORD - LOCAL dest_ajust_width:DWORD - LOCAL source_area : dword - LOCAL dest_area : dword -*/ - - int x1_pixel; - int y1_pixel; - int dest_x1; - int dest_y1; - int scr_adjust_width; - int dest_adjust_width; - int source_area; - int dest_area; - - __asm { - - ;This Clipping algorithm is a derivation of the very well known - ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency - ;it is probably the most commontly implemented algorithm both in software - ;and hardware for clipping lines, rectangles, and convex polygons against - ;a rectagular clipping window. For reference see - ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes - ; pages 113 to 177". - ; Briefly consist in computing the Sutherland code for both end point of - ; the rectangle to find out if the rectangle is: - ; - trivially accepted (no further clipping test, display rectangle) - ; - trivially rejected (return with no action) - ; - retangle must be iteratively clipped again edges of the clipping window - ; and the remaining retangle is display. - - ; Clip Source Rectangle against source Window boundaries. - mov esi,[this_object] ; get ptr to src - xor ecx,ecx ; Set sutherland code to zero - xor edx,edx ; Set sutherland code to zero - - ; compute the difference in the X axis and get the bit signs into ecx , edx - mov edi,[esi]GraphicViewPortClass.Width ; get width into register - mov ebx,[x_pixel] ; Get first end point x_pixel into register - mov eax,[x_pixel] ; Get second end point x_pixel into register - add ebx,[pixel_width] ; second point x1_pixel = x + width - shld ecx, eax,1 ; the sign bit of x_pixel is sutherland code0 bit4 - mov [x1_pixel],ebx ; save second for future use - inc edi ; move the right edge by one unit - shld edx,ebx,1 ; the sign bit of x1_pixel is sutherland code0 bit4 - sub eax,edi ; compute the difference x0_pixel - width - sub ebx,edi ; compute the difference x1_pixel - width - shld ecx,eax,1 ; the sign bit of the difference is sutherland code0 bit3 - shld edx,ebx,1 ; the sign bit of the difference is sutherland code0 bit3 - - ; the following code is just a repeticion of the above code - ; in the Y axis. - mov edi,[esi]GraphicViewPortClass.Height ; get height into register - mov ebx,[y_pixel] - mov eax,[y_pixel] - add ebx,[pixel_height] - shld ecx,eax,1 - mov [y1_pixel ],ebx - inc edi - shld edx,ebx,1 - sub eax,edi - sub ebx,edi - shld ecx,eax,1 - shld edx,ebx,1 - - ; Here we have the to Sutherland code into cl and dl - xor cl,5 ; bit 2 and 0 are complented, reverse then - xor dl,5 ; bit 2 and 0 are complented, reverse then - mov al,cl ; save code1 in case we have to clip iteratively - test dl,cl ; if any bit in code0 and its counter bit - jnz real_out ; in code1 is set then the rectangle in outside - or al,dl ; if all bit of code0 the counter bit in - jz clip_against_dest ; in code1 is set to zero, then all - ; end points of the rectangle are - ; inside the clipping window - - ; if we are here the polygon have to be clip iteratively - test cl,1000b ; if bit 4 in code0 is set then - jz scr_left_ok ; x_pixel is smaller than zero - mov [x_pixel],0 ; set x_pixel to cero. - - scr_left_ok: - test cl,0010b ; if bit 2 in code0 is set then - jz scr_bottom_ok ; y_pixel is smaller than zero - mov [ y_pixel ],0 ; set y_pixel to cero. - - scr_bottom_ok: - test dl,0100b ; if bit 3 in code1 is set then - jz scr_right_ok ; x1_pixel is greater than the width - mov eax,[esi]GraphicViewPortClass.Width ; get width into register - mov [ x1_pixel ],eax ; set x1_pixel to width. - scr_right_ok: - test dl,0001b ; if bit 0 in code1 is set then - jz clip_against_dest ; y1_pixel is greater than the width - mov eax,[esi]GraphicViewPortClass.Height ; get height into register - mov [ y1_pixel ],eax ; set y1_pixel to height. - - ; Clip Source Rectangle against destination Window boundaries. - clip_against_dest: - - ; build the destination rectangle before clipping - ; dest_x1 = dest_x0 + ( x1_pixel - x_pixel ) - ; dest_y1 = dest_y0 + ( y1_pixel - y_pixel ) - mov eax,[dest_x0] ; get dest_x0 into eax - mov ebx,[dest_y0] ; get dest_y0 into ebx - sub eax,[x_pixel] ; subtract x_pixel from eax - sub ebx,[y_pixel] ; subtract y_pixel from ebx - add eax,[x1_pixel] ; add x1_pixel to eax - add ebx,[y1_pixel] ; add y1_pixel to ebx - mov [dest_x1],eax ; save eax into dest_x1 - mov [dest_y1],ebx ; save eax into dest_y1 - - - ; The followin code is a repeticion of the Sutherland clipping - ; descrived above. - mov esi,[dest] ; get ptr to src - xor ecx,ecx - xor edx,edx - mov edi,[esi]GraphicViewPortClass.Width ; get width into register - mov eax,[dest_x0] - mov ebx,[dest_x1] - shld ecx,eax,1 - inc edi - shld edx,ebx,1 - sub eax,edi - sub ebx,edi - shld ecx,eax,1 - shld edx,ebx,1 - - mov edi,[esi]GraphicViewPortClass.Height ; get height into register - mov eax,[dest_y0] - mov ebx,[dest_y1] - shld ecx,eax,1 - inc edi - shld edx,ebx,1 - sub eax,edi - sub ebx,edi - shld ecx,eax,1 - shld edx,ebx,1 - - xor cl,5 - xor dl,5 - mov al,cl - test dl,cl - jnz real_out - or al,dl - jz do_blit - - test cl,1000b - jz dest_left_ok - mov eax,[ dest_x0 ] - mov [ dest_x0 ],0 - sub [ x_pixel ],eax - - dest_left_ok: - test cl,0010b - jz dest_bottom_ok - mov eax,[ dest_y0 ] - mov [ dest_y0 ],0 - sub [ y_pixel ],eax - - - dest_bottom_ok: - test dl,0100b - jz dest_right_ok - mov ebx,[esi]GraphicViewPortClass.Width ; get width into register - mov eax,[ dest_x1 ] - mov [ dest_x1 ],ebx - sub eax,ebx - sub [ x1_pixel ],eax - - dest_right_ok: - test dl,0001b - jz do_blit - mov ebx,[esi]GraphicViewPortClass.Height ; get width into register - mov eax,[ dest_y1 ] - mov [ dest_y1 ],ebx - sub eax,ebx - sub [ y1_pixel ],eax - - - ; Here is where we do the actual blit - do_blit: - cld - mov ebx,[this_object] - mov esi,[ebx]GraphicViewPortClass.Offset - mov eax,[ebx]GraphicViewPortClass.XAdd - add eax,[ebx]GraphicViewPortClass.Width - add eax,[ebx]GraphicViewPortClass.Pitch - mov ecx,eax - mul [y_pixel] - add esi,[x_pixel] - mov [source_area],ecx - add esi,eax - - add ecx,[x_pixel ] - sub ecx,[x1_pixel ] - mov [scr_adjust_width ],ecx - - mov ebx,[dest] - mov edi,[ebx]GraphicViewPortClass.Offset - mov eax,[ebx]GraphicViewPortClass.XAdd - add eax,[ebx]GraphicViewPortClass.Width - add eax,[ebx]GraphicViewPortClass.Pitch - mov ecx,eax - mul [ dest_y0 ] - add edi,[ dest_x0 ] - mov [ dest_area ],ecx - add edi,eax - - mov eax,[ dest_x1 ] - sub eax,[ dest_x0 ] - jle real_out - sub ecx,eax - mov [ dest_adjust_width ],ecx - - mov edx,[ dest_y1 ] - sub edx,[ dest_y0 ] - jle real_out - - cmp esi,edi - jz real_out - jl backupward_blit - - ; ******************************************************************** - ; Forward bitblit - - test [ trans ],1 - jnz forward_Blit_trans - - - ; the inner loop is so efficient that - ; the optimal consept no longer apply because - ; the optimal byte have to by a number greather than 9 bytes - cmp eax,10 - jl forward_loop_bytes - - forward_loop_dword: - mov ecx,edi - mov ebx,eax - neg ecx - and ecx,3 - sub ebx,ecx - rep movsb - mov ecx,ebx - shr ecx,2 - rep movsd - mov ecx,ebx - and ecx,3 - rep movsb - add esi,[ scr_adjust_width ] - add edi,[ dest_adjust_width ] - dec edx - jnz forward_loop_dword - jmp real_out //ret - - forward_loop_bytes: - mov ecx,eax - rep movsb - add esi,[ scr_adjust_width ] - add edi,[ dest_adjust_width ] - dec edx - jnz forward_loop_bytes - jmp real_out - - forward_Blit_trans: - mov ecx,eax - and ecx,01fh - lea ecx,[ ecx + ecx * 4 ] - neg ecx - shr eax,5 - lea ecx,[ transp_reference + ecx * 2 ] - mov [ y1_pixel ],ecx - - forward_loop_trans: - mov ecx,eax - jmp [ y1_pixel ] - forward_trans_line: - //REPT 32 - //local transp_pixel - //No REPT in msvc inline assembly. - // Save ECX and use as counter instead. ST - 12/19/2018 5:41PM - push ecx - mov ecx, 32 - - rept_loop: - mov bl,[ esi ] - test bl,bl - jz transp_pixel - mov [ edi ],bl - transp_pixel: - inc esi - inc edi - - dec ecx //ST - 12/19/2018 5:44PM - jnz rept_loop //ST - 12/19/2018 5:44PM - - pop ecx //ST - 12/19/2018 5:44PM - - //ENDM - transp_reference: - dec ecx - jge forward_trans_line - add esi,[ scr_adjust_width ] - add edi,[ dest_adjust_width ] - dec edx - jnz forward_loop_trans - jmp real_out //ret - - - ; ************************************************************************ - ; backward bitblit - - backupward_blit: - - mov ebx,[ source_area ] - dec edx - add esi,eax - imul ebx,edx - std - lea esi,[ esi + ebx - 1 ] - - mov ebx,[ dest_area ] - add edi,eax - imul ebx,edx - lea edi,[ edi + ebx - 1] - - test [ trans ],1 - jnz backward_Blit_trans - - cmp eax,15 - jl backward_loop_bytes - - backward_loop_dword: - push edi - push esi - lea ecx,[edi+1] - mov ebx,eax - and ecx,3 ; Get non aligned bytes. - sub ebx,ecx ; remove that from the total size to be copied later. - rep movsb ; do the copy. - sub esi,3 - mov ecx,ebx ; Get number of bytes left. - sub edi,3 - shr ecx,2 ; Do 4 bytes at a time. - rep movsd ; do the dword copy. - mov ecx,ebx - add esi,3 - add edi,3 - and ecx,03h - rep movsb ; finnish the remaining bytes. - pop esi - pop edi - sub esi,[ source_area ] - sub edi,[ dest_area ] - dec edx - jge backward_loop_dword - cld - jmp real_out //ret - - backward_loop_bytes: - push edi - mov ecx,eax ; remove that from the total size to be copied later. - push esi - rep movsb ; do the copy. - pop esi - pop edi - sub esi,[ source_area ] - sub edi,[ dest_area ] - dec edx - jge backward_loop_bytes - cld - jmp real_out //ret - - backward_Blit_trans: - mov ecx,eax - and ecx,01fh - lea ecx,[ ecx + ecx * 4 ] - neg ecx - shr eax,5 - lea ecx,[ back_transp_reference + ecx * 2 ] - mov [ y1_pixel ],ecx - - backward_loop_trans: - mov ecx,eax - push edi - push esi - jmp [ y1_pixel ] - backward_trans_line: - //REPT 32 - //local transp_pixel2 - //No REPT in msvc inline assembly. - // Save ECX and use as counter instead. ST - 12/19/2018 5:41PM - push ecx - mov ecx, 32 - rept_loop2: - mov bl,[ esi ] - test bl,bl - jz transp_pixel2 - mov [ edi ],bl - transp_pixel2: - dec esi - dec edi - - dec ecx //ST - 12/19/2018 5:44PM - jnz rept_loop2 //ST - 12/19/2018 5:44PM - - pop ecx //ST - 12/19/2018 5:44PM - - //ENDM - - back_transp_reference: - dec ecx - jge backward_trans_line - pop esi - pop edi - sub esi,[ source_area ] - sub edi,[ dest_area ] - dec edx - jge backward_loop_trans - cld - //ret - - real_out: - } -} - - - - - - - - - - - - -/* -;*************************************************************************** -;* VVC::SCALE -- Scales a virtual viewport to another virtual viewport * -;* * -;* INPUT: * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 06/16/1994 PWG : Created. * -;*=========================================================================* - PROC Linear_Scale_To_Linear C NEAR - USES eax,ebx,ecx,edx,esi,edi -*/ - -// Ran out of registers so had to use ebp. ST - 12/19/2018 6:22PM -#pragma warning (push) -#pragma warning (disable : 4731) - -BOOL __cdecl Linear_Scale_To_Linear(void *this_object, void *dest, int src_x, int src_y, int dst_x, int dst_y, int src_width, int src_height, int dst_width, int dst_height, BOOL trans, char *remap) -{ -/* - - ;*=================================================================== - ;* Define the arguements that our function takes. - ;*=================================================================== - ARG this_object:DWORD ; pointer to source view port - ARG dest:DWORD ; pointer to destination view port - ARG src_x:DWORD ; source x offset into view port - ARG src_y:DWORD ; source y offset into view port - ARG dst_x:DWORD ; dest x offset into view port - ARG dst_y:DWORD ; dest y offset into view port - ARG src_width:DWORD ; width of source rectangle - ARG src_height:DWORD ; height of source rectangle - ARG dst_width:DWORD ; width of dest rectangle - ARG dst_height:DWORD ; width of dest height - ARG trans:DWORD ; is this transparent? - ARG remap:DWORD ; pointer to table to remap source - - ;*=================================================================== - ;* Define local variables to hold the viewport characteristics - ;*=================================================================== - local src_x0 : dword - local src_y0 : dword - local src_x1 : dword - local src_y1 : dword - - local dst_x0 : dword - local dst_y0 : dword - local dst_x1 : dword - local dst_y1 : dword - - local src_win_width : dword - local dst_win_width : dword - local dy_intr : dword - local dy_frac : dword - local dy_acc : dword - local dx_frac : dword - - local counter_x : dword - local counter_y : dword - local remap_counter :dword - local entry : dword -*/ - - int src_x0; - int src_y0; - int src_x1; - int src_y1; - - int dst_x0; - int dst_y0; - int dst_x1; - int dst_y1; - - int src_win_width; - int dst_win_width; - int dy_intr; - int dy_frac; - int dy_acc; - int dx_frac; - - int counter_x; - int counter_y; - int remap_counter; - int entry; - - - __asm { - - ;*=================================================================== - ;* Check for scale error when to or from size 0,0 - ;*=================================================================== - cmp [dst_width],0 - je all_done - cmp [dst_height],0 - je all_done - cmp [src_width],0 - je all_done - cmp [src_height],0 - je all_done - - mov eax , [ src_x ] - mov ebx , [ src_y ] - mov [ src_x0 ] , eax - mov [ src_y0 ] , ebx - add eax , [ src_width ] - add ebx , [ src_height ] - mov [ src_x1 ] , eax - mov [ src_y1 ] , ebx - - mov eax , [ dst_x ] - mov ebx , [ dst_y ] - mov [ dst_x0 ] , eax - mov [ dst_y0 ] , ebx - add eax , [ dst_width ] - add ebx , [ dst_height ] - mov [ dst_x1 ] , eax - mov [ dst_y1 ] , ebx - - ; Clip Source Rectangle against source Window boundaries. - mov esi , [ this_object ] ; get ptr to src - xor ecx , ecx - xor edx , edx - mov edi , [esi]GraphicViewPortClass.Width ; get width into register - mov eax , [ src_x0 ] - mov ebx , [ src_x1 ] - shld ecx , eax , 1 - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi,[esi]GraphicViewPortClass.Height ; get height into register - mov eax , [ src_y0 ] - mov ebx , [ src_y1 ] - shld ecx , eax , 1 - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz all_done - or al , dl - jz clip_against_dest - mov bl , dl - test cl , 1000b - jz src_left_ok - xor eax , eax - mov [ src_x0 ] , eax - sub eax , [ src_x ] - imul [ dst_width ] - idiv [ src_width ] - add eax , [ dst_x ] - mov [ dst_x0 ] , eax - - src_left_ok: - test cl , 0010b - jz src_bottom_ok - xor eax , eax - mov [ src_y0 ] , eax - sub eax , [ src_y ] - imul [ dst_height ] - idiv [ src_height ] - add eax , [ dst_y ] - mov [ dst_y0 ] , eax - - src_bottom_ok: - test bl , 0100b - jz src_right_ok - mov eax , [esi]GraphicViewPortClass.Width ; get width into register - mov [ src_x1 ] , eax - sub eax , [ src_x ] - imul [ dst_width ] - idiv [ src_width ] - add eax , [ dst_x ] - mov [ dst_x1 ] , eax - - src_right_ok: - test bl , 0001b - jz clip_against_dest - mov eax , [esi]GraphicViewPortClass.Height ; get width into register - mov [ src_y1 ] , eax - sub eax , [ src_y ] - imul [ dst_height ] - idiv [ src_height ] - add eax , [ dst_y ] - mov [ dst_y1 ] , eax - - ; Clip destination Rectangle against source Window boundaries. - clip_against_dest: - mov esi , [ dest ] ; get ptr to src - xor ecx , ecx - xor edx , edx - mov edi , [esi]GraphicViewPortClass.Width ; get width into register - mov eax , [ dst_x0 ] - mov ebx , [ dst_x1 ] - shld ecx , eax , 1 - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi,[esi]GraphicViewPortClass.Height ; get height into register - mov eax , [ dst_y0 ] - mov ebx , [ dst_y1 ] - shld ecx , eax , 1 - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz all_done - or al , dl - jz do_scaling - mov bl , dl - test cl , 1000b - jz dst_left_ok - xor eax , eax - mov [ dst_x0 ] , eax - sub eax , [ dst_x ] - imul [ src_width ] - idiv [ dst_width ] - add eax , [ src_x ] - mov [ src_x0 ] , eax - - dst_left_ok: - test cl , 0010b - jz dst_bottom_ok - xor eax , eax - mov [ dst_y0 ] , eax - sub eax , [ dst_y ] - imul [ src_height ] - idiv [ dst_height ] - add eax , [ src_y ] - mov [ src_y0 ] , eax - - dst_bottom_ok: - test bl , 0100b - jz dst_right_ok - mov eax , [esi]GraphicViewPortClass.Width ; get width into register - mov [ dst_x1 ] , eax - sub eax , [ dst_x ] - imul [ src_width ] - idiv [ dst_width ] - add eax , [ src_x ] - mov [ src_x1 ] , eax - - dst_right_ok: - test bl , 0001b - jz do_scaling - - mov eax , [esi]GraphicViewPortClass.Height ; get width into register - mov [ dst_y1 ] , eax - sub eax , [ dst_y ] - imul [ src_height ] - idiv [ dst_height ] - add eax , [ src_y ] - mov [ src_y1 ] , eax - - do_scaling: - - cld - mov ebx , [ this_object ] - mov esi , [ebx]GraphicViewPortClass. Offset - mov eax , [ebx]GraphicViewPortClass. XAdd - add eax , [ebx]GraphicViewPortClass. Width - add eax , [ebx]GraphicViewPortClass. Pitch - mov [ src_win_width ] , eax - mul [ src_y0 ] - add esi , [ src_x0 ] - add esi , eax - - mov ebx , [ dest ] - mov edi , [ebx]GraphicViewPortClass. Offset - mov eax , [ebx]GraphicViewPortClass. XAdd - add eax , [ebx]GraphicViewPortClass. Width - add eax , [ebx]GraphicViewPortClass. Pitch - mov [ dst_win_width ] , eax - mul [ dst_y0 ] - add edi , [ dst_x0 ] - add edi , eax - - mov eax , [ src_height ] - xor edx , edx - mov ebx , [ dst_height ] - idiv [ dst_height ] - imul eax , [ src_win_width ] - neg ebx - mov [ dy_intr ] , eax - mov [ dy_frac ] , edx - mov [ dy_acc ] , ebx - - mov eax , [ src_width ] - xor edx , edx - shl eax , 16 - idiv [ dst_width ] - xor edx , edx - shld edx , eax , 16 - shl eax , 16 - - mov ecx , [ dst_y1 ] - mov ebx , [ dst_x1 ] - sub ecx , [ dst_y0 ] - jle all_done - sub ebx , [ dst_x0 ] - jle all_done - - mov [ counter_y ] , ecx - - cmp [ trans ] , 0 - jnz transparency - - cmp [ remap ] , 0 - jnz normal_remap - - ; ************************************************************************* - ; normal scale - mov ecx , ebx - and ecx , 01fh - lea ecx , [ ecx + ecx * 2 ] - shr ebx , 5 - neg ecx - mov [ counter_x ] , ebx - lea ecx , [ ref_point + ecx + ecx * 2 ] - mov [ entry ] , ecx - - outter_loop: - push esi - push edi - xor ecx , ecx - mov ebx , [ counter_x ] - jmp [ entry ] - inner_loop: - // REPT not supported for inline asm. ST - 12/19/2018 6:11PM - //REPT 32 - push ebx //ST - 12/19/2018 6:11PM - mov ebx,32 //ST - 12/19/2018 6:11PM -rept_loop: - mov cl , [ esi ] - add ecx , eax - adc esi , edx - mov [ edi ] , cl - inc edi - - dec ebx //ST - 12/19/2018 6:11PM - jnz rept_loop //ST - 12/19/2018 6:11PM - pop ebx //ST - 12/19/2018 6:11PM - //ENDM - ref_point: - dec ebx - jge inner_loop - - pop edi - pop esi - add edi , [ dst_win_width ] - add esi , [ dy_intr ] - - mov ebx , [ dy_acc ] - add ebx , [ dy_frac ] - jle skip_line - add esi , [ src_win_width ] - sub ebx , [ dst_height ] - skip_line: - dec [ counter_y ] - mov [ dy_acc ] , ebx - jnz outter_loop - jmp all_done //ret - - - ; ************************************************************************* - ; normal scale with remap - - normal_remap: - mov ecx , ebx - mov [ dx_frac ], eax - and ecx , 01fh - mov eax , [ remap ] - shr ebx , 5 - imul ecx , - 13 - mov [ counter_x ] , ebx - lea ecx , [ remapref_point + ecx ] - mov [ entry ] , ecx - - remapoutter_loop: - mov ebx , [ counter_x ] - push esi - mov [ remap_counter ] , ebx - push edi - xor ecx , ecx - xor ebx , ebx - jmp [ entry ] - remapinner_loop: - // REPT not supported for inline asm. ST - 12/19/2018 6:11PM - //REPT 32 - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - mov bl , [ esi ] - add ecx , [ dx_frac ] - adc esi , edx - mov cl , [ eax + ebx ] - mov [ edi ] , cl - inc edi - - //ENDM - remapref_point: - dec [ remap_counter ] - jge remapinner_loop - - pop edi - pop esi - add edi , [ dst_win_width ] - add esi , [ dy_intr ] - - mov ebx , [ dy_acc ] - add ebx , [ dy_frac ] - jle remapskip_line - add esi , [ src_win_width ] - sub ebx , [ dst_height ] - remapskip_line: - dec [ counter_y ] - mov [ dy_acc ] , ebx - jnz remapoutter_loop - jmp all_done //ret - - - ;**************************************************************************** - ; scale with trnsparency - - transparency: - cmp [ remap ] , 0 - jnz trans_remap - - ; ************************************************************************* - ; normal scale with transparency - mov ecx , ebx - and ecx , 01fh - imul ecx , -13 - shr ebx , 5 - mov [ counter_x ] , ebx - lea ecx , [ trans_ref_point + ecx ] - mov [ entry ] , ecx - - trans_outter_loop: - xor ecx , ecx - push esi - push edi - mov ebx , [ counter_x ] - jmp [ entry ] - trans_inner_loop: - - // REPT not supported for inline asm. ST - 12/19/2018 6:11PM - //REPT 32 - push ebx //ST - 12/19/2018 6:11PM - mov ebx,32 //ST - 12/19/2018 6:11PM -rept_loop2: - - mov cl , [ esi ] - test cl , cl - jz trans_pixel - mov [ edi ] , cl - trans_pixel: - add ecx , eax - adc esi , edx - inc edi - - dec ebx //ST - 12/19/2018 6:11PM - jnz rept_loop2 //ST - 12/19/2018 6:11PM - pop ebx //ST - 12/19/2018 6:11PM - - //ENDM - trans_ref_point: - dec ebx - jge trans_inner_loop - - pop edi - pop esi - add edi , [ dst_win_width ] - add esi , [ dy_intr ] - - mov ebx , [ dy_acc ] - add ebx , [ dy_frac ] - jle trans_skip_line - add esi , [ src_win_width ] - sub ebx , [ dst_height ] - trans_skip_line: - dec [ counter_y ] - mov [ dy_acc ] , ebx - jnz trans_outter_loop - jmp all_done //ret - - - ; ************************************************************************* - ; normal scale with remap - - trans_remap: - mov ecx , ebx - mov [ dx_frac ], eax - and ecx , 01fh - mov eax , [ remap ] - shr ebx , 5 - imul ecx , - 17 - mov [ counter_x ] , ebx - lea ecx , [ trans_remapref_point + ecx ] - mov [ entry ] , ecx - - trans_remapoutter_loop: - mov ebx , [ counter_x ] - push esi - mov [ remap_counter ] , ebx - push edi - xor ecx , ecx - xor ebx , ebx - jmp [ entry ] - - - trans_remapinner_loop: - // REPT not supported for inline asm. ST - 12/19/2018 6:11PM - //REPT 32 - // Run out of registers so use ebp - push ebp //ST - 12/19/2018 6:11PM - mov ebp,32 //ST - 12/19/2018 6:11PM -rept_loop3: - mov bl , [ esi ] - test bl , bl - jz trans_pixel2 - mov cl , [ eax + ebx ] - mov [ edi ] , cl - trans_pixel2: - add ecx , [ dx_frac ] - adc esi , edx - inc edi - - dec ebp //ST - 12/19/2018 6:11PM - jnz rept_loop3 //ST - 12/19/2018 6:11PM - pop ebp //ST - 12/19/2018 6:11PM - - //ENDM - - trans_remapref_point: - dec [ remap_counter ] - jge trans_remapinner_loop - - pop edi - pop esi - add edi , [ dst_win_width ] - add esi , [ dy_intr ] - - mov ebx , [ dy_acc ] - add ebx , [ dy_frac ] - jle trans_remapskip_line - add esi , [ src_win_width ] - sub ebx , [ dst_height ] - trans_remapskip_line: - dec [ counter_y ] - mov [ dy_acc ] , ebx - jnz trans_remapoutter_loop - //ret - - - all_done: - } -} - - -#pragma warning (pop) - - - - - - - - - - - - - - - - - - - - -unsigned int LastIconset = 0; -unsigned int StampPtr = 0; // DD 0 ; Pointer to icon data. - -unsigned int IsTrans = 0; // DD 0 ; Pointer to transparent icon flag table. - -unsigned int MapPtr = 0; // DD 0 ; Pointer to icon map. -unsigned int IconWidth = 0; // DD 0 ; Width of icon in pixels. -unsigned int IconHeight = 0; // DD 0 ; Height of icon in pixels. -unsigned int IconSize = 0; // DD 0 ; Number of bytes for each icon data. -unsigned int IconCount = 0; // DD 0 ; Number of icons in the set. - - - -#if (0) -LastIconset DD 0 ; Pointer to last iconset initialized. -StampPtr DD 0 ; Pointer to icon data. - -IsTrans DD 0 ; Pointer to transparent icon flag table. - -MapPtr DD 0 ; Pointer to icon map. -IconWidth DD 0 ; Width of icon in pixels. -IconHeight DD 0 ; Height of icon in pixels. -IconSize DD 0 ; Number of bytes for each icon data. -IconCount DD 0 ; Number of icons in the set. - - -GLOBAL C Buffer_Draw_Stamp:near -GLOBAL C Buffer_Draw_Stamp_Clip:near - -; 256 color icon system. -#endif - - -/* -;*********************************************************** -; INIT_STAMPS -; -; VOID cdecl Init_Stamps(VOID *icondata); -; -; This routine initializes the stamp data. -; Bounds Checking: NONE -; -;* -*/ -extern "C" void __cdecl Init_Stamps(unsigned int icondata) -{ - - __asm { - pushad // ST - 12/20/2018 10:30AM - - ; Verify legality of parameter. - cmp [icondata],0 - je short fini - - ; Don't initialize if already initialized to this set (speed reasons). - mov edi,[icondata] - cmp [LastIconset],edi - je short fini - mov [LastIconset],edi - - ; Record number of icons in set. - movzx eax,[edi]IControl_Type.Count - mov [IconCount],eax - - ; Record width of icon. - movzx eax,[edi]IControl_Type.Width - mov [IconWidth],eax - - ; Record height of icon. - movzx ebx,[edi]IControl_Type.Height - mov [IconHeight],ebx - - ; Record size of icon (in bytes). - mul ebx - mov [IconSize],eax - - ; Record hard pointer to icon map data. - mov eax,[edi]IControl_Type.Map - add eax,edi - mov [MapPtr],eax - -//nomap: - ; Record hard pointer to icon data. - mov eax,edi - add eax,[edi]IControl_Type.Icons - mov [StampPtr],eax - - ; Record the transparent table. - mov eax,edi - add eax,[edi]IControl_Type.TransFlag - mov [IsTrans],eax - -fini: - popad // ST - 12/20/2018 10:30AM - - } -} - - -/* -;*********************************************************** - -;*********************************************************** -; DRAW_STAMP -; -; VOID cdecl Buffer_Draw_Stamp(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap); -; -; This routine renders the icon at the given coordinate. -; -; The remap table is a 256 byte simple pixel translation table to use when -; drawing the icon. Transparency check is performed AFTER the remap so it is possible to -; remap valid colors to be invisible (for special effect reasons). -; This routine is fastest when no remap table is passed in. -;* -*/ - -void __cdecl Buffer_Draw_Stamp(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap) -{ - unsigned int modulo = 0; - unsigned int iwidth = 0; - unsigned char doremap = 0; - - -/* - PROC Buffer_Draw_Stamp C near - - ARG this_object:DWORD ; this is a member function - ARG icondata:DWORD ; Pointer to icondata. - ARG icon:DWORD ; Icon number to draw. - ARG x_pixel:DWORD ; X coordinate of icon. - ARG y_pixel:DWORD ; Y coordinate of icon. - ARG remap:DWORD ; Remap table. - - LOCAL modulo:DWORD ; Modulo to get to next row. - LOCAL iwidth:DWORD ; Icon width (here for speedy access). - LOCAL doremap:BYTE ; Should remapping occur? -*/ - - __asm { - - pushad - cmp [icondata],0 - je proc_out - - ; Initialize the stamp data if necessary. - mov eax,[icondata] - cmp [LastIconset],eax - je short noreset - push eax - call Init_Stamps - pop eax // Clean up stack. ST - 12/20/2018 10:42AM -noreset: - - ; Determine if the icon number requested is actually in the set. - ; Perform the logical icon to actual icon number remap if necessary. - mov ebx,[icon] - cmp [MapPtr],0 - je short notmap - mov edi,[MapPtr] - mov bl,[edi+ebx] -notmap: - cmp ebx,[IconCount] - jae proc_out - mov [icon],ebx ; Updated icon number. - - ; If the remap table pointer passed in is NULL, then flag this condition - ; so that the faster (non-remapping) icon draw loop will be used. - cmp [remap],0 - setne [doremap] - - ; Get pointer to position to render icon. EDI = ptr to destination page. - mov ebx,[this_object] - mov edi,[ebx]GraphicViewPortClass.Offset - mov eax,[ebx]GraphicViewPortClass.Width - add eax,[ebx]GraphicViewPortClass.XAdd - add eax,[ebx]GraphicViewPortClass.Pitch - push eax ; save viewport full width for lower - mul [y_pixel] - add edi,eax - add edi,[x_pixel] - - ; Determine row modulo for advancing to next line. - pop eax ; retrieve viewport width - sub eax,[IconWidth] - mov [modulo],eax - - ; Setup some working variables. - mov ecx,[IconHeight] ; Row counter. - mov eax,[IconWidth] - mov [iwidth],eax ; Stack copy of byte width for easy BP access. - - ; Fetch pointer to start of icon's data. ESI = ptr to icon data. - mov eax,[icon] - mul [IconSize] - mov esi,[StampPtr] - add esi,eax - - ; Determine whether simple icon draw is sufficient or whether the - ; extra remapping icon draw is needed. - cmp [BYTE PTR doremap],0 - je short istranscheck - - ;************************************************************ - ; Complex icon draw -- extended remap. - ; EBX = Palette pointer (ready for XLAT instruction). - ; EDI = Pointer to icon destination in page. - ; ESI = Pointer to icon data. - ; ECX = Number of pixel rows. - ;;; mov edx,[remap] - mov ebx,[remap] - xor eax,eax -xrowloop: - push ecx - mov ecx,[iwidth] - -xcolumnloop: - lodsb - ;;; mov ebx,edx - ;;; add ebx,eax - ;;; mov al,[ebx] ; New real color to draw. - xlatb - or al,al - jz short xskip1 ; Transparency skip check. - mov [edi],al -xskip1: - inc edi - loop xcolumnloop - - pop ecx - add edi,[modulo] - loop xrowloop - jmp short proc_out - - - ;************************************************************ - ; Check to see if transparent or generic draw is necessary. -istranscheck: - mov ebx,[IsTrans] - add ebx,[icon] - cmp [BYTE PTR ebx],0 - jne short rowloop - - ;************************************************************ - ; Fast non-transparent icon draw routine. - ; ES:DI = Pointer to icon destination in page. - ; DS:SI = Pointer to icon data. - ; CX = Number of pixel rows. - mov ebx,ecx - shr ebx,2 - mov edx,[modulo] - mov eax,[iwidth] - shr eax,2 -loop1: - mov ecx,eax - rep movsd - add edi,edx - - mov ecx,eax - rep movsd - add edi,edx - - mov ecx,eax - rep movsd - add edi,edx - - mov ecx,eax - rep movsd - add edi,edx - - dec ebx - jnz loop1 - jmp short proc_out - - ;************************************************************ - ; Transparent icon draw routine -- no extended remap. - ; ES:DI = Pointer to icon destination in page. - ; DS:SI = Pointer to icon data. - ; CX = Number of pixel rows. -rowloop: - push ecx - mov ecx,[iwidth] - -columnloop: - lodsb - or al,al - jz short skip1 ; Transparency check. - mov [edi],al -skip1: - inc edi - loop columnloop - - pop ecx - add edi,[modulo] - loop rowloop - - ; Cleanup and exit icon drawing routine. -proc_out: - popad - //ret - } -} - - - - -/* -;*********************************************************** -; DRAW_STAMP_CLIP -; -; VOID cdecl MCGA_Draw_Stamp_Clip(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap, LONG min_x, LONG min_y, LONG max_x, LONG max_y); -; -; This routine renders the icon at the given coordinate. -; -; The remap table is a 256 byte simple pixel translation table to use when -; drawing the icon. Transparency check is performed AFTER the remap so it is possible to -; remap valid colors to be invisible (for special effect reasons). -; This routine is fastest when no remap table is passed in. -;* -*/ -void __cdecl Buffer_Draw_Stamp_Clip(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int min_x, int min_y, int max_x, int max_y) -{ - - - unsigned int modulo = 0; - unsigned int iwidth = 0; - unsigned int skip = 0; - unsigned char doremap = 0; - - -/* - ARG this_object:DWORD ; this is a member function - ARG icondata:DWORD ; Pointer to icondata. - ARG icon:DWORD ; Icon number to draw. - ARG x_pixel:DWORD ; X coordinate of icon. - ARG y_pixel:DWORD ; Y coordinate of icon. - ARG remap:DWORD ; Remap table. - ARG min_x:DWORD ; Clipping rectangle boundary - ARG min_y:DWORD ; Clipping rectangle boundary - ARG max_x:DWORD ; Clipping rectangle boundary - ARG max_y:DWORD ; Clipping rectangle boundary - - LOCAL modulo:DWORD ; Modulo to get to next row. - LOCAL iwidth:DWORD ; Icon width (here for speedy access). - LOCAL skip:DWORD ; amount to skip per row of icon data - LOCAL doremap:BYTE ; Should remapping occur? -*/ - __asm { - pushad - cmp [icondata],0 - je proc_out - - ; Initialize the stamp data if necessary. - mov eax,[icondata] - cmp [LastIconset],eax - je short noreset2 - push eax - call Init_Stamps - pop eax // Clean up stack. ST - 12/20/2018 10:42AM -noreset2: - - ; Determine if the icon number requested is actually in the set. - ; Perform the logical icon to actual icon number remap if necessary. - mov ebx,[icon] - cmp [MapPtr],0 - je short notmap2 - mov edi,[MapPtr] - mov bl,[edi+ebx] -notmap2: - cmp ebx,[IconCount] - jae proc_out - mov [icon],ebx ; Updated icon number. - - ; Setup some working variables. - mov ecx,[IconHeight] ; Row counter. - mov eax,[IconWidth] - mov [iwidth],eax ; Stack copy of byte width for easy BP access. - - ; Fetch pointer to start of icon's data. ESI = ptr to icon data. - mov eax,[icon] - mul [IconSize] - mov esi,[StampPtr] - add esi,eax - - ; Update the clipping window coordinates to be valid maxes instead of width & height - ; , and change the coordinates to be window-relative - mov ebx,[min_x] - add [max_x],ebx - add [x_pixel],ebx ; make it window-relative - mov ebx,[min_y] - add [max_y],ebx - add [y_pixel],ebx ; make it window-relative - - ; See if the icon is within the clipping window - ; First, verify that the icon position is less than the maximums - mov ebx,[x_pixel] - cmp ebx,[max_x] - jge proc_out - mov ebx,[y_pixel] - cmp ebx,[max_y] - jge proc_out - ; Now verify that the icon position is >= the minimums - add ebx,[IconHeight] - cmp ebx,[min_y] - jle proc_out - mov ebx,[x_pixel] - add ebx,[IconWidth] - cmp ebx,[min_x] - jle proc_out - - ; Now, clip the x, y, width, and height variables to be within the - ; clipping rectangle - mov ebx,[x_pixel] - cmp ebx,[min_x] - jge nominxclip - ; x < minx, so must clip - mov ebx,[min_x] - sub ebx,[x_pixel] - add esi,ebx ; source ptr += (minx - x) - sub [iwidth],ebx ; icon width -= (minx - x) - mov ebx,[min_x] - mov [x_pixel],ebx - -nominxclip: - mov eax,[IconWidth] - sub eax,[iwidth] - mov [skip],eax - - ; Check for x+width > max_x - mov eax,[x_pixel] - add eax,[iwidth] - cmp eax,[max_x] - jle nomaxxclip - ; x+width is greater than max_x, so must clip width down - mov eax,[iwidth] ; eax = old width - mov ebx,[max_x] - sub ebx,[x_pixel] - mov [iwidth],ebx ; iwidth = max_x - xpixel - sub eax,ebx - add [skip],eax ; skip += (old width - iwidth) -nomaxxclip: - ; check if y < miny - mov eax,[min_y] - cmp eax,[y_pixel] ; if(miny <= y_pixel), no clip needed - jle nominyclip - sub eax,[y_pixel] - sub ecx,eax ; height -= (miny - y) - mul [IconWidth] - add esi,eax ; icon source ptr += (width * (miny - y)) - mov eax,[min_y] - mov [y_pixel],eax ; y = miny -nominyclip: - ; check if (y+height) > max y - mov eax,[y_pixel] - add eax,ecx - cmp eax,[max_y] ; if (y + height <= max_y), no clip needed - jle nomaxyclip - mov ecx,[max_y] ; height = max_y - y_pixel - sub ecx,[y_pixel] -nomaxyclip: - - ; If the remap table pointer passed in is NULL, then flag this condition - ; so that the faster (non-remapping) icon draw loop will be used. - cmp [remap],0 - setne [doremap] - - ; Get pointer to position to render icon. EDI = ptr to destination page. - mov ebx,[this_object] - mov edi,[ebx]GraphicViewPortClass.Offset - mov eax,[ebx]GraphicViewPortClass.Width - add eax,[ebx]GraphicViewPortClass.XAdd - add eax,[ebx]GraphicViewPortClass.Pitch - push eax ; save viewport full width for lower - mul [y_pixel] - add edi,eax - add edi,[x_pixel] - - ; Determine row modulo for advancing to next line. - pop eax ; retrieve viewport width - sub eax,[iwidth] - mov [modulo],eax - - ; Determine whether simple icon draw is sufficient or whether the - ; extra remapping icon draw is needed. - cmp [BYTE PTR doremap],0 - je short istranscheck2 - - ;************************************************************ - ; Complex icon draw -- extended remap. - ; EBX = Palette pointer (ready for XLAT instruction). - ; EDI = Pointer to icon destination in page. - ; ESI = Pointer to icon data. - ; ECX = Number of pixel rows. - mov ebx,[remap] - xor eax,eax -xrowloopc: - push ecx - mov ecx,[iwidth] - -xcolumnloopc: - lodsb - xlatb - or al,al - jz short xskip1c ; Transparency skip check. - mov [edi],al -xskip1c: - inc edi - loop xcolumnloopc - - pop ecx - add edi,[modulo] - add esi,[skip] - loop xrowloopc - jmp short proc_out - - - ;************************************************************ - ; Check to see if transparent or generic draw is necessary. -istranscheck2: - mov ebx,[IsTrans] - add ebx,[icon] - cmp [BYTE PTR ebx],0 - jne short rowloopc - - ;************************************************************ - ; Fast non-transparent icon draw routine. - ; ES:DI = Pointer to icon destination in page. - ; DS:SI = Pointer to icon data. - ; CX = Number of pixel rows. - mov ebx,ecx - mov edx,[modulo] - mov eax,[iwidth] - - ; - ; Optimise copy by dword aligning the destination - ; -loop1c: - push eax - //rept 3 // No rept in inline asm. ST - 12/20/2018 10:43AM - test edi,3 - jz aligned - movsb - dec eax - jz finishedit - - test edi,3 - jz aligned - movsb - dec eax - jz finishedit - - test edi,3 - jz aligned - movsb - dec eax - jz finishedit - - //endm -aligned: - mov ecx,eax - shr ecx,2 - rep movsd - mov ecx,eax - and ecx,3 - rep movsb - -finishedit: - add edi,edx - add esi,[skip] - pop eax - - dec ebx - jnz loop1c - jmp short proc_out - - ;************************************************************ - ; Transparent icon draw routine -- no extended remap. - ; ES:DI = Pointer to icon destination in page. - ; DS:SI = Pointer to icon data. - ; CX = Number of pixel rows. -rowloopc: - push ecx - mov ecx,[iwidth] - -columnloopc: - lodsb - or al,al - jz short skip1c ; Transparency check. - mov [edi],al -skip1c: - inc edi - loop columnloopc - - pop ecx - add edi,[modulo] - add esi,[skip] - loop rowloopc - - ; Cleanup and exit icon drawing routine. -proc_out: - popad - //ret - } -} - - - - - - - - - - - - - - - - VOID __cdecl Buffer_Draw_Line(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color); - VOID __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color); - VOID __cdecl Buffer_Remap(void * thisptr, int sx, int sy, int width, int height, void *remap); - VOID __cdecl Buffer_Fill_Quad(void * thisptr, VOID *span_buff, int x0, int y0, int x1, int y1, - int x2, int y2, int x3, int y3, int color); - void __cdecl Buffer_Draw_Stamp(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap); - void __cdecl Buffer_Draw_Stamp_Clip(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int ,int,int,int); - void * __cdecl Get_Font_Palette_Ptr ( void ); - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : REMAP.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : July 1, 1994 * -;* * -;* Last Update : July 1, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -*/ - - -VOID __cdecl Buffer_Remap(void * this_object, int sx, int sy, int width, int height, void *remap) -{ -/* - PROC Buffer_Remap C NEAR - USES eax,ebx,ecx,edx,esi,edi - - ;*=================================================================== - ;* Define the arguements that our function takes. - ;*=================================================================== - ARG this_object:DWORD - ARG x0_pixel:DWORD - ARG y0_pixel:DWORD - ARG region_width:DWORD - ARG region_height:DWORD - ARG remap :DWORD - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - local x1_pixel : DWORD - local y1_pixel : DWORD - local win_width : dword - local counter_x : dword -*/ - - unsigned int x0_pixel = (unsigned int) sx; - unsigned int y0_pixel = (unsigned int) sy; - unsigned int region_width = (unsigned int) width; - unsigned int region_height = (unsigned int) height; - - unsigned int x1_pixel = 0; - unsigned int y1_pixel = 0; - unsigned int win_width = 0; - unsigned int counter_x = 0; - - __asm { - - cmp [ remap ] , 0 - jz real_out - - ; Clip Source Rectangle against source Window boundaries. - mov esi , [ this_object ] ; get ptr to src - xor ecx , ecx - xor edx , edx - mov edi , [esi]GraphicViewPortClass.Width ; get width into register - mov ebx , [ x0_pixel ] - mov eax , [ x0_pixel ] - add ebx , [ region_width ] - shld ecx , eax , 1 - mov [ x1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi,[esi]GraphicViewPortClass.Height ; get height into register - mov ebx , [ y0_pixel ] - mov eax , [ y0_pixel ] - add ebx , [ region_height ] - shld ecx , eax , 1 - mov [ y1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz real_out - or al , dl - jz do_remap - - test cl , 1000b - jz scr_left_ok - mov [ x0_pixel ] , 0 - -scr_left_ok: - test cl , 0010b - jz scr_bottom_ok - mov [ y0_pixel ] , 0 - -scr_bottom_ok: - test dl , 0100b - jz scr_right_ok - mov eax , [esi]GraphicViewPortClass.Width ; get width into register - mov [ x1_pixel ] , eax -scr_right_ok: - test dl , 0001b - jz do_remap - mov eax , [esi]GraphicViewPortClass.Height ; get width into register - mov [ y1_pixel ] , eax - - -do_remap: - cld - mov edi , [esi]GraphicViewPortClass.Offset - mov eax , [esi]GraphicViewPortClass.XAdd - mov ebx , [ x1_pixel ] - add eax , [esi]GraphicViewPortClass.Width - add eax , [esi]GraphicViewPortClass.Pitch - mov esi , eax - mul [ y0_pixel ] - add edi , [ x0_pixel ] - sub ebx , [ x0_pixel ] - jle real_out - add edi , eax - sub esi , ebx - - mov ecx , [ y1_pixel ] - sub ecx , [ y0_pixel ] - jle real_out - mov eax , [ remap ] - mov [ counter_x ] , ebx - xor edx , edx - -outer_loop: - mov ebx , [ counter_x ] -inner_loop: - mov dl , [ edi ] - mov dl , [ eax + edx ] - mov [ edi ] , dl - inc edi - dec ebx - jnz inner_loop - add edi , esi - dec ecx - jnz outer_loop - - - - -real_out: -// ret - } -} - - - - - - - - - - - - - - - -/* -; ************************************************************************** -; ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S * -; ************************************************************************** -; * * -; * Project Name : WSA Support routines * -; * * -; * File Name : XORDELTA.ASM * -; * * -; * Programmer : Scott K. Bowen * -; * * -; * Last Update :May 23, 1994 [SKB] * -; * * -; *------------------------------------------------------------------------* -; * Functions: * -;* Apply_XOR_Delta -- Apply XOR delta data to a buffer. * -;* Apply_XOR_Delta_To_Page_Or_Viewport -- Calls the copy or the XOR funti* -;* Copy_Delta_buffer -- Copies XOR Delta Data to a section of a page. * -;* XOR_Delta_Buffer -- Xor's the data in a XOR Delta format to a page. * -; * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* - -IDEAL -P386 -MODEL USE32 FLAT -*/ - - -/* -LOCALS ?? - -; These are used to call Apply_XOR_Delta_To_Page_Or_Viewport() to setup flags parameter. If -; These change, make sure and change their values in wsa.cpp. -DO_XOR equ 0 -DO_COPY equ 1 -TO_VIEWPORT equ 0 -TO_PAGE equ 2 - -; -; Routines defined in this module -; -; -; UWORD Apply_XOR_Delta(UWORD page_seg, BYTE *delta_ptr); -; PUBLIC Apply_XOR_Delta_To_Page_Or_Viewport(UWORD page_seg, BYTE *delta_ptr, WORD width, WORD copy) -; -; PROC C XOR_Delta_Buffer -; PROC C Copy_Delta_Buffer -; - -GLOBAL C Apply_XOR_Delta:NEAR -GLOBAL C Apply_XOR_Delta_To_Page_Or_Viewport:NEAR -*/ - -#define DO_XOR 0 -#define DO_COPY 1 -#define TO_VIEWPORT 0 -#define TO_PAGE 2 - -void __cdecl XOR_Delta_Buffer(int nextrow); -void __cdecl Copy_Delta_Buffer(int nextrow); - - -/* -;*************************************************************************** -;* APPLY_XOR_DELTA -- Apply XOR delta data to a linear buffer. * -;* AN example of this in C is at the botton of the file commented out. * -;* * -;* INPUT: BYTE *target - destination buffer. * -;* BYTE *delta - xor data to be delta uncompress. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 05/23/1994 SKB : Created. * -;*=========================================================================* -*/ -unsigned int __cdecl Apply_XOR_Delta(char *target, char *delta) -{ -/* -PROC Apply_XOR_Delta C near - USES ebx,ecx,edx,edi,esi - ARG target:DWORD ; pointers. - ARG delta:DWORD ; pointers. -*/ - - __asm { - - ; Optimized for 486/pentium by rearanging instructions. - mov edi,[target] ; get our pointers into offset registers. - mov esi,[delta] - - cld ; make sure we go forward - xor ecx,ecx ; use cx for loop - - top_loop: - xor eax,eax ; clear out eax. - mov al,[esi] ; get delta source byte - inc esi - - test al,al ; check for a SHORTDUMP ; check al incase of sign value. - je short_run - js check_others - - ; - ; SHORTDUMP - ; - mov ecx,eax ; stick count in cx - - dump_loop: - mov al,[esi] ;get delta XOR byte - xor [edi],al ; xor that byte on the dest - inc esi - inc edi - dec ecx - jnz dump_loop - jmp top_loop - - ; - ; SHORTRUN - ; - - short_run: - mov cl,[esi] ; get count - inc esi ; inc delta source - - do_run: - mov al,[esi] ; get XOR byte - inc esi - - run_loop: - xor [edi],al ; xor that byte. - - inc edi ; go to next dest pixel - dec ecx ; one less to go. - jnz run_loop - jmp top_loop - - ; - ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP - ; - - check_others: - sub eax,080h ; opcode -= 0x80 - jnz do_skip ; if zero then get next word, otherwise use remainder. - - mov ax,[esi] - lea esi,[esi+2] ; get word code in ax - test ax,ax ; set flags. (not 32bit register so neg flag works) - jle not_long_skip - - ; - ; SHORTSKIP AND LONGSKIP - ; - do_skip: - add edi,eax ; do the skip. - jmp top_loop - - - not_long_skip: - jz stop ; long count of zero means stop - sub eax,08000h ; opcode -= 0x8000 - test eax,04000h ; is it a LONGRUN (code & 0x4000)? - je long_dump - - ; - ; LONGRUN - ; - sub eax,04000h ; opcode -= 0x4000 - mov ecx,eax ; use cx as loop count - jmp do_run ; jump to run code. - - - ; - ; LONGDUMP - ; - - long_dump: - mov ecx,eax ; use cx as loop count - jmp dump_loop ; go to the dump loop. - - stop: - } -} - - -/* -;---------------------------------------------------------------------------- - -;*************************************************************************** -;* APPLY_XOR_DELTA_To_Page_Or_Viewport -- Calls the copy or the XOR funtion. * -;* * -;* * -;* This funtion is call to either xor or copy XOR_Delta data onto a * -;* page instead of a buffer. The routine will set up the registers * -;* need for the actual routines that will perform the copy or xor. * -;* * -;* The registers are setup as follows : * -;* es:edi - destination segment:offset onto page. * -;* ds:esi - source buffer segment:offset of delta data. * -;* dx,cx,ax - are all zeroed out before entry. * -;* * -;* INPUT: * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 03/09/1992 SB : Created. * -;*=========================================================================* -*/ - -void __cdecl Apply_XOR_Delta_To_Page_Or_Viewport(void *target, void *delta, int width, int nextrow, int copy) -{ - /* - USES ebx,ecx,edx,edi,esi - ARG target:DWORD ; pointer to the destination buffer. - ARG delta:DWORD ; pointer to the delta buffer. - ARG width:DWORD ; width of animation. - ARG nextrow:DWORD ; Page/Buffer width - anim width. - ARG copy:DWORD ; should it be copied or xor'd? - */ - - __asm { - - mov edi,[target] ; Get the target pointer. - mov esi,[delta] ; Get the destination pointer. - - xor eax,eax ; clear eax, later put them into ecx and edx. - - cld ; make sure we go forward - - mov ebx,[nextrow] ; get the amount to add to get to next row from end. push it later... - - mov ecx,eax ; use cx for loop - mov edx,eax ; use dx to count the relative column. - - push ebx ; push nextrow onto the stack for Copy/XOR_Delta_Buffer. - mov ebx,[width] ; bx will hold the max column for speed compares - - ; At this point, all the registers have been set up. Now call the correct function - ; to either copy or xor the data. - - cmp [copy],DO_XOR ; Do we want to copy or XOR - je xorfunct ; Jump to XOR if not copy - call Copy_Delta_Buffer ; Call the function to copy the delta buffer. - jmp didcopy ; jump past XOR - xorfunct: - call XOR_Delta_Buffer ; Call funtion to XOR the deltat buffer. - didcopy: - pop ebx ; remove the push done to pass a value. - } -} - - -/* -;---------------------------------------------------------------------------- - - -;*************************************************************************** -;* XOR_DELTA_BUFFER -- Xor's the data in a XOR Delta format to a page. * -;* This will only work right if the page has the previous data on it. * -;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. * -;* The registers must be setup as follows : * -;* * -;* INPUT: * -;* es:edi - destination segment:offset onto page. * -;* ds:esi - source buffer segment:offset of delta data. * -;* edx,ecx,eax - are all zeroed out before entry. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 03/09/1992 SB : Created. * -;*=========================================================================* -*/ -void __cdecl XOR_Delta_Buffer(int nextrow) -{ - /* - ARG nextrow:DWORD - */ - - __asm { - - top_loop: - xor eax,eax ; clear out eax. - mov al,[esi] ; get delta source byte - inc esi - - test al,al ; check for a SHORTDUMP ; check al incase of sign value. - je short_run - js check_others - - ; - ; SHORTDUMP - ; - mov ecx,eax ; stick count in cx - - dump_loop: - mov al,[esi] ; get delta XOR byte - xor [edi],al ; xor that byte on the dest - inc esi - inc edx ; increment our count on current column - inc edi - cmp edx,ebx ; are we at the final column - jne end_col1 ; if not the jmp over the code - - sub edi,edx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row - end_col1: - - dec ecx - jnz dump_loop - jmp top_loop - - ; - ; SHORTRUN - ; - - short_run: - mov cl,[esi] ; get count - inc esi ; inc delta source - - do_run: - mov al,[esi] ; get XOR byte - inc esi - - run_loop: - xor [edi],al ; xor that byte. - - inc edx ; increment our count on current column - inc edi ; go to next dest pixel - cmp edx,ebx ; are we at the final column - jne end_col2 ; if not the jmp over the code - - sub edi,ebx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row - end_col2: - - - dec ecx - jnz run_loop - jmp top_loop - - ; - ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP - ; - - check_others: - sub eax,080h ; opcode -= 0x80 - jnz do_skip ; if zero then get next word, otherwise use remainder. - - mov ax,[esi] ; get word code in ax - lea esi,[esi+2] - test ax,ax ; set flags. (not 32bit register so neg flag works) - jle not_long_skip - - ; - ; SHORTSKIP AND LONGSKIP - ; - do_skip: - sub edi,edx ; go back to beginning or row. - add edx,eax ; incriment our count on current row - recheck3: - cmp edx,ebx ; are we past the end of the row - jb end_col3 ; if not the jmp over the code - - sub edx,ebx ; Subtract width from the col counter - add edi,[nextrow] ; jump to start of next row - jmp recheck3 ; jump up to see if we are at the right row - end_col3: - add edi,edx ; get to correct position in row. - jmp top_loop - - - not_long_skip: - jz stop ; long count of zero means stop - sub eax,08000h ; opcode -= 0x8000 - test eax,04000h ; is it a LONGRUN (code & 0x4000)? - je long_dump - - ; - ; LONGRUN - ; - sub eax,04000h ; opcode -= 0x4000 - mov ecx,eax ; use cx as loop count - jmp do_run ; jump to run code. - - - ; - ; LONGDUMP - ; - - long_dump: - mov ecx,eax ; use cx as loop count - jmp dump_loop ; go to the dump loop. - - stop: - - } -} - - -/* -;---------------------------------------------------------------------------- - - -;*************************************************************************** -;* COPY_DELTA_BUFFER -- Copies XOR Delta Data to a section of a page. * -;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. * -;* The registers must be setup as follows : * -;* * -;* INPUT: * -;* es:edi - destination segment:offset onto page. * -;* ds:esi - source buffer segment:offset of delta data. * -;* dx,cx,ax - are all zeroed out before entry. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 03/09/1992 SB : Created. * -;*=========================================================================* -*/ -void __cdecl Copy_Delta_Buffer(int nextrow) -{ - /* - ARG nextrow:DWORD - */ - - __asm { - - top_loop: - xor eax,eax ; clear out eax. - mov al,[esi] ; get delta source byte - inc esi - - test al,al ; check for a SHORTDUMP ; check al incase of sign value. - je short_run - js check_others - - ; - ; SHORTDUMP - ; - mov ecx,eax ; stick count in cx - - dump_loop: - mov al,[esi] ; get delta XOR byte - - mov [edi],al ; store that byte on the dest - - inc edx ; increment our count on current column - inc esi - inc edi - cmp edx,ebx ; are we at the final column - jne end_col1 ; if not the jmp over the code - - sub edi,edx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row - end_col1: - - dec ecx - jnz dump_loop - jmp top_loop - - ; - ; SHORTRUN - ; - - short_run: - mov cl,[esi] ; get count - inc esi ; inc delta source - - do_run: - mov al,[esi] ; get XOR byte - inc esi - - run_loop: - mov [edi],al ; store the byte (instead of XOR against current color) - - inc edx ; increment our count on current column - inc edi ; go to next dest pixel - cmp edx,ebx ; are we at the final column - jne end_col2 ; if not the jmp over the code - - sub edi,ebx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row - end_col2: - - - dec ecx - jnz run_loop - jmp top_loop - - ; - ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP - ; - - check_others: - sub eax,080h ; opcode -= 0x80 - jnz do_skip ; if zero then get next word, otherwise use remainder. - - mov ax,[esi] ; get word code in ax - lea esi,[esi+2] - test ax,ax ; set flags. (not 32bit register so neg flag works) - jle not_long_skip - - ; - ; SHORTSKIP AND LONGSKIP - ; - do_skip: - sub edi,edx ; go back to beginning or row. - add edx,eax ; incriment our count on current row - recheck3: - cmp edx,ebx ; are we past the end of the row - jb end_col3 ; if not the jmp over the code - - sub edx,ebx ; Subtract width from the col counter - add edi,[nextrow] ; jump to start of next row - jmp recheck3 ; jump up to see if we are at the right row - end_col3: - add edi,edx ; get to correct position in row. - jmp top_loop - - - not_long_skip: - jz stop ; long count of zero means stop - sub eax,08000h ; opcode -= 0x8000 - test eax,04000h ; is it a LONGRUN (code & 0x4000)? - je long_dump - - ; - ; LONGRUN - ; - sub eax,04000h ; opcode -= 0x4000 - mov ecx,eax ; use cx as loop count - jmp do_run ; jump to run code. - - - ; - ; LONGDUMP - ; - - long_dump: - mov ecx,eax ; use cx as loop count - jmp dump_loop ; go to the dump loop. - - stop: - - } -} -/* -;---------------------------------------------------------------------------- -*/ - - - - - - - - - - - - - - - - - - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : Westwood Library * -;* * -;* File Name : FADING.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : August 20, 1993 * -;* * -;* Last Update : August 20, 1993 [JLB] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Build_Fading_Table :NEAR - - CODESEG - -;*********************************************************** -; BUILD_FADING_TABLE -; -; void *Build_Fading_Table(void *palette, void *dest, long int color, long int frac); -; -; This routine will create the fading effect table used to coerce colors -; from toward a common value. This table is used when Fading_Effect is -; active. -; -; Bounds Checking: None -;* -*/ -void * __cdecl Build_Fading_Table(void const *palette, void const *dest, long int color, long int frac) -{ - /* - PROC Build_Fading_Table C near - USES ebx, ecx, edi, esi - ARG palette:DWORD - ARG dest:DWORD - ARG color:DWORD - ARG frac:DWORD - - LOCAL matchvalue:DWORD ; Last recorded match value. - LOCAL targetred:BYTE ; Target gun red. - LOCAL targetgreen:BYTE ; Target gun green. - LOCAL targetblue:BYTE ; Target gun blue. - LOCAL idealred:BYTE - LOCAL idealgreen:BYTE - LOCAL idealblue:BYTE - LOCAL matchcolor:BYTE ; Tentative match color. - */ - - int matchvalue = 0; //:DWORD ; Last recorded match value. - unsigned char targetred = 0; //BYTE ; Target gun red. - unsigned char targetgreen = 0; //BYTE ; Target gun green. - unsigned char targetblue = 0; //BYTE ; Target gun blue. - unsigned char idealred = 0; //BYTE - unsigned char idealgreen = 0; //BYTE - unsigned char idealblue = 0; //BYTE - unsigned char matchcolor = 0; //:BYTE ; Tentative match color. - - __asm { - cld - - ; If the source palette is NULL, then just return with current fading table pointer. - cmp [palette],0 - je fini - cmp [dest],0 - je fini - - ; Fractions above 255 become 255. - mov eax,[frac] - cmp eax,0100h - jb short ok - mov [frac],0FFh - ok: - - ; Record the target gun values. - mov esi,[palette] - mov ebx,[color] - add esi,ebx - add esi,ebx - add esi,ebx - lodsb - mov [targetred],al - lodsb - mov [targetgreen],al - lodsb - mov [targetblue],al - - ; Main loop. - xor ebx,ebx ; Remap table index. - - ; Transparent black never gets remapped. - mov edi,[dest] - mov [edi],bl - inc edi - - ; EBX = source palette logical number (1..255). - ; EDI = running pointer into dest remap table. - mainloop: - inc ebx - mov esi,[palette] - add esi,ebx - add esi,ebx - add esi,ebx - - mov edx,[frac] - shr edx,1 - ; new = orig - ((orig-target) * fraction); - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetred] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl ax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealred],dh ; preserve ideal color gun value. - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetgreen] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl ax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealgreen],dh ; preserve ideal color gun value. - - lodsb ; orig - mov dh,al ; preserve it for later. - sub al,[targetblue] ; al = (orig-target) - imul dl ; ax = (orig-target)*fraction - shl ax,1 - sub dh,ah ; dh = orig - ((orig-target) * fraction) - mov [idealblue],dh ; preserve ideal color gun value. - - ; Sweep through the entire existing palette to find the closest - ; matching color. Never matches with color 0. - - mov eax,[color] - mov [matchcolor],al ; Default color (self). - mov [matchvalue],-1 ; Ridiculous match value init. - mov ecx,255 - - mov esi,[palette] ; Pointer to original palette. - add esi,3 - - ; BH = color index. - mov bh,1 - innerloop: - - ; Recursion through the fading table won't work if a color is allowed - ; to remap to itself. Prevent this from occuring. - add esi,3 - cmp bh,bl - je short notclose - sub esi,3 - - xor edx,edx ; Comparison value starts null. - mov eax,edx - ; Build the comparison value based on the sum of the differences of the color - ; guns squared. - lodsb - sub al,[idealred] - mov ah,al - imul ah - add edx,eax - - lodsb - sub al,[idealgreen] - mov ah,al - imul ah - add edx,eax - - lodsb - sub al,[idealblue] - mov ah,al - imul ah - add edx,eax - jz short perfect ; If perfect match found then quit early. - - cmp edx,[matchvalue] - ja short notclose - mov [matchvalue],edx ; Record new possible color. - mov [matchcolor],bh - notclose: - inc bh ; Checking color index. - loop innerloop - mov bh,[matchcolor] - perfect: - mov [matchcolor],bh - xor bh,bh ; Make BX valid main index again. - - ; When the loop exits, we have found the closest match. - mov al,[matchcolor] - stosb - cmp ebx,255 - jne mainloop - - fini: - mov eax,[dest] -// ret - - - } -} - - - - - - - - - - - - - - - - - - - - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood Library * -;* * -;* File Name : PAL.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 30, 1992 * -;* * -;* Last Update : April 27, 1994 [BR] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Set_Palette_Range -- Sets changed values in the palette. * -;* Bump_Color -- adjusts specified color in specified palette * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -;********************** Model & Processor Directives ************************ -IDEAL -P386 -MODEL USE32 FLAT - - -;include "keyboard.inc" -FALSE = 0 -TRUE = 1 - -;****************************** Declarations ******************************** -GLOBAL C Set_Palette_Range:NEAR -GLOBAL C Bump_Color:NEAR -GLOBAL C CurrentPalette:BYTE:768 -GLOBAL C PaletteTable:byte:1024 - - -;********************************** Data ************************************ -LOCALS ?? - - DATASEG - -CurrentPalette DB 768 DUP(255) ; copy of current values of DAC regs -PaletteTable DB 1024 DUP(0) - -IFNDEF LIB_EXTERNS_RESOLVED -VertBlank DW 0 ; !!!! this should go away -ENDIF - - -;********************************** Code ************************************ - CODESEG -*/ - -extern "C" unsigned char CurrentPalette[768] = {255}; // DB 768 DUP(255) ; copy of current values of DAC regs -extern "C" unsigned char PaletteTable[1024] = {0}; // DB 1024 DUP(0) - - -/* -;*************************************************************************** -;* SET_PALETTE_RANGE -- Sets a palette range to the new pal * -;* * -;* INPUT: * -;* * -;* OUTPUT: * -;* * -;* PROTO: * -;* * -;* WARNINGS: This routine is optimized for changing a small number of * -;* colors in the palette. -;* * -;* HISTORY: * -;* 03/07/1995 PWG : Created. * -;*=========================================================================* -*/ -void __cdecl Set_Palette_Range(void *palette) -{ - memcpy(CurrentPalette, palette, 768); - Set_DD_Palette(palette); - - /* - PROC Set_Palette_Range C NEAR - ARG palette:DWORD - - GLOBAL Set_DD_Palette_:near - GLOBAL Wait_Vert_Blank_:near - - pushad - mov esi,[palette] - mov ecx,768/4 - mov edi,offset CurrentPalette - cld - rep movsd - ;call Wait_Vert_Blank_ - mov eax,[palette] - push eax - call Set_DD_Palette_ - pop eax - popad - ret - */ -} - - -/* -;*************************************************************************** -;* Bump_Color -- adjusts specified color in specified palette * -;* * -;* INPUT: * -;* VOID *palette - palette to modify * -;* WORD changable - color # to change * -;* WORD target - color to bend toward * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 04/27/1994 BR : Converted to 32-bit. * -;*=========================================================================* -; BOOL cdecl Bump_Color(VOID *palette, WORD changable, WORD target); -*/ -BOOL __cdecl Bump_Color(void *pal, int color, int desired) -{ - /* -PROC Bump_Color C NEAR - USES ebx,ecx,edi,esi - ARG pal:DWORD, color:WORD, desired:WORD - LOCAL changed:WORD ; Has palette changed? - */ - - short short_color = (short) color; - short short_desired = (short) desired; - bool changed = false; - - __asm { - mov edi,[pal] ; Original palette pointer. - mov esi,edi - mov eax,0 - mov ax,[short_color] - add edi,eax - add edi,eax - add edi,eax ; Offset to changable color. - mov ax,[short_desired] - add esi,eax - add esi,eax - add esi,eax ; Offset to target color. - - mov [changed],FALSE ; Presume no change. - mov ecx,3 ; Three color guns. - - ; Check the color gun. - colorloop: - mov al,[BYTE PTR esi] - sub al,[BYTE PTR edi] ; Carry flag is set if subtraction needed. - jz short gotit - mov [changed],TRUE - inc [BYTE PTR edi] ; Presume addition. - jnc short gotit ; oops, subtraction needed so dec twice. - dec [BYTE PTR edi] - dec [BYTE PTR edi] - gotit: - inc edi - inc esi - loop colorloop - - movzx eax,[changed] - } -} - - - - - - - - - - - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : GraphicViewPortClass * -;* * -;* File Name : PUTPIXEL.ASM * -;* * -;* Programmer : Phil Gorrow * -;* * -;* Start Date : June 7, 1994 * -;* * -;* Last Update : June 8, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* VVPC::Put_Pixel -- Puts a pixel on a virtual viewport * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -INCLUDE ".\drawbuff.inc" -INCLUDE ".\gbuffer.inc" - - -CODESEG -*/ - -/* -;*************************************************************************** -;* VVPC::PUT_PIXEL -- Puts a pixel on a virtual viewport * -;* * -;* INPUT: WORD the x position for the pixel relative to the upper * -;* left corner of the viewport * -;* WORD the y pos for the pixel relative to the upper left * -;* corner of the viewport * -;* UBYTE the color of the pixel to write * -;* * -;* OUTPUT: none * -;* * -;* WARNING: If pixel is to be placed outside of the viewport then * -;* this routine will abort. * -;* * -;* HISTORY: * -;* 06/08/1994 PWG : Created. * -;*=========================================================================* - PROC Buffer_Put_Pixel C near - USES eax,ebx,ecx,edx,edi -*/ - -void __cdecl Buffer_Put_Pixel(void * this_object, int x_pixel, int y_pixel, unsigned char color) -{ - - /* - ARG this_object:DWORD ; this is a member function - ARG x_pixel:DWORD ; x position of pixel to set - ARG y_pixel:DWORD ; y position of pixel to set - ARG color:BYTE ; what color should we clear to - */ - - __asm { - - - ;*=================================================================== - ; Get the viewport information and put bytes per row in ecx - ;*=================================================================== - mov ebx,[this_object] ; get a pointer to viewport - xor eax,eax - mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset - mov ecx,[ebx]GraphicViewPortClass.Height ; edx = height of viewport - mov edx,[ebx]GraphicViewPortClass.Width ; ecx = width of viewport - - ;*=================================================================== - ; Verify that the X pixel offset if legal - ;*=================================================================== - mov eax,[x_pixel] ; find the x position - cmp eax,edx ; is it out of bounds - jae short done ; if so then get out - add edi,eax ; otherwise add in offset - - ;*=================================================================== - ; Verify that the Y pixel offset if legal - ;*=================================================================== - mov eax,[y_pixel] ; get the y position - cmp eax,ecx ; is it out of bounds - jae done ; if so then get out - add edx,[ebx]GraphicViewPortClass.XAdd ; otherwise find bytes per row - add edx,[ebx]GraphicViewPortClass.Pitch ; add in direct draw pitch - mul edx ; offset = bytes per row * y - add edi,eax ; add it into the offset - - ;*=================================================================== - ; Write the pixel to the screen - ;*=================================================================== - mov al,[color] ; read in color value - mov [edi],al ; write it to the screen - done: - } -} - - - - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : cliprect.asm * -;* * -;* Programmer : Julio R Jerez * -;* * -;* Start Date : Mar, 2 1995 * -;* * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* int Clip_Rect ( int * x , int * y , int * dw , int * dh , * -;* int width , int height ) ; * -;* int Confine_Rect ( int * x , int * y , int * dw , int * dh , * -;* int width , int height ) ; * -;* * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Clip_Rect :NEAR -GLOBAL C Confine_Rect :NEAR - -CODESEG - -;*************************************************************************** -;* Clip_Rect -- clip a given rectangle against a given window * -;* * -;* INPUT: &x , &y , &w , &h -> Pointer to rectangle being clipped * -;* width , height -> dimension of clipping window * -;* * -;* OUTPUT: a) Zero if the rectangle is totally contained by the * -;* clipping window. * -;* b) A negative value if the rectangle is totally outside the * -;* the clipping window * -;* c) A positive value if the rectangle was clipped against the * -;* clipping window, also the values pointed by x, y, w, h will * -;* be modified to new clipped values * -;* * -;* 05/03/1995 JRJ : added comment * -;*=========================================================================* -; int Clip_Rect (int* x, int* y, int* dw, int* dh, int width, int height); * -*/ - -extern "C" int __cdecl Clip_Rect ( int * x , int * y , int * w , int * h , int width , int height ) -{ - -/* - PROC Clip_Rect C near - uses ebx,ecx,edx,esi,edi - arg x:dword - arg y:dword - arg w:dword - arg h:dword - arg width:dword - arg height:dword -*/ - - __asm { - - ;This Clipping algorithm is a derivation of the very well known - ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency - ;it is probably the most commontly implemented algorithm both in software - ;and hardware for clipping lines, rectangles, and convex polygons against - ;a rectagular clipping window. For reference see - ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes - ; pages 113 to 177". - ; Briefly consist in computing the Sutherland code for both end point of - ; the rectangle to find out if the rectangle is: - ; - trivially accepted (no further clipping test, return the oroginal data) - ; - trivially rejected (return with no action, return error code) - ; - retangle must be iteratively clipped again edges of the clipping window - ; and return the clipped rectangle - - ; get all four pointer into regisnters - mov esi,[x] ; esi = pointer to x - mov edi,[y] ; edi = pointer to x - mov eax,[w] ; eax = pointer to dw - mov ebx,[h] ; ebx = pointer to dh - - ; load the actual data into reg - mov esi,[esi] ; esi = x0 - mov edi,[edi] ; edi = y0 - mov eax,[eax] ; eax = dw - mov ebx,[ebx] ; ebx = dh - - ; create a wire frame of the type [x0,y0] , [x1,y1] - add eax,esi ; eax = x1 = x0 + dw - add ebx,edi ; ebx = y1 = y0 + dh - - ; we start we suthenland code0 and code1 set to zero - xor ecx,ecx ; cl = sutherland boolean code0 - xor edx,edx ; dl = sutherland boolean code0 - - ; now we start computing the to suthenland boolean code for x0 , x1 - shld ecx,esi,1 ; bit3 of code0 = sign bit of (x0 - 0) - shld edx,eax,1 ; bit3 of code1 = sign bit of (x1 - 0) - sub esi,[width] ; get the difference (x0 - (width + 1)) - sub eax,[width] ; get the difference (x1 - (width + 1)) - dec esi - dec eax - shld ecx,esi,1 ; bit2 of code0 = sign bit of (x0 - (width + 1)) - shld edx,eax,1 ; bit2 of code1 = sign bit of (x0 - (width + 1)) - - ; now we start computing the to suthenland boolean code for y0 , y1 - shld ecx,edi,1 ; bit1 of code0 = sign bit of (y0 - 0) - shld edx,ebx,1 ; bit1 of code1 = sign bit of (y0 - 0) - sub edi,[height] ; get the difference (y0 - (height + 1)) - sub ebx,[height] ; get the difference (y1 - (height + 1)) - dec edi - dec ebx - shld ecx,edi,1 ; bit0 of code0 = sign bit of (y0 - (height + 1)) - shld edx,ebx,1 ; bit0 of code1 = sign bit of (y1 - (height + 1)) - - ; Bit 2 and 0 of cl and bl are complemented - xor cl,5 ; reverse bit2 and bit0 in code0 - xor dl,5 ; reverse bit2 and bit0 in code1 - - ; now perform the rejection test - mov eax,-1 ; set return code to false - mov bl,cl ; save code0 for future use - test dl,cl ; if any two pair of bit in code0 and code1 is set - jnz clip_out ; then rectangle is outside the window - - ; now perform the aceptance test - xor eax,eax ; set return code to true - or bl,dl ; if all pair of bits in code0 and code1 are reset - jz clip_out ; then rectangle is insize the window. ' - - ; we need to clip the rectangle iteratively - mov eax,-1 ; set return code to false - test cl,1000b ; if bit3 of code0 is set then the rectangle - jz left_ok ; spill out the left edge of the window - mov edi,[x] ; edi = a pointer to x0 - mov ebx,[w] ; ebx = a pointer to dw - mov esi,[edi] ; esi = x0 - mov [dword ptr edi],0 ; set x0 to 0 "this the left edge value" - add [ebx],esi ; adjust dw by x0, since x0 must be negative - - left_ok: - test cl,0010b ; if bit1 of code0 is set then the rectangle - jz bottom_ok ; spill out the bottom edge of the window - mov edi,[y] ; edi = a pointer to y0 - mov ebx,[h] ; ebx = a pointer to dh - mov esi,[edi] ; esi = y0 - mov [dword ptr edi],0 ; set y0 to 0 "this the bottom edge value" - add [ebx],esi ; adjust dh by y0, since y0 must be negative - - bottom_ok: - test dl,0100b ; if bit2 of code1 is set then the rectangle - jz right_ok ; spill out the right edge of the window - mov edi,[w] ; edi = a pointer to dw - mov esi,[x] ; esi = a pointer to x - mov ebx,[width] ; ebx = the width of the window - sub ebx,[esi] ; the new dw is the difference (width-x0) - mov [edi],ebx ; adjust dw to (width - x0) - jle clip_out ; if (width-x0) = 0 then the clipped retangle - ; has no width we are done - right_ok: - test dl,0001b ; if bit0 of code1 is set then the rectangle - jz clip_ok ; spill out the top edge of the window - mov edi,[h] ; edi = a pointer to dh - mov esi,[y] ; esi = a pointer to y0 - mov ebx,[height] ; ebx = the height of the window - sub ebx,[esi] ; the new dh is the difference (height-y0) - mov [edi],ebx ; adjust dh to (height-y0) - jle clip_out ; if (width-x0) = 0 then the clipped retangle - ; has no width we are done - clip_ok: - mov eax,1 ; signal the calling program that the rectangle was modify - clip_out: - //ret - } - - //ENDP Clip_Rect -} - -/* -;*************************************************************************** -;* Confine_Rect -- clip a given rectangle against a given window * -;* * -;* INPUT: &x,&y,w,h -> Pointer to rectangle being clipped * -;* width,height -> dimension of clipping window * -;* * -;* OUTPUT: a) Zero if the rectangle is totally contained by the * -;* clipping window. * -;* c) A positive value if the rectangle was shifted in position * -;* to fix inside the clipping window, also the values pointed * -;* by x, y, will adjusted to a new values * -;* * -;* NOTE: this function make not attempt to verify if the rectangle is * -;* bigger than the clipping window and at the same time wrap around* -;* it. If that is the case the result is meaningless * -;*=========================================================================* -; int Confine_Rect (int* x, int* y, int dw, int dh, int width, int height); * -*/ - -extern "C" int __cdecl Confine_Rect ( int * x , int * y , int w , int h , int width , int height ) -{ - -/* - PROC Confine_Rect C near - uses ebx, esi,edi - arg x:dword - arg y:dword - arg w:dword - arg h:dword - arg width :dword - arg height:dword -*/ - __asm { - - xor eax,eax - mov ebx,[x] - mov edi,[w] - - mov esi,[ebx] - add edi,[ebx] - - sub edi,[width] - neg esi - dec edi - - test esi,edi - jl x_axix_ok - mov eax,1 - - test esi,esi - jl shift_right - mov [dword ptr ebx],0 - jmp x_axix_ok - shift_right: - inc edi - sub [ebx],edi - x_axix_ok: - mov ebx,[y] - mov edi,[h] - - mov esi,[ebx] - add edi,[ebx] - - sub edi,[height] - neg esi - dec edi - - test esi,edi - jl confi_out - mov eax,1 - - test esi,esi - jl shift_top - mov [dword ptr ebx],0 - - //ret - jmp confi_out - shift_top: - inc edi - sub [ebx],edi - confi_out: - //ret - - //ENDP Confine_Rect - } -} - - - - - - - - - -/* -; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp#57 $ -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Library routine * -;* * -;* File Name : UNCOMP.ASM * -;* * -;* Programmer : Christopher Yates * -;* * -;* Last Update : 20 August, 1990 [CY] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* * -; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); * -;* * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C LCW_Uncompress :NEAR - -CODESEG - -; ---------------------------------------------------------------- -; -; Here are prototypes for the routines defined within this module: -; -; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); -; -; ---------------------------------------------------------------- -*/ - -extern "C" unsigned long __cdecl LCW_Uncompress(void *source, void *dest, unsigned long length_) -{ -//PROC LCW_Uncompress C near -// -// USES ebx,ecx,edx,edi,esi -// -// ARG source:DWORD -// ARG dest:DWORD -// ARG length:DWORD -//;LOCALS -// LOCAL a1stdest:DWORD -// LOCAL maxlen:DWORD -// LOCAL lastbyte:DWORD -// LOCAL lastcom:DWORD -// LOCAL lastcom1:DWORD - - unsigned long a1stdest; - unsigned long maxlen; - unsigned long lastbyte; - //unsigned long lastcom; - //unsigned long lastcom1; - - __asm { - - - mov edi,[dest] - mov esi,[source] - mov edx,[length_] - - ; - ; - ; uncompress data to the following codes in the format b = byte, w = word - ; n = byte code pulled from compressed data - ; Bit field of n command description - ; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3 - ; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes - ; n=11xxxxxx,w1 med run run x+3 bytes from offset w1 - ; n=11111111,w1,w2 long copy copy w1 bytes from offset w2 - ; n=11111110,w1,b1 long run run byte b1 for w1 bytes - ; n=10000000 end end of data reached - ; - - mov [a1stdest],edi - add edx,edi - mov [lastbyte],edx - cld ; make sure all lod and sto are forward - mov ebx,esi ; save the source offset - - loop_label: - mov eax,[lastbyte] - sub eax,edi ; get the remaining byte to uncomp - jz short out_label ; were done - - mov [maxlen],eax ; save for string commands - mov esi,ebx ; mov in the source index - - xor eax,eax - mov al,[esi] - inc esi - test al,al ; see if its a short run - js short notshort - - mov ecx,eax ;put count nibble in cl - - mov ah,al ; put rel offset high nibble in ah - and ah,0Fh ; only 4 bits count - - shr cl,4 ; get run -3 - add ecx,3 ; get actual run length - - cmp ecx,[maxlen] ; is it too big to fit? - jbe short rsok ; if not, its ok - - mov ecx,[maxlen] ; if so, max it out so it dosen't overrun - - rsok: - mov al,[esi] ; get rel offset low byte - lea ebx,[esi+1] ; save the source offset - mov esi,edi ; get the current dest - sub esi,eax ; get relative offset - - rep movsb - - jmp loop_label - - notshort: - test al,40h ; is it a length? - jne short notlength ; if not it could be med or long run - - cmp al,80h ; is it the end? - je short out_label ; if so its over - - mov cl,al ; put the byte in count register - and ecx,3Fh ; and off the extra bits - - cmp ecx,[maxlen] ; is it too big to fit? - jbe short lenok ; if not, its ok - - mov ecx,[maxlen] ; if so, max it out so it dosen't overrun - - lenok: - rep movsb - - mov ebx,esi ; save the source offset - jmp loop_label - - out_label: - mov eax,edi - sub eax,[a1stdest] - jmp label_exit - - notlength: - mov cl,al ; get the entire code - and ecx,3Fh ; and off all but the size -3 - add ecx,3 ; add 3 for byte count - - cmp al,0FEh - jne short notrunlength - - xor ecx,ecx - mov cx,[esi] - - xor eax,eax - mov al,[esi+2] - lea ebx,[esi+3] ;save the source offset - - cmp ecx,[maxlen] ; is it too big to fit? - jbe short runlenok ; if not, its ok - - mov ecx,[maxlen] ; if so, max it out so it dosen't overrun - - runlenok: - test ecx,0ffe0h - jnz dont_use_stosb - rep stosb - jmp loop_label - - - dont_use_stosb: - mov ah,al - mov edx,eax - shl eax,16 - or eax,edx - - test edi,3 - jz aligned - - mov [edi],eax - mov edx,edi - and edi,0fffffffch - lea edi,[edi+4] - and edx,3 - dec dl - xor dl,3 - sub ecx,edx - - aligned: - mov edx,ecx - shr ecx,2 - rep stosd - - and edx,3 - jz loop_label - mov ecx,edx - rep stosb - jmp loop_label - - - - - - - notrunlength: - cmp al,0FFh ; is it a long run? - jne short notlong ; if not use the code as the size - - xor ecx,ecx - xor eax,eax - mov cx,[esi] ; if so, get the size - lea esi,[esi+2] - - notlong: - mov ax,[esi] ;get the real index - add eax,[a1stdest] ;add in the 1st index - lea ebx,[esi+2] ;save the source offset - cmp ecx,[maxlen] ;compare for overrun - mov esi,eax ;use eax as new source - jbe short runok ; if not, its ok - - mov ecx,[maxlen] ; if so, max it out so it dosen't overrun - - runok: - test ecx,0ffe0h - jnz dont_use_movsb - rep movsb - jmp loop_label - - - - - dont_use_movsb: - lea edx,[edi+0fffffffch] - cmp esi,edx - ja use_movsb - - test edi,3 - jz aligned2 - - mov eax,[esi] - mov [edi],eax - mov edx,edi - and edi,0fffffffch - lea edi,[edi+4] - and edx,3 - dec dl - xor dl,3 - sub ecx,edx - add esi,edx - - aligned2: - mov edx,ecx - shr ecx,2 - and edx,3 - rep movsd - mov ecx,edx - use_movsb: - rep movsb - jmp loop_label - - - - - label_exit: - mov eax,edi - mov ebx,[dest] - sub eax,ebx - - //ret - - } -} - - - - - - - - - - - - - - -/* -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : TOPAGE.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : June 8, 1994 * -;* * -;* Last Update : June 15, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Buffer_To_Page -- Copies a linear buffer to a virtual viewport * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -IDEAL -P386 -MODEL USE32 FLAT - -TRANSP equ 0 - - -INCLUDE ".\drawbuff.inc" -INCLUDE ".\gbuffer.inc" - -CODESEG - -;*************************************************************************** -;* VVC::TOPAGE -- Copies a linear buffer to a virtual viewport * -;* * -;* INPUT: WORD x_pixel - x pixel on viewport to copy from * -;* WORD y_pixel - y pixel on viewport to copy from * -;* WORD pixel_width - the width of copy region * -;* WORD pixel_height - the height of copy region * -;* BYTE * src - buffer to copy from * -;* VVPC * dest - virtual viewport to copy to * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: Coordinates and dimensions will be adjusted if they exceed * -;* the boundaries. In the event that no adjustment is * -;* possible this routine will abort. If the size of the * -;* region to copy exceeds the size passed in for the buffer * -;* the routine will automatically abort. * -;* * -;* HISTORY: * -;* 06/15/1994 PWG : Created. * -;*=========================================================================* - */ - -extern "C" long __cdecl Buffer_To_Page(int x_pixel, int y_pixel, int pixel_width, int pixel_height, void *src, void *dest) -{ - -/* - PROC Buffer_To_Page C near - USES eax,ebx,ecx,edx,esi,edi - - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ARG x_pixel :DWORD ; x pixel position in source - ARG y_pixel :DWORD ; y pixel position in source - ARG pixel_width :DWORD ; width of rectangle to blit - ARG pixel_height:DWORD ; height of rectangle to blit - ARG src :DWORD ; this is a member function - ARG dest :DWORD ; what are we blitting to - -; ARG trans :DWORD ; do we deal with transparents? - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL x1_pixel :dword - LOCAL y1_pixel :dword - local scr_x : dword - local scr_y : dword - LOCAL dest_ajust_width:DWORD - LOCAL scr_ajust_width:DWORD - LOCAL dest_area : dword -*/ - - unsigned long x1_pixel; - unsigned long y1_pixel; - unsigned long scr_x; - unsigned long scr_y; - unsigned long dest_ajust_width; - unsigned long scr_ajust_width; - //unsigned long dest_area; - - __asm { - - cmp [ src ] , 0 - jz real_out - - - ; Clip dest Rectangle against source Window boundaries. - - mov [ scr_x ] , 0 - mov [ scr_y ] , 0 - mov esi , [ dest ] ; get ptr to dest - xor ecx , ecx - xor edx , edx - mov edi , [esi]GraphicViewPortClass.Width ; get width into register - mov ebx , [ x_pixel ] - mov eax , [ x_pixel ] - add ebx , [ pixel_width ] - shld ecx , eax , 1 - mov [ x1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi, [esi]GraphicViewPortClass.Height ; get height into register - mov ebx , [ y_pixel ] - mov eax , [ y_pixel ] - add ebx , [ pixel_height ] - shld ecx , eax , 1 - mov [ y1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz real_out - or al , dl - jz do_blit - - test cl , 1000b - jz dest_left_ok - mov eax , [ x_pixel ] - neg eax - mov [ x_pixel ] , 0 - mov [ scr_x ] , eax - - dest_left_ok: - test cl , 0010b - jz dest_bottom_ok - mov eax , [ y_pixel ] - neg eax - mov [ y_pixel ] , 0 - mov [ scr_y ] , eax - - dest_bottom_ok: - test dl , 0100b - jz dest_right_ok - mov eax , [esi]GraphicViewPortClass.Width ; get width into register - mov [ x1_pixel ] , eax - dest_right_ok: - test dl , 0001b - jz do_blit - mov eax , [esi]GraphicViewPortClass.Height ; get width into register - mov [ y1_pixel ] , eax - - do_blit: - - cld - - mov eax , [esi]GraphicViewPortClass.XAdd - add eax , [esi]GraphicViewPortClass.Width - add eax , [esi]GraphicViewPortClass.Pitch - mov edi , [esi]GraphicViewPortClass.Offset - - mov ecx , eax - mul [ y_pixel ] - add edi , [ x_pixel ] - add edi , eax - - add ecx , [ x_pixel ] - sub ecx , [ x1_pixel ] - mov [ dest_ajust_width ] , ecx - - - mov esi , [ src ] - mov eax , [ pixel_width ] - sub eax , [ x1_pixel ] - add eax , [ x_pixel ] - mov [ scr_ajust_width ] , eax - - mov eax , [ scr_y ] - mul [ pixel_width ] - add eax , [ scr_x ] - add esi , eax - - mov edx , [ y1_pixel ] - mov eax , [ x1_pixel ] - - sub edx , [ y_pixel ] - jle real_out - sub eax , [ x_pixel ] - jle real_out - - - ; ******************************************************************** - ; Forward bitblit only - - //IF TRANSP - // test [ trans ] , 1 - // jnz forward_Blit_trans - //ENDIF - - - ; the inner loop is so efficient that - ; the optimal consept no longer apply because - ; the optimal byte have to by a number greather than 9 bytes - cmp eax , 10 - jl forward_loop_bytes - - forward_loop_dword: - mov ecx , edi - mov ebx , eax - neg ecx - and ecx , 3 - sub ebx , ecx - rep movsb - mov ecx , ebx - shr ecx , 2 - rep movsd - mov ecx , ebx - and ecx , 3 - rep movsb - add esi , [ scr_ajust_width ] - add edi , [ dest_ajust_width ] - dec edx - jnz forward_loop_dword - jmp real_out //ret - - forward_loop_bytes: - mov ecx , eax - rep movsb - add esi , [ scr_ajust_width ] - add edi , [ dest_ajust_width ] - dec edx ; decrement the height - jnz forward_loop_bytes - // ret - - //IF TRANSP - // - // - //forward_Blit_trans: - // - // - // mov ecx , eax - // and ecx , 01fh - // lea ecx , [ ecx + ecx * 4 ] - // neg ecx - // shr eax , 5 - // lea ecx , [ transp_reference + ecx * 2 ] - // mov [ y1_pixel ] , ecx - // - // - //forward_loop_trans: - // mov ecx , eax - // jmp [ y1_pixel ] - //forward_trans_line: - // REPT 32 - // local transp_pixel - // mov bl , [ esi ] - // inc esi - // test bl , bl - // jz transp_pixel - // mov [ edi ] , bl - // transp_pixel: - // inc edi - // ENDM - // transp_reference: - // dec ecx - // jge forward_trans_line - // add esi , [ scr_ajust_width ] - // add edi , [ dest_ajust_width ] - // dec edx - // jnz forward_loop_trans - // ret - //ENDIF - - real_out: - //ret - } -} - - //ENDP Buffer_To_Page - //END - - - - - - - - - -/* - -;*************************************************************************** -;* VVPC::GET_PIXEL -- Gets a pixel from the current view port * -;* * -;* INPUT: WORD the x pixel on the screen. * -;* WORD the y pixel on the screen. * -;* * -;* OUTPUT: UBYTE the pixel at the specified location * -;* * -;* WARNING: If pixel is to be placed outside of the viewport then * -;* this routine will abort. * -;* * -;* HISTORY: * -;* 06/07/1994 PWG : Created. * -;*=========================================================================* - PROC Buffer_Get_Pixel C near - USES ebx,ecx,edx,edi - - ARG this_object:DWORD ; this is a member function - ARG x_pixel:DWORD ; x position of pixel to set - ARG y_pixel:DWORD ; y position of pixel to set -*/ - -extern "C" int __cdecl Buffer_Get_Pixel(void * this_object, int x_pixel, int y_pixel) -{ - __asm { - - ;*=================================================================== - ; Get the viewport information and put bytes per row in ecx - ;*=================================================================== - mov ebx,[this_object] ; get a pointer to viewport - xor eax,eax - mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset - mov ecx,[ebx]GraphicViewPortClass.Height ; edx = height of viewport - mov edx,[ebx]GraphicViewPortClass.Width ; ecx = width of viewport - - ;*=================================================================== - ; Verify that the X pixel offset if legal - ;*=================================================================== - mov eax,[x_pixel] ; find the x position - cmp eax,edx ; is it out of bounds - jae short exit_label ; if so then get out - add edi,eax ; otherwise add in offset - - ;*=================================================================== - ; Verify that the Y pixel offset if legal - ;*=================================================================== - mov eax,[y_pixel] ; get the y position - cmp eax,ecx ; is it out of bounds - jae exit_label ; if so then get out - add edx,[ebx]GraphicViewPortClass.XAdd ; otherwise find bytes per row - add edx,[ebx]GraphicViewPortClass.Pitch ; otherwise find bytes per row - mul edx ; offset = bytes per row * y - add edi,eax ; add it into the offset - - ;*=================================================================== - ; Write the pixel to the screen - ;*=================================================================== - xor eax,eax ; clear the word - mov al,[edi] ; read in the pixel - exit_label: - //ret - //ENDP Buffer_Get_Pixel - - } -} - - diff --git a/code/TIBERIANDAWN/WIN32LIB/EXTERNS.H b/code/TIBERIANDAWN/WIN32LIB/EXTERNS.H deleted file mode 100644 index 4414091..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/EXTERNS.H +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB32 Example * - * * - * File Name : EXTERNS.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - -extern char NoTimer; -extern char NoKeyBoard; diff --git a/code/TIBERIANDAWN/WIN32LIB/FACINGFF.ASM b/code/TIBERIANDAWN/WIN32LIB/FACINGFF.ASM deleted file mode 100644 index a487324..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FACINGFF.ASM +++ /dev/null @@ -1,162 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : FACINGFF.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 8, 1991 * -;* * -;* Last Update : February 6, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Desired_Facing256 -- Determines facing to reach a position. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -;IDEAL -;P386 -;MODEL USE32 FLAT - -GLOBAL C Desired_Facing256 :NEAR -; INCLUDE "wwlib.i" -INCLUDE "..\include\gbuffer.inc" - - CODESEG - -;*************************************************************************** -;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. * -;* * -;* This is a desired facing algorithm that has a resolution of 0 * -;* through 255. * -;* * -;* INPUT: srcx,srcy -- Source coordinate. * -;* * -;* dstx,dsty -- Destination coordinate. * -;* * -;* OUTPUT: Returns with the desired facing to face the destination * -;* coordinate from the position of the source coordinate. North * -;* is 0, East is 64, etc. * -;* * -;* WARNINGS: This routine is slower than the other forms of desired * -;* facing calculation. Use this routine when accuracy is * -;* required. * -;* * -;* HISTORY: * -;* 12/24/1991 JLB : Adapted. * -;*=========================================================================*/ -; LONG cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty) - PROC Desired_Facing256 C near - USES ebx, ecx, edx - - ARG srcx:DWORD - ARG srcy:DWORD - ARG dstx:DWORD - ARG dsty:DWORD - - xor ebx,ebx ; Facing number. - - ; Determine absolute X delta and left/right direction. - mov ecx,[dstx] - sub ecx,[srcx] - jge short ??xnotneg - neg ecx - mov ebx,11000000b ; Set bit 7 and 6 for leftward. -??xnotneg: - - ; Determine absolute Y delta and top/bottom direction. - mov eax,[srcy] - sub eax,[dsty] - jge short ??ynotneg - xor ebx,01000000b ; Complement bit 6 for downward. - neg eax -??ynotneg: - - ; Set DX=64 for quadrants 0 and 2. - mov edx,ebx - and edx,01000000b - xor edx,01000000b - - ; Determine if the direction is closer to the Y axis and make sure that - ; CX holds the larger of the two deltas. This is in preparation for the - ; divide. - cmp eax,ecx - jb short ??gotaxis - xchg eax,ecx - xor edx,01000000b ; Closer to Y axis so make DX=64 for quad 0 and 2. -??gotaxis: - - ; If closer to the X axis then add 64 for quadrants 0 and 2. If - ; closer to the Y axis then add 64 for quadrants 1 and 3. Determined - ; add value is in DX and save on stack. - push edx - - ; Make sure that the division won't overflow. Reduce precision until - ; the larger number is less than 256 if it appears that an overflow - ; will occur. If the high byte of the divisor is not zero, then this - ; guarantees no overflow, so just abort shift operation. - test eax,0FFFFFF00h - jnz short ??nooverflow -??again: - test ecx,0FFFFFF00h - jz short ??nooverflow - shr ecx,1 - shr eax,1 - jmp short ??again -??nooverflow: - - ; Make sure that the division won't underflow (divide by zero). If - ; this would occur, then set the quotient to $FF and skip divide. - or ecx,ecx - jnz short ??nounderflow - mov eax,0FFFFFFFFh - jmp short ??divcomplete - - ; Derive a pseudo angle number for the octant. The angle is based - ; on $00 = angle matches long axis, $00 = angle matches $FF degrees. -??nounderflow: - xor edx,edx - shld edx,eax,8 ; shift high byte of eax into dl - shl eax,8 - div ecx -??divcomplete: - - ; Integrate the 5 most significant bits into the angle index. If DX - ; is not zero, then it is 64. This means that the dividend must be negated - ; before it is added into the final angle value. - shr eax,3 - pop edx - or edx,edx - je short ??noneg - dec edx - neg eax -??noneg: - add eax,edx - add eax,ebx - and eax,0FFH - ret - - ENDP Desired_Facing256 - - - - END \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/FACINGFF.h b/code/TIBERIANDAWN/WIN32LIB/FACINGFF.h deleted file mode 100644 index 9af5356..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FACINGFF.h +++ /dev/null @@ -1,458 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : FACINGFF.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 8, 1991 * -;* * -;* Last Update : February 6, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Desired_Facing256 -- Determines facing to reach a position. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -*/ - -#ifndef FACINGFF_H -#define FACINGFF_H - -//IDEAL -//P386 -//MODEL USE32 FLAT - -//GLOBAL C Desired_Facing256 :NEAR -//; INCLUDE "wwlib.i" -//INCLUDE "..\include\gbuffer.inc" - -// CODESEG -/* -;*************************************************************************** -;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. * -;* * -;* This is a desired facing algorithm that has a resolution of 0 * -;* through 255. * -;* * -;* INPUT: srcx,srcy -- Source coordinate. * -;* * -;* dstx,dsty -- Destination coordinate. * -;* * -;* OUTPUT: Returns with the desired facing to face the destination * -;* coordinate from the position of the source coordinate. North * -;* is 0, East is 64, etc. * -;* * -;* WARNINGS: This routine is slower than the other forms of desired * -;* facing calculation. Use this routine when accuracy is * -;* required. * -;* * -;* HISTORY: * -;* 12/24/1991 JLB : Adapted. * -;*=========================================================================*/ - -int __cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty); - - -#if (0) - PROC Desired_Facing256 C near - USES ebx, ecx, edx - - ARG srcx:DWORD - ARG srcy:DWORD - ARG dstx:DWORD - ARG dsty:DWORD - - xor ebx,ebx ; Facing number. - - ; Determine absolute X delta and left/right direction. - mov ecx,[dstx] - sub ecx,[srcx] - jge short ??xnotneg - neg ecx - mov ebx,11000000b ; Set bit 7 and 6 for leftward. -??xnotneg: - - ; Determine absolute Y delta and top/bottom direction. - mov eax,[srcy] - sub eax,[dsty] - jge short ??ynotneg - xor ebx,01000000b ; Complement bit 6 for downward. - neg eax -??ynotneg: - - ; Set DX=64 for quadrants 0 and 2. - mov edx,ebx - and edx,01000000b - xor edx,01000000b - - ; Determine if the direction is closer to the Y axis and make sure that - ; CX holds the larger of the two deltas. This is in preparation for the - ; divide. - cmp eax,ecx - jb short ??gotaxis - xchg eax,ecx - xor edx,01000000b ; Closer to Y axis so make DX=64 for quad 0 and 2. -??gotaxis: - - ; If closer to the X axis then add 64 for quadrants 0 and 2. If - ; closer to the Y axis then add 64 for quadrants 1 and 3. Determined - ; add value is in DX and save on stack. - push edx - - ; Make sure that the division won't overflow. Reduce precision until - ; the larger number is less than 256 if it appears that an overflow - ; will occur. If the high byte of the divisor is not zero, then this - ; guarantees no overflow, so just abort shift operation. - test eax,0FFFFFF00h - jnz short ??nooverflow -??again: - test ecx,0FFFFFF00h - jz short ??nooverflow - shr ecx,1 - shr eax,1 - jmp short ??again -??nooverflow: - - ; Make sure that the division won't underflow (divide by zero). If - ; this would occur, then set the quotient to $FF and skip divide. - or ecx,ecx - jnz short ??nounderflow - mov eax,0FFFFFFFFh - jmp short ??divcomplete - - ; Derive a pseudo angle number for the octant. The angle is based - ; on $00 = angle matches long axis, $00 = angle matches $FF degrees. -??nounderflow: - xor edx,edx - shld edx,eax,8 ; shift high byte of eax into dl - shl eax,8 - div ecx -??divcomplete: - - ; Integrate the 5 most significant bits into the angle index. If DX - ; is not zero, then it is 64. This means that the dividend must be negated - ; before it is added into the final angle value. - shr eax,3 - pop edx - or edx,edx - je short ??noneg - dec edx - neg eax -??noneg: - add eax,edx - add eax,ebx - and eax,0FFH - ret - - ENDP Desired_Facing256 - - - - END -#endif - - - - - - - - - - - - - - - - - - - -/* - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : FACING8.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 8, 1991 * -;* * -;* Last Update : February 6, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Desired_Facing8 -- Determines facing to reach a position. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Desired_Facing8 :NEAR -; INCLUDE "wwlib.i" - - DATASEG - -; 8 direction desired facing lookup table. Build the index according -; to the following bits: -; -; bit 3 = Is y2 < y1? -; bit 2 = Is x2 < x1? -; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)? -; bit 0 = Is the facing closer to a major axis? -//NewFacing8 DB 1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4 - -// CODESEG -*/ - -/* -;*************************************************************************** -;* DESIRED_FACING8 -- Determines facing to reach a position. * -;* * -;* This routine will return with the most desirable facing to reach * -;* one position from another. It is accurate to a resolution of 0 to * -;* 7. * -;* * -;* INPUT: x1,y1 -- Position of origin point. * -;* * -;* x2,y2 -- Position of target. * -;* * -;* OUTPUT: Returns desired facing as a number from 0..255 with an * -;* accuracy of 32 degree increments. * -;* * -;* WARNINGS: If the two coordinates are the same, then -1 will be * -;* returned. It is up to you to handle this case. * -;* * -;* HISTORY: * -;* 07/15/1991 JLB : Documented. * -;* 08/08/1991 JLB : Same position check. * -;* 08/14/1991 JLB : New algorithm * -;* 02/06/1995 BWG : Convert to 32-bit * -;*=========================================================================* -*/ -int __cdecl Desired_Facing8(long x1, long y1, long x2, long y2); - -#if (0) - PROC Desired_Facing8 C near - USES ebx, ecx, edx - - ARG x1:DWORD - ARG y1:DWORD - ARG x2:DWORD - ARG y2:DWORD - - xor ebx,ebx ; Index byte (built). - - ; Determine Y axis difference. - mov edx,[y1] - mov ecx,[y2] - sub edx,ecx ; DX = Y axis (signed). - jns short ??absy - inc ebx ; Set the signed bit. - neg edx ; ABS(y) -??absy: - - ; Determine X axis difference. - shl ebx,1 - mov eax,[x1] - mov ecx,[x2] - sub ecx,eax ; CX = X axis (signed). - jns short ??absx - inc ebx ; Set the signed bit. - neg ecx ; ABS(x) -??absx: - - ; Determine the greater axis. - cmp ecx,edx - jb short ??dxisbig - xchg ecx,edx -??dxisbig: - rcl ebx,1 ; Y > X flag bit. - - ; Determine the closeness or farness of lesser axis. - mov eax,edx - inc eax ; Round up. - shr eax,1 - - cmp ecx,eax - rcl ebx,1 ; Close to major axis bit. - - xor eax,eax - mov al,[NewFacing8+ebx] - - ; Normalize to 0..FF range. - shl eax,5 - - ret - - ENDP Desired_Facing8 - - - END - -#endif - - - - -/* - ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/WIN32LIB/FACINGFF.h#57 $ -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Support Library * -;* * -;* File Name : FACING16.ASM * -;* * -;* Programmer : Joe L. Bostic * -;* * -;* Start Date : May 8, 1991 * -;* * -;* Last Update : February 6, 1995 [BWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Desired_Facing16 -- Converts coordinates into a facing number. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -GLOBAL C Desired_Facing16 :NEAR -; INCLUDE "wwlib.i" - - DATASEG - -; 16 direction desired facing lookup table. Build the index according -; to the following bits: -; -; bit 4 = Is y2 < y1? -; bit 3 = Is x2 < x1? -; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)? -; bit 1 = Is the lesser absolute difference very close to zero? -; bit 0 = Is the lesser absolute difference very close to the greater dist? -NewFacing16 DB 3, 2, 4,-1, 1, 2,0,-1 - DB 13,14,12,-1,15,14,0,-1 - DB 5, 6, 4,-1, 7, 6,8,-1 - DB 11,10,12,-1, 9,10,8,-1 - - CODESEG - -;*************************************************************************** -;* DESIRED_FACING16 -- Converts coordinates into a facing number. * -;* * -;* This converts coordinates into a desired facing number that ranges * -;* from 0 to 15 (0 equals North and going clockwise). * -;* * -;* INPUT: x1,y1 -- Position of origin point. * -;* * -;* x2,y2 -- Position of target. * -;* * -;* OUTPUT: Returns desired facing as a number from 0 to 255 but * -;* accurate to 22.5 degree increments. * -;* * -;* WARNINGS: If the two coordinates are the same, then -1 will be * -;* returned. It is up to you to handle this case. * -;* * -;* HISTORY: * -;* 08/14/1991 JLB : Created. * -;*=========================================================================* -*/ -long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2); - -#if (0) - PROC Desired_Facing16 C near - USES ebx, ecx, edx - - ARG x1:DWORD - ARG y1:DWORD - ARG x2:DWORD - ARG y2:DWORD - - xor ebx,ebx ; Index byte (built). - - ; Determine Y axis difference. - mov edx,[y1] - mov ecx,[y2] - sub edx,ecx ; DX = Y axis (signed). - jns short ??absy - inc ebx ; Set the signed bit. - neg edx ; ABS(y) -??absy: - - ; Determine X axis difference. - shl ebx,1 - mov eax,[x1] - mov ecx,[x2] - sub ecx,eax ; CX = X axis (signed). - jns short ??absx - inc ebx ; Set the signed bit. - neg ecx ; ABS(x) -??absx: - - ; Determine the greater axis. - cmp ecx,edx - jb short ??dxisbig - xchg ecx,edx -??dxisbig: - rcl ebx,1 ; Y > X flag bit. - - ; Determine the closeness or farness of lesser axis. - mov eax,edx - inc eax ; Round up. - shr eax,1 - inc eax ; Round up. - shr eax,1 ; 1/4 of greater axis. - - cmp ecx,eax - rcl ebx,1 ; Very close to major axis bit. - - sub edx,eax - cmp edx,ecx - rcl ebx,1 ; Very far from major axis bit. - - xor eax,eax - mov al,[NewFacing16+ebx] - - ; Normalize to 0..FF range. - shl eax,4 - - ret - - ENDP Desired_Facing16 - - END -#endif - - - - -#endif FACINGFF_H diff --git a/code/TIBERIANDAWN/WIN32LIB/FASTFILE.H b/code/TIBERIANDAWN/WIN32LIB/FASTFILE.H deleted file mode 100644 index 2ba372b..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FASTFILE.H +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*========================================================================== - * - * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. - * - * File: fastfile.h - * Content: Definitions for fastfile access. - * - * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED - * WARRANTIES OF MERCHANTBILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. - * - ***************************************************************************/ - -typedef LPVOID HFASTFILE; - -extern BOOL FastFileInit( LPSTR fname, int max_handles ); -extern void FastFileFini( void ); -extern HFASTFILE FastFileOpen( LPSTR name ); -extern BOOL FastFileClose( HFASTFILE pfe ); -extern BOOL FastFileRead( HFASTFILE pfh, LPVOID ptr, int size ); -extern BOOL FastFileSeek( HFASTFILE pfe, int off, int how ); -extern long FastFileTell( HFASTFILE pfe ); -extern LPVOID FastFileLock( HFASTFILE pfe, int off, int len ); -extern BOOL FastFileUnlock( HFASTFILE pfe, int off, int len ); diff --git a/code/TIBERIANDAWN/WIN32LIB/FILE.H b/code/TIBERIANDAWN/WIN32LIB/FILE.H deleted file mode 100644 index e9009fd..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FILE.H +++ /dev/null @@ -1,257 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Library - Filio header stuff. * - * * - * File Name : FILE.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : September 13, 1993 * - * * - * Last Update : April 11, 1994 * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FILE_H -#define FILE_H - -#ifndef FILETEMP_H -// This should be removed once the library is all intacked. -#include "filetemp.h" -#endif - -/*=========================================================================*/ -/* File IO system defines and enumerations */ -/*=========================================================================*/ - -#define XMAXPATH 80 - -/* -** These are the Open_File, Read_File, and Seek_File constants. -*/ -#ifndef READ -#define READ 1 // Read access. -#endif -#ifndef WRITE -#define WRITE 2 // Write access. -#endif -#ifndef SEEK_SET -#define SEEK_SET 0 // Seek from start of file. -#define SEEK_CUR 1 // Seek relative from current location. -#define SEEK_END 2 // Seek from end of file. -#endif - - -typedef enum { - FILEB_PROCESSED=8,// Was the packed file header of this file processed? - FILEB_PRELOAD, // Scan for and make file resident at WWDOS_Init time? - FILEB_RESIDENT, // Make resident at Open_File time? - FILEB_FLUSH, // Un-resident at Close_File time? - FILEB_PACKED, // Is this file packed? - FILEB_KEEP, // Don't ever flush this resident file? - FILEB_PRIORITY, // Flush this file last? - - FILEB_LAST -} FileFlags_Type; - -#define FILEF_NONE 0 -#define FILEF_PROCESSED (1< - -#ifdef __cplusplus -extern "C" { -#endif - -extern int __cdecl Find_First(unsigned char *fname, unsigned int mode, struct find_t *ffblk); -extern int __cdecl Find_Next(struct find_t *ffblk); - -#ifdef __cplusplus -} -#endif - - - - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/FILEPCX.H b/code/TIBERIANDAWN/WIN32LIB/FILEPCX.H deleted file mode 100644 index 0fa4695..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FILEPCX.H +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : iff * -;* * -;* File Name : FILEPCX.H * -;* * -;* Programmer : Julio R. Jerez * -;* * -;* Start Date : May 2, 1995 * -;* * -;* Last Update : May 2, 1995 [JRJ] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* GraphicBufferClass* Read_PCX_File (char* name, BYTE* palette,void *buff, long size); -;* GraphicBufferClass* Read_PCX_File (char* name, BYTE* palette, BufferClass& Buff); -;* int Write_PCX_File (char* name, GraphicViewPortClass& pic, BYTE* palette );* -;*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ -#include -#include -#include -#include - -#ifndef PCX_H -#define PCX_H - - -typedef struct { - char red ; - char green ; - char blue ; - } RGB ; - -typedef struct { - char id ; - char version ; - char encoding ; - char pixelsize ; - short x ; - short y ; - short width ; - short height ; - short xres ; - short yres ; - RGB ega_palette [ 16 ] ; - char nothing ; - char color_planes ; - short byte_per_line ; - short palette_type ; - char filler [ 58 ] ; - } PCX_HEADER ; - -GraphicBufferClass* Read_PCX_File (char* name, char* palette= NULL,void *buff=NULL, long size=0); -GraphicBufferClass* Read_PCX_File (char* name, BufferClass& Buff,char* palette= NULL) ; -int Write_PCX_File (char* name, GraphicViewPortClass& pic, unsigned char* palette ); - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/FILETEMP.H b/code/TIBERIANDAWN/WIN32LIB/FILETEMP.H deleted file mode 100644 index 47e92cb..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FILETEMP.H +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Temp header for file routines. * - * * - * File Name : FILETEMP.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : April 20, 1994 * - * * - * Last Update : April 20, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FILETEMP_H -#define FILETEMP_H - -///////////////////////////////////////////////////////////////////// -// THIS DOES NOT BELONG HERE. IT WAS PUT HERE JUST TO GET THE THING -// TO COMPILE. ONCE THE BUFFER AND PAGE SYSTEMS ARE PUT IN, THESE -// WILL NEED TO BE TAKEN OUT AND MODS MADE TO ANY FUNCTION USING BuffType. -// SKB 4/20/94. - - - -/*=========================================================================*/ -/* Defines and such that must go into wwstd.h */ -/*=========================================================================*/ -// Look at FileErrorType below for the IO_Error function. -//extern WORD __cdecl ( __cdecl IO_Error)(FileErrorType error, BYTE const *filename); -VOID __cdecl Prog_End(VOID); -extern WORD Hard_Error_Occured; - - - -//////////////////////// END OF DON'T BELONG ////////////////////////////////// - -#endif //FILETEMP_H - diff --git a/code/TIBERIANDAWN/WIN32LIB/FONT.CPP b/code/TIBERIANDAWN/WIN32LIB/FONT.CPP deleted file mode 100644 index 8681a0e..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FONT.CPP +++ /dev/null @@ -1,138 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - /*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : LIBRARY * - * * - * File Name : FONT.C * - * * - * Programmer : David Dettmer * - * * - * Last Update : July 20, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Char_Pixel_Width -- Return pixel width of a character. * - * String_Pixel_Width -- Return pixel width of a string of characters. * - * Get_Next_Text_Print_XY -- Calculates X and Y given ret value from Text_P* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "font.h" -#include -#include -#include -#include -#include -#include -#include - - -/*************************************************************************** - * CHAR_PIXEL_WIDTH -- Return pixel width of a character. * - * * - * Retreives the pixel width of a character from the font width block. * - * * - * INPUT: Character. * - * * - * OUTPUT: Pixel width of a string of characters. * - * * - * WARNINGS: Set_Font must have been called first. * - * * - * HISTORY: * - * 01/31/1992 DRD : Created. * - * 06/30/1994 SKB : Converted to 32 bit library. * - *=========================================================================*/ -int __cdecl Char_Pixel_Width(char chr) -{ - int width; - - width = (unsigned char)*(FontWidthBlockPtr + (unsigned char)chr) + FontXSpacing; - - return(width); -} - - -/*************************************************************************** - * STRING_PIXEL_WIDTH -- Return pixel width of a string of characters. * - * * - * Calculates the pixel width of a string of characters. This uses * - * the font width block for the widths. * - * * - * INPUT: Pointer to string of characters. * - * * - * OUTPUT: Pixel width of a string of characters. * - * * - * WARNINGS: Set_Font must have been called first. * - * * - * HISTORY: * - * 01/30/1992 DRD : Created. * - * 01/31/1992 DRD : Use Char_Pixel_Width. * - * 06/30/1994 SKB : Converted to 32 bit library. * - *=========================================================================*/ -unsigned int __cdecl String_Pixel_Width(char const *string) -{ - WORD width; // Working accumulator of string width. - WORD largest = 0; // Largest recorded width of the string. - - if (!string) return(0); - - width = 0; - while (*string) { - if (*string == '\r') { - string++; - largest = MAX(largest, width); - width = 0; - } else { - width += Char_Pixel_Width(*string++); // add each char's width - } - } - largest = MAX(largest, width); - return(largest); -} - - - -/*************************************************************************** - * GET_NEXT_TEXT_PRINT_XY -- Calculates X and Y given ret value from Text_P* - * * - * * - * INPUT: VVPC& vp - viewport that was printed to. * - * unsigned long offset - offset that Text_Print returned. * - * INT *x - x return value. * - * INT *y - y return value. * - * * - * OUTPUT: x and y are set. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/20/1994 SKB : Created. * - *=========================================================================*/ -VOID __cdecl Get_Next_Text_Print_XY(GraphicViewPortClass& gp, unsigned long offset, INT *x, INT *y) -{ - INT buffwidth; - - if (offset) { - buffwidth = gp.Get_Width() + gp.Get_XAdd(); - offset -= gp.Get_Offset(); - *x = offset % buffwidth; - *y = offset / buffwidth; - } else { - *x = *y = 0; - } -} diff --git a/code/TIBERIANDAWN/WIN32LIB/FONT.H b/code/TIBERIANDAWN/WIN32LIB/FONT.H deleted file mode 100644 index 1160f5f..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FONT.H +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Font and text print 32 bit library * - * * - * File Name : FONT.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : June 27, 1994 * - * * - * Last Update : June 29, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * VVPC::Text_Print -- Text print into a virtual viewport. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FONT_H -#define FONT_H - -#ifndef GBUFFER_H -#include -#endif - - -//////////////////////////////////////// Defines ////////////////////////////////////////// - -// defines for font header, offsets to block offsets - -#define FONTINFOBLOCK 4 -#define FONTOFFSETBLOCK 6 -#define FONTWIDTHBLOCK 8 -#define FONTDATABLOCK 10 -#define FONTHEIGHTBLOCK 12 - -// defines for font info block - -#define FONTINFOMAXHEIGHT 4 -#define FONTINFOMAXWIDTH 5 - -//////////////////////////////////////// Prototypes ////////////////////////////////////////// - -/*=========================================================================*/ -/* The following prototypes are for the file: SET_FONT.CPP */ -/*=========================================================================*/ - -void * __cdecl Set_Font(void const *fontptr); - -/*=========================================================================*/ -/* The following prototypes are for the file: FONT.CPP */ -/*=========================================================================*/ - -int __cdecl Char_Pixel_Width(char chr); -unsigned int __cdecl String_Pixel_Width(char const *string); -void __cdecl Get_Next_Text_Print_XY(GraphicViewPortClass& vp, unsigned long offset, INT *x, INT *y); - -/*=========================================================================*/ -/* The following prototypes are for the file: LOADFONT.CPP */ -/*=========================================================================*/ - -void * __cdecl Load_Font(char const *name); - -/*=========================================================================*/ -/* The following prototypes are for the file: TEXTPRNT.ASM */ -/*=========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -void __cdecl Set_Font_Palette_Range(void const *palette, INT start_idx, INT end_idx); - - -#ifdef __cplusplus -} -#endif - -/*=========================================================================*/ - - - - - -//////////////////////////////////////// External varables /////////////////////////////////////// -extern "C" int FontXSpacing; -extern "C" int FontYSpacing; -extern char FontWidth ; -extern char FontHeight; -extern char *FontWidthBlockPtr; - - -extern "C" void const *FontPtr; - - - - -#endif // FONT_H diff --git a/code/TIBERIANDAWN/WIN32LIB/FUNCTION.H b/code/TIBERIANDAWN/WIN32LIB/FUNCTION.H deleted file mode 100644 index 0f0eea9..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/FUNCTION.H +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*=========================================================================*/ -/* The following prototypes are for the file: SOUNDIO.CPP */ -/*=========================================================================*/ - -short Decompress_Frame(void * source, void * dest, short size); -int __cdecl Stream_Sample_Vol(void *buffer, long size, BOOL (*callback); -int __cdecl Stream_Sample(void *buffer, long size, BOOL (*callback); -int __cdecl File_Stream_Sample(char const *filename); -int __cdecl File_Stream_Sample_Vol(char const *filename, int volume); -void __cdecl _saveregs _loadds Sound_Callback(void); -void __cdecl far _saveregs _loadds maintenance_callback(void); -void __cdecl Load_Sample(char const *filename); -long __cdecl Load_Sample_Into_Buffer(char const *filename, void *buffer, long size); -long __cdecl Sample_Read(int fh, void *buffer, long size); -void __cdecl Free_Sample(void const *sample); -BOOL __cdecl Sound_Init(int sfx, int score, int sample); -void far VQA_TimerCallback(void); -BOOL Audio_Init(int sample, int address, int inter, int dma); -void __cdecl Sound_End(void); -void __cdecl Stop_Sample(int handle); -BOOL __cdecl Sample_Status(int handle); -BOOL __cdecl Is_Sample_Playing(void const * sample); -void __cdecl Stop_Sample_Playing(void const * sample); -int __cdecl Play_Sample(void const *sample); -int __cdecl Play_Sample_Vol(void const *sample, int priority, int volume); -int __cdecl Set_Sound_Vol(int volume); -int __cdecl Set_Score_Vol(int volume); -void __cdecl Fade_Sample(int handle, int ticks); \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/GBUFFER.CPP b/code/TIBERIANDAWN/WIN32LIB/GBUFFER.CPP deleted file mode 100644 index e4e8edf..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/GBUFFER.CPP +++ /dev/null @@ -1,707 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood 32 bit Library * - * * - * File Name : GBUFFER.CPP * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : May 3, 1994 * - * * - * Last Update : October 9, 1995 [] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * VVPC::VirtualViewPort -- Default constructor for a virtual viewport * - * VVPC:~VirtualViewPortClass -- Destructor for a virtual viewport * - * VVPC::Clear -- Clears a graphic page to correct color * - * VBC::VideoBufferClass -- Lowlevel constructor for video buffer class * - * GVPC::Change -- Changes position and size of a Graphic View Port * - * VVPC::Change -- Changes position and size of a Video View Port * - * Set_Logic_Page -- Sets LogicPage to new buffer * - * GBC::DD_Init -- Inits a direct draw surface for a GBC * - * GBC::Init -- Core function responsible for initing a GBC * - * GBC::Lock -- Locks a Direct Draw Surface * - * GBC::Unlock -- Unlocks a direct draw surface * - * GBC::GraphicBufferClass -- Default constructor (requires explicit init)* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef GBUFFER_H -#include "gbuffer.h" -#include "misc.h" -#endif -//#pragma inline - -int TotalLocks; -BOOL AllowHardwareBlitFills = TRUE; - - -//int CacheAllowed; - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - - - -/*************************************************************************** - * GVPC::GRAPHICVIEWPORTCLASS -- Constructor for basic view port class * - * m * - * INPUT: GraphicBufferClass * gbuffer - buffer to attach to * - * int x - x offset into buffer * - * int y - y offset into buffer * - * int w - view port width in pixels * - * int h - view port height in pixels * - * * - * OUTPUT: Constructors may not have a return value * - * * - * HISTORY: * - * 05/09/1994 PWG : Created. * - *=========================================================================*/ -GraphicViewPortClass::GraphicViewPortClass(GraphicBufferClass *gbuffer, int x, int y, int w, int h) : - LockCount(0), - GraphicBuff(NULL) -{ - Attach(gbuffer, x, y, w, h); -} - -/*************************************************************************** - * GVPC::GRAPHICVIEWPORTCLASS -- Default constructor for view port class * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 05/09/1994 PWG : Created. * - *=========================================================================*/ -GraphicViewPortClass::GraphicViewPortClass(void) -{ -} - -/*************************************************************************** - * GVPC::~GRAPHICVIEWPORTCLASS -- Destructor for GraphicViewPortClass * - * * - * INPUT: none * - * * - * OUTPUT: A destructor may not return a value. * - * * - * HISTORY: * - * 05/10/1994 PWG : Created. * - *=========================================================================*/ -GraphicViewPortClass::~GraphicViewPortClass(void) -{ - Offset = 0; - Width = 0; // Record width of Buffer - Height = 0; // Record height of Buffer - XAdd = 0; // Record XAdd of Buffer - XPos = 0; // Record XPos of Buffer - YPos = 0; // Record YPos of Buffer - Pitch = 0; // Record width of Buffer - IsDirectDraw = FALSE; - LockCount = 0; - GraphicBuff = NULL; -} - -/*************************************************************************** - * GVPC::ATTACH -- Attaches a viewport to a buffer class * - * * - * INPUT: GraphicBufferClass *g_buff - pointer to gbuff to attach to * - * int x - x position to attach to * - * int y - y position to attach to * - * int w - width of the view port * - * int h - height of the view port * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 05/10/1994 PWG : Created. * - *=========================================================================*/ -void GraphicViewPortClass::Attach(GraphicBufferClass *gbuffer, int x, int y, int w, int h) -{ - /*======================================================================*/ - /* Can not attach a Graphic View Port if it is actually the physical */ - /* representation of a Graphic Buffer. */ - /*======================================================================*/ - if (this == Get_Graphic_Buffer()) { - return; - } - - /*======================================================================*/ - /* Verify that the x and y coordinates are valid and placed within the */ - /* physical buffer. */ - /*======================================================================*/ - if (x < 0) // you cannot place view port off - x = 0; // the left edge of physical buf - if (x >= gbuffer->Get_Width()) // you cannot place left edge off - x = gbuffer->Get_Width() - 1; // the right edge of physical buf - if (y < 0) // you cannot place view port off - y = 0; // the top edge of physical buf - if (y >= gbuffer->Get_Height()) // you cannot place view port off - y = gbuffer->Get_Height() - 1; // bottom edge of physical buf - - /*======================================================================*/ - /* Adjust the width and height of necessary */ - /*======================================================================*/ - if (x + w > gbuffer->Get_Width()) // if the x plus width is larger - w = gbuffer->Get_Width() - x; // than physical, fix width - - if (y + h > gbuffer->Get_Height()) // if the y plus height is larger - h = gbuffer->Get_Height() - y; // than physical, fix height - - /*======================================================================*/ - /* Get a pointer to the top left edge of the buffer. */ - /*======================================================================*/ - Offset = gbuffer->Get_Offset() + ((gbuffer->Get_Width()+gbuffer->Get_Pitch()) * y) + x; - - /*======================================================================*/ - /* Copy over all of the variables that we need to store. */ - /*======================================================================*/ - XPos = x; - YPos = y; - XAdd = gbuffer->Get_Width() - w; - Width = w; - Height = h; - Pitch = gbuffer->Get_Pitch(); - GraphicBuff = gbuffer; - IsDirectDraw= gbuffer->IsDirectDraw; -} - - -/*************************************************************************** - * GVPC::CHANGE -- Changes position and size of a Graphic View Port * - * * - * INPUT: int the new x pixel position of the graphic view port * - * int the new y pixel position of the graphic view port * - * int the new width of the viewport in pixels * - * int the new height of the viewport in pixels * - * * - * OUTPUT: BOOL whether the Graphic View Port could be sucessfully * - * resized. * - * * - * WARNINGS: You may not resize a Graphic View Port which is derived * - * from a Graphic View Port Buffer, * - * * - * HISTORY: * - * 09/14/1994 SKB : Created. * - *=========================================================================*/ -BOOL GraphicViewPortClass::Change(int x, int y, int w, int h) -{ - /*======================================================================*/ - /* Can not change a Graphic View Port if it is actually the physical */ - /* representation of a Graphic Buffer. */ - /*======================================================================*/ - if (this == Get_Graphic_Buffer()) { - return(FALSE); - } - - /*======================================================================*/ - /* Since there is no allocated information, just re-attach it to the */ - /* existing graphic buffer as if we were creating the */ - /* GraphicViewPort. */ - /*======================================================================*/ - Attach(Get_Graphic_Buffer(), x, y, w, h); - return(TRUE); -} - - -/*************************************************************************** - * GBC::DD_INIT -- Inits a direct draw surface for a GBC * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 10/09/1995 : Created. * - *=========================================================================*/ -void GraphicBufferClass::DD_Init(GBC_Enum flags) -{ - // - // Create the direct draw surface description - // - memset (&VideoSurfaceDescription , 0 , sizeof ( VideoSurfaceDescription )); - - VideoSurfaceDescription.dwSize = sizeof( VideoSurfaceDescription ); - VideoSurfaceDescription.dwFlags = DDSD_CAPS; - VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - - if (!(flags & GBC_VISIBLE)) { - VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - VideoSurfaceDescription.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; - VideoSurfaceDescription.dwHeight = Height; - VideoSurfaceDescription.dwWidth = Width; - } - - // - // Need to set the DDSCAPS_MODEX flag if we want a 320 wide mode - // - if ( Width == 320 ) { - VideoSurfaceDescription.ddsCaps.dwCaps |= DDSCAPS_MODEX; - } - - // - // Call CreateSurface - // - DirectDrawObject->CreateSurface( &VideoSurfaceDescription , &VideoSurfacePtr , NULL); - AllSurfaces.Add_DD_Surface (VideoSurfacePtr); - - if ( GBC_VISIBLE & flags ){ - PaletteSurface=VideoSurfacePtr; - } - - Allocated = FALSE; // even if system alloced, dont flag it cuz - // we dont want it freed. - IsDirectDraw = TRUE; // flag it as a video surface - Offset = NOT_LOCKED; // flag it as unavailable for reading or writing - LockCount = 0; // surface is not locked -} - - -void GraphicBufferClass::Attach_DD_Surface (GraphicBufferClass * attach_buffer) -{ - VideoSurfacePtr->AddAttachedSurface (attach_buffer->Get_DD_Surface()); -} - - -/*************************************************************************** - * GBC::INIT -- Core function responsible for initing a GBC * - * * - * INPUT: int - the width in pixels of the GraphicBufferClass * - * int - the heigh in pixels of the GraphicBufferClass * - * void * - pointer to user supplied buffer (system will * - * allocate space if buffer is NULL) * - * long - size of the user provided buffer * - * GBC_Enum - flags if this is defined as a direct draw * - * surface * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 10/09/1995 : Created. * - *=========================================================================*/ -void GraphicBufferClass::Init(int w, int h, void *buffer, long size, GBC_Enum flags) -{ - Size = size; // find size of physical buffer - Width = w; // Record width of Buffer - Height = h; // Record height of Buffer - - // - // If the surface we are creating is a direct draw object then - // we need to do a direct draw init. Otherwise we will do - // a normal alloc. - // - if (flags & (GBC_VIDEOMEM | GBC_VISIBLE)) { - DD_Init(flags); - } else { - if (buffer) { // if buffer is specified - Buffer = (BYTE *)buffer; // point to it and mark - Allocated = FALSE; // it as user allocated - } else { - if (!Size) Size = w*h; - Buffer = new BYTE[Size]; // otherwise allocate it and - Allocated = TRUE; // mark it system alloced - } - Offset = (INT_PTR)Buffer; // Get offset to the buffer - IsDirectDraw = FALSE; - } - - Pitch = 0; // Record width of Buffer - XAdd = 0; // Record XAdd of Buffer - XPos = 0; // Record XPos of Buffer - YPos = 0; // Record YPos of Buffer - GraphicBuff = this; // Get a pointer to our self -} - - -/*********************************************************************************************** - * GBC::Un_Init -- releases the video surface belonging to this gbuffer * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 6/6/96 12:44PM ST : Created * - *=============================================================================================*/ - -void GraphicBufferClass::Un_Init (void) -{ - if ( IsDirectDraw ){ - - if ( VideoSurfacePtr ){ - - while ( LockCount ){ - - if (VideoSurfacePtr->Unlock ( NULL ) == DDERR_SURFACELOST){ - if (Gbuffer_Focus_Loss_Function){ - Gbuffer_Focus_Loss_Function(); - } - AllSurfaces.Restore_Surfaces(); - } - } - - AllSurfaces.Remove_DD_Surface (VideoSurfacePtr); - VideoSurfacePtr->Release(); - VideoSurfacePtr = NULL; - } - } -} - - -/*************************************************************************** - * GBC::GRAPHICBUFFERCLASS -- Default constructor (requires explicit init) * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 10/09/1995 : Created. * - *=========================================================================*/ -GraphicBufferClass::GraphicBufferClass(void) -{ - GraphicBuff = this; // Get a pointer to our self - VideoSurfacePtr = NULL; - memset(&VideoSurfaceDescription, 0, sizeof(DDSURFACEDESC)); -} - - -/*************************************************************************** - * GBC::GRAPHICBUFFERCLASS -- Constructor for fixed size buffers * - * * - * INPUT: long size - size of the buffer to create * - * int w - width of buffer in pixels (default = 320) * - * int h - height of buffer in pixels (default = 200) * - * void *buffer - a pointer to the buffer if any (optional) * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/13/1994 PWG : Created. * - *=========================================================================*/ -GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer, long size) -{ - Init(w, h, buffer, size, GBC_NONE); -} -/*=========================================================================* - * GBC::GRAPHICBUFFERCLASS -- inline constructor for GraphicBufferClass * - * * - * INPUT: int w - width of buffer in pixels (default = 320) * - * int h - height of buffer in pixels (default = 200) * - * void *buffer - a pointer to the buffer if any (optional) * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 05/03/1994 PWG : Created. * - *=========================================================================*/ -GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer) -{ - Init(w, h, buffer, w * h, GBC_NONE); -} - -/*====================================================================================* - * GBC::GRAPHICBUFFERCLASS -- contructor for GraphicsBufferClass with special flags * - * * - * INPUT: int w - width of buffer in pixels (default = 320) * - * int h - height of buffer in pixels (default = 200) * - * void *buffer - unused * - * unsigned flags - flags for creation of special buffer types * - * GBC_VISIBLE - buffer is a visible screen surface * - * GBC_VIDEOMEM - buffer resides in video memory * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 09-21-95 04:19pm ST : Created * - *====================================================================================*/ -GraphicBufferClass::GraphicBufferClass(int w, int h, GBC_Enum flags) -{ - Init(w, h, NULL, w * h, flags); -} - -/*=========================================================================* - * GBC::~GRAPHICBUFFERCLASS -- Destructor for the graphic buffer class * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 05/03/1994 PWG : Created. * - *=========================================================================*/ -GraphicBufferClass::~GraphicBufferClass() -{ - -// -// Release the direct draw surface if it exists -// - Un_Init(); -} - - - -/*************************************************************************** - * SET_LOGIC_PAGE -- Sets LogicPage to new buffer * - * * - * INPUT: GraphicBufferClass * the buffer we are going to set * - * * - * OUTPUT: GraphicBufferClass * the previous buffer type * - * * - * WARNINGS: * - * * - * HISTORY: * - * 02/23/1995 PWG : Created. * - *=========================================================================*/ -GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass *ptr) -{ - GraphicViewPortClass *old = LogicPage; - LogicPage = ptr; - return(old); -} - -/*************************************************************************** - * SET_LOGIC_PAGE -- Sets LogicPage to new buffer * - * * - * INPUT: GraphicBufferClass & the buffer we are going to set * - * * - * OUTPUT: GraphicBufferClass * the previous buffer type * - * * - * WARNINGS: * - * * - * HISTORY: * - * 02/23/1995 PWG : Created. * - *=========================================================================*/ -GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass &ptr) -{ - GraphicViewPortClass *old = LogicPage; - LogicPage = &ptr; - return(old); -} - - -/*************************************************************************** - * GBC::LOCK -- Locks a Direct Draw Surface * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 10/09/1995 : Created. * - * 10/09/1995 : Code stolen from Steve Tall * - *=========================================================================*/ -extern void Colour_Debug (int call_number); -extern bool GameInFocus; - -extern void Block_Mouse(GraphicBufferClass *buffer); -extern void Unblock_Mouse(GraphicBufferClass *buffer); - -BOOL GraphicBufferClass::Lock(void) -{ - HRESULT result; - int restore_attempts=0; - - // - // If its not a direct draw surface then the lock is always sucessful. - // - if (!IsDirectDraw) return(TRUE); - - /* - ** If the video surface pointer is null then return - */ - if (!VideoSurfacePtr) return (FALSE); - - /* - ** If we dont have focus then return failure - */ - if (!GameInFocus) return (FALSE); - - - Block_Mouse(this); - - - // - // If surface is already locked then inc the lock count and return true - // - if (LockCount){ - LockCount++; - Unblock_Mouse(this); - return(TRUE); - } - - // - // If it isn't locked at all then we will have to request that Direct - // Draw actually lock the surface. - // - - if (VideoSurfacePtr){ - while (!LockCount && restore_attempts<2) { - result = VideoSurfacePtr->Lock ( NULL - , &(VideoSurfaceDescription) - , DDLOCK_WAIT - , NULL); - - switch (result){ - case DD_OK : - Offset = (unsigned long)VideoSurfaceDescription.lpSurface; - Pitch = VideoSurfaceDescription.lPitch; - Pitch -= Width; - LockCount++; // increment count so we can track if - TotalLocks++; // Total number of times we have locked (for debugging) - //Colour_Debug (1); - Unblock_Mouse(this); - return (TRUE); // we locked it multiple times. - - case DDERR_SURFACELOST : - if (Gbuffer_Focus_Loss_Function){ - Gbuffer_Focus_Loss_Function(); - } - AllSurfaces.Restore_Surfaces(); - restore_attempts++; - break; - - default : - Unblock_Mouse(this); - return (FALSE); - } - } - } - //Colour_Debug(1); - Unblock_Mouse(this); - return (FALSE); //Return false because we couldnt lock or restore the surface -} - -/*************************************************************************** - * GBC::UNLOCK -- Unlocks a direct draw surface * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 10/09/1995 : Created. * - * 10/09/1995 : Code stolen from Steve Tall * - *=========================================================================*/ - - -BOOL GraphicBufferClass::Unlock(void) -{ - // - // If there is no lock count or this is not a direct draw surface - // then just return true as there is no harm done. - // - if (!(LockCount && IsDirectDraw)) { - return(TRUE); - } - - // - // If lock count is directly equal to one then we actually need to - // unlock so just give it a shot. - // - if (LockCount == 1 && VideoSurfacePtr) { - Block_Mouse(this); - if ( VideoSurfacePtr->Unlock ( NULL ) != DD_OK ){ - Unblock_Mouse(this); - return(FALSE); - } else { - Offset=NOT_LOCKED; - LockCount--; - Unblock_Mouse(this); - return(TRUE); - } - } - //Colour_Debug (0); - LockCount--; - return(TRUE); -} - - -/*********************************************************************************************** - * GVPC::DD_Linear_Blit_To_Linear -- blit using the hardware blitter * - * * - * * - * * - * INPUT: destination vvpc * - * x coord to blit from * - * y coord to blit from * - * x coord to blit to * - * y coord to blit to * - * width to blit * - * height to blit * - * * - * OUTPUT: DD_OK if successful * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 09-22-95 11:05am ST : Created * - *=============================================================================================*/ - -HRESULT GraphicViewPortClass::DD_Linear_Blit_To_Linear ( - GraphicViewPortClass &dest - , int source_x - , int source_y - , int dest_x - , int dest_y - , int width - , int height - , BOOL mask ) - -{ - RECT source_rectangle; - RECT dest_rectangle; - int key_source=0; - - if ( mask ){ - key_source=DDBLT_KEYSRC; - } - - - source_rectangle.left = source_x; - source_rectangle.top = source_y; - source_rectangle.right = source_x+width; - source_rectangle.bottom = source_y+height; - - dest_rectangle.left = dest_x; - dest_rectangle.top = dest_y; - dest_rectangle.right = dest_x+width; - dest_rectangle.bottom = dest_y+height; - - return ( dest.GraphicBuff->Get_DD_Surface()->Blt ( &dest_rectangle, - GraphicBuff->Get_DD_Surface(), - &source_rectangle, - key_source | DDBLT_WAIT | DDBLT_ASYNC, - NULL ) ); -} - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/GBUFFER.H b/code/TIBERIANDAWN/WIN32LIB/GBUFFER.H deleted file mode 100644 index 7f2d51b..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/GBUFFER.H +++ /dev/null @@ -1,1372 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood 32 Bit Library * - * * - * File Name : GBUFFER.H * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : May 26, 1994 * - * * - * Last Update : October 9, 1995 [] * - * * - *************************************************************************** - * * - * This module contains the definition for the graphic buffer class. The * - * primary functionality of the graphic buffer class is handled by inline * - * functions that make a call through function pointers to the correct * - * routine. This has two benefits: * - * * - * * - * 1) C++ name mangling is not a big deal since the function pointers * - * point to functions in standard C format. * - * 2) The function pointers can be changed when we set a different * - * graphic mode. This allows us to have both supervga and mcga * - * routines present in memory at once. * - * * - * In the basic library, these functions point to stub routines which just * - * return. This makes a product that just uses a graphic buffer take the * - * minimum amount of code space. For programs that require MCGA or VESA * - * support, all that is necessary to do is link either the MCGA or VESA * - * specific libraries in, previous to WWLIB32. The linker will then * - * overide the the necessary stub functions automatically. * - * * - * In addition, there are helpful inline function calls for parameter * - * ellimination. This header file gives the defintion for all * - * GraphicViewPort and GraphicBuffer classes. * - * * - * Terminology: * - * * - * Buffer Class - A class which consists of a pointer to an allocated * - * buffer and the size of the buffer that was allocated. * - * * - * Graphic ViewPort - The Graphic ViewPort defines a window into a * - * Graphic Buffer. This means that although a Graphic Buffer * - * represents linear memory, this may not be true with a Graphic * - * Viewport. All low level functions that act directly on a graphic * - * viewport are included within this class. This includes but is not * - * limited to most of the functions which can act on a Video Viewport * - * Video Buffer. * - * * - * Graphic Buffer - A Graphic Buffer is an instance of an allocated buffer * - * used to represent a rectangular region of graphics memory. * - * The HidBuff and BackBuff are excellent examples of a Graphic Buffer. * - * * - * Below is a tree which shows the relationship of the VideoBuffer and * - * Buffer classes to the GraphicBuffer class: * - * * - * BUFFER.H GBUFFER.H BUFFER.H VBUFFER.H * - * ---------- ---------- ---------- ---------- * - * | Buffer | | Graphic | | Buffer | | Video | * - * | Class | | ViewPort | | Class | | ViewPort | * - * ---------- ---------- ---------- ---------- * - * \ / \ / * - * \ / \ / * - * ---------- ---------- * - * | Graphic | | Video | * - * | Buffer | | Buffer | * - * ---------- ---------- * - * GBUFFER.H VBUFFER.H * - *-------------------------------------------------------------------------* - * Functions: * - * GBC::GraphicBufferClass -- inline constructor for GraphicBufferClass * - * GVPC::Remap -- Short form to remap an entire graphic view port * - * GVPC::Get_XPos -- Returns x offset for a graphic viewport class * - * GVPC::Get_Ypos -- Return y offset in a GraphicViewPortClass * - * VVPC::Get_XPos -- Get the x pos of the VP on the Video * - * VVPC::Get_YPos -- Get the y pos of the VP on the video * - * GBC::Get_Graphic_Buffer -- Get the graphic buffer of the VP. * - * GVPC::Draw_Line -- Stub function to draw line in Graphic Viewport Class* - * GVPC::Fill_Rect -- Stub function to fill rectangle in a GVPC * - * GVPC::Remap -- Stub function to remap a GVPC * - * GVPC::Print -- stub func to print a text string * - * GVPC::Print -- Stub function to print an integer * - * GVPC::Print -- Stub function to print a short to a graphic viewport * - * GVPC::Print -- stub function to print a long on a graphic view port * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#ifndef _WIN32 // Denzil 6/2/98 Watcom 11.0 complains without this check -#define _WIN32 -#endif // _WIN32 - -#define WIN32_LEAN_AND_MEAN -#include - - -#ifndef GBUFFER_H -#define GBUFFER_H - -/*=========================================================================*/ -/* If we have not already loaded the standard library header, than we can */ -/* load it. */ -/*=========================================================================*/ - -#ifndef WWSTD_H -#include "wwstd.h" -#endif - -#ifndef DRAWBUFF_H -#include "drawbuff.h" -#endif - -//#ifndef BUFFER_H -#include "buffer.h" -//#endif - -#ifndef WINDOWS_H -#include "ww_win.h" -#endif -#include - -#include "iconcach.h" - - - -//#ifndef FUNCTION_H - -//#pragma off (unreferenced) - -//#ifndef BITMAPCLASS -//#define BITMAPCLASS -class BitmapClass -{ - public: - BitmapClass(int w, int h, unsigned char * data) : - Width(w), Height(h), Data(data) {}; - - int Width; - int Height; - unsigned char * Data; -}; - -class TPoint2D -{ - public: - TPoint2D(int xx, int yy) : x(xx), y(yy) {}; - TPoint2D(void) : x(0), y(0) {}; - - int x; - int y; -}; -//#endif - -//#pragma on (unreferenced) -//#endif - - -////////////////////////////////////////////////////////////////////////// -// -// Defines for direct draw -// -// -extern LPDIRECTDRAW DirectDrawObject; //pointer to direct draw object -extern HWND MainWindow; //handle to programs main window - -/* -** Pointer to function to call if we detect a focus loss -*/ -extern void (*Gbuffer_Focus_Loss_Function)(void); - -enum GBC_Enum { - GBC_NONE = 0, - GBC_VIDEOMEM = 1, - GBC_VISIBLE = 2, -}; - -#define NOT_LOCKED NULL - -/*=========================================================================*/ -/* Define the screen width and height to make portability to other modules */ -/* easier. */ -/*=========================================================================*/ -#define DEFAULT_SCREEN_WIDTH 768 -#define DEFAULT_SCREEN_HEIGHT 768 - -/*=========================================================================*/ -/* Let the compiler know that a GraphicBufferClass exists so that it can */ -/* keep a pointer to it in a VideoViewPortClass. */ -/*=========================================================================*/ -class GraphicViewPortClass; -class GraphicBufferClass; -class VideoViewPortClass; -class VideoBufferClass; - -GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass *ptr); -GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass &ptr); - -/*=========================================================================*/ -/* GraphicViewPortClass - Holds viewport information on a viewport which */ -/* has been attached to a GraphicBuffer. A viewport is effectively a */ -/* rectangular subset of the full buffer which is used for clipping and */ -/* the like. */ -/* */ -/* char *Buffer - is the offset to view port buffer */ -/* int Width - is the width of view port */ -/* int Height - is the height of view port */ -/* int XAdd - is add value to go from the end of a line */ -/* to the beginning of the next line */ -/* int XPos; - x offset into its associated VideoBuffer */ -/* int YPos; - y offset into its associated VideoBuffer */ -/*=========================================================================*/ -class GraphicViewPortClass { - public: - - /*===================================================================*/ - /* Define the base constructor and destructors for the class */ - /*===================================================================*/ - GraphicViewPortClass(GraphicBufferClass* graphic_buff, int x, int y, int w, int h); - GraphicViewPortClass(); - ~GraphicViewPortClass(); - - /*===================================================================*/ - /* define functions to get at the private data members */ - /*===================================================================*/ - long Get_Offset(void); - int Get_Height(void); - int Get_Width(void); - int Get_XAdd(void); - int Get_XPos(void); - int Get_YPos(void); - int Get_Pitch(void); - inline BOOL Get_IsDirectDraw(void); - GraphicBufferClass *Get_Graphic_Buffer(void); - - /*===================================================================*/ - /* Define a function which allows us to change a video viewport on */ - /* the fly. */ - /*===================================================================*/ - BOOL Change(int x, int y, int w, int h); - - /*===================================================================*/ - /* Define the set of common graphic functions that are supported by */ - /* both Graphic ViewPorts and VideoViewPorts. */ - /*===================================================================*/ - long Size_Of_Region(int w, int h); - void Put_Pixel(int x, int y, unsigned char color); - int Get_Pixel(int x, int y); - void Clear(unsigned char color = 0); - long To_Buffer(int x, int y, int w, int h, void *buff, long size); - long To_Buffer(int x, int y, int w, int h, BufferClass *buff); - long To_Buffer(BufferClass *buff); - HRESULT Blit( GraphicViewPortClass& dest, int x_pixel, int y_pixel, int dx_pixel, - int dy_pixel, int pixel_width, int pixel_height, BOOL trans = FALSE); - HRESULT Blit( GraphicViewPortClass& dest, int dx, int dy, BOOL trans = FALSE); - HRESULT Blit( GraphicViewPortClass& dest, BOOL trans = FALSE); - HRESULT Blit( VideoViewPortClass& dest, int x_pixel, int y_pixel, int dx_pixel, - int dy_pixel, int pixel_width, int pixel_height, BOOL trans = FALSE); - HRESULT Blit( VideoViewPortClass& dest, int dx, int dy, BOOL trans = FALSE); - HRESULT Blit( VideoViewPortClass& dest, BOOL trans = FALSE); - BOOL Scale( GraphicViewPortClass &dest, int src_x, int src_y, int dst_x, - int dst_y, int src_w, int src_h, int dst_w, int dst_h, BOOL trans = FALSE, char *remap = NULL); - BOOL Scale( GraphicViewPortClass &dest, int src_x, int src_y, int dst_x, - int dst_y, int src_w, int src_h, int dst_w, int dst_h, char *remap); - BOOL Scale( GraphicViewPortClass &dest, BOOL trans = FALSE, char *remap = NULL); - BOOL Scale( GraphicViewPortClass &dest, char *remap); - BOOL Scale( VideoViewPortClass &dest, int src_x, int src_y, int dst_x, - int dst_y, int src_w, int src_h, int dst_w, int dst_h, BOOL trans = FALSE, char *remap = NULL); - BOOL Scale( VideoViewPortClass &dest, int src_x, int src_y, int dst_x, - int dst_y, int src_w, int src_h, int dst_w, int dst_h, char *remap); - BOOL Scale( VideoViewPortClass &dest, BOOL trans = FALSE, char *remap = NULL); - BOOL Scale( VideoViewPortClass &dest, char *remap); - unsigned long Print(char const *string, int x_pixel, int y_pixel, int fcolor, int bcolor); - unsigned long Print(short num, int x_pixel, int y_pixel, int fcol, int bcol); - unsigned long Print(int num, int x_pixel, int y_pixel, int fcol, int bcol); - unsigned long Print(long num, int x_pixel, int y_pixel, int fcol, int bcol); - - /*===================================================================*/ - /* Define the list of graphic functions which work only with a */ - /* graphic buffer. */ - /*===================================================================*/ - VOID Draw_Line(int sx, int sy, int dx, int dy, unsigned char color); - VOID Draw_Rect(int sx, int sy, int dx, int dy, unsigned char color); - VOID Fill_Rect(int sx, int sy, int dx, int dy, unsigned char color); - VOID Fill_Quad(VOID *span_buff, int x0, int y0, int x1, int y1, - int x2, int y2, int x3, int y3, int color); - VOID Remap(int sx, int sy, int width, int height, VOID *remap); - VOID Remap(VOID *remap); - void Draw_Stamp(void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap); - void Draw_Stamp(void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int clip_window); - -// PG_TO_FIX -// This seems to be missing. Might not be needed anyway since it looks like it's only used for UI drawing. ST - 12/17/2018 6:11PM - void Texture_Fill_Rect (int xpos, int ypos, int width, int height, void const *shape_pointer, int source_width, int source_height) { - return; - } - -// This doesnt seem to exist anywhere?? - Steve T 9/26/95 6:05PM -// VOID Grey_Out_Region(int x, int y, int width, int height, int color); - - // - // New members to lock and unlock the direct draw video memory - // - inline BOOL Lock (); - inline BOOL Unlock(); - inline int Get_LockCount(); - - // Member to blit using direct draw access to hardware blitter - HRESULT DD_Linear_Blit_To_Linear ( GraphicViewPortClass &dest, int source_x, int source_y, int dest_x, int dest_y, int width , int height, BOOL mask ); - - /*===================================================================*/ - /* Define functions to attach the viewport to a graphicbuffer */ - /*===================================================================*/ - VOID Attach(GraphicBufferClass *graphic_buff, int x, int y, int w, int h); - void Attach(GraphicBufferClass *video_buff, int w, int h); - - protected: - - /*===================================================================*/ - /* Define the data used by a GraphicViewPortClass */ - /*===================================================================*/ - long Offset; // offset to graphic page - int Width; // width of graphic page - int Height; // height of graphic page - int XAdd; // xadd for graphic page (0) - int XPos; // x offset in relation to graphicbuff - int YPos; // y offset in relation to graphicbuff - long Pitch; //Distance from one line to the next - GraphicBufferClass *GraphicBuff; // related graphic buff - BOOL IsDirectDraw; //Flag to let us know if it is a direct draw surface - int LockCount; // Count for stacking locks if non-zero the buffer -}; // is a locked DD surface - -/*=========================================================================*/ -/* GraphicBufferClass - A GraphicBuffer refers to an actual instance of an */ -/* allocated buffer. The GraphicBuffer may be drawn to directly */ -/* becuase it inherits a ViewPort which represents its physcial size. */ -/* */ -/* BYTE *Buffer - is the offset to graphic buffer */ -/* int Width - is the width of graphic buffer */ -/* int Height - is the height of graphic buffer */ -/* int XAdd - is the xadd of graphic buffer */ -/* int XPos; - will be 0 because it is graphicbuff */ -/* int YPos; - will be 0 because it is graphicbuff */ -/* long Pitch - modulo of buffer for reading and writing */ -/* BOOL IsDirectDraw - flag if its a direct draw surface */ -/*=========================================================================*/ -class GraphicBufferClass : public GraphicViewPortClass, public BufferClass { - - public: - GraphicBufferClass(int w, int h, GBC_Enum flags); - GraphicBufferClass(int w, int h, void *buffer, long size); - GraphicBufferClass(int w, int h, void *buffer = 0); - GraphicBufferClass(void); - ~GraphicBufferClass(); - - void DD_Init(GBC_Enum flags); - void Init(int w, int h, void *buffer, long size, GBC_Enum flags); - void Un_Init(void); - void GraphicBufferClass::Attach_DD_Surface (GraphicBufferClass * attach_buffer); - BOOL Lock(void); - BOOL Unlock(void); - - void Scale_Rotate(BitmapClass &bmp,TPoint2D const &pt,long scale,unsigned char angle); - - // Member to get a pointer to a direct draw surface - LPDIRECTDRAWSURFACE Get_DD_Surface ( void ); - - protected: - LPDIRECTDRAWSURFACE VideoSurfacePtr; //Pointer to the related direct draw surface - DDSURFACEDESC VideoSurfaceDescription;//Description of the said surface - -}; - - - -inline int GraphicViewPortClass::Get_LockCount(void) -{ - return (LockCount); -} - - - -/*********************************************************************************************** - * GVPC::Get_IsDirectDraw -- provide read access to the IsDirectDraw flag * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: IsDirectDraw * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/29/95 1:02PM ST : Created * - *=============================================================================================*/ -inline BOOL GraphicViewPortClass::Get_IsDirectDraw(void) -{ - return (IsDirectDraw); -} - - - -/*********************************************************************************************** - * GBC::Get_DD_Surface -- returns a pointer to the buffer direct draw surface * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: ptr to direct draw surface * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 9/29/95 9:43AM ST : Created * - *=============================================================================================*/ -inline LPDIRECTDRAWSURFACE GraphicBufferClass::Get_DD_Surface ( void ) -{ - return ( VideoSurfacePtr ); - -} - - - -/*********************************************************************************************** - * GVPC::Lock -- lock the graphics buffer for reading or writing * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: TRUE if surface was successfully locked * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 09-19-95 12:33pm ST : Created * - * 10/09/1995 : Moved actually functionality to GraphicBuffer * - *=============================================================================================*/ -inline BOOL GraphicViewPortClass::Lock(void) -{ - BOOL lock = GraphicBuff->Lock(); - if ( !lock ) return(FALSE); - - if (this != GraphicBuff) { - Attach(GraphicBuff, XPos, YPos, Width, Height); - } - return(TRUE); -} - -/*********************************************************************************************** - * GVPC::Unlock -- unlock the video buffer * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: TRUE if surface was successfully unlocked * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 09-19-95 02:20pm ST : Created * - * 10/09/1995 : Moved actually functionality to GraphicBuffer * - *=============================================================================================*/ -inline BOOL GraphicViewPortClass::Unlock(void) -{ - BOOL unlock = GraphicBuff->Unlock(); - if (!unlock) return(FALSE); - if (this != GraphicBuff && IsDirectDraw && !GraphicBuff->LockCount) { - Offset = 0; - } - return(TRUE); -} - - -/*************************************************************************** - * GVPC::GET_OFFSET -- Get offset for virtual view port class instance * - * * - * INPUT: none * - * * - * OUTPUT: long the offset for the virtual viewport instance * - * * - * HISTORY: * - * 06/07/1994 PWG : Created. * - *=========================================================================*/ -inline long GraphicViewPortClass::Get_Offset(void) -{ - return(Offset); -} - -/*************************************************************************** - * GVPC::GET_HEIGHT -- Gets the height of a virtual viewport instance * - * * - * INPUT: none * - * * - * OUTPUT: WORD the height of the virtual viewport instance * - * * - * HISTORY: * - * 06/07/1994 PWG : Created. * - *=========================================================================*/ -inline int GraphicViewPortClass::Get_Height(void) -{ - return(Height); -} - -/*************************************************************************** - * GVPC::GET_WIDTH -- Get the width of a virtual viewport instance * - * * - * INPUT: none * - * * - * OUTPUT: WORD the width of the virtual viewport instance * - * * - * HISTORY: * - * 06/07/1994 PWG : Created. * - *=========================================================================*/ -inline int GraphicViewPortClass::Get_Width(void) -{ - return(Width); -} - - -/*************************************************************************** - * GVPC::GET_XADD -- Get the X add offset for virtual viewport instance * - * * - * INPUT: none * - * * - * OUTPUT: WORD the xadd for a virtual viewport instance * - * * - * HISTORY: * - * 06/07/1994 PWG : Created. * - *=========================================================================*/ -inline int GraphicViewPortClass::Get_XAdd(void) -{ - return(XAdd); -} -/*************************************************************************** - * GVPC::GET_XPOS -- Get the x pos of the VP on the Video * - * * - * INPUT: none * - * * - * OUTPUT: WORD the x offset to VideoBufferClass * - * * - * HISTORY: * - * 08/22/1994 SKB : Created. * - *=========================================================================*/ -inline int GraphicViewPortClass::Get_XPos(void) -{ - return(XPos); -} - - -/*************************************************************************** - * GVPC::GET_YPOS -- Get the y pos of the VP on the video * - * * - * INPUT: none * - * * - * OUTPUT: WORD the x offset to VideoBufferClass * - * * - * WARNINGS: * - * * - * HISTORY: * - * 08/22/1994 SKB : Created. * - *=========================================================================*/ -inline int GraphicViewPortClass::Get_YPos(void) -{ - return(YPos); -} - -/*************************************************************************** - * GVPC::GET_GRAPHIC_BUFFER -- Get the graphic buffer of the VP. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * HISTORY: * - * 08/22/1994 SKB : Created. * - *=========================================================================*/ -inline GraphicBufferClass *GraphicViewPortClass::Get_Graphic_Buffer(void) -{ - return (GraphicBuff); -} - -/*************************************************************************** - * GVPC::SIZE_OF_REGION -- stub to call curr graphic mode Size_Of_Region * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 03/01/1995 BWG : Created. * - *=========================================================================*/ -inline long GraphicViewPortClass::Size_Of_Region(int w, int h) -{ - return Buffer_Size_Of_Region(this, w, h); -} - - -/*************************************************************************** - * GVPC::PUT_PIXEL -- stub to call curr graphic mode Put_Pixel * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline void GraphicViewPortClass::Put_Pixel(int x, int y, unsigned char color) -{ - - if (Lock()){ - Buffer_Put_Pixel(this, x, y, color); - } - Unlock(); - - -} - -/*************************************************************************** - * GVPC::GET_PIXEL -- stub to call curr graphic mode Get_Pixel * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline int GraphicViewPortClass::Get_Pixel(int x, int y) -{ - int return_code=0; - - if (Lock()){ - return_code=(Buffer_Get_Pixel(this, x, y)); - } - Unlock(); - return(return_code); - -} - -/*************************************************************************** - * GVPC::CLEAR -- stub to call curr graphic mode Clear * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline void GraphicViewPortClass::Clear(unsigned char color) -{ - if (Lock()){ - Buffer_Clear(this, color); - } - Unlock(); - -} - -/*************************************************************************** - * GVPC::TO_BUFFER -- stub 1 to call curr graphic mode To_Buffer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline long GraphicViewPortClass::To_Buffer(int x, int y, int w, int h, void *buff, long size) -{ - long return_code=0; - if (Lock()){ - return_code = (Buffer_To_Buffer(this, x, y, w, h, buff, size)); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::TO_BUFFER -- stub 2 to call curr graphic mode To_Buffer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline long GraphicViewPortClass::To_Buffer(int x, int y, int w, int h, BufferClass *buff) -{ - long return_code=0; - if (Lock()){ - return_code = (Buffer_To_Buffer(this, x, y, w, h, buff->Get_Buffer(), buff->Get_Size())); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::TO_BUFFER -- stub 3 to call curr graphic mode To_Buffer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline long GraphicViewPortClass::To_Buffer(BufferClass *buff) -{ - long return_code=0; - if (Lock()){ - return_code = (Buffer_To_Buffer(this, 0, 0, Width, Height, buff->Get_Buffer(), buff->Get_Size())); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::BLIT -- stub 1 to call curr graphic mode Blit to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline HRESULT GraphicViewPortClass::Blit( GraphicViewPortClass& dest, int x_pixel, int y_pixel, int dx_pixel, - int dy_pixel, int pixel_width, int pixel_height, BOOL trans) -{ - HRESULT return_code=0; - - if ( IsDirectDraw && dest.IsDirectDraw ){ - return(DD_Linear_Blit_To_Linear( dest, XPos+x_pixel, YPos+y_pixel - , dest.Get_XPos()+dx_pixel, dest.Get_YPos()+dy_pixel - , pixel_width, pixel_height, trans)); - } else { - - if (Lock()){ - if (dest.Lock()){ - return_code=(Linear_Blit_To_Linear(this, &dest, x_pixel, y_pixel - , dx_pixel, dy_pixel - , pixel_width, pixel_height, trans)); - } - dest.Unlock(); - } - Unlock(); - } - - return ( return_code ); -} - -/*************************************************************************** - * GVPC::BLIT -- Stub 2 to call curr graphic mode Blit to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline HRESULT GraphicViewPortClass::Blit( GraphicViewPortClass& dest, int dx, int dy, BOOL trans) -{ - HRESULT return_code=0; - - - if ( IsDirectDraw && dest.IsDirectDraw ){ - return(DD_Linear_Blit_To_Linear( dest, XPos, YPos - , dest.Get_XPos()+dx, dest.Get_YPos()+dy - , Width, Height, trans)); - } else { - - if (Lock()){ - if (dest.Lock()){ - return_code=(Linear_Blit_To_Linear(this, &dest, 0, 0 - , dx, dy - , Width, Height, trans)); - } - dest.Unlock(); - } - Unlock(); - } - - return (return_code); - -} - -/*************************************************************************** - * GVPC::BLIT -- stub 3 to call curr graphic mode Blit to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline HRESULT GraphicViewPortClass::Blit( GraphicViewPortClass& dest, BOOL trans) -{ - HRESULT return_code=0; - - - if ( IsDirectDraw && dest.IsDirectDraw ){ - return(DD_Linear_Blit_To_Linear( dest, XPos, YPos - , dest.Get_XPos(), dest.Get_YPos() - , MAX( Width, dest.Get_Width()) - , MAX( Height, dest.Get_Height()) - , trans)); - } else { - - if (Lock()){ - if (dest.Lock()){ - return_code=(Linear_Blit_To_Linear(this, &dest, 0, 0 - , 0, 0 - , Width, Height, trans)); - } - dest.Unlock(); - } - Unlock(); - } - - return (return_code); - -} - - -/*************************************************************************** - * GVPC::SCALE -- stub 1 to call curr graphic mode Scale to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline BOOL GraphicViewPortClass::Scale( GraphicViewPortClass &dest, int src_x, int src_y, int dst_x, - int dst_y, int src_w, int src_h, int dst_w, int dst_h, BOOL trans, char *remap) -{ - BOOL return_code=0; - if (Lock()){ - if (dest.Lock()){ - return_code = (Linear_Scale_To_Linear(this, &dest, src_x, src_y, dst_x, dst_y, src_w, src_h, dst_w, dst_h, trans, remap)); - } - dest.Unlock(); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::SCALE -- stub 2 to call curr graphic mode Scale to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline BOOL GraphicViewPortClass::Scale( GraphicViewPortClass &dest, int src_x, int src_y, int dst_x, - int dst_y, int src_w, int src_h, int dst_w, int dst_h, char *remap) -{ - BOOL return_code=0; - if (Lock()){ - if (dest.Lock()){ - return_code = (Linear_Scale_To_Linear(this, &dest, src_x, src_y, dst_x, dst_y, src_w, src_h, dst_w, dst_h, FALSE, remap)); - } - dest.Unlock(); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::SCALE -- stub 3 to call curr graphic mode Scale to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline BOOL GraphicViewPortClass::Scale( GraphicViewPortClass &dest, BOOL trans, char *remap) -{ - BOOL return_code=0; - if (Lock()){ - if (dest.Lock()){ - return_code = (Linear_Scale_To_Linear(this, &dest, 0, 0, 0, 0, Width, Height, dest.Get_Width(), dest.Get_Height(), trans, remap)); - } - dest.Unlock(); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::SCALE -- stub 4 to call curr graphic mode Scale to GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/06/1995 PWG : Created. * - *=========================================================================*/ -inline BOOL GraphicViewPortClass::Scale( GraphicViewPortClass &dest, char *remap) -{ - BOOL return_code=0; - if (Lock()){ - if (dest.Lock()){ - return_code = (Linear_Scale_To_Linear(this, &dest, 0, 0, 0, 0, Width, Height, dest.Get_Width(), dest.Get_Height(), FALSE, remap)); - } - dest.Unlock(); - } - Unlock(); - return ( return_code ); -} -/*************************************************************************** - * GVPC::PRINT -- stub func to print a text string * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/17/1995 PWG : Created. * - *=========================================================================*/ -inline unsigned long GraphicViewPortClass::Print(char const *str, int x, int y, int fcol, int bcol) -{ - unsigned long return_code=0; - if (Lock()){ - return_code = (Buffer_Print(this, str, x, y, fcol, bcol)); - } - Unlock(); - return ( return_code ); -} - -#pragma warning (disable:4996) - -/*************************************************************************** - * GVPC::PRINT -- Stub function to print an integer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - *=========================================================================*/ -inline unsigned long GraphicViewPortClass::Print(int num, int x, int y, int fcol, int bcol) -{ - char str[17]; - - unsigned long return_code=0; - if (Lock()){ - return_code = (Buffer_Print(this, itoa(num, str, 10), x, y, fcol, bcol)); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::PRINT -- Stub function to print a short to a graphic viewport * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - *=========================================================================*/ -inline unsigned long GraphicViewPortClass::Print(short num, int x, int y, int fcol, int bcol) -{ - char str[17]; - - unsigned long return_code=0; - if (Lock()){ - return_code = (Buffer_Print(this, itoa(num, str, 10), x, y, fcol, bcol)); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::PRINT -- stub function to print a long on a graphic view port * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - *=========================================================================*/ -inline unsigned long GraphicViewPortClass::Print(long num, int x, int y, int fcol, int bcol) -{ - char str[33]; - - unsigned long return_code=0; - if (Lock()){ - return_code = (Buffer_Print(this, ltoa(num, str,10), x, y, fcol, bcol)); - } - Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * GVPC::DRAW_STAMP -- stub function to draw a tile on a graphic view port * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - *=========================================================================*/ -inline void GraphicViewPortClass::Draw_Stamp(void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap) -{ - if (Lock()){ - Buffer_Draw_Stamp(this, icondata, icon, x_pixel, y_pixel, remap); - } - Unlock(); -} - - - -/*************************************************************************** - * GVPC::DRAW_STAMP -- stub function to draw a tile on a graphic view port * - * This version clips the tile to a window * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/31/1995 BWG : Created. * - *=========================================================================*/ -extern BOOL IconCacheAllowed; -inline void GraphicViewPortClass::Draw_Stamp(void const * icondata, int icon, int x_pixel, int y_pixel, void const * remap, int clip_window) -{ - int cache_index=-1; - - int drewit = 0; - if (IconCacheAllowed){ - if (IsDirectDraw){ - if (!remap){ - cache_index = Is_Icon_Cached(icondata,icon); - } - - if (cache_index != -1){ - if (CachedIcons[cache_index].Get_Is_Cached() ){ - CachedIcons[cache_index].Draw_It (GraphicBuff->Get_DD_Surface() , x_pixel, y_pixel, - WindowList[clip_window][WINDOWX] + XPos, - WindowList[clip_window][WINDOWY] +YPos, - WindowList[clip_window][WINDOWWIDTH], - WindowList[clip_window][WINDOWHEIGHT]); - CachedIconsDrawn++; - drewit = 1; - } - } - } - } - - - if (drewit == 0) { - if (Lock()){ - UnCachedIconsDrawn++; - Buffer_Draw_Stamp_Clip(this, icondata, icon, x_pixel, y_pixel, remap, WindowList[clip_window][WINDOWX], WindowList[clip_window][WINDOWY], WindowList[clip_window][WINDOWWIDTH], WindowList[clip_window][WINDOWHEIGHT]); - } - } - Unlock(); -} - - -/*************************************************************************** - * GVPC::DRAW_LINE -- Stub function to draw line in Graphic Viewport Class * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/16/1995 PWG : Created. * - *=========================================================================*/ -inline VOID GraphicViewPortClass::Draw_Line(int sx, int sy, int dx, int dy, unsigned char color) -{ - if (Lock()){ - Buffer_Draw_Line(this, sx, sy, dx, dy, color); - } - Unlock(); -} - -/*************************************************************************** - * GVPC::FILL_RECT -- Stub function to fill rectangle in a GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/16/1995 PWG : Created. * - *=========================================================================*/ -inline VOID GraphicViewPortClass::Fill_Rect(int sx, int sy, int dx, int dy, unsigned char color) -{ - if ( AllowHardwareBlitFills - && IsDirectDraw - && ( (dx-sx) * (dy-sy) >= (32*32) ) - && GraphicBuff->Get_DD_Surface()->GetBltStatus(DDGBS_CANBLT) == DD_OK){ - DDBLTFX blit_effects; - RECT dest_rectangle; - - dest_rectangle.left =sx+XPos; - dest_rectangle.top =sy+YPos; - dest_rectangle.right =dx+XPos; - dest_rectangle.bottom=dy+YPos; - - if (dest_rectangle.left= Width + XPos){ - dest_rectangle.right = Width +XPos -1; - } - - if (dest_rectangle.top= Height + YPos){ - dest_rectangle.bottom = Height + YPos -1; - } - - if (dest_rectangle.left >= dest_rectangle.right) return; - if (dest_rectangle.top >= dest_rectangle.bottom) return; - - dest_rectangle.right++; - dest_rectangle.bottom++; - - blit_effects.dwSize=sizeof(blit_effects); - blit_effects.dwFillColor = color; - GraphicBuff->Get_DD_Surface()->Blt(&dest_rectangle, - NULL, - NULL, - DDBLT_WAIT | DDBLT_ASYNC | DDBLT_COLORFILL, - &blit_effects); - } else { - if (Lock()){ - Buffer_Fill_Rect(this, sx, sy, dx, dy, color); - Unlock(); - } - } -} - - -/*************************************************************************** - * GVPC::REMAP -- Stub function to remap a GVPC * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/16/1995 PWG : Created. * - *=========================================================================*/ -inline VOID GraphicViewPortClass::Remap(int sx, int sy, int width, int height, VOID *remap) -{ - if (Lock()){ - Buffer_Remap(this, sx, sy, width, height, remap); - } - Unlock(); -} - - -inline VOID GraphicViewPortClass::Fill_Quad(VOID *span_buff, int x0, int y0, int x1, int y1, - int x2, int y2, int x3, int y3, int color) -{ - if (Lock()){ - Buffer_Fill_Quad(this, span_buff, x0, y0, x1, y1, x2, y2, x3, y3, color); - } - Unlock(); -} - -/*************************************************************************** - * GVPC::REMAP -- Short form to remap an entire graphic view port * - * * - * INPUT: BYTE * to the remap table to use * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 07/01/1994 PWG : Created. * - *=========================================================================*/ -inline VOID GraphicViewPortClass::Remap(VOID *remap) -{ - if (Lock()){ - Buffer_Remap(this, 0, 0, Width, Height, remap); - } - Unlock(); -} - -inline int GraphicViewPortClass::Get_Pitch(void) -{ - return(Pitch); -} -/*=========================================================================*/ -/* The following BufferClass functions are defined here because they act */ -/* on graphic viewports. */ -/*=========================================================================*/ - - -/*************************************************************************** - * BUFFER_TO_PAGE -- Generic 'c' callable form of Buffer_To_Page * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 01/12/1995 PWG : Created. * - *=========================================================================*/ -inline long Buffer_To_Page(int x, int y, int w, int h, void *Buffer, GraphicViewPortClass &view) -{ - long return_code=0; - if (view.Lock()){ - return_code = (Buffer_To_Page(x, y, w, h, Buffer, &view)); - } - view.Unlock(); - return ( return_code ); -} - -/*************************************************************************** - * BC::TO_PAGE -- Copys a buffer class to a page with definable w, h * - * * - * INPUT: int width - the width of copy region * - * int height - the height of copy region * - * GVPC& dest - virtual viewport to copy to * - * * - * OUTPUT: none * - * * - * WARNINGS: x and y position are the upper left corner of the dest * - * viewport * - * * - * HISTORY: * - * 07/01/1994 PWG : Created. * - *=========================================================================*/ -inline long BufferClass::To_Page(int w, int h, GraphicViewPortClass &view) -{ - long return_code=0; - if (view.Lock()){ - return_code = (Buffer_To_Page(0, 0, w, h, Buffer, &view)); - } - view.Unlock(); - return ( return_code ); -} -/*************************************************************************** - * BC::TO_PAGE -- Copys a buffer class to a page with definable w, h * - * * - * INPUT: GVPC& dest - virtual viewport to copy to * - * * - * OUTPUT: none * - * * - * WARNINGS: x and y position are the upper left corner of the dest * - * viewport. width and height are assumed to be the * - * viewport's width and height. * - * * - * HISTORY: * - * 07/01/1994 PWG : Created. * - *=========================================================================*/ -inline long BufferClass::To_Page(GraphicViewPortClass &view) -{ - long return_code=0; - if (view.Lock()){ - return_code = (Buffer_To_Page(0, 0, view.Get_Width(), view.Get_Height(), Buffer, &view)); - } - view.Unlock(); - return ( return_code ); -} -/*************************************************************************** - * BC::TO_PAGE -- Copys a buffer class to a page with definable x, y, w, h * - * * - * INPUT: int x - x pixel on viewport to copy from * - * int y - y pixel on viewport to copy from * - * int width - the width of copy region * - * int height - the height of copy region * - * GVPC& dest - virtual viewport to copy to * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 07/01/1994 PWG : Created. * - *=========================================================================*/ -inline long BufferClass::To_Page(int x, int y, int w, int h, GraphicViewPortClass &view) -{ - long return_code=0; - if (view.Lock()){ - return_code = (Buffer_To_Page(x, y, w, h, Buffer, &view)); - } - view.Unlock(); - return ( return_code ); -} - - -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/GBUFFER.INC b/code/TIBERIANDAWN/WIN32LIB/GBUFFER.INC deleted file mode 100644 index 09f2e45..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/GBUFFER.INC +++ /dev/null @@ -1,48 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 Bit Library * -;* * -;* File Name : GBUFFER.INC * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : May 26, 1994 * -;* * -;* Last Update : May 26, 1994 [PWG] * -;* * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -;****************************************************************************** -; Much testing was done to determine that only when there are 14 or more bytes -; being copied does it speed the time it takes to do copies in this algorithm. -; For this reason and because 1 and 2 byte copies crash, is the special case -; used. SKB 4/21/94. Tested on 486 66mhz. Copied by PWG 6/7/04. -OPTIMAL_BYTE_COPY equ 14 - -GraphicViewPort struct -GVPOffset DD ? ; offset to virtual viewport -GVPWidth DD ? ; width of virtual viewport -GVPHeight DD ? ; height of virtual viewport -GVPXAdd DD ? ; x mod to get to next line -GVPXPos DD ? ; x pos relative to Graphic Buff -GVPYPos DD ? ; y pos relative to Graphic Buff -GVPPitch dd ? ; modulo of graphic view port -GVPBuffPtr DD ? ; ptr to associated Graphic Buff -GraphicViewPort ends \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/GETSHAPE.CPP b/code/TIBERIANDAWN/WIN32LIB/GETSHAPE.CPP deleted file mode 100644 index fd0a0ce..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/GETSHAPE.CPP +++ /dev/null @@ -1,358 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : GETSHAPE.CPP * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : April 5, 1992 * - * * - * Last Update : May 25, 1994 [BR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Get_Shape_Size -- Fetch the size of the shape in memory. * - * Get_Shape_Uncomp_Size -- gets shape's uncompressed size in bytes * - * Get_Shape_Data -- retrieves a shape's special prefix data * - * Extract_Shape_Count -- returns # of shapes in the given shape block * - * Extract_Shape -- Gets pointer to shape in given shape block * - * Get_Shape_Width -- gets shape width in pixels * - * Get_Shape_Height -- gets shape height in pixels * - * Set_Shape_Height -- modifies shape's height * - * Restore_Shape_Height -- restores a shape to its original height * - * Get_Shape_Original_Height -- gets shape's unmodified height * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* -********************************* Includes ********************************** -*/ -#include "wwstd.h" -#include "shape.h" - - -/*************************************************************************** - * Get_Shape_Size -- Fetch the size of the shape in memory. * - * * - * The shape size returned includes both the shape header & its data. * - * * - * INPUT: * - * shape pointer to shape * - * * - * OUTPUT: * - * shape's size in memory * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int cdecl Get_Shape_Size(VOID const *shape) -{ - Shape_Type *shp = (Shape_Type *)shape; - - /* - ------------------------- Return if NULL pointer ------------------------- - */ - if (!shape) - return(0); - - /* - -------------------------- Returns shape's size -------------------------- - */ - return (shp->ShapeSize); - -} /* end of Get_Shape_Size */ - - -/*************************************************************************** - * Get_Shape_Uncomp_Size -- gets shape's uncompressed size in bytes * - * * - * INPUT: * - * shape pointer to shape * - * * - * OUTPUT: * - * shape's size in bytes when uncompressed * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int Get_Shape_Uncomp_Size(VOID const *shape) -{ - Shape_Type *shp = (Shape_Type *)shape; - - return (shp->DataLength); - -} /* end of Get_Shape_Uncomp_Size */ - - -/*************************************************************************** - * Get_Shape_Data -- retrieves a shape's special prefix data * - * * - * MAKESHPS.EXE can store special data values along with a shape. These * - * values are inserted in the shape table >before< the shape's header. * - * So, this routine uses the 'data' parameter as a negative index from * - * the given shape pointer. * - * * - * INPUT: * - * shape pointer to shape * - * data index of WORD data value to get * - * * - * OUTPUT: * - * data value * - * * - * WARNINGS: * - * The shape pointer must be a pointer into a shape table created by * - * MAKESHPS.EXE; it >cannot< be a pointer to shape returned by Make_Shape! * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -WORD cdecl Get_Shape_Data(VOID const *shape, WORD data) -{ - WORD *word_ptr = (WORD *)shape; - WORD retval; - - retval = *(word_ptr - (data+1)); - - return (retval); - -} /* end of Get_Shape_Data */ - - -/*************************************************************************** - * Extract_Shape_Count -- returns # of shapes in the given shape block * - * * - * The # of shapes in a shape block is the first WORD in the block, so * - * this is the value returned. * - * * - * INPUT: * - * buffer pointer to shape block, created with MAKESHPS.EXE * - * * - * OUTPUT: * - * # shapes in the block * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int cdecl Extract_Shape_Count(VOID const *buffer) -{ - ShapeBlock_Type *block = (ShapeBlock_Type *)buffer; - - return (block->NumShapes); - -} /* end of Extract_Shape_Count */ - - -/*************************************************************************** - * Extract_Shape -- Gets pointer to shape in given shape block * - * * - * INPUT: * - * buffer pointer to shape block, created with MAKESHPS.EXE * - * shape index of shape to get * - * * - * OUTPUT: * - * pointer to shape in the shape block * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -VOID * cdecl Extract_Shape(VOID const *buffer, int shape) -{ - ShapeBlock_Type *block = (ShapeBlock_Type*) buffer; - //int numshapes; // Number of shapes - long offset; // Offset of shape data, from start of block - char *bytebuf = (char*) buffer; - - /* - ----------------------- Return if invalid argument ----------------------- - */ - if (!buffer || shape < 0 || shape >= block->NumShapes) - return(NULL); - - offset = block->Offsets[shape]; - - return(bytebuf + 2 + offset); - -} /* end of Extract_Shape */ - - -/*************************************************************************** - * Get_Shape_Width -- gets shape width in pixels * - * * - * INPUT: * - * shape pointer to a shape * - * * - * OUTPUT: * - * shape width in pixels * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int Get_Shape_Width(VOID const *shape) -{ - Shape_Type *shp = (Shape_Type *)shape; - - return (shp->Width); - -} /* end of Get_Shape_Width */ - - -/*************************************************************************** - * Get_Shape_Height -- gets shape height in pixels * - * * - * INPUT: * - * shape pointer to a shape * - * * - * OUTPUT: * - * shape height in pixels * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int Get_Shape_Height(VOID const *shape) -{ - Shape_Type *shp = (Shape_Type *)shape; - - return (shp->Height); - -} /* end of Get_Shape_Height */ - - -/*************************************************************************** - * Set_Shape_Height -- modifies shape's height * - * * - * The new height must be shorter than the original height. This effect * - * chops off the lower portion of the shape, like it's sinking into the * - * ground. * - * * - * INPUT: * - * shape pointer to a shape * - * newheight new shape height * - * * - * OUTPUT: * - * old shape height * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int cdecl Set_Shape_Height(VOID const *shape, WORD newheight) -{ - Shape_Type *shp = (Shape_Type *)shape; - WORD oldheight; - - oldheight = shp->Height; - shp->Height = newheight; - - return(oldheight); - -} /* end of Set_Shape_Height */ - - -/*************************************************************************** - * Restore_Shape_Height -- restores a shape to its original height * - * * - * INPUT: * - * shape pointer to a shape * - * * - * OUTPUT: * - * old shape height * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int cdecl Restore_Shape_Height(VOID *shape) -{ - Shape_Type *shp = (Shape_Type *)shape; - WORD oldheight; - - oldheight = shp->Height; - shp->Height = shp->OriginalHeight; - - return(oldheight); - -} /* end of Restore_Shape_Height */ - - -/*************************************************************************** - * Get_Shape_Original_Height -- gets shape's unmodified height * - * * - * INPUT: * - * shape pointer to a shape * - * * - * OUTPUT: * - * shape's unmodified height * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int Get_Shape_Original_Height(VOID const *shape) -{ - Shape_Type *shp = (Shape_Type *)shape; - - return (shp->OriginalHeight); - -} /* end of Get_Shape_Original_Height */ - - -/************************* end of getshape.cpp *****************************/ diff --git a/code/TIBERIANDAWN/WIN32LIB/ICONCACH.H b/code/TIBERIANDAWN/WIN32LIB/ICONCACH.H deleted file mode 100644 index f2e3205..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/ICONCACH.H +++ /dev/null @@ -1,150 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Drawbuff - Westwood win95 library * - * * - * File Name : Iconcach.H * - * * - * Programmer : Steve Tall * - * * - * Start Date : November 8th, 1995 * - * * - * Last Update : November 16th, 1995 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: This file cantains definition of the IconCacheClass and associated non member * - * function prototypes. * - * * - * Functions: * - * IconCacheClass::Get_Is_Cached -- member to allow access to private IsCached flag * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - -#ifndef ICONCACH_H -#define ICONCACH_H - -#include - -#define ICON_WIDTH 24 // Icons must be this width to be cached -#define ICON_HEIGHT 24 // Icons must be this height to be cached -#define MAX_CACHED_ICONS 500 // Maximum number of icons that can be cached -#define MAX_ICON_SETS 100 // Maximum number of icon sets that can be registered -#define MAX_LOOKUP_ENTRIES 3000 // Size of icon index table - - -/* -** IconCacheClass for tracking individual icons cached into video memory -** -** Use Register_Icon_Set to identify a set of icons as cachable. Once registered, the icons -** will be cached automatically when drawn. -** Use Invalidate_Cached_Icons at the end of icon drawing to release the video memory used by the -** caching system. -** Restore_Cached_Icons may be used to reload the icons into video memory after a focus loss. -** -*/ - -class IconCacheClass { - - public: - - IconCacheClass (void); // class constructor - ~IconCacheClass (void); // class destructor - - void Restore(void); // restore the surface - BOOL Cache_It (void * icon_ptr); // Cache the icon to video memory - void Uncache_It (void); // Restore the video memory and flag the icon as uncached - void Draw_It (LPDIRECTDRAWSURFACE dest_surface , int x_pixel, int y_pixel, int window_left , int window_top , int window_width , int window_height); - inline BOOL Get_Is_Cached(void); // Return the IsCached member - - int TimesDrawn; // counter of times cached icon has been drawn - int TimesFailed; // counter of times cached icon has failed to draw - - - private: - - LPDIRECTDRAWSURFACE CacheSurface; // Ptr to direct draw surface where icon resides - BOOL IsCached; // Flag to say whether an icon is cached - BOOL SurfaceLost; // Flag to indicate that our icons surface has been lost - int DrawFrequency; // Number of times icon has been drawn - void *IconSource; // Ptr to original icon data in system memory - -}; - - - -/* -** Structure to keep track of registered icon sets -** -*/ - -typedef struct tIconSetType{ - IControl_Type *IconSetPtr; // Ptr to icon set data - int IconListOffset; // Offset into icon index table for this icon set -}IconSetType; - - -extern IconCacheClass CachedIcons[MAX_CACHED_ICONS]; - -extern void Invalidate_Cached_Icons (void); -extern void Restore_Cached_Icons (void); -extern void Register_Icon_Set (void *icon_data , BOOL pre_cache); - -// -// Prototypes for assembly language procedures in STMPCACH.ASM -// -extern "C" void Clear_Icon_Pointers (void); -extern "C" void Cache_Copy_Icon (void const *icon_ptr ,void * , int); -extern "C" int Is_Icon_Cached (void const *icon_data , int icon); -extern "C" int Get_Icon_Index (void *icon_ptr); -extern "C" int Get_Free_Index (void); -extern "C" BOOL Cache_New_Icon (int icon_index, void *icon_ptr); -extern "C" int Get_Free_Cache_Slot(void); - - -extern int CachedIconsDrawn; -extern int UnCachedIconsDrawn; - - -/*********************************************************************************************** - * ICC::Get_Is_Cached -- member to allow access to the private IsCached flag * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: IsCached * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 11/13/95 9:42AM ST : Created * - *=============================================================================================*/ -inline BOOL IconCacheClass::Get_Is_Cached (void) -{ - return (IsCached); -} - - - - - -#endif //ICONCACH_H - diff --git a/code/TIBERIANDAWN/WIN32LIB/ICONSET.CPP b/code/TIBERIANDAWN/WIN32LIB/ICONSET.CPP deleted file mode 100644 index ad399b7..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/ICONSET.CPP +++ /dev/null @@ -1,340 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Library * - * * - * File Name : ICONSET.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : June 9, 1991 * - * * - * Last Update : September 15, 1993 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Load_Icon_Set -- Loads an icons set and initializes it. * - * Free_Icon_Set -- Frees allocations made by Load_Icon_Set(). * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -//#include "function.h" - -//#define _WIN32 -//#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -//#include -#include -#include -#include "tile.h" -#include - - -// Misc? ST - 1/3/2019 10:40AM -//extern int Misc; -int Misc; - -void * Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize); -void Free_Icon_Set(void const *iconset); -long Get_Icon_Set_Size(void const *iconset); -int Get_Icon_Set_Width(void const *iconset); -int Get_Icon_Set_Height(void const *iconset); -void * Get_Icon_Set_Icondata(void const *iconset); -void * Get_Icon_Set_Trans(void const *iconset); -void * Get_Icon_Set_Remapdata(void const *iconset); -void * Get_Icon_Set_Palettedata(void const *iconset); -int Get_Icon_Set_Count(void const *iconset); -void * Get_Icon_Set_Map(void const *iconset); - - -//#define ICON_PALETTE_BYTES 16 -//#define ICON_MAX 256 - -/*************************************************************************** -** The terrain is rendered by using icons. These are the buffers that hold -** the icon data, remap tables, and remap index arrays. -*/ -//PRIVATE char *IconPalette = NULL; // MCGA only. -//PRIVATE char *IconRemap = NULL; // MCGA only. - -#define FORM_RPAL MAKE_ID('R','P','A','L') -#define FORM_RTBL MAKE_ID('R','T','B','L') -#define FORM_SSET MAKE_ID('S','S','E','T') -#define FORM_SINF MAKE_ID('S','I','N','F') -#define FORM_ICON MAKE_ID('I','C','O','N') -#define FORM_TRNS MAKE_ID('T','R','N','S') -#define FORM_MAP MAKE_ID('M','A','P',' ') - - - -/*************************************************************************** - * LOAD_ICON_SET -- Loads an icons set and initializes it. * - * * - * This routine will load an IFF icon set from disk. It handles all * - * of the necessary allocations. * - * * - * INPUT: filename -- Name of the icon file. * - * * - * buffer -- Pointer to paragraph aligned buffer to hold data. * - * * - * size -- Size of the buffer (in bytes). * - * * - * OUTPUT: none * - * * - * WARNINGS: In EEGA mode the iconset buffer will be free because the * - * icons will have been transferred to card ram. * - * * - * HISTORY: * - * 06/21/1991 JLB : Created. * - * 07/01/1991 JLB : Determines icon size from file. * - * 07/15/1991 JLB : Load and uncompress onto the same buffer. * - * 09/15/1993 JLB : Added EMS support. * - *=========================================================================*/ -void * Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize) -{ - int fh; // File handle of iconset. - int bytespericon; // The number of bytes per icon. - unsigned long icons=0; // Number of icons loaded. - unsigned long size; // Size of the icon chunk (raw). - - unsigned long transsize; - void *transptr=NULL; - - unsigned long mapsize; // Icon map chunk size. - void *mapptr=NULL; // Icon map pointer. - void *returnptr=NULL; // Iconset pointer returned by routine. - BOOL allocated=FALSE; // Was the iconset block allocated? - IControl_Type *idata=NULL; // Icon data loaded. - long id; // ID of file openned. - struct { - char Width; // Width of icon in bytes. - char Height; // Height of icon in bytes. - char Format; // Graphic mode. - //lint -esym(754,Format) - char Bitplanes; // Number of bitplanes per icon. - } sinf; - - /* - ** Open the icon set for loading. If it is not a legal icon set - ** data file, then abort. - */ - fh = Open_Iff_File(filename); - if (fh != WW_ERROR) { - Read_File(fh, &id, sizeof(long)); - if (id == FORM_ICON) { - - /* - ** Determine the size of the icons and set up the graphic - ** system accordingly. Also get the sizes of the various - ** data blocks that have to be loaded. - */ - Read_Iff_Chunk(fh, FORM_SINF, &sinf, sizeof(sinf)); - bytespericon = ((((int)sinf.Width)<<3)*(((int)sinf.Height)<<3)*(int)sinf.Bitplanes)>>3; - - size = Get_Iff_Chunk_Size(fh,FORM_SSET); - transsize = Get_Iff_Chunk_Size(fh, FORM_TRNS); - mapsize = Get_Iff_Chunk_Size(fh, FORM_MAP); - - /* - ** Allocate the icon buffer if one isn't provided. First try EMS and - ** then try conventional RAM. - */ - allocated = FALSE; - if (!iconsetptr) { - buffsize = size + transsize + mapsize + sizeof(IControl_Type); - - Misc = buffsize; - iconsetptr = Alloc(buffsize, MEM_NORMAL); - allocated = (iconsetptr != NULL); - } - - if (iconsetptr && (size+transsize+mapsize+sizeof(IControl_Type)) <= (unsigned long)buffsize) { - - idata = (IControl_Type *)iconsetptr; - - memset(idata, 0, sizeof(IControl_Type)); - - /* - ** Initialize the iconset header structure. - */ - idata->Width = (short)(((short)sinf.Width)<<3); - idata->Height = (short)(((short)sinf.Height)<<3); - idata->Allocated = (short)allocated; - idata->Icons = (unsigned char *)iconsetptr + sizeof(IControl_Type); - idata->Map = (unsigned char *) (idata->Icons + size); - idata->TransFlag = sizeof(IControl_Type) + size + mapsize; - idata->Size = buffsize; - - { - long val; - - val = Read_Iff_Chunk(fh, FORM_SSET, Add_Long_To_Pointer(iconsetptr, sizeof(IControl_Type)), size); - icons = (int)(val/(long)bytespericon); - idata = (IControl_Type *)iconsetptr; - } - - if (mapsize) { - icons = mapsize; - } - idata->Count = (short)icons; - - /* - ** Limit buffer to only the size needed. This is done AFTER loading of the - ** raw icon data because it might have been compressed and thus need any - ** extra space to perform an overlapped decompression. - */ - if ((unsigned long)buffsize > size + transsize + mapsize + sizeof(IControl_Type)) { - buffsize = size + transsize + mapsize + sizeof(IControl_Type); - } - - transptr = Add_Long_To_Pointer(iconsetptr, idata->TransFlag); - Read_Iff_Chunk(fh, FORM_TRNS, transptr, transsize); - idata = (IControl_Type *)iconsetptr; - - mapptr = (void*)idata->Map; - Read_Iff_Chunk(fh, FORM_MAP, mapptr, mapsize); - - /* - ** Let the graphic overlay know of the icon data. This could involve - ** translation and other data manipulations. - */ - //Init_Stamps(iconsetptr); - - returnptr = iconsetptr; - } - } - Close_Iff_File(fh); - } - - return (returnptr); // Return with icon pointer. -} - - -/*************************************************************************** - * FREE_ICON_SET -- Frees allocations made by Load_Icon_Set(). * - * * - * This routine is used to free up any allocations by Load_Icon_Set(). * - * Use this routine when a new icon set is to be loaded. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/21/1991 JLB : Created. * - *=========================================================================*/ -void Free_Icon_Set(void const *iconset) -{ - IControl_Type *icontrol; - - icontrol = (IControl_Type *)iconset; - if (icontrol) { - if (icontrol->Allocated) { - Free((void *)iconset); - } - } -} - - -long Get_Icon_Set_Size(void const *iconset) -{ - IControl_Type *icontrol; - long size=0; - - icontrol = (IControl_Type *)iconset; - if (icontrol) { - size = icontrol->Size; - } - return(size); -} - - -int Get_Icon_Set_Width(void const *iconset) -{ - IControl_Type *icontrol; - int width=0; - - icontrol = (IControl_Type *)iconset; - if (icontrol) { - width = icontrol->Width; - } - return(width); -} - - -int Get_Icon_Set_Height(void const *iconset) -{ - IControl_Type *icontrol; - int height=0; - - icontrol = (IControl_Type *)iconset; - if (icontrol) { - height = icontrol->Height; - } - return(height); -} - - -void * Get_Icon_Set_Icondata(void const *iconset) -{ - IControl_Type *icontrol; - icontrol = (IControl_Type *)iconset; - if (icontrol) - return(Add_Long_To_Pointer(iconset, (LONG)icontrol->Icons)); - return(NULL); -} - -void * Get_Icon_Set_Trans(void const *iconset) -{ - IControl_Type *icontrol; - void *ptr=NULL; - - icontrol = (IControl_Type *)iconset; - if (icontrol) { - ptr = Add_Long_To_Pointer((void *)iconset, icontrol->TransFlag); - } - return(ptr); -} - - -int Get_Icon_Set_Count(void const *iconset) -{ - IControl_Type *icontrol; - int count; - - icontrol = (IControl_Type *)iconset; - if (icontrol) { - count = icontrol->Count; - } - return(count); -} - - -void * Get_Icon_Set_Map(void const *iconset) -{ - IControl_Type *icontrol; - icontrol = (IControl_Type *)iconset; - if (icontrol) - return(Add_Long_To_Pointer(iconset, (LONG)icontrol->Map)); - return(NULL); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/IFF.CPP b/code/TIBERIANDAWN/WIN32LIB/IFF.CPP deleted file mode 100644 index b0a47a1..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/IFF.CPP +++ /dev/null @@ -1,325 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : IFF.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 16, 1991 * - * * - * Last Update : April 19, 1994 [SKB] * - * * - * * - * IFF reader code designed for loading pictures (ILBM or PBM). * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Close_Iff_File -- Closes an IFF file handle. * - * Get_Iff_Chunk_Size -- Get the size of the given IFF chunk. * - * Open_Iff_File -- Opens an IFF file for reading. * - * Read_Iff_Chunk -- Reads a chunk from an IFF file. * - * Write_Iff_Chunk -- Writes an IFF chuck out. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "iff.h" -#include "file.h" - -#define ID_FORM MAKE_ID('F','O','R','M') - -#ifdef MIN -#undef MIN -#endif - -/*************************************************************************** - * OPEN_IFF_FILE -- Opens an IFF file for reading. * - * * - * This function will open an IFF file for reading. It will perform * - * a the simple validity test of checking the first four bytes to make * - * sure they are "FORM". The value returned is the filehandle of the * - * opened file. * - * * - * INPUT: filename - ASCII name of the IFF file to be opened. * - * * - * OUTPUT: Returns the filehandle. If there is an error or the file * - * is not an IFF FORM then -1 will be returned. * - * * - * WARNINGS: You are responsible for error handling if this function * - * returns -1 (not an IFF file). * - * * - * HISTORY: * - * 05/16/1991 JLB : Created. * - * 04/19/1994 SKB : Update to 32 bit library. * - *=========================================================================*/ -int __cdecl Open_Iff_File(char const *filename) -{ - int fh; // File handle. - long type; // IFF file type. - - - /* We want to be able to open the file for READ | WRITE, but we do not - want the Open_File to create it. So check to see if it exists before - the Open_File */ - -// fh = Open_File(filename, READ); // Open the source file for READ -// Close_File(fh); - - //fh = Open_File(filename, READ | WRITE); // Open the source file again - fh = Open_File(filename, READ); // Open the source file again - - // Validate that it is a FORM type. - - Read_File(fh, &type, 4L); - - if (type == ID_FORM) { - - // The file is valid (so far). Position the read so that the actual - // IFF file type code can be read. - - Seek_File(fh, 4L, SEEK_CUR); // Skip the filesize bytes. - - } else { - - // This is NOT an IFF file. Close the source file and return with - // the error code. - Close_File(fh); - fh = WW_ERROR; - } - return fh; -} - - -/*************************************************************************** - * CLOSE_IFF_FILE -- Closes an IFF file handle. * - * * - * The routine will close the file that was opened with the * - * Open_Iff_File() function. * - * * - * INPUT: fh - File handle that was returned from Open_Iff_File(). * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/16/1991 JLB : Created. * - * 04/19/1994 SKB : Update to 32 bit library. * - *=========================================================================*/ -void __cdecl Close_Iff_File(int fh) -{ - if (fh != WW_ERROR) Close_File(fh); -} - - -/*************************************************************************** - * GET_IFF_CHUNK_SIZE -- Get the size of the given IFF chunk. * - * * - * INPUT: int file handle to open IFF file, long id to get size of * - * * - * OUTPUT: long size of the chunk or 0L if it was not found * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/03/1991 CY : Created. * - * 04/19/1994 SKB : Update to 32 bit library. * - *=========================================================================*/ -unsigned long __cdecl Get_Iff_Chunk_Size(int fh, long id) -{ - long form; // Chunk iff form name. - long chunksize; // Size of the chunk. - char first_iteration; // Check once the current chunk name - - - first_iteration = TRUE; - - for (;;) { - if (Read_File(fh, &form, 4L) != 4L && !first_iteration) break; - - - if (Read_File(fh, (char *) &chunksize, 4L) != 4L && !first_iteration) break; - -#if(IBM) - chunksize = Reverse_Long(chunksize); -#endif - - if (id == form) { - Seek_File(fh, -8L, SEEK_CUR); // Seek back to the start of - return(chunksize); // the chunk & return size - } else { - - if (first_iteration) { - Seek_File(fh, 12L, SEEK_SET); // Start at beginning of file. - first_iteration = FALSE; // Don't do this again - } else { - - /* Otherwise, go to the next chunk in the file */ - - chunksize = (chunksize + 1) & 0xFFFFFFFEL; - Seek_File(fh, chunksize, SEEK_CUR); - } - } - } - - return(0L); -} - - -/*************************************************************************** - * READ_IFF_CHUNK -- Reads a chunk from an IFF file. * - * * - * Once an IFF file is opened, various chunks must be read from it. * - * This routine will search through the IFF file and load in the * - * specified chunk. It will scan through the entire file when * - * searching for the chunk. It will load the FIRST chunk of the given * - * type. * - * * - * INPUT: fh - File handle of IFF file. * - * * - * id - Chunk ID code. * - * * - * buffer - Pointer to buffer to load the chunk. * - * * - * maxsize - Maximum data bytes to read. * - * * - * OUTPUT: Returns with the number of bytes read from the chunk. * - * If 0 is returned, this indicates that the chunk wasn't * - * found. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/16/1991 JLB : Created. * - * 04/19/1994 SKB : Update to 32 bit library. * - *=========================================================================*/ -unsigned long __cdecl Read_Iff_Chunk(int fh, long id, void *buffer, unsigned long maxsize) -{ - long form; // Chunk iff form name. - unsigned long chunksize; // Size of the chunk. - char first_iteration; // Check once the current chunk name - - first_iteration = TRUE; - - for (;;) { - if (Read_File(fh, &form, 4L) != 4L && !first_iteration) break; - - if (Read_File(fh, (char *) &chunksize, 4L) != 4L && !first_iteration) break; - -#if(IBM) - chunksize = Reverse_Long(chunksize); -#endif - - if (id == form) { - - maxsize = MIN(maxsize, chunksize); - Read_File(fh, buffer, maxsize); // Read the buffer. - - chunksize = (chunksize + 1) & 0xFFFFFFFEL; - if (maxsize < chunksize) { - Seek_File(fh, chunksize - maxsize, SEEK_CUR); - } - return(maxsize); - } else { - - if (first_iteration) { - Seek_File(fh, 12L, SEEK_SET); // Start at beginning of file. - first_iteration = FALSE; // Don't do this again - - } else { - - /* Otherwise, go to the next chunk in the file */ - - chunksize = (chunksize + 1) & 0xFFFFFFFEL; - Seek_File(fh, chunksize, SEEK_CUR); - } - } - } - - return(0L); -} - - - -/*************************************************************************** - * WRITE_IFF_CHUNK -- Writes an IFF chuck out. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/19/1994 SKB : Created. * - *=========================================================================*/ -void __cdecl Write_Iff_Chunk(int file, long id, void *buffer, long length) -{ - long pos; // Current position in the IFF file. - long oldpos; // Record of start of chunk offset. - long endpos; // end of file offset before we write our data - long value; - BOOL odd; // Is length odd? - char pad = 0; // Optional padding byte for even sized chunks. - - /* - ** Get the current end of file (before we write more data to the file) - */ - pos = Seek_File (file, 0L, SEEK_CUR); - endpos = Seek_File (file, 0L, SEEK_END); - Seek_File (file, pos, SEEK_SET); - - if (length) { - value = id; - odd = (short)length & 0x01; - - Write_File(file, &value, 4L); - oldpos = Seek_File(file, 0L, SEEK_CUR); - Write_File(file, &value, 4L); - Write_File(file, buffer, length); - pos = Seek_File(file, 0L, SEEK_CUR); - if (odd) { - Write_File(file, &pad, 1L); - } - - /* - ** Update the chunk size long. - */ - Seek_File(file, oldpos, SEEK_SET); - value = IFFize_LONG((pos - oldpos)-4); - Write_File(file, &value, 4L); - - /* - ** Update the file size LONG. if we are not just overwriting existing data - */ - // (MCC) - if ( endpos < pos ) { - Seek_File(file, 4L, SEEK_SET); - value = IFFize_LONG((pos+odd) - 8); - Write_File(file, &value, 4L); - } - - /* - ** Return to end of file. - */ - Seek_File(file, 0L, SEEK_END); - } -} - - diff --git a/code/TIBERIANDAWN/WIN32LIB/IFF.H b/code/TIBERIANDAWN/WIN32LIB/IFF.H deleted file mode 100644 index 51f8c57..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/IFF.H +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Part of the FILEIO Library * - * * - * File Name : IFF.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : April 20, 1994 * - * * - * Last Update : April 20, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef IFF_H -#define IFF_H - -#ifndef GBUFFER_H -#include -#endif - -#ifndef MISC_H -#include // This is needed fro Reverse_WORD and _LONG -#endif - -#ifndef MEMFLAGS_H -#include // This is needed for MemoryFlagType. -#endif - -#define LZW_SUPPORTED FALSE - -/*=========================================================================*/ -/* Iff and Load Picture system defines and enumerations */ -/*=========================================================================*/ - -#define MAKE_ID(a,b,c,d) ((long) ((long) d << 24) | ((long) c << 16) | ((long) b << 8) | (long)(a)) -#define IFFize_WORD(a) Reverse_Word(a) -#define IFFize_LONG(a) Reverse_Long(a) - - -//lint -strong(AJX,PicturePlaneType) -typedef enum { - BM_AMIGA, // Bit plane format (8K per bitplane). - BM_MCGA, // Byte per pixel format (64K). - - BM_DEFAULT=BM_MCGA // Default picture format. -} PicturePlaneType; - -/* -** This is the compression type code. This value is used in the compressed -** file header to indicate the method of compression used. Note that the -** LZW method may not be supported. -*/ -//lint -strong(AJX,CompressionType) -typedef enum { - NOCOMPRESS, // No compression (raw data). - LZW12, // LZW 12 bit codes. - LZW14, // LZW 14 bit codes. - HORIZONTAL, // Run length encoding (RLE). - LCW // Westwood proprietary compression. -} CompressionType; - -/* -** Compressed blocks of data must start with this header structure. -** Note that disk based compressed files have an additional two -** leading bytes that indicate the size of the entire file. -*/ -//lint -strong(AJX,CompHeaderType) -typedef struct { - char Method; // Compression method (CompressionType). - char pad; // Reserved pad byte (always 0). - long Size; // Size of the uncompressed data. - short Skip; // Number of bytes to skip before data. -} CompHeaderType; - - -/*=========================================================================*/ -/* The following prototypes are for the file: IFF.CPP */ -/*=========================================================================*/ - -int __cdecl Open_Iff_File(char const *filename); -void __cdecl Close_Iff_File(int fh); -unsigned long __cdecl Get_Iff_Chunk_Size(int fh, long id); -unsigned long __cdecl Read_Iff_Chunk(int fh, long id, void *buffer, unsigned long maxsize); -void __cdecl Write_Iff_Chunk(int file, long id, void *buffer, long length); - - -/*=========================================================================*/ -/* The following prototypes are for the file: LOADPICT.CPP */ -/*=========================================================================*/ - -int __cdecl Load_Picture(char const *filename, BufferClass& scratchbuf, BufferClass& destbuf, unsigned char *palette=NULL, PicturePlaneType format=BM_DEFAULT); - - -/*=========================================================================*/ -/* The following prototypes are for the file: LOAD.CPP */ -/*=========================================================================*/ - -unsigned long __cdecl Load_Data(char const *name, void *ptr, unsigned long size); -unsigned long __cdecl Write_Data(char const *name, void *ptr, unsigned long size); -void * __cdecl Load_Alloc_Data(char const *name, MemoryFlagType flags); -unsigned long __cdecl Load_Uncompress(char const *file, BufferClass& uncomp_buff, BufferClass& dest_buff, void *reserved_data=NULL); -unsigned long __cdecl Uncompress_Data(void const *src, void *dst); -void __cdecl Set_Uncomp_Buffer(int buffer_segment, int size_of_buffer); - -/*=========================================================================*/ -/* The following prototypes are for the file: WRITELBM.CPP */ -/*=========================================================================*/ - -PUBLIC BOOL Write_LBM_File(int lbmhandle, BufferClass& buff, int bitplanes, unsigned char *palette); - - - -/*========================= Assembly Functions ============================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/*=========================================================================*/ -/* The following prototypes are for the file: PACK2PLN.ASM */ -/*=========================================================================*/ - -extern void __cdecl Pack_2_Plane(void *buffer, void * pageptr, int planebit); - -/*=========================================================================*/ -/* The following prototypes are for the file: LCWCOMP.ASM */ -/*=========================================================================*/ - -extern unsigned long __cdecl LCW_Compress(void *source, void *dest, unsigned long length); - -/*=========================================================================*/ -/* The following prototypes are for the file: LCWUNCMP.ASM */ -/*=========================================================================*/ - -extern unsigned long __cdecl LCW_Uncompress(void *source, void *dest, unsigned long length); - -#ifdef __cplusplus -} -#endif -/*=========================================================================*/ - - - -#endif //IFF_H diff --git a/code/TIBERIANDAWN/WIN32LIB/INDEXTB.INC b/code/TIBERIANDAWN/WIN32LIB/INDEXTB.INC deleted file mode 100644 index 36d8e03..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/INDEXTB.INC +++ /dev/null @@ -1,1445 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;**************************************************************************** -;* wIndexTable - ADPCM Lookup table for indexes -;**************************************************************************** - - align 4 - -wIndexTable DW 0 * 2 ; Index = 0 Token = 0 - DW 0 * 2 ; Index = 0 Token = 1 - DW 0 * 2 ; Index = 0 Token = 2 - DW 0 * 2 ; Index = 0 Token = 3 - DW 32 * 2 ; Index = 0 Token = 4 - DW 64 * 2 ; Index = 0 Token = 5 - DW 96 * 2 ; Index = 0 Token = 6 - DW 128 * 2 ; Index = 0 Token = 7 - DW 0 * 2 ; Index = 0 Token = 8 - DW 0 * 2 ; Index = 0 Token = 9 - DW 0 * 2 ; Index = 0 Token = 10 - DW 0 * 2 ; Index = 0 Token = 11 - DW 32 * 2 ; Index = 0 Token = 12 - DW 64 * 2 ; Index = 0 Token = 13 - DW 96 * 2 ; Index = 0 Token = 14 - DW 128 * 2 ; Index = 0 Token = 15 - DW 0 * 2 ; Index = 1 Token = 0 - DW 0 * 2 ; Index = 1 Token = 1 - DW 0 * 2 ; Index = 1 Token = 2 - DW 0 * 2 ; Index = 1 Token = 3 - DW 48 * 2 ; Index = 1 Token = 4 - DW 80 * 2 ; Index = 1 Token = 5 - DW 112 * 2 ; Index = 1 Token = 6 - DW 144 * 2 ; Index = 1 Token = 7 - DW 0 * 2 ; Index = 1 Token = 8 - DW 0 * 2 ; Index = 1 Token = 9 - DW 0 * 2 ; Index = 1 Token = 10 - DW 0 * 2 ; Index = 1 Token = 11 - DW 48 * 2 ; Index = 1 Token = 12 - DW 80 * 2 ; Index = 1 Token = 13 - DW 112 * 2 ; Index = 1 Token = 14 - DW 144 * 2 ; Index = 1 Token = 15 - DW 16 * 2 ; Index = 2 Token = 0 - DW 16 * 2 ; Index = 2 Token = 1 - DW 16 * 2 ; Index = 2 Token = 2 - DW 16 * 2 ; Index = 2 Token = 3 - DW 64 * 2 ; Index = 2 Token = 4 - DW 96 * 2 ; Index = 2 Token = 5 - DW 128 * 2 ; Index = 2 Token = 6 - DW 160 * 2 ; Index = 2 Token = 7 - DW 16 * 2 ; Index = 2 Token = 8 - DW 16 * 2 ; Index = 2 Token = 9 - DW 16 * 2 ; Index = 2 Token = 10 - DW 16 * 2 ; Index = 2 Token = 11 - DW 64 * 2 ; Index = 2 Token = 12 - DW 96 * 2 ; Index = 2 Token = 13 - DW 128 * 2 ; Index = 2 Token = 14 - DW 160 * 2 ; Index = 2 Token = 15 - DW 32 * 2 ; Index = 3 Token = 0 - DW 32 * 2 ; Index = 3 Token = 1 - DW 32 * 2 ; Index = 3 Token = 2 - DW 32 * 2 ; Index = 3 Token = 3 - DW 80 * 2 ; Index = 3 Token = 4 - DW 112 * 2 ; Index = 3 Token = 5 - DW 144 * 2 ; Index = 3 Token = 6 - DW 176 * 2 ; Index = 3 Token = 7 - DW 32 * 2 ; Index = 3 Token = 8 - DW 32 * 2 ; Index = 3 Token = 9 - DW 32 * 2 ; Index = 3 Token = 10 - DW 32 * 2 ; Index = 3 Token = 11 - DW 80 * 2 ; Index = 3 Token = 12 - DW 112 * 2 ; Index = 3 Token = 13 - DW 144 * 2 ; Index = 3 Token = 14 - DW 176 * 2 ; Index = 3 Token = 15 - DW 48 * 2 ; Index = 4 Token = 0 - DW 48 * 2 ; Index = 4 Token = 1 - DW 48 * 2 ; Index = 4 Token = 2 - DW 48 * 2 ; Index = 4 Token = 3 - DW 96 * 2 ; Index = 4 Token = 4 - DW 128 * 2 ; Index = 4 Token = 5 - DW 160 * 2 ; Index = 4 Token = 6 - DW 192 * 2 ; Index = 4 Token = 7 - DW 48 * 2 ; Index = 4 Token = 8 - DW 48 * 2 ; Index = 4 Token = 9 - DW 48 * 2 ; Index = 4 Token = 10 - DW 48 * 2 ; Index = 4 Token = 11 - DW 96 * 2 ; Index = 4 Token = 12 - DW 128 * 2 ; Index = 4 Token = 13 - DW 160 * 2 ; Index = 4 Token = 14 - DW 192 * 2 ; Index = 4 Token = 15 - DW 64 * 2 ; Index = 5 Token = 0 - DW 64 * 2 ; Index = 5 Token = 1 - DW 64 * 2 ; Index = 5 Token = 2 - DW 64 * 2 ; Index = 5 Token = 3 - DW 112 * 2 ; Index = 5 Token = 4 - DW 144 * 2 ; Index = 5 Token = 5 - DW 176 * 2 ; Index = 5 Token = 6 - DW 208 * 2 ; Index = 5 Token = 7 - DW 64 * 2 ; Index = 5 Token = 8 - DW 64 * 2 ; Index = 5 Token = 9 - DW 64 * 2 ; Index = 5 Token = 10 - DW 64 * 2 ; Index = 5 Token = 11 - DW 112 * 2 ; Index = 5 Token = 12 - DW 144 * 2 ; Index = 5 Token = 13 - DW 176 * 2 ; Index = 5 Token = 14 - DW 208 * 2 ; Index = 5 Token = 15 - DW 80 * 2 ; Index = 6 Token = 0 - DW 80 * 2 ; Index = 6 Token = 1 - DW 80 * 2 ; Index = 6 Token = 2 - DW 80 * 2 ; Index = 6 Token = 3 - DW 128 * 2 ; Index = 6 Token = 4 - DW 160 * 2 ; Index = 6 Token = 5 - DW 192 * 2 ; Index = 6 Token = 6 - DW 224 * 2 ; Index = 6 Token = 7 - DW 80 * 2 ; Index = 6 Token = 8 - DW 80 * 2 ; Index = 6 Token = 9 - DW 80 * 2 ; Index = 6 Token = 10 - DW 80 * 2 ; Index = 6 Token = 11 - DW 128 * 2 ; Index = 6 Token = 12 - DW 160 * 2 ; Index = 6 Token = 13 - DW 192 * 2 ; Index = 6 Token = 14 - DW 224 * 2 ; Index = 6 Token = 15 - DW 96 * 2 ; Index = 7 Token = 0 - DW 96 * 2 ; Index = 7 Token = 1 - DW 96 * 2 ; Index = 7 Token = 2 - DW 96 * 2 ; Index = 7 Token = 3 - DW 144 * 2 ; Index = 7 Token = 4 - DW 176 * 2 ; Index = 7 Token = 5 - DW 208 * 2 ; Index = 7 Token = 6 - DW 240 * 2 ; Index = 7 Token = 7 - DW 96 * 2 ; Index = 7 Token = 8 - DW 96 * 2 ; Index = 7 Token = 9 - DW 96 * 2 ; Index = 7 Token = 10 - DW 96 * 2 ; Index = 7 Token = 11 - DW 144 * 2 ; Index = 7 Token = 12 - DW 176 * 2 ; Index = 7 Token = 13 - DW 208 * 2 ; Index = 7 Token = 14 - DW 240 * 2 ; Index = 7 Token = 15 - DW 112 * 2 ; Index = 8 Token = 0 - DW 112 * 2 ; Index = 8 Token = 1 - DW 112 * 2 ; Index = 8 Token = 2 - DW 112 * 2 ; Index = 8 Token = 3 - DW 160 * 2 ; Index = 8 Token = 4 - DW 192 * 2 ; Index = 8 Token = 5 - DW 224 * 2 ; Index = 8 Token = 6 - DW 256 * 2 ; Index = 8 Token = 7 - DW 112 * 2 ; Index = 8 Token = 8 - DW 112 * 2 ; Index = 8 Token = 9 - DW 112 * 2 ; Index = 8 Token = 10 - DW 112 * 2 ; Index = 8 Token = 11 - DW 160 * 2 ; Index = 8 Token = 12 - DW 192 * 2 ; Index = 8 Token = 13 - DW 224 * 2 ; Index = 8 Token = 14 - DW 256 * 2 ; Index = 8 Token = 15 - DW 128 * 2 ; Index = 9 Token = 0 - DW 128 * 2 ; Index = 9 Token = 1 - DW 128 * 2 ; Index = 9 Token = 2 - DW 128 * 2 ; Index = 9 Token = 3 - DW 176 * 2 ; Index = 9 Token = 4 - DW 208 * 2 ; Index = 9 Token = 5 - DW 240 * 2 ; Index = 9 Token = 6 - DW 272 * 2 ; Index = 9 Token = 7 - DW 128 * 2 ; Index = 9 Token = 8 - DW 128 * 2 ; Index = 9 Token = 9 - DW 128 * 2 ; Index = 9 Token = 10 - DW 128 * 2 ; Index = 9 Token = 11 - DW 176 * 2 ; Index = 9 Token = 12 - DW 208 * 2 ; Index = 9 Token = 13 - DW 240 * 2 ; Index = 9 Token = 14 - DW 272 * 2 ; Index = 9 Token = 15 - DW 144 * 2 ; Index = 10 Token = 0 - DW 144 * 2 ; Index = 10 Token = 1 - DW 144 * 2 ; Index = 10 Token = 2 - DW 144 * 2 ; Index = 10 Token = 3 - DW 192 * 2 ; Index = 10 Token = 4 - DW 224 * 2 ; Index = 10 Token = 5 - DW 256 * 2 ; Index = 10 Token = 6 - DW 288 * 2 ; Index = 10 Token = 7 - DW 144 * 2 ; Index = 10 Token = 8 - DW 144 * 2 ; Index = 10 Token = 9 - DW 144 * 2 ; Index = 10 Token = 10 - DW 144 * 2 ; Index = 10 Token = 11 - DW 192 * 2 ; Index = 10 Token = 12 - DW 224 * 2 ; Index = 10 Token = 13 - DW 256 * 2 ; Index = 10 Token = 14 - DW 288 * 2 ; Index = 10 Token = 15 - DW 160 * 2 ; Index = 11 Token = 0 - DW 160 * 2 ; Index = 11 Token = 1 - DW 160 * 2 ; Index = 11 Token = 2 - DW 160 * 2 ; Index = 11 Token = 3 - DW 208 * 2 ; Index = 11 Token = 4 - DW 240 * 2 ; Index = 11 Token = 5 - DW 272 * 2 ; Index = 11 Token = 6 - DW 304 * 2 ; Index = 11 Token = 7 - DW 160 * 2 ; Index = 11 Token = 8 - DW 160 * 2 ; Index = 11 Token = 9 - DW 160 * 2 ; Index = 11 Token = 10 - DW 160 * 2 ; Index = 11 Token = 11 - DW 208 * 2 ; Index = 11 Token = 12 - DW 240 * 2 ; Index = 11 Token = 13 - DW 272 * 2 ; Index = 11 Token = 14 - DW 304 * 2 ; Index = 11 Token = 15 - DW 176 * 2 ; Index = 12 Token = 0 - DW 176 * 2 ; Index = 12 Token = 1 - DW 176 * 2 ; Index = 12 Token = 2 - DW 176 * 2 ; Index = 12 Token = 3 - DW 224 * 2 ; Index = 12 Token = 4 - DW 256 * 2 ; Index = 12 Token = 5 - DW 288 * 2 ; Index = 12 Token = 6 - DW 320 * 2 ; Index = 12 Token = 7 - DW 176 * 2 ; Index = 12 Token = 8 - DW 176 * 2 ; Index = 12 Token = 9 - DW 176 * 2 ; Index = 12 Token = 10 - DW 176 * 2 ; Index = 12 Token = 11 - DW 224 * 2 ; Index = 12 Token = 12 - DW 256 * 2 ; Index = 12 Token = 13 - DW 288 * 2 ; Index = 12 Token = 14 - DW 320 * 2 ; Index = 12 Token = 15 - DW 192 * 2 ; Index = 13 Token = 0 - DW 192 * 2 ; Index = 13 Token = 1 - DW 192 * 2 ; Index = 13 Token = 2 - DW 192 * 2 ; Index = 13 Token = 3 - DW 240 * 2 ; Index = 13 Token = 4 - DW 272 * 2 ; Index = 13 Token = 5 - DW 304 * 2 ; Index = 13 Token = 6 - DW 336 * 2 ; Index = 13 Token = 7 - DW 192 * 2 ; Index = 13 Token = 8 - DW 192 * 2 ; Index = 13 Token = 9 - DW 192 * 2 ; Index = 13 Token = 10 - DW 192 * 2 ; Index = 13 Token = 11 - DW 240 * 2 ; Index = 13 Token = 12 - DW 272 * 2 ; Index = 13 Token = 13 - DW 304 * 2 ; Index = 13 Token = 14 - DW 336 * 2 ; Index = 13 Token = 15 - DW 208 * 2 ; Index = 14 Token = 0 - DW 208 * 2 ; Index = 14 Token = 1 - DW 208 * 2 ; Index = 14 Token = 2 - DW 208 * 2 ; Index = 14 Token = 3 - DW 256 * 2 ; Index = 14 Token = 4 - DW 288 * 2 ; Index = 14 Token = 5 - DW 320 * 2 ; Index = 14 Token = 6 - DW 352 * 2 ; Index = 14 Token = 7 - DW 208 * 2 ; Index = 14 Token = 8 - DW 208 * 2 ; Index = 14 Token = 9 - DW 208 * 2 ; Index = 14 Token = 10 - DW 208 * 2 ; Index = 14 Token = 11 - DW 256 * 2 ; Index = 14 Token = 12 - DW 288 * 2 ; Index = 14 Token = 13 - DW 320 * 2 ; Index = 14 Token = 14 - DW 352 * 2 ; Index = 14 Token = 15 - DW 224 * 2 ; Index = 15 Token = 0 - DW 224 * 2 ; Index = 15 Token = 1 - DW 224 * 2 ; Index = 15 Token = 2 - DW 224 * 2 ; Index = 15 Token = 3 - DW 272 * 2 ; Index = 15 Token = 4 - DW 304 * 2 ; Index = 15 Token = 5 - DW 336 * 2 ; Index = 15 Token = 6 - DW 368 * 2 ; Index = 15 Token = 7 - DW 224 * 2 ; Index = 15 Token = 8 - DW 224 * 2 ; Index = 15 Token = 9 - DW 224 * 2 ; Index = 15 Token = 10 - DW 224 * 2 ; Index = 15 Token = 11 - DW 272 * 2 ; Index = 15 Token = 12 - DW 304 * 2 ; Index = 15 Token = 13 - DW 336 * 2 ; Index = 15 Token = 14 - DW 368 * 2 ; Index = 15 Token = 15 - DW 240 * 2 ; Index = 16 Token = 0 - DW 240 * 2 ; Index = 16 Token = 1 - DW 240 * 2 ; Index = 16 Token = 2 - DW 240 * 2 ; Index = 16 Token = 3 - DW 288 * 2 ; Index = 16 Token = 4 - DW 320 * 2 ; Index = 16 Token = 5 - DW 352 * 2 ; Index = 16 Token = 6 - DW 384 * 2 ; Index = 16 Token = 7 - DW 240 * 2 ; Index = 16 Token = 8 - DW 240 * 2 ; Index = 16 Token = 9 - DW 240 * 2 ; Index = 16 Token = 10 - DW 240 * 2 ; Index = 16 Token = 11 - DW 288 * 2 ; Index = 16 Token = 12 - DW 320 * 2 ; Index = 16 Token = 13 - DW 352 * 2 ; Index = 16 Token = 14 - DW 384 * 2 ; Index = 16 Token = 15 - DW 256 * 2 ; Index = 17 Token = 0 - DW 256 * 2 ; Index = 17 Token = 1 - DW 256 * 2 ; Index = 17 Token = 2 - DW 256 * 2 ; Index = 17 Token = 3 - DW 304 * 2 ; Index = 17 Token = 4 - DW 336 * 2 ; Index = 17 Token = 5 - DW 368 * 2 ; Index = 17 Token = 6 - DW 400 * 2 ; Index = 17 Token = 7 - DW 256 * 2 ; Index = 17 Token = 8 - DW 256 * 2 ; Index = 17 Token = 9 - DW 256 * 2 ; Index = 17 Token = 10 - DW 256 * 2 ; Index = 17 Token = 11 - DW 304 * 2 ; Index = 17 Token = 12 - DW 336 * 2 ; Index = 17 Token = 13 - DW 368 * 2 ; Index = 17 Token = 14 - DW 400 * 2 ; Index = 17 Token = 15 - DW 272 * 2 ; Index = 18 Token = 0 - DW 272 * 2 ; Index = 18 Token = 1 - DW 272 * 2 ; Index = 18 Token = 2 - DW 272 * 2 ; Index = 18 Token = 3 - DW 320 * 2 ; Index = 18 Token = 4 - DW 352 * 2 ; Index = 18 Token = 5 - DW 384 * 2 ; Index = 18 Token = 6 - DW 416 * 2 ; Index = 18 Token = 7 - DW 272 * 2 ; Index = 18 Token = 8 - DW 272 * 2 ; Index = 18 Token = 9 - DW 272 * 2 ; Index = 18 Token = 10 - DW 272 * 2 ; Index = 18 Token = 11 - DW 320 * 2 ; Index = 18 Token = 12 - DW 352 * 2 ; Index = 18 Token = 13 - DW 384 * 2 ; Index = 18 Token = 14 - DW 416 * 2 ; Index = 18 Token = 15 - DW 288 * 2 ; Index = 19 Token = 0 - DW 288 * 2 ; Index = 19 Token = 1 - DW 288 * 2 ; Index = 19 Token = 2 - DW 288 * 2 ; Index = 19 Token = 3 - DW 336 * 2 ; Index = 19 Token = 4 - DW 368 * 2 ; Index = 19 Token = 5 - DW 400 * 2 ; Index = 19 Token = 6 - DW 432 * 2 ; Index = 19 Token = 7 - DW 288 * 2 ; Index = 19 Token = 8 - DW 288 * 2 ; Index = 19 Token = 9 - DW 288 * 2 ; Index = 19 Token = 10 - DW 288 * 2 ; Index = 19 Token = 11 - DW 336 * 2 ; Index = 19 Token = 12 - DW 368 * 2 ; Index = 19 Token = 13 - DW 400 * 2 ; Index = 19 Token = 14 - DW 432 * 2 ; Index = 19 Token = 15 - DW 304 * 2 ; Index = 20 Token = 0 - DW 304 * 2 ; Index = 20 Token = 1 - DW 304 * 2 ; Index = 20 Token = 2 - DW 304 * 2 ; Index = 20 Token = 3 - DW 352 * 2 ; Index = 20 Token = 4 - DW 384 * 2 ; Index = 20 Token = 5 - DW 416 * 2 ; Index = 20 Token = 6 - DW 448 * 2 ; Index = 20 Token = 7 - DW 304 * 2 ; Index = 20 Token = 8 - DW 304 * 2 ; Index = 20 Token = 9 - DW 304 * 2 ; Index = 20 Token = 10 - DW 304 * 2 ; Index = 20 Token = 11 - DW 352 * 2 ; Index = 20 Token = 12 - DW 384 * 2 ; Index = 20 Token = 13 - DW 416 * 2 ; Index = 20 Token = 14 - DW 448 * 2 ; Index = 20 Token = 15 - DW 320 * 2 ; Index = 21 Token = 0 - DW 320 * 2 ; Index = 21 Token = 1 - DW 320 * 2 ; Index = 21 Token = 2 - DW 320 * 2 ; Index = 21 Token = 3 - DW 368 * 2 ; Index = 21 Token = 4 - DW 400 * 2 ; Index = 21 Token = 5 - DW 432 * 2 ; Index = 21 Token = 6 - DW 464 * 2 ; Index = 21 Token = 7 - DW 320 * 2 ; Index = 21 Token = 8 - DW 320 * 2 ; Index = 21 Token = 9 - DW 320 * 2 ; Index = 21 Token = 10 - DW 320 * 2 ; Index = 21 Token = 11 - DW 368 * 2 ; Index = 21 Token = 12 - DW 400 * 2 ; Index = 21 Token = 13 - DW 432 * 2 ; Index = 21 Token = 14 - DW 464 * 2 ; Index = 21 Token = 15 - DW 336 * 2 ; Index = 22 Token = 0 - DW 336 * 2 ; Index = 22 Token = 1 - DW 336 * 2 ; Index = 22 Token = 2 - DW 336 * 2 ; Index = 22 Token = 3 - DW 384 * 2 ; Index = 22 Token = 4 - DW 416 * 2 ; Index = 22 Token = 5 - DW 448 * 2 ; Index = 22 Token = 6 - DW 480 * 2 ; Index = 22 Token = 7 - DW 336 * 2 ; Index = 22 Token = 8 - DW 336 * 2 ; Index = 22 Token = 9 - DW 336 * 2 ; Index = 22 Token = 10 - DW 336 * 2 ; Index = 22 Token = 11 - DW 384 * 2 ; Index = 22 Token = 12 - DW 416 * 2 ; Index = 22 Token = 13 - DW 448 * 2 ; Index = 22 Token = 14 - DW 480 * 2 ; Index = 22 Token = 15 - DW 352 * 2 ; Index = 23 Token = 0 - DW 352 * 2 ; Index = 23 Token = 1 - DW 352 * 2 ; Index = 23 Token = 2 - DW 352 * 2 ; Index = 23 Token = 3 - DW 400 * 2 ; Index = 23 Token = 4 - DW 432 * 2 ; Index = 23 Token = 5 - DW 464 * 2 ; Index = 23 Token = 6 - DW 496 * 2 ; Index = 23 Token = 7 - DW 352 * 2 ; Index = 23 Token = 8 - DW 352 * 2 ; Index = 23 Token = 9 - DW 352 * 2 ; Index = 23 Token = 10 - DW 352 * 2 ; Index = 23 Token = 11 - DW 400 * 2 ; Index = 23 Token = 12 - DW 432 * 2 ; Index = 23 Token = 13 - DW 464 * 2 ; Index = 23 Token = 14 - DW 496 * 2 ; Index = 23 Token = 15 - DW 368 * 2 ; Index = 24 Token = 0 - DW 368 * 2 ; Index = 24 Token = 1 - DW 368 * 2 ; Index = 24 Token = 2 - DW 368 * 2 ; Index = 24 Token = 3 - DW 416 * 2 ; Index = 24 Token = 4 - DW 448 * 2 ; Index = 24 Token = 5 - DW 480 * 2 ; Index = 24 Token = 6 - DW 512 * 2 ; Index = 24 Token = 7 - DW 368 * 2 ; Index = 24 Token = 8 - DW 368 * 2 ; Index = 24 Token = 9 - DW 368 * 2 ; Index = 24 Token = 10 - DW 368 * 2 ; Index = 24 Token = 11 - DW 416 * 2 ; Index = 24 Token = 12 - DW 448 * 2 ; Index = 24 Token = 13 - DW 480 * 2 ; Index = 24 Token = 14 - DW 512 * 2 ; Index = 24 Token = 15 - DW 384 * 2 ; Index = 25 Token = 0 - DW 384 * 2 ; Index = 25 Token = 1 - DW 384 * 2 ; Index = 25 Token = 2 - DW 384 * 2 ; Index = 25 Token = 3 - DW 432 * 2 ; Index = 25 Token = 4 - DW 464 * 2 ; Index = 25 Token = 5 - DW 496 * 2 ; Index = 25 Token = 6 - DW 528 * 2 ; Index = 25 Token = 7 - DW 384 * 2 ; Index = 25 Token = 8 - DW 384 * 2 ; Index = 25 Token = 9 - DW 384 * 2 ; Index = 25 Token = 10 - DW 384 * 2 ; Index = 25 Token = 11 - DW 432 * 2 ; Index = 25 Token = 12 - DW 464 * 2 ; Index = 25 Token = 13 - DW 496 * 2 ; Index = 25 Token = 14 - DW 528 * 2 ; Index = 25 Token = 15 - DW 400 * 2 ; Index = 26 Token = 0 - DW 400 * 2 ; Index = 26 Token = 1 - DW 400 * 2 ; Index = 26 Token = 2 - DW 400 * 2 ; Index = 26 Token = 3 - DW 448 * 2 ; Index = 26 Token = 4 - DW 480 * 2 ; Index = 26 Token = 5 - DW 512 * 2 ; Index = 26 Token = 6 - DW 544 * 2 ; Index = 26 Token = 7 - DW 400 * 2 ; Index = 26 Token = 8 - DW 400 * 2 ; Index = 26 Token = 9 - DW 400 * 2 ; Index = 26 Token = 10 - DW 400 * 2 ; Index = 26 Token = 11 - DW 448 * 2 ; Index = 26 Token = 12 - DW 480 * 2 ; Index = 26 Token = 13 - DW 512 * 2 ; Index = 26 Token = 14 - DW 544 * 2 ; Index = 26 Token = 15 - DW 416 * 2 ; Index = 27 Token = 0 - DW 416 * 2 ; Index = 27 Token = 1 - DW 416 * 2 ; Index = 27 Token = 2 - DW 416 * 2 ; Index = 27 Token = 3 - DW 464 * 2 ; Index = 27 Token = 4 - DW 496 * 2 ; Index = 27 Token = 5 - DW 528 * 2 ; Index = 27 Token = 6 - DW 560 * 2 ; Index = 27 Token = 7 - DW 416 * 2 ; Index = 27 Token = 8 - DW 416 * 2 ; Index = 27 Token = 9 - DW 416 * 2 ; Index = 27 Token = 10 - DW 416 * 2 ; Index = 27 Token = 11 - DW 464 * 2 ; Index = 27 Token = 12 - DW 496 * 2 ; Index = 27 Token = 13 - DW 528 * 2 ; Index = 27 Token = 14 - DW 560 * 2 ; Index = 27 Token = 15 - DW 432 * 2 ; Index = 28 Token = 0 - DW 432 * 2 ; Index = 28 Token = 1 - DW 432 * 2 ; Index = 28 Token = 2 - DW 432 * 2 ; Index = 28 Token = 3 - DW 480 * 2 ; Index = 28 Token = 4 - DW 512 * 2 ; Index = 28 Token = 5 - DW 544 * 2 ; Index = 28 Token = 6 - DW 576 * 2 ; Index = 28 Token = 7 - DW 432 * 2 ; Index = 28 Token = 8 - DW 432 * 2 ; Index = 28 Token = 9 - DW 432 * 2 ; Index = 28 Token = 10 - DW 432 * 2 ; Index = 28 Token = 11 - DW 480 * 2 ; Index = 28 Token = 12 - DW 512 * 2 ; Index = 28 Token = 13 - DW 544 * 2 ; Index = 28 Token = 14 - DW 576 * 2 ; Index = 28 Token = 15 - DW 448 * 2 ; Index = 29 Token = 0 - DW 448 * 2 ; Index = 29 Token = 1 - DW 448 * 2 ; Index = 29 Token = 2 - DW 448 * 2 ; Index = 29 Token = 3 - DW 496 * 2 ; Index = 29 Token = 4 - DW 528 * 2 ; Index = 29 Token = 5 - DW 560 * 2 ; Index = 29 Token = 6 - DW 592 * 2 ; Index = 29 Token = 7 - DW 448 * 2 ; Index = 29 Token = 8 - DW 448 * 2 ; Index = 29 Token = 9 - DW 448 * 2 ; Index = 29 Token = 10 - DW 448 * 2 ; Index = 29 Token = 11 - DW 496 * 2 ; Index = 29 Token = 12 - DW 528 * 2 ; Index = 29 Token = 13 - DW 560 * 2 ; Index = 29 Token = 14 - DW 592 * 2 ; Index = 29 Token = 15 - DW 464 * 2 ; Index = 30 Token = 0 - DW 464 * 2 ; Index = 30 Token = 1 - DW 464 * 2 ; Index = 30 Token = 2 - DW 464 * 2 ; Index = 30 Token = 3 - DW 512 * 2 ; Index = 30 Token = 4 - DW 544 * 2 ; Index = 30 Token = 5 - DW 576 * 2 ; Index = 30 Token = 6 - DW 608 * 2 ; Index = 30 Token = 7 - DW 464 * 2 ; Index = 30 Token = 8 - DW 464 * 2 ; Index = 30 Token = 9 - DW 464 * 2 ; Index = 30 Token = 10 - DW 464 * 2 ; Index = 30 Token = 11 - DW 512 * 2 ; Index = 30 Token = 12 - DW 544 * 2 ; Index = 30 Token = 13 - DW 576 * 2 ; Index = 30 Token = 14 - DW 608 * 2 ; Index = 30 Token = 15 - DW 480 * 2 ; Index = 31 Token = 0 - DW 480 * 2 ; Index = 31 Token = 1 - DW 480 * 2 ; Index = 31 Token = 2 - DW 480 * 2 ; Index = 31 Token = 3 - DW 528 * 2 ; Index = 31 Token = 4 - DW 560 * 2 ; Index = 31 Token = 5 - DW 592 * 2 ; Index = 31 Token = 6 - DW 624 * 2 ; Index = 31 Token = 7 - DW 480 * 2 ; Index = 31 Token = 8 - DW 480 * 2 ; Index = 31 Token = 9 - DW 480 * 2 ; Index = 31 Token = 10 - DW 480 * 2 ; Index = 31 Token = 11 - DW 528 * 2 ; Index = 31 Token = 12 - DW 560 * 2 ; Index = 31 Token = 13 - DW 592 * 2 ; Index = 31 Token = 14 - DW 624 * 2 ; Index = 31 Token = 15 - DW 496 * 2 ; Index = 32 Token = 0 - DW 496 * 2 ; Index = 32 Token = 1 - DW 496 * 2 ; Index = 32 Token = 2 - DW 496 * 2 ; Index = 32 Token = 3 - DW 544 * 2 ; Index = 32 Token = 4 - DW 576 * 2 ; Index = 32 Token = 5 - DW 608 * 2 ; Index = 32 Token = 6 - DW 640 * 2 ; Index = 32 Token = 7 - DW 496 * 2 ; Index = 32 Token = 8 - DW 496 * 2 ; Index = 32 Token = 9 - DW 496 * 2 ; Index = 32 Token = 10 - DW 496 * 2 ; Index = 32 Token = 11 - DW 544 * 2 ; Index = 32 Token = 12 - DW 576 * 2 ; Index = 32 Token = 13 - DW 608 * 2 ; Index = 32 Token = 14 - DW 640 * 2 ; Index = 32 Token = 15 - DW 512 * 2 ; Index = 33 Token = 0 - DW 512 * 2 ; Index = 33 Token = 1 - DW 512 * 2 ; Index = 33 Token = 2 - DW 512 * 2 ; Index = 33 Token = 3 - DW 560 * 2 ; Index = 33 Token = 4 - DW 592 * 2 ; Index = 33 Token = 5 - DW 624 * 2 ; Index = 33 Token = 6 - DW 656 * 2 ; Index = 33 Token = 7 - DW 512 * 2 ; Index = 33 Token = 8 - DW 512 * 2 ; Index = 33 Token = 9 - DW 512 * 2 ; Index = 33 Token = 10 - DW 512 * 2 ; Index = 33 Token = 11 - DW 560 * 2 ; Index = 33 Token = 12 - DW 592 * 2 ; Index = 33 Token = 13 - DW 624 * 2 ; Index = 33 Token = 14 - DW 656 * 2 ; Index = 33 Token = 15 - DW 528 * 2 ; Index = 34 Token = 0 - DW 528 * 2 ; Index = 34 Token = 1 - DW 528 * 2 ; Index = 34 Token = 2 - DW 528 * 2 ; Index = 34 Token = 3 - DW 576 * 2 ; Index = 34 Token = 4 - DW 608 * 2 ; Index = 34 Token = 5 - DW 640 * 2 ; Index = 34 Token = 6 - DW 672 * 2 ; Index = 34 Token = 7 - DW 528 * 2 ; Index = 34 Token = 8 - DW 528 * 2 ; Index = 34 Token = 9 - DW 528 * 2 ; Index = 34 Token = 10 - DW 528 * 2 ; Index = 34 Token = 11 - DW 576 * 2 ; Index = 34 Token = 12 - DW 608 * 2 ; Index = 34 Token = 13 - DW 640 * 2 ; Index = 34 Token = 14 - DW 672 * 2 ; Index = 34 Token = 15 - DW 544 * 2 ; Index = 35 Token = 0 - DW 544 * 2 ; Index = 35 Token = 1 - DW 544 * 2 ; Index = 35 Token = 2 - DW 544 * 2 ; Index = 35 Token = 3 - DW 592 * 2 ; Index = 35 Token = 4 - DW 624 * 2 ; Index = 35 Token = 5 - DW 656 * 2 ; Index = 35 Token = 6 - DW 688 * 2 ; Index = 35 Token = 7 - DW 544 * 2 ; Index = 35 Token = 8 - DW 544 * 2 ; Index = 35 Token = 9 - DW 544 * 2 ; Index = 35 Token = 10 - DW 544 * 2 ; Index = 35 Token = 11 - DW 592 * 2 ; Index = 35 Token = 12 - DW 624 * 2 ; Index = 35 Token = 13 - DW 656 * 2 ; Index = 35 Token = 14 - DW 688 * 2 ; Index = 35 Token = 15 - DW 560 * 2 ; Index = 36 Token = 0 - DW 560 * 2 ; Index = 36 Token = 1 - DW 560 * 2 ; Index = 36 Token = 2 - DW 560 * 2 ; Index = 36 Token = 3 - DW 608 * 2 ; Index = 36 Token = 4 - DW 640 * 2 ; Index = 36 Token = 5 - DW 672 * 2 ; Index = 36 Token = 6 - DW 704 * 2 ; Index = 36 Token = 7 - DW 560 * 2 ; Index = 36 Token = 8 - DW 560 * 2 ; Index = 36 Token = 9 - DW 560 * 2 ; Index = 36 Token = 10 - DW 560 * 2 ; Index = 36 Token = 11 - DW 608 * 2 ; Index = 36 Token = 12 - DW 640 * 2 ; Index = 36 Token = 13 - DW 672 * 2 ; Index = 36 Token = 14 - DW 704 * 2 ; Index = 36 Token = 15 - DW 576 * 2 ; Index = 37 Token = 0 - DW 576 * 2 ; Index = 37 Token = 1 - DW 576 * 2 ; Index = 37 Token = 2 - DW 576 * 2 ; Index = 37 Token = 3 - DW 624 * 2 ; Index = 37 Token = 4 - DW 656 * 2 ; Index = 37 Token = 5 - DW 688 * 2 ; Index = 37 Token = 6 - DW 720 * 2 ; Index = 37 Token = 7 - DW 576 * 2 ; Index = 37 Token = 8 - DW 576 * 2 ; Index = 37 Token = 9 - DW 576 * 2 ; Index = 37 Token = 10 - DW 576 * 2 ; Index = 37 Token = 11 - DW 624 * 2 ; Index = 37 Token = 12 - DW 656 * 2 ; Index = 37 Token = 13 - DW 688 * 2 ; Index = 37 Token = 14 - DW 720 * 2 ; Index = 37 Token = 15 - DW 592 * 2 ; Index = 38 Token = 0 - DW 592 * 2 ; Index = 38 Token = 1 - DW 592 * 2 ; Index = 38 Token = 2 - DW 592 * 2 ; Index = 38 Token = 3 - DW 640 * 2 ; Index = 38 Token = 4 - DW 672 * 2 ; Index = 38 Token = 5 - DW 704 * 2 ; Index = 38 Token = 6 - DW 736 * 2 ; Index = 38 Token = 7 - DW 592 * 2 ; Index = 38 Token = 8 - DW 592 * 2 ; Index = 38 Token = 9 - DW 592 * 2 ; Index = 38 Token = 10 - DW 592 * 2 ; Index = 38 Token = 11 - DW 640 * 2 ; Index = 38 Token = 12 - DW 672 * 2 ; Index = 38 Token = 13 - DW 704 * 2 ; Index = 38 Token = 14 - DW 736 * 2 ; Index = 38 Token = 15 - DW 608 * 2 ; Index = 39 Token = 0 - DW 608 * 2 ; Index = 39 Token = 1 - DW 608 * 2 ; Index = 39 Token = 2 - DW 608 * 2 ; Index = 39 Token = 3 - DW 656 * 2 ; Index = 39 Token = 4 - DW 688 * 2 ; Index = 39 Token = 5 - DW 720 * 2 ; Index = 39 Token = 6 - DW 752 * 2 ; Index = 39 Token = 7 - DW 608 * 2 ; Index = 39 Token = 8 - DW 608 * 2 ; Index = 39 Token = 9 - DW 608 * 2 ; Index = 39 Token = 10 - DW 608 * 2 ; Index = 39 Token = 11 - DW 656 * 2 ; Index = 39 Token = 12 - DW 688 * 2 ; Index = 39 Token = 13 - DW 720 * 2 ; Index = 39 Token = 14 - DW 752 * 2 ; Index = 39 Token = 15 - DW 624 * 2 ; Index = 40 Token = 0 - DW 624 * 2 ; Index = 40 Token = 1 - DW 624 * 2 ; Index = 40 Token = 2 - DW 624 * 2 ; Index = 40 Token = 3 - DW 672 * 2 ; Index = 40 Token = 4 - DW 704 * 2 ; Index = 40 Token = 5 - DW 736 * 2 ; Index = 40 Token = 6 - DW 768 * 2 ; Index = 40 Token = 7 - DW 624 * 2 ; Index = 40 Token = 8 - DW 624 * 2 ; Index = 40 Token = 9 - DW 624 * 2 ; Index = 40 Token = 10 - DW 624 * 2 ; Index = 40 Token = 11 - DW 672 * 2 ; Index = 40 Token = 12 - DW 704 * 2 ; Index = 40 Token = 13 - DW 736 * 2 ; Index = 40 Token = 14 - DW 768 * 2 ; Index = 40 Token = 15 - DW 640 * 2 ; Index = 41 Token = 0 - DW 640 * 2 ; Index = 41 Token = 1 - DW 640 * 2 ; Index = 41 Token = 2 - DW 640 * 2 ; Index = 41 Token = 3 - DW 688 * 2 ; Index = 41 Token = 4 - DW 720 * 2 ; Index = 41 Token = 5 - DW 752 * 2 ; Index = 41 Token = 6 - DW 784 * 2 ; Index = 41 Token = 7 - DW 640 * 2 ; Index = 41 Token = 8 - DW 640 * 2 ; Index = 41 Token = 9 - DW 640 * 2 ; Index = 41 Token = 10 - DW 640 * 2 ; Index = 41 Token = 11 - DW 688 * 2 ; Index = 41 Token = 12 - DW 720 * 2 ; Index = 41 Token = 13 - DW 752 * 2 ; Index = 41 Token = 14 - DW 784 * 2 ; Index = 41 Token = 15 - DW 656 * 2 ; Index = 42 Token = 0 - DW 656 * 2 ; Index = 42 Token = 1 - DW 656 * 2 ; Index = 42 Token = 2 - DW 656 * 2 ; Index = 42 Token = 3 - DW 704 * 2 ; Index = 42 Token = 4 - DW 736 * 2 ; Index = 42 Token = 5 - DW 768 * 2 ; Index = 42 Token = 6 - DW 800 * 2 ; Index = 42 Token = 7 - DW 656 * 2 ; Index = 42 Token = 8 - DW 656 * 2 ; Index = 42 Token = 9 - DW 656 * 2 ; Index = 42 Token = 10 - DW 656 * 2 ; Index = 42 Token = 11 - DW 704 * 2 ; Index = 42 Token = 12 - DW 736 * 2 ; Index = 42 Token = 13 - DW 768 * 2 ; Index = 42 Token = 14 - DW 800 * 2 ; Index = 42 Token = 15 - DW 672 * 2 ; Index = 43 Token = 0 - DW 672 * 2 ; Index = 43 Token = 1 - DW 672 * 2 ; Index = 43 Token = 2 - DW 672 * 2 ; Index = 43 Token = 3 - DW 720 * 2 ; Index = 43 Token = 4 - DW 752 * 2 ; Index = 43 Token = 5 - DW 784 * 2 ; Index = 43 Token = 6 - DW 816 * 2 ; Index = 43 Token = 7 - DW 672 * 2 ; Index = 43 Token = 8 - DW 672 * 2 ; Index = 43 Token = 9 - DW 672 * 2 ; Index = 43 Token = 10 - DW 672 * 2 ; Index = 43 Token = 11 - DW 720 * 2 ; Index = 43 Token = 12 - DW 752 * 2 ; Index = 43 Token = 13 - DW 784 * 2 ; Index = 43 Token = 14 - DW 816 * 2 ; Index = 43 Token = 15 - DW 688 * 2 ; Index = 44 Token = 0 - DW 688 * 2 ; Index = 44 Token = 1 - DW 688 * 2 ; Index = 44 Token = 2 - DW 688 * 2 ; Index = 44 Token = 3 - DW 736 * 2 ; Index = 44 Token = 4 - DW 768 * 2 ; Index = 44 Token = 5 - DW 800 * 2 ; Index = 44 Token = 6 - DW 832 * 2 ; Index = 44 Token = 7 - DW 688 * 2 ; Index = 44 Token = 8 - DW 688 * 2 ; Index = 44 Token = 9 - DW 688 * 2 ; Index = 44 Token = 10 - DW 688 * 2 ; Index = 44 Token = 11 - DW 736 * 2 ; Index = 44 Token = 12 - DW 768 * 2 ; Index = 44 Token = 13 - DW 800 * 2 ; Index = 44 Token = 14 - DW 832 * 2 ; Index = 44 Token = 15 - DW 704 * 2 ; Index = 45 Token = 0 - DW 704 * 2 ; Index = 45 Token = 1 - DW 704 * 2 ; Index = 45 Token = 2 - DW 704 * 2 ; Index = 45 Token = 3 - DW 752 * 2 ; Index = 45 Token = 4 - DW 784 * 2 ; Index = 45 Token = 5 - DW 816 * 2 ; Index = 45 Token = 6 - DW 848 * 2 ; Index = 45 Token = 7 - DW 704 * 2 ; Index = 45 Token = 8 - DW 704 * 2 ; Index = 45 Token = 9 - DW 704 * 2 ; Index = 45 Token = 10 - DW 704 * 2 ; Index = 45 Token = 11 - DW 752 * 2 ; Index = 45 Token = 12 - DW 784 * 2 ; Index = 45 Token = 13 - DW 816 * 2 ; Index = 45 Token = 14 - DW 848 * 2 ; Index = 45 Token = 15 - DW 720 * 2 ; Index = 46 Token = 0 - DW 720 * 2 ; Index = 46 Token = 1 - DW 720 * 2 ; Index = 46 Token = 2 - DW 720 * 2 ; Index = 46 Token = 3 - DW 768 * 2 ; Index = 46 Token = 4 - DW 800 * 2 ; Index = 46 Token = 5 - DW 832 * 2 ; Index = 46 Token = 6 - DW 864 * 2 ; Index = 46 Token = 7 - DW 720 * 2 ; Index = 46 Token = 8 - DW 720 * 2 ; Index = 46 Token = 9 - DW 720 * 2 ; Index = 46 Token = 10 - DW 720 * 2 ; Index = 46 Token = 11 - DW 768 * 2 ; Index = 46 Token = 12 - DW 800 * 2 ; Index = 46 Token = 13 - DW 832 * 2 ; Index = 46 Token = 14 - DW 864 * 2 ; Index = 46 Token = 15 - DW 736 * 2 ; Index = 47 Token = 0 - DW 736 * 2 ; Index = 47 Token = 1 - DW 736 * 2 ; Index = 47 Token = 2 - DW 736 * 2 ; Index = 47 Token = 3 - DW 784 * 2 ; Index = 47 Token = 4 - DW 816 * 2 ; Index = 47 Token = 5 - DW 848 * 2 ; Index = 47 Token = 6 - DW 880 * 2 ; Index = 47 Token = 7 - DW 736 * 2 ; Index = 47 Token = 8 - DW 736 * 2 ; Index = 47 Token = 9 - DW 736 * 2 ; Index = 47 Token = 10 - DW 736 * 2 ; Index = 47 Token = 11 - DW 784 * 2 ; Index = 47 Token = 12 - DW 816 * 2 ; Index = 47 Token = 13 - DW 848 * 2 ; Index = 47 Token = 14 - DW 880 * 2 ; Index = 47 Token = 15 - DW 752 * 2 ; Index = 48 Token = 0 - DW 752 * 2 ; Index = 48 Token = 1 - DW 752 * 2 ; Index = 48 Token = 2 - DW 752 * 2 ; Index = 48 Token = 3 - DW 800 * 2 ; Index = 48 Token = 4 - DW 832 * 2 ; Index = 48 Token = 5 - DW 864 * 2 ; Index = 48 Token = 6 - DW 896 * 2 ; Index = 48 Token = 7 - DW 752 * 2 ; Index = 48 Token = 8 - DW 752 * 2 ; Index = 48 Token = 9 - DW 752 * 2 ; Index = 48 Token = 10 - DW 752 * 2 ; Index = 48 Token = 11 - DW 800 * 2 ; Index = 48 Token = 12 - DW 832 * 2 ; Index = 48 Token = 13 - DW 864 * 2 ; Index = 48 Token = 14 - DW 896 * 2 ; Index = 48 Token = 15 - DW 768 * 2 ; Index = 49 Token = 0 - DW 768 * 2 ; Index = 49 Token = 1 - DW 768 * 2 ; Index = 49 Token = 2 - DW 768 * 2 ; Index = 49 Token = 3 - DW 816 * 2 ; Index = 49 Token = 4 - DW 848 * 2 ; Index = 49 Token = 5 - DW 880 * 2 ; Index = 49 Token = 6 - DW 912 * 2 ; Index = 49 Token = 7 - DW 768 * 2 ; Index = 49 Token = 8 - DW 768 * 2 ; Index = 49 Token = 9 - DW 768 * 2 ; Index = 49 Token = 10 - DW 768 * 2 ; Index = 49 Token = 11 - DW 816 * 2 ; Index = 49 Token = 12 - DW 848 * 2 ; Index = 49 Token = 13 - DW 880 * 2 ; Index = 49 Token = 14 - DW 912 * 2 ; Index = 49 Token = 15 - DW 784 * 2 ; Index = 50 Token = 0 - DW 784 * 2 ; Index = 50 Token = 1 - DW 784 * 2 ; Index = 50 Token = 2 - DW 784 * 2 ; Index = 50 Token = 3 - DW 832 * 2 ; Index = 50 Token = 4 - DW 864 * 2 ; Index = 50 Token = 5 - DW 896 * 2 ; Index = 50 Token = 6 - DW 928 * 2 ; Index = 50 Token = 7 - DW 784 * 2 ; Index = 50 Token = 8 - DW 784 * 2 ; Index = 50 Token = 9 - DW 784 * 2 ; Index = 50 Token = 10 - DW 784 * 2 ; Index = 50 Token = 11 - DW 832 * 2 ; Index = 50 Token = 12 - DW 864 * 2 ; Index = 50 Token = 13 - DW 896 * 2 ; Index = 50 Token = 14 - DW 928 * 2 ; Index = 50 Token = 15 - DW 800 * 2 ; Index = 51 Token = 0 - DW 800 * 2 ; Index = 51 Token = 1 - DW 800 * 2 ; Index = 51 Token = 2 - DW 800 * 2 ; Index = 51 Token = 3 - DW 848 * 2 ; Index = 51 Token = 4 - DW 880 * 2 ; Index = 51 Token = 5 - DW 912 * 2 ; Index = 51 Token = 6 - DW 944 * 2 ; Index = 51 Token = 7 - DW 800 * 2 ; Index = 51 Token = 8 - DW 800 * 2 ; Index = 51 Token = 9 - DW 800 * 2 ; Index = 51 Token = 10 - DW 800 * 2 ; Index = 51 Token = 11 - DW 848 * 2 ; Index = 51 Token = 12 - DW 880 * 2 ; Index = 51 Token = 13 - DW 912 * 2 ; Index = 51 Token = 14 - DW 944 * 2 ; Index = 51 Token = 15 - DW 816 * 2 ; Index = 52 Token = 0 - DW 816 * 2 ; Index = 52 Token = 1 - DW 816 * 2 ; Index = 52 Token = 2 - DW 816 * 2 ; Index = 52 Token = 3 - DW 864 * 2 ; Index = 52 Token = 4 - DW 896 * 2 ; Index = 52 Token = 5 - DW 928 * 2 ; Index = 52 Token = 6 - DW 960 * 2 ; Index = 52 Token = 7 - DW 816 * 2 ; Index = 52 Token = 8 - DW 816 * 2 ; Index = 52 Token = 9 - DW 816 * 2 ; Index = 52 Token = 10 - DW 816 * 2 ; Index = 52 Token = 11 - DW 864 * 2 ; Index = 52 Token = 12 - DW 896 * 2 ; Index = 52 Token = 13 - DW 928 * 2 ; Index = 52 Token = 14 - DW 960 * 2 ; Index = 52 Token = 15 - DW 832 * 2 ; Index = 53 Token = 0 - DW 832 * 2 ; Index = 53 Token = 1 - DW 832 * 2 ; Index = 53 Token = 2 - DW 832 * 2 ; Index = 53 Token = 3 - DW 880 * 2 ; Index = 53 Token = 4 - DW 912 * 2 ; Index = 53 Token = 5 - DW 944 * 2 ; Index = 53 Token = 6 - DW 976 * 2 ; Index = 53 Token = 7 - DW 832 * 2 ; Index = 53 Token = 8 - DW 832 * 2 ; Index = 53 Token = 9 - DW 832 * 2 ; Index = 53 Token = 10 - DW 832 * 2 ; Index = 53 Token = 11 - DW 880 * 2 ; Index = 53 Token = 12 - DW 912 * 2 ; Index = 53 Token = 13 - DW 944 * 2 ; Index = 53 Token = 14 - DW 976 * 2 ; Index = 53 Token = 15 - DW 848 * 2 ; Index = 54 Token = 0 - DW 848 * 2 ; Index = 54 Token = 1 - DW 848 * 2 ; Index = 54 Token = 2 - DW 848 * 2 ; Index = 54 Token = 3 - DW 896 * 2 ; Index = 54 Token = 4 - DW 928 * 2 ; Index = 54 Token = 5 - DW 960 * 2 ; Index = 54 Token = 6 - DW 992 * 2 ; Index = 54 Token = 7 - DW 848 * 2 ; Index = 54 Token = 8 - DW 848 * 2 ; Index = 54 Token = 9 - DW 848 * 2 ; Index = 54 Token = 10 - DW 848 * 2 ; Index = 54 Token = 11 - DW 896 * 2 ; Index = 54 Token = 12 - DW 928 * 2 ; Index = 54 Token = 13 - DW 960 * 2 ; Index = 54 Token = 14 - DW 992 * 2 ; Index = 54 Token = 15 - DW 864 * 2 ; Index = 55 Token = 0 - DW 864 * 2 ; Index = 55 Token = 1 - DW 864 * 2 ; Index = 55 Token = 2 - DW 864 * 2 ; Index = 55 Token = 3 - DW 912 * 2 ; Index = 55 Token = 4 - DW 944 * 2 ; Index = 55 Token = 5 - DW 976 * 2 ; Index = 55 Token = 6 - DW 1008 * 2 ; Index = 55 Token = 7 - DW 864 * 2 ; Index = 55 Token = 8 - DW 864 * 2 ; Index = 55 Token = 9 - DW 864 * 2 ; Index = 55 Token = 10 - DW 864 * 2 ; Index = 55 Token = 11 - DW 912 * 2 ; Index = 55 Token = 12 - DW 944 * 2 ; Index = 55 Token = 13 - DW 976 * 2 ; Index = 55 Token = 14 - DW 1008 * 2 ; Index = 55 Token = 15 - DW 880 * 2 ; Index = 56 Token = 0 - DW 880 * 2 ; Index = 56 Token = 1 - DW 880 * 2 ; Index = 56 Token = 2 - DW 880 * 2 ; Index = 56 Token = 3 - DW 928 * 2 ; Index = 56 Token = 4 - DW 960 * 2 ; Index = 56 Token = 5 - DW 992 * 2 ; Index = 56 Token = 6 - DW 1024 * 2 ; Index = 56 Token = 7 - DW 880 * 2 ; Index = 56 Token = 8 - DW 880 * 2 ; Index = 56 Token = 9 - DW 880 * 2 ; Index = 56 Token = 10 - DW 880 * 2 ; Index = 56 Token = 11 - DW 928 * 2 ; Index = 56 Token = 12 - DW 960 * 2 ; Index = 56 Token = 13 - DW 992 * 2 ; Index = 56 Token = 14 - DW 1024 * 2 ; Index = 56 Token = 15 - DW 896 * 2 ; Index = 57 Token = 0 - DW 896 * 2 ; Index = 57 Token = 1 - DW 896 * 2 ; Index = 57 Token = 2 - DW 896 * 2 ; Index = 57 Token = 3 - DW 944 * 2 ; Index = 57 Token = 4 - DW 976 * 2 ; Index = 57 Token = 5 - DW 1008 * 2 ; Index = 57 Token = 6 - DW 1040 * 2 ; Index = 57 Token = 7 - DW 896 * 2 ; Index = 57 Token = 8 - DW 896 * 2 ; Index = 57 Token = 9 - DW 896 * 2 ; Index = 57 Token = 10 - DW 896 * 2 ; Index = 57 Token = 11 - DW 944 * 2 ; Index = 57 Token = 12 - DW 976 * 2 ; Index = 57 Token = 13 - DW 1008 * 2 ; Index = 57 Token = 14 - DW 1040 * 2 ; Index = 57 Token = 15 - DW 912 * 2 ; Index = 58 Token = 0 - DW 912 * 2 ; Index = 58 Token = 1 - DW 912 * 2 ; Index = 58 Token = 2 - DW 912 * 2 ; Index = 58 Token = 3 - DW 960 * 2 ; Index = 58 Token = 4 - DW 992 * 2 ; Index = 58 Token = 5 - DW 1024 * 2 ; Index = 58 Token = 6 - DW 1056 * 2 ; Index = 58 Token = 7 - DW 912 * 2 ; Index = 58 Token = 8 - DW 912 * 2 ; Index = 58 Token = 9 - DW 912 * 2 ; Index = 58 Token = 10 - DW 912 * 2 ; Index = 58 Token = 11 - DW 960 * 2 ; Index = 58 Token = 12 - DW 992 * 2 ; Index = 58 Token = 13 - DW 1024 * 2 ; Index = 58 Token = 14 - DW 1056 * 2 ; Index = 58 Token = 15 - DW 928 * 2 ; Index = 59 Token = 0 - DW 928 * 2 ; Index = 59 Token = 1 - DW 928 * 2 ; Index = 59 Token = 2 - DW 928 * 2 ; Index = 59 Token = 3 - DW 976 * 2 ; Index = 59 Token = 4 - DW 1008 * 2 ; Index = 59 Token = 5 - DW 1040 * 2 ; Index = 59 Token = 6 - DW 1072 * 2 ; Index = 59 Token = 7 - DW 928 * 2 ; Index = 59 Token = 8 - DW 928 * 2 ; Index = 59 Token = 9 - DW 928 * 2 ; Index = 59 Token = 10 - DW 928 * 2 ; Index = 59 Token = 11 - DW 976 * 2 ; Index = 59 Token = 12 - DW 1008 * 2 ; Index = 59 Token = 13 - DW 1040 * 2 ; Index = 59 Token = 14 - DW 1072 * 2 ; Index = 59 Token = 15 - DW 944 * 2 ; Index = 60 Token = 0 - DW 944 * 2 ; Index = 60 Token = 1 - DW 944 * 2 ; Index = 60 Token = 2 - DW 944 * 2 ; Index = 60 Token = 3 - DW 992 * 2 ; Index = 60 Token = 4 - DW 1024 * 2 ; Index = 60 Token = 5 - DW 1056 * 2 ; Index = 60 Token = 6 - DW 1088 * 2 ; Index = 60 Token = 7 - DW 944 * 2 ; Index = 60 Token = 8 - DW 944 * 2 ; Index = 60 Token = 9 - DW 944 * 2 ; Index = 60 Token = 10 - DW 944 * 2 ; Index = 60 Token = 11 - DW 992 * 2 ; Index = 60 Token = 12 - DW 1024 * 2 ; Index = 60 Token = 13 - DW 1056 * 2 ; Index = 60 Token = 14 - DW 1088 * 2 ; Index = 60 Token = 15 - DW 960 * 2 ; Index = 61 Token = 0 - DW 960 * 2 ; Index = 61 Token = 1 - DW 960 * 2 ; Index = 61 Token = 2 - DW 960 * 2 ; Index = 61 Token = 3 - DW 1008 * 2 ; Index = 61 Token = 4 - DW 1040 * 2 ; Index = 61 Token = 5 - DW 1072 * 2 ; Index = 61 Token = 6 - DW 1104 * 2 ; Index = 61 Token = 7 - DW 960 * 2 ; Index = 61 Token = 8 - DW 960 * 2 ; Index = 61 Token = 9 - DW 960 * 2 ; Index = 61 Token = 10 - DW 960 * 2 ; Index = 61 Token = 11 - DW 1008 * 2 ; Index = 61 Token = 12 - DW 1040 * 2 ; Index = 61 Token = 13 - DW 1072 * 2 ; Index = 61 Token = 14 - DW 1104 * 2 ; Index = 61 Token = 15 - DW 976 * 2 ; Index = 62 Token = 0 - DW 976 * 2 ; Index = 62 Token = 1 - DW 976 * 2 ; Index = 62 Token = 2 - DW 976 * 2 ; Index = 62 Token = 3 - DW 1024 * 2 ; Index = 62 Token = 4 - DW 1056 * 2 ; Index = 62 Token = 5 - DW 1088 * 2 ; Index = 62 Token = 6 - DW 1120 * 2 ; Index = 62 Token = 7 - DW 976 * 2 ; Index = 62 Token = 8 - DW 976 * 2 ; Index = 62 Token = 9 - DW 976 * 2 ; Index = 62 Token = 10 - DW 976 * 2 ; Index = 62 Token = 11 - DW 1024 * 2 ; Index = 62 Token = 12 - DW 1056 * 2 ; Index = 62 Token = 13 - DW 1088 * 2 ; Index = 62 Token = 14 - DW 1120 * 2 ; Index = 62 Token = 15 - DW 992 * 2 ; Index = 63 Token = 0 - DW 992 * 2 ; Index = 63 Token = 1 - DW 992 * 2 ; Index = 63 Token = 2 - DW 992 * 2 ; Index = 63 Token = 3 - DW 1040 * 2 ; Index = 63 Token = 4 - DW 1072 * 2 ; Index = 63 Token = 5 - DW 1104 * 2 ; Index = 63 Token = 6 - DW 1136 * 2 ; Index = 63 Token = 7 - DW 992 * 2 ; Index = 63 Token = 8 - DW 992 * 2 ; Index = 63 Token = 9 - DW 992 * 2 ; Index = 63 Token = 10 - DW 992 * 2 ; Index = 63 Token = 11 - DW 1040 * 2 ; Index = 63 Token = 12 - DW 1072 * 2 ; Index = 63 Token = 13 - DW 1104 * 2 ; Index = 63 Token = 14 - DW 1136 * 2 ; Index = 63 Token = 15 - DW 1008 * 2 ; Index = 64 Token = 0 - DW 1008 * 2 ; Index = 64 Token = 1 - DW 1008 * 2 ; Index = 64 Token = 2 - DW 1008 * 2 ; Index = 64 Token = 3 - DW 1056 * 2 ; Index = 64 Token = 4 - DW 1088 * 2 ; Index = 64 Token = 5 - DW 1120 * 2 ; Index = 64 Token = 6 - DW 1152 * 2 ; Index = 64 Token = 7 - DW 1008 * 2 ; Index = 64 Token = 8 - DW 1008 * 2 ; Index = 64 Token = 9 - DW 1008 * 2 ; Index = 64 Token = 10 - DW 1008 * 2 ; Index = 64 Token = 11 - DW 1056 * 2 ; Index = 64 Token = 12 - DW 1088 * 2 ; Index = 64 Token = 13 - DW 1120 * 2 ; Index = 64 Token = 14 - DW 1152 * 2 ; Index = 64 Token = 15 - DW 1024 * 2 ; Index = 65 Token = 0 - DW 1024 * 2 ; Index = 65 Token = 1 - DW 1024 * 2 ; Index = 65 Token = 2 - DW 1024 * 2 ; Index = 65 Token = 3 - DW 1072 * 2 ; Index = 65 Token = 4 - DW 1104 * 2 ; Index = 65 Token = 5 - DW 1136 * 2 ; Index = 65 Token = 6 - DW 1168 * 2 ; Index = 65 Token = 7 - DW 1024 * 2 ; Index = 65 Token = 8 - DW 1024 * 2 ; Index = 65 Token = 9 - DW 1024 * 2 ; Index = 65 Token = 10 - DW 1024 * 2 ; Index = 65 Token = 11 - DW 1072 * 2 ; Index = 65 Token = 12 - DW 1104 * 2 ; Index = 65 Token = 13 - DW 1136 * 2 ; Index = 65 Token = 14 - DW 1168 * 2 ; Index = 65 Token = 15 - DW 1040 * 2 ; Index = 66 Token = 0 - DW 1040 * 2 ; Index = 66 Token = 1 - DW 1040 * 2 ; Index = 66 Token = 2 - DW 1040 * 2 ; Index = 66 Token = 3 - DW 1088 * 2 ; Index = 66 Token = 4 - DW 1120 * 2 ; Index = 66 Token = 5 - DW 1152 * 2 ; Index = 66 Token = 6 - DW 1184 * 2 ; Index = 66 Token = 7 - DW 1040 * 2 ; Index = 66 Token = 8 - DW 1040 * 2 ; Index = 66 Token = 9 - DW 1040 * 2 ; Index = 66 Token = 10 - DW 1040 * 2 ; Index = 66 Token = 11 - DW 1088 * 2 ; Index = 66 Token = 12 - DW 1120 * 2 ; Index = 66 Token = 13 - DW 1152 * 2 ; Index = 66 Token = 14 - DW 1184 * 2 ; Index = 66 Token = 15 - DW 1056 * 2 ; Index = 67 Token = 0 - DW 1056 * 2 ; Index = 67 Token = 1 - DW 1056 * 2 ; Index = 67 Token = 2 - DW 1056 * 2 ; Index = 67 Token = 3 - DW 1104 * 2 ; Index = 67 Token = 4 - DW 1136 * 2 ; Index = 67 Token = 5 - DW 1168 * 2 ; Index = 67 Token = 6 - DW 1200 * 2 ; Index = 67 Token = 7 - DW 1056 * 2 ; Index = 67 Token = 8 - DW 1056 * 2 ; Index = 67 Token = 9 - DW 1056 * 2 ; Index = 67 Token = 10 - DW 1056 * 2 ; Index = 67 Token = 11 - DW 1104 * 2 ; Index = 67 Token = 12 - DW 1136 * 2 ; Index = 67 Token = 13 - DW 1168 * 2 ; Index = 67 Token = 14 - DW 1200 * 2 ; Index = 67 Token = 15 - DW 1072 * 2 ; Index = 68 Token = 0 - DW 1072 * 2 ; Index = 68 Token = 1 - DW 1072 * 2 ; Index = 68 Token = 2 - DW 1072 * 2 ; Index = 68 Token = 3 - DW 1120 * 2 ; Index = 68 Token = 4 - DW 1152 * 2 ; Index = 68 Token = 5 - DW 1184 * 2 ; Index = 68 Token = 6 - DW 1216 * 2 ; Index = 68 Token = 7 - DW 1072 * 2 ; Index = 68 Token = 8 - DW 1072 * 2 ; Index = 68 Token = 9 - DW 1072 * 2 ; Index = 68 Token = 10 - DW 1072 * 2 ; Index = 68 Token = 11 - DW 1120 * 2 ; Index = 68 Token = 12 - DW 1152 * 2 ; Index = 68 Token = 13 - DW 1184 * 2 ; Index = 68 Token = 14 - DW 1216 * 2 ; Index = 68 Token = 15 - DW 1088 * 2 ; Index = 69 Token = 0 - DW 1088 * 2 ; Index = 69 Token = 1 - DW 1088 * 2 ; Index = 69 Token = 2 - DW 1088 * 2 ; Index = 69 Token = 3 - DW 1136 * 2 ; Index = 69 Token = 4 - DW 1168 * 2 ; Index = 69 Token = 5 - DW 1200 * 2 ; Index = 69 Token = 6 - DW 1232 * 2 ; Index = 69 Token = 7 - DW 1088 * 2 ; Index = 69 Token = 8 - DW 1088 * 2 ; Index = 69 Token = 9 - DW 1088 * 2 ; Index = 69 Token = 10 - DW 1088 * 2 ; Index = 69 Token = 11 - DW 1136 * 2 ; Index = 69 Token = 12 - DW 1168 * 2 ; Index = 69 Token = 13 - DW 1200 * 2 ; Index = 69 Token = 14 - DW 1232 * 2 ; Index = 69 Token = 15 - DW 1104 * 2 ; Index = 70 Token = 0 - DW 1104 * 2 ; Index = 70 Token = 1 - DW 1104 * 2 ; Index = 70 Token = 2 - DW 1104 * 2 ; Index = 70 Token = 3 - DW 1152 * 2 ; Index = 70 Token = 4 - DW 1184 * 2 ; Index = 70 Token = 5 - DW 1216 * 2 ; Index = 70 Token = 6 - DW 1248 * 2 ; Index = 70 Token = 7 - DW 1104 * 2 ; Index = 70 Token = 8 - DW 1104 * 2 ; Index = 70 Token = 9 - DW 1104 * 2 ; Index = 70 Token = 10 - DW 1104 * 2 ; Index = 70 Token = 11 - DW 1152 * 2 ; Index = 70 Token = 12 - DW 1184 * 2 ; Index = 70 Token = 13 - DW 1216 * 2 ; Index = 70 Token = 14 - DW 1248 * 2 ; Index = 70 Token = 15 - DW 1120 * 2 ; Index = 71 Token = 0 - DW 1120 * 2 ; Index = 71 Token = 1 - DW 1120 * 2 ; Index = 71 Token = 2 - DW 1120 * 2 ; Index = 71 Token = 3 - DW 1168 * 2 ; Index = 71 Token = 4 - DW 1200 * 2 ; Index = 71 Token = 5 - DW 1232 * 2 ; Index = 71 Token = 6 - DW 1264 * 2 ; Index = 71 Token = 7 - DW 1120 * 2 ; Index = 71 Token = 8 - DW 1120 * 2 ; Index = 71 Token = 9 - DW 1120 * 2 ; Index = 71 Token = 10 - DW 1120 * 2 ; Index = 71 Token = 11 - DW 1168 * 2 ; Index = 71 Token = 12 - DW 1200 * 2 ; Index = 71 Token = 13 - DW 1232 * 2 ; Index = 71 Token = 14 - DW 1264 * 2 ; Index = 71 Token = 15 - DW 1136 * 2 ; Index = 72 Token = 0 - DW 1136 * 2 ; Index = 72 Token = 1 - DW 1136 * 2 ; Index = 72 Token = 2 - DW 1136 * 2 ; Index = 72 Token = 3 - DW 1184 * 2 ; Index = 72 Token = 4 - DW 1216 * 2 ; Index = 72 Token = 5 - DW 1248 * 2 ; Index = 72 Token = 6 - DW 1280 * 2 ; Index = 72 Token = 7 - DW 1136 * 2 ; Index = 72 Token = 8 - DW 1136 * 2 ; Index = 72 Token = 9 - DW 1136 * 2 ; Index = 72 Token = 10 - DW 1136 * 2 ; Index = 72 Token = 11 - DW 1184 * 2 ; Index = 72 Token = 12 - DW 1216 * 2 ; Index = 72 Token = 13 - DW 1248 * 2 ; Index = 72 Token = 14 - DW 1280 * 2 ; Index = 72 Token = 15 - DW 1152 * 2 ; Index = 73 Token = 0 - DW 1152 * 2 ; Index = 73 Token = 1 - DW 1152 * 2 ; Index = 73 Token = 2 - DW 1152 * 2 ; Index = 73 Token = 3 - DW 1200 * 2 ; Index = 73 Token = 4 - DW 1232 * 2 ; Index = 73 Token = 5 - DW 1264 * 2 ; Index = 73 Token = 6 - DW 1296 * 2 ; Index = 73 Token = 7 - DW 1152 * 2 ; Index = 73 Token = 8 - DW 1152 * 2 ; Index = 73 Token = 9 - DW 1152 * 2 ; Index = 73 Token = 10 - DW 1152 * 2 ; Index = 73 Token = 11 - DW 1200 * 2 ; Index = 73 Token = 12 - DW 1232 * 2 ; Index = 73 Token = 13 - DW 1264 * 2 ; Index = 73 Token = 14 - DW 1296 * 2 ; Index = 73 Token = 15 - DW 1168 * 2 ; Index = 74 Token = 0 - DW 1168 * 2 ; Index = 74 Token = 1 - DW 1168 * 2 ; Index = 74 Token = 2 - DW 1168 * 2 ; Index = 74 Token = 3 - DW 1216 * 2 ; Index = 74 Token = 4 - DW 1248 * 2 ; Index = 74 Token = 5 - DW 1280 * 2 ; Index = 74 Token = 6 - DW 1312 * 2 ; Index = 74 Token = 7 - DW 1168 * 2 ; Index = 74 Token = 8 - DW 1168 * 2 ; Index = 74 Token = 9 - DW 1168 * 2 ; Index = 74 Token = 10 - DW 1168 * 2 ; Index = 74 Token = 11 - DW 1216 * 2 ; Index = 74 Token = 12 - DW 1248 * 2 ; Index = 74 Token = 13 - DW 1280 * 2 ; Index = 74 Token = 14 - DW 1312 * 2 ; Index = 74 Token = 15 - DW 1184 * 2 ; Index = 75 Token = 0 - DW 1184 * 2 ; Index = 75 Token = 1 - DW 1184 * 2 ; Index = 75 Token = 2 - DW 1184 * 2 ; Index = 75 Token = 3 - DW 1232 * 2 ; Index = 75 Token = 4 - DW 1264 * 2 ; Index = 75 Token = 5 - DW 1296 * 2 ; Index = 75 Token = 6 - DW 1328 * 2 ; Index = 75 Token = 7 - DW 1184 * 2 ; Index = 75 Token = 8 - DW 1184 * 2 ; Index = 75 Token = 9 - DW 1184 * 2 ; Index = 75 Token = 10 - DW 1184 * 2 ; Index = 75 Token = 11 - DW 1232 * 2 ; Index = 75 Token = 12 - DW 1264 * 2 ; Index = 75 Token = 13 - DW 1296 * 2 ; Index = 75 Token = 14 - DW 1328 * 2 ; Index = 75 Token = 15 - DW 1200 * 2 ; Index = 76 Token = 0 - DW 1200 * 2 ; Index = 76 Token = 1 - DW 1200 * 2 ; Index = 76 Token = 2 - DW 1200 * 2 ; Index = 76 Token = 3 - DW 1248 * 2 ; Index = 76 Token = 4 - DW 1280 * 2 ; Index = 76 Token = 5 - DW 1312 * 2 ; Index = 76 Token = 6 - DW 1344 * 2 ; Index = 76 Token = 7 - DW 1200 * 2 ; Index = 76 Token = 8 - DW 1200 * 2 ; Index = 76 Token = 9 - DW 1200 * 2 ; Index = 76 Token = 10 - DW 1200 * 2 ; Index = 76 Token = 11 - DW 1248 * 2 ; Index = 76 Token = 12 - DW 1280 * 2 ; Index = 76 Token = 13 - DW 1312 * 2 ; Index = 76 Token = 14 - DW 1344 * 2 ; Index = 76 Token = 15 - DW 1216 * 2 ; Index = 77 Token = 0 - DW 1216 * 2 ; Index = 77 Token = 1 - DW 1216 * 2 ; Index = 77 Token = 2 - DW 1216 * 2 ; Index = 77 Token = 3 - DW 1264 * 2 ; Index = 77 Token = 4 - DW 1296 * 2 ; Index = 77 Token = 5 - DW 1328 * 2 ; Index = 77 Token = 6 - DW 1360 * 2 ; Index = 77 Token = 7 - DW 1216 * 2 ; Index = 77 Token = 8 - DW 1216 * 2 ; Index = 77 Token = 9 - DW 1216 * 2 ; Index = 77 Token = 10 - DW 1216 * 2 ; Index = 77 Token = 11 - DW 1264 * 2 ; Index = 77 Token = 12 - DW 1296 * 2 ; Index = 77 Token = 13 - DW 1328 * 2 ; Index = 77 Token = 14 - DW 1360 * 2 ; Index = 77 Token = 15 - DW 1232 * 2 ; Index = 78 Token = 0 - DW 1232 * 2 ; Index = 78 Token = 1 - DW 1232 * 2 ; Index = 78 Token = 2 - DW 1232 * 2 ; Index = 78 Token = 3 - DW 1280 * 2 ; Index = 78 Token = 4 - DW 1312 * 2 ; Index = 78 Token = 5 - DW 1344 * 2 ; Index = 78 Token = 6 - DW 1376 * 2 ; Index = 78 Token = 7 - DW 1232 * 2 ; Index = 78 Token = 8 - DW 1232 * 2 ; Index = 78 Token = 9 - DW 1232 * 2 ; Index = 78 Token = 10 - DW 1232 * 2 ; Index = 78 Token = 11 - DW 1280 * 2 ; Index = 78 Token = 12 - DW 1312 * 2 ; Index = 78 Token = 13 - DW 1344 * 2 ; Index = 78 Token = 14 - DW 1376 * 2 ; Index = 78 Token = 15 - DW 1248 * 2 ; Index = 79 Token = 0 - DW 1248 * 2 ; Index = 79 Token = 1 - DW 1248 * 2 ; Index = 79 Token = 2 - DW 1248 * 2 ; Index = 79 Token = 3 - DW 1296 * 2 ; Index = 79 Token = 4 - DW 1328 * 2 ; Index = 79 Token = 5 - DW 1360 * 2 ; Index = 79 Token = 6 - DW 1392 * 2 ; Index = 79 Token = 7 - DW 1248 * 2 ; Index = 79 Token = 8 - DW 1248 * 2 ; Index = 79 Token = 9 - DW 1248 * 2 ; Index = 79 Token = 10 - DW 1248 * 2 ; Index = 79 Token = 11 - DW 1296 * 2 ; Index = 79 Token = 12 - DW 1328 * 2 ; Index = 79 Token = 13 - DW 1360 * 2 ; Index = 79 Token = 14 - DW 1392 * 2 ; Index = 79 Token = 15 - DW 1264 * 2 ; Index = 80 Token = 0 - DW 1264 * 2 ; Index = 80 Token = 1 - DW 1264 * 2 ; Index = 80 Token = 2 - DW 1264 * 2 ; Index = 80 Token = 3 - DW 1312 * 2 ; Index = 80 Token = 4 - DW 1344 * 2 ; Index = 80 Token = 5 - DW 1376 * 2 ; Index = 80 Token = 6 - DW 1408 * 2 ; Index = 80 Token = 7 - DW 1264 * 2 ; Index = 80 Token = 8 - DW 1264 * 2 ; Index = 80 Token = 9 - DW 1264 * 2 ; Index = 80 Token = 10 - DW 1264 * 2 ; Index = 80 Token = 11 - DW 1312 * 2 ; Index = 80 Token = 12 - DW 1344 * 2 ; Index = 80 Token = 13 - DW 1376 * 2 ; Index = 80 Token = 14 - DW 1408 * 2 ; Index = 80 Token = 15 - DW 1280 * 2 ; Index = 81 Token = 0 - DW 1280 * 2 ; Index = 81 Token = 1 - DW 1280 * 2 ; Index = 81 Token = 2 - DW 1280 * 2 ; Index = 81 Token = 3 - DW 1328 * 2 ; Index = 81 Token = 4 - DW 1360 * 2 ; Index = 81 Token = 5 - DW 1392 * 2 ; Index = 81 Token = 6 - DW 1408 * 2 ; Index = 81 Token = 7 - DW 1280 * 2 ; Index = 81 Token = 8 - DW 1280 * 2 ; Index = 81 Token = 9 - DW 1280 * 2 ; Index = 81 Token = 10 - DW 1280 * 2 ; Index = 81 Token = 11 - DW 1328 * 2 ; Index = 81 Token = 12 - DW 1360 * 2 ; Index = 81 Token = 13 - DW 1392 * 2 ; Index = 81 Token = 14 - DW 1408 * 2 ; Index = 81 Token = 15 - DW 1296 * 2 ; Index = 82 Token = 0 - DW 1296 * 2 ; Index = 82 Token = 1 - DW 1296 * 2 ; Index = 82 Token = 2 - DW 1296 * 2 ; Index = 82 Token = 3 - DW 1344 * 2 ; Index = 82 Token = 4 - DW 1376 * 2 ; Index = 82 Token = 5 - DW 1408 * 2 ; Index = 82 Token = 6 - DW 1408 * 2 ; Index = 82 Token = 7 - DW 1296 * 2 ; Index = 82 Token = 8 - DW 1296 * 2 ; Index = 82 Token = 9 - DW 1296 * 2 ; Index = 82 Token = 10 - DW 1296 * 2 ; Index = 82 Token = 11 - DW 1344 * 2 ; Index = 82 Token = 12 - DW 1376 * 2 ; Index = 82 Token = 13 - DW 1408 * 2 ; Index = 82 Token = 14 - DW 1408 * 2 ; Index = 82 Token = 15 - DW 1312 * 2 ; Index = 83 Token = 0 - DW 1312 * 2 ; Index = 83 Token = 1 - DW 1312 * 2 ; Index = 83 Token = 2 - DW 1312 * 2 ; Index = 83 Token = 3 - DW 1360 * 2 ; Index = 83 Token = 4 - DW 1392 * 2 ; Index = 83 Token = 5 - DW 1408 * 2 ; Index = 83 Token = 6 - DW 1408 * 2 ; Index = 83 Token = 7 - DW 1312 * 2 ; Index = 83 Token = 8 - DW 1312 * 2 ; Index = 83 Token = 9 - DW 1312 * 2 ; Index = 83 Token = 10 - DW 1312 * 2 ; Index = 83 Token = 11 - DW 1360 * 2 ; Index = 83 Token = 12 - DW 1392 * 2 ; Index = 83 Token = 13 - DW 1408 * 2 ; Index = 83 Token = 14 - DW 1408 * 2 ; Index = 83 Token = 15 - DW 1328 * 2 ; Index = 84 Token = 0 - DW 1328 * 2 ; Index = 84 Token = 1 - DW 1328 * 2 ; Index = 84 Token = 2 - DW 1328 * 2 ; Index = 84 Token = 3 - DW 1376 * 2 ; Index = 84 Token = 4 - DW 1408 * 2 ; Index = 84 Token = 5 - DW 1408 * 2 ; Index = 84 Token = 6 - DW 1408 * 2 ; Index = 84 Token = 7 - DW 1328 * 2 ; Index = 84 Token = 8 - DW 1328 * 2 ; Index = 84 Token = 9 - DW 1328 * 2 ; Index = 84 Token = 10 - DW 1328 * 2 ; Index = 84 Token = 11 - DW 1376 * 2 ; Index = 84 Token = 12 - DW 1408 * 2 ; Index = 84 Token = 13 - DW 1408 * 2 ; Index = 84 Token = 14 - DW 1408 * 2 ; Index = 84 Token = 15 - DW 1344 * 2 ; Index = 85 Token = 0 - DW 1344 * 2 ; Index = 85 Token = 1 - DW 1344 * 2 ; Index = 85 Token = 2 - DW 1344 * 2 ; Index = 85 Token = 3 - DW 1392 * 2 ; Index = 85 Token = 4 - DW 1408 * 2 ; Index = 85 Token = 5 - DW 1408 * 2 ; Index = 85 Token = 6 - DW 1408 * 2 ; Index = 85 Token = 7 - DW 1344 * 2 ; Index = 85 Token = 8 - DW 1344 * 2 ; Index = 85 Token = 9 - DW 1344 * 2 ; Index = 85 Token = 10 - DW 1344 * 2 ; Index = 85 Token = 11 - DW 1392 * 2 ; Index = 85 Token = 12 - DW 1408 * 2 ; Index = 85 Token = 13 - DW 1408 * 2 ; Index = 85 Token = 14 - DW 1408 * 2 ; Index = 85 Token = 15 - DW 1360 * 2 ; Index = 86 Token = 0 - DW 1360 * 2 ; Index = 86 Token = 1 - DW 1360 * 2 ; Index = 86 Token = 2 - DW 1360 * 2 ; Index = 86 Token = 3 - DW 1408 * 2 ; Index = 86 Token = 4 - DW 1408 * 2 ; Index = 86 Token = 5 - DW 1408 * 2 ; Index = 86 Token = 6 - DW 1408 * 2 ; Index = 86 Token = 7 - DW 1360 * 2 ; Index = 86 Token = 8 - DW 1360 * 2 ; Index = 86 Token = 9 - DW 1360 * 2 ; Index = 86 Token = 10 - DW 1360 * 2 ; Index = 86 Token = 11 - DW 1408 * 2 ; Index = 86 Token = 12 - DW 1408 * 2 ; Index = 86 Token = 13 - DW 1408 * 2 ; Index = 86 Token = 14 - DW 1408 * 2 ; Index = 86 Token = 15 - DW 1376 * 2 ; Index = 87 Token = 0 - DW 1376 * 2 ; Index = 87 Token = 1 - DW 1376 * 2 ; Index = 87 Token = 2 - DW 1376 * 2 ; Index = 87 Token = 3 - DW 1408 * 2 ; Index = 87 Token = 4 - DW 1408 * 2 ; Index = 87 Token = 5 - DW 1408 * 2 ; Index = 87 Token = 6 - DW 1408 * 2 ; Index = 87 Token = 7 - DW 1376 * 2 ; Index = 87 Token = 8 - DW 1376 * 2 ; Index = 87 Token = 9 - DW 1376 * 2 ; Index = 87 Token = 10 - DW 1376 * 2 ; Index = 87 Token = 11 - DW 1408 * 2 ; Index = 87 Token = 12 - DW 1408 * 2 ; Index = 87 Token = 13 - DW 1408 * 2 ; Index = 87 Token = 14 - DW 1408 * 2 ; Index = 87 Token = 15 - DW 1392 * 2 ; Index = 88 Token = 0 - DW 1392 * 2 ; Index = 88 Token = 1 - DW 1392 * 2 ; Index = 88 Token = 2 - DW 1392 * 2 ; Index = 88 Token = 3 - DW 1408 * 2 ; Index = 88 Token = 4 - DW 1408 * 2 ; Index = 88 Token = 5 - DW 1408 * 2 ; Index = 88 Token = 6 - DW 1408 * 2 ; Index = 88 Token = 7 - DW 1392 * 2 ; Index = 88 Token = 8 - DW 1392 * 2 ; Index = 88 Token = 9 - DW 1392 * 2 ; Index = 88 Token = 10 - DW 1392 * 2 ; Index = 88 Token = 11 - DW 1408 * 2 ; Index = 88 Token = 12 - DW 1408 * 2 ; Index = 88 Token = 13 - DW 1408 * 2 ; Index = 88 Token = 14 - DW 1408 * 2 ; Index = 88 Token = 15 diff --git a/code/TIBERIANDAWN/WIN32LIB/IRANDOM.CPP b/code/TIBERIANDAWN/WIN32LIB/IRANDOM.CPP deleted file mode 100644 index 8802b28..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/IRANDOM.CPP +++ /dev/null @@ -1,176 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : LIBRARY * - * * - * File Name : IRANDOM.C * - * * - * Programmer : Barry W. Green * - * * - * Last Update : 10 Feb, 1995 [BWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include -#include "misc.h" - - - -extern "C" unsigned long RandNumb = 0x12349876; - - - -/* IRANDOM ---------------------------------------------------------- - - IRandom returns a random value between min and max inclusive. - - INPUTS: int min and int max - - RETURNS: int random number -*/ - -int IRandom(int minval, int maxval) -{ - int num,mask; - - // Keep minval and maxval straight. - if (minval > maxval) { - minval ^= maxval; - maxval ^= minval; - minval ^= maxval; - } - - mask = Get_Random_Mask(maxval - minval); - - while( (num = (rand() & mask) + minval) > maxval ) ; - return(num); -} - - - -unsigned char Random(void) -{ - __asm { - lea esi, [RandNumb] //; get offset in segment of RandNumb - xor eax,eax - mov al,[esi] - shr al,1 //; shift right 1 bit (bit0 in carry) - shr al,1 - rcl [BYTE PTR esi+2],1 //; rcl byte 3 of RandNumb - rcl [BYTE PTR esi+1],1 //; rcl byte 2 of RandNumb - cmc //; complement carry - sbb al,[esi] //; sbb byte 1 of RandNumb - shr al,1 //; sets carry - rcr [BYTE PTR esi],1 //; rcr byte 1 of RandNumb - mov al,[esi] //; reload byte 1 of RandNumb - xor al,[esi+1] //; xor with byte 2 of RandNumb - } -} - - - -int Get_Random_Mask(int maxval) -{ - __asm { - - bsr ecx,[maxval] // ; put bit position of highest bit in ecx - mov eax, 1 // ; set one bit on in eax - jz invalid // ; if BSR shows maxval==0, return eax=1 - inc ecx // ; get one bit higher than count showed - shl eax,cl // ; move our EAX bit into position - dec eax // ; dec it to create the mask. -invalid: - } -} - - - - -#if (0) - -RandNumb DD 12349876H - -; -; UBYTE Random(VOID); -; int Get_Random_Mask(int maxval); -; -; ---------------------------------------------------------------- - -;----------------------------------------------------------------- -; RANDOM -; -; UBYTE Random(VOID); -; -;* - - PROC Random C near - USES esi - - lea esi, [RandNumb] ; get offset in segment of RandNumb - xor eax,eax - mov al,[esi] - shr al,1 ; shift right 1 bit (bit0 in carry) - shr al,1 - rcl [BYTE PTR esi+2],1 ; rcl byte 3 of RandNumb - rcl [BYTE PTR esi+1],1 ; rcl byte 2 of RandNumb - cmc ; complement carry - sbb al,[esi] ; sbb byte 1 of RandNumb - shr al,1 ; sets carry - rcr [BYTE PTR esi],1 ; rcr byte 1 of RandNumb - mov al,[esi] ; reload byte 1 of RandNumb - xor al,[esi+1] ; xor with byte 2 of RandNumb - - ret - - ENDP Random - - -;----------------------------------------------------------------- -; GET_RANDOM_MASK - returns an AND value that is large enough that it -; encloses the 'maxval' parameter. -; -; int Get_Random_Mask(int maxval); -; -;* - - PROC Get_Random_Mask C near - USES ecx - ARG maxval:DWORD - -; This function takes as a parameter a maximum value, for example, 61. It -; then tries to create an AND mask that is big enough to enclose that number. -; For our example case, that AND mask would be 0x3F. It does this by scanning -; for the highest bit in the number, then making an all-1's mask from that -; bit position down to bit 0. - bsr ecx,[maxval] ; put bit position of highest bit in ecx - mov eax,1 ; set one bit on in eax - jz ??invalid ; if BSR shows maxval==0, return eax=1 - inc ecx ; get one bit higher than count showed - shl eax,cl ; move our EAX bit into position - dec eax ; dec it to create the mask. -??invalid: - ret - ENDP Get_Random_Mask -;---------------------------------------------------------------------------- - - END -#endif \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.CPP b/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.CPP deleted file mode 100644 index cec88cc..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.CPP +++ /dev/null @@ -1,533 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - * * - * Project Name : Westwood Keyboard Library * - * * - * File Name : KEYBOARD.CPP * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 10/16/95 * - * * - * Last Update : October 26, 1995 [] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * WWKeyboardClass::Put -- Logic to insert a key into the keybuffer] * - * WWKeyboardClass::Get -- Logic to get a metakey from the buffer * - * WWKeyboardClass::Check -- Checks to see if a key is in the buffer * - * WWKeyboardClass::Put_Key_Message -- Translates and inserts wParam into Keyboard Buffer * - * WWKeyboardClass::Buff_Get -- Lowlevel function to get a key from key buffer * - * WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels * - * WWKeyboardClass::Get_Mouse_Y -- returns the mouses current y position in pixels * - * WWKeyboardClass::Get_Mouse_XY -- Returns the mouses x,y position via reference vars * - * Check_Key -- compatability routine for old 32 bit library * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "keyboard.h" -#include "timer.h" -#include "mono.h" - -void Message_Loop(void); - -WWKeyboardClass *_Kbd; - -/*********************************************************************************************** - * WWKeyboardClass::WWKeyBoardClass -- Construction for Westwood Keyboard Class * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 10/16/1995 PWG : Created. * - *=============================================================================================*/ -WWKeyboardClass::WWKeyboardClass(void) -{ - _Kbd = this; - // - // Initialize the keyboard remap table for our system (note it would be bad if someone - // switched keyboard modes after this happened. - // - memset(VKRemap, 0, 256); - memset(AsciiRemap, 0, 2048); - short lp; - for (lp = 31; lp < 255; lp ++) { - if (isprint(lp)) { - int vk_key = VkKeyScan((unsigned char)lp); - if (vk_key > 0 && vk_key < 2048) { - AsciiRemap[vk_key] = (unsigned char)lp; - VKRemap[lp] = (unsigned char)(vk_key & 0xFF); - } - } - } - - // - // Build a remap table of the different keys which are affected by the caps lock and - // the num lock. - // - memset(ToggleKeys, 0, 256); - for (lp = 0; lp < 255; lp++ ) { - if (isalpha(lp) && isupper(lp)) { - ToggleKeys[lp] = 1; - } - if (lp >= VK_NUMPAD0 && lp <= VK_DIVIDE) { - ToggleKeys[lp] = 2; - } - } - - // - // Our buffer should start devoid of keys. - // - memset(Buffer, 0, 256); - Head = 0; - Tail = 0; - - // - // There should be no starting queued mouse events for us to have to worry - // about. - // - MouseQX = 0; - MouseQY = 0; - MState = 0; - Conditional = 0; - CurrentCursor = NULL; -} - -/*********************************************************************************************** - * WWKeyboardClass::Buff_Get -- Lowlevel function to get a key from key buffer * - * * - * INPUT: none * - * * - * OUTPUT: int - the key value that was pulled from buffer (includes bits) * * - * * - * WARNINGS: If the key was a mouse event MouseQX and MouseQY will be updated * - * * - * HISTORY: * - * 10/17/1995 PWG : Created. * - *=============================================================================================*/ -int WWKeyboardClass::Buff_Get(void) -{ - while (!Check()) {} // wait for key in buffer - int temp = Buffer[Head]; // get key out of the buffer - int newhead = Head; // save off head for manipulation - if (Is_Mouse_Key(temp)) { // if key is a mouse then - MouseQX = Buffer[(Head + 1) & 255]; // get the x and y pos - MouseQY = Buffer[(Head + 2) & 255]; // from the buffer - newhead += 3; // adjust head forward - } else { - newhead += 1; // adjust head forward - } - newhead &= 255; - Head = newhead; - return(temp); -} - -BOOL WWKeyboardClass::Is_Mouse_Key(int key) -{ - key &= 0xFF; - return (key == VK_LBUTTON || key == VK_MBUTTON || key == VK_RBUTTON); -} - - -/*********************************************************************************************** - * WWKeyboardClass::Check -- Checks to see if a key is in the buffer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/16/1995 PWG : Created. * - *=============================================================================================*/ -BOOL WWKeyboardClass::Check(void) -{ - Message_Loop(); - unsigned short temp; // store temp holding spot for key - if (Head == Tail) return(FALSE); // if no keys in buff then get out - temp = Buffer[Head]; // get key out of the buffer - return(temp); // send it back to main program -} - -/*********************************************************************************************** - * WWKeyboardClass::Get -- Logic to get a metakey from the buffer * - * * - * INPUT: none * - * * - * OUTPUT: int - the meta key taken from the buffer. * - * * - * WARNINGS: This routine will not return until a keypress is received * - * * - * HISTORY: * - * 10/16/1995 PWG : Created. * - *=============================================================================================*/ -int WWKeyboardClass::Get(void) -{ - int temp,bits; // store temp holding spot for key - - while (!Check()) {} // wait for key in buffer - temp = Buff_Get(); // get key from the buffer - - bits = temp & 0xFF00; // save of keyboard bits - - if (!(bits & WWKEY_VK_BIT)) { // if its not a virtual key - temp = AsciiRemap[temp&0x1FF] | bits; // convert to ascii equivalent - } - return(temp); // return the key that we pulled out -} - -/*********************************************************************************************** - * WWKeyboardClass::Put -- Logic to insert a key into the keybuffer] * - * * - * INPUT: int - the key to insert into the buffer * - * * - * OUTPUT: bool - true if key is sucessfuly inserted. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 10/16/1995 PWG : Created. * - *=============================================================================================*/ -BOOL WWKeyboardClass::Put(int key) -{ - int temp = (Tail + 1) & 255; - if (temp != Head) - { - Buffer[Tail] = (short)key; - - // - // Critical Line - // - Tail = temp; - return(TRUE); - } - return(FALSE); -} -/*********************************************************************************************** - * WWKeyboardClass::Put_Key_Message -- Translates and inserts wParam into Keyboard Buffer * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/16/1995 PWG : Created. * - *=============================================================================================*/ -BOOL WWKeyboardClass::Put_Key_Message(UINT vk_key, BOOL release, BOOL dbl) -{ - int bits = 0; - // - // Get the status of all of the different keyboard modifiers. Note, only pay attention - // to numlock and caps lock if we are dealing with a key that is affected by them. Note - // that we do not want to set the shift, ctrl and alt bits for Mouse keypresses as this - // would be incompatible with the dos version. - // - if (vk_key != VK_LBUTTON && vk_key != VK_MBUTTON && vk_key != VK_RBUTTON) { - int shift = (GetKeyState(VK_SHIFT) & 0xFF00) != 0; - int ctrl = (GetKeyState(VK_CONTROL) & 0xFF00) != 0; - int alt = (GetKeyState(VK_MENU) & 0xFF00) != 0; - int caps = ((GetKeyState(VK_CAPITAL) & 0x00FF) != 0) && (ToggleKeys[vk_key] == 1); - int nums = ((GetKeyState(VK_NUMLOCK) & 0x00FF) != 0) && (ToggleKeys[vk_key] == 2); - - // - // Set the proper bits for whatever the key we got is. - // - if (shift || caps || nums) { - bits |= WWKEY_SHIFT_BIT; - } - if (ctrl) { - bits |= WWKEY_CTRL_BIT; - } - if (alt) { - bits |= WWKEY_ALT_BIT; - } - } - if (!AsciiRemap[vk_key|bits]) { - bits |= WWKEY_VK_BIT; - } - if (release) { - bits |= WWKEY_RLS_BIT; - } - if (dbl) { - bits |= WWKEY_DBL_BIT; - } - // - // Finally use the put command to enter the key into the keyboard - // system. - // - return(Put(vk_key|bits)); -} - -void WWKeyboardClass::Clear(void) -{ - Head = Tail; -} - -int WWKeyboardClass::To_ASCII(int key) -{ - if ( key && WWKEY_RLS_BIT) - return(KN_NONE); - return(key); -} - -int WWKeyboardClass::Down(int key) -{ - return(GetAsyncKeyState(key&0xFF)); -} - -VOID WWKeyboardClass::Split(int &key, int &shift, int &ctrl, int &alt, int &rls, int &dbl) -{ - shift = (key & WWKEY_SHIFT_BIT) != 0; - ctrl = (key & WWKEY_CTRL_BIT) != 0; - alt = (key & WWKEY_ALT_BIT) != 0; - rls = (key & WWKEY_RLS_BIT) != 0; - dbl = (key & WWKEY_DBL_BIT) != 0; - key = (key & 0xFF); - -} - - -extern "C" { - void __cdecl Stop_Execution (void); -} - -//#pragma off(unreferenced) -void WWKeyboardClass::Message_Handler(HWND , UINT message, UINT wParam, LONG lParam) -{ - return; -#if (0) // ST - 12/20/2018 11:27AM - switch (message) { - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - if ( wParam==VK_SCROLL ){ - Stop_Execution(); - } else { - Put_Key_Message(wParam); - } - break; - - case WM_SYSKEYUP: - case WM_KEYUP: - Put_Key_Message(wParam, TRUE); - break; - - case WM_LBUTTONDOWN: - Put_Key_Message(VK_LBUTTON); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_LBUTTONUP: - Put_Key_Message(VK_LBUTTON, TRUE); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_LBUTTONDBLCLK: - Put_Key_Message(VK_LBUTTON, TRUE, TRUE); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_MBUTTONDOWN: - Put_Key_Message(VK_MBUTTON); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_MBUTTONUP: - Put_Key_Message(VK_MBUTTON, TRUE); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_MBUTTONDBLCLK: - Put_Key_Message(VK_MBUTTON, TRUE, TRUE); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_RBUTTONDOWN: - Put_Key_Message(VK_RBUTTON); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_RBUTTONUP: - Put_Key_Message(VK_RBUTTON, TRUE); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - - case WM_RBUTTONDBLCLK: - Put_Key_Message(VK_RBUTTON, TRUE, TRUE); - Put(LOWORD(lParam)); - Put(HIWORD(lParam)); - break; - case WM_MOUSEMOVE: - if (CurrentCursor) - SetCursor(CurrentCursor); - break; - } -#endif -} -//#pragma on(unreferenced) - - - - -void Message_Loop(void) -{ - - MSG msg; - - while (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )) { - if( !GetMessage( &msg, NULL, 0, 0 ) ){ - return; - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - - - -} - - - -/*************************************************************************** - * CHECK_KEY -- compatability routine for old 32 bit library * - * * - * This routine checks to see if there is a key in the keyboard buffer * - * and returns it to the sender if there is. It does not remove the key * - * from the buffer. * - * * - * INPUT: none * - * * - * OUTPUT: The key that was pressed. * - * * - * WARNINGS: You must declare a WWKeyboardClass object before calling * - * this routine. * - * * - * HISTORY: * - * 10/26/1995 : Created. * - *=========================================================================*/ -int Check_Key(void) -{ - if (!_Kbd) return(KA_NONE); - return(_Kbd->Check() & ~WWKEY_SHIFT_BIT); -} - -void Clear_KeyBuffer(void) -{ - if (!_Kbd) return; - _Kbd->Clear(); -} - -int Check_Key_Num(void) -{ - if (!_Kbd) return(KN_NONE); - int key = _Kbd->Check(); - int flags = key & 0xFF00; - key = key & 0x00FF; - - if (isupper(key)) { - key = tolower(key); - if ( !(flags & WWKEY_VK_BIT) ) { - flags |= WWKEY_SHIFT_BIT; - } - } - - return(key | flags); -} - -int Get_Key_Num(void) -{ - if (!_Kbd) return(KN_NONE); - int key = _Kbd->Get(); - int flags = key & 0xFF00; - key = key & 0x00FF; - - if (isupper(key)) { - key = tolower(key); - if ( !(flags & WWKEY_VK_BIT) ) { - flags |= WWKEY_SHIFT_BIT; - } - } - return(key | flags); -} - -int KN_To_KA(int key) -{ - if ( key & WWKEY_RLS_BIT) { - return(KA_NONE); - } - if (!(key & WWKEY_VK_BIT)) { - int flags = key & 0xFF00; - key = key & 0x00FF; - if (flags & WWKEY_SHIFT_BIT) { - key = toupper(key); - flags &= ~WWKEY_SHIFT_BIT; - } - }else{ - /* - ** If its a numeric keypad key then fix it up - */ - if ((key & 0xff) >=VK_NUMPAD0 && (key & 0xff) <=VK_NUMPAD9){ - key = (key & 0xff) - VK_NUMPAD0 + KA_0; - } - } - return(key); -} - -int KN_To_VK(int key) -{ - if (!_Kbd) return(KN_NONE); - if ( key & WWKEY_RLS_BIT) { - return(VK_NONE); - } - - int flags = key & 0xFF00; - if (!(flags & WWKEY_VK_BIT)) { - key = _Kbd->VKRemap[key & 0x00FF] | flags; - } - key &= ~WWKEY_VK_BIT; - return(key); -} - -int Key_Down(int key) -{ - if (!_Kbd) return(FALSE); - return(_Kbd->Down(key)); -} - -int Get_Key(void) -{ - int retval; - - if (!_Kbd) return(KN_NONE); - retval = _Kbd->Get() & ~WWKEY_SHIFT_BIT; - if (retval & WWKEY_RLS_BIT) { - retval = KN_NONE; - } - return(retval); -} diff --git a/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.H b/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.H deleted file mode 100644 index 8233bc4..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.H +++ /dev/null @@ -1,675 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - * * - * Project Name : Westwood Keyboard Library * - * * - * File Name : KEYBOARD.H * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 10/16/95 * - * * - * Last Update : October 16, 1995 [PWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef KEYBOARD_H -#define KEYBOARD_H - -#include - -typedef enum { - WWKEY_SHIFT_BIT = 0x100, - WWKEY_CTRL_BIT = 0x200, - WWKEY_ALT_BIT = 0x400, - WWKEY_RLS_BIT = 0x800, - WWKEY_VK_BIT = 0x1000, - WWKEY_DBL_BIT = 0x2000, - WWKEY_BTN_BIT = 0x8000, -} WWKey_Type; - -class WWKeyboardClass -{ - public: - /*===================================================================*/ - /* Define the base constructor and destructors for the class */ - /*===================================================================*/ - WWKeyboardClass(); - - /*===================================================================*/ - /* Define the functions which work with the Keyboard Class */ - /*===================================================================*/ - BOOL Check(void); // checks keybuff for meta key - int Get(void); // gets a meta key from the keybuffer - BOOL Put(int key); // dumps a key into the keybuffer - BOOL Put_Key_Message( UINT vk_key, BOOL release = FALSE, // handles keyboard related message - BOOL dbl = FALSE); // and mouse clicks and dbl clicks - int Check_Num(void); // checks keybuff for a keynum key - int Get_VK(void); // gets keynum key from key buff - int Check_ACII(void); // checks keybuff for an ascii key - int Get_ASCII(void); // gets an ascii key from keybuff - int Check_Bits(void); // checks keybuff for key w/ bits - int Get_Bits(void); // get key from keybuff w/ bits - int To_ASCII(int num); // converts keynum to ascii value - int Option_On(int option); // turns specified option on - int Option_Off(int option); // turns specified option off - void Clear(void); // clears all keys from keybuffer - int Down(int key); // tests to see if a key is down - void AI(void); // messaging logic for key manager - - /*===================================================================*/ - /* Define the main hook for the message processing loop. */ - /*===================================================================*/ - void Message_Handler(HWND hwnd, UINT message, UINT wParam, LONG lParam); - - /*===================================================================*/ - /* Define public routines which can be used on keys in general. */ - /*===================================================================*/ - VOID Split(int &key, int &shift, int &ctrl, int &alt, int &rls, int &dbl); - BOOL Is_Mouse_Key(int key); - - - /*===================================================================*/ - /* Define the public access variables which are used with the */ - /* Keyboard Class. */ - /*===================================================================*/ - int MouseQX; - int MouseQY; - - unsigned char VKRemap[256]; // gives vk for any ascii char - private: - /*===================================================================*/ - /* Define the private access functions which are used by keyboard */ - /*===================================================================*/ - int Buff_Get(void); - - - /*===================================================================*/ - /* Define the private access variables which are used with the */ - /* Keyboard Class. */ - /*===================================================================*/ - unsigned char AsciiRemap[2048]; // remap for shft/ctrl/alt key combos - unsigned short Buffer[256]; // buffer which holds actual keypresses - unsigned char ToggleKeys[256]; // determines toggles which affect key - long Head; // the head position in keyboard buffer - long Tail; // the tail position in keyboard buffer - int MState; - int Conditional; - HANDLE CurrentCursor; -}; - - -#define VK_NONE 0x00 -#define VK_LBUTTON 0x01 -#define VK_RBUTTON 0x02 -#define VK_CANCEL 0x03 -#define VK_MBUTTON 0x04 -#define VK_NONE_05 0x05 -#define VK_NONE_06 0x06 -#define VK_NONE_07 0x07 -#define VK_BACK 0x08 -#define VK_TAB 0x09 -#define VK_NONE_0A 0x0A -#define VK_NONE_0B 0x0B -#define VK_CLEAR 0x0C -#define VK_RETURN 0x0D -#define VK_NONE_0E 0x0E -#define VK_NONE_0F 0x0F -#define VK_SHIFT 0x10 -#define VK_CONTROL 0x11 -#define VK_MENU 0x12 -#define VK_PAUSE 0x13 -#define VK_CAPITAL 0x14 -#define VK_NONE_15 0x15 -#define VK_NONE_16 0x16 -#define VK_NONE_17 0x17 -#define VK_NONE_18 0x18 -#define VK_NONE_19 0x19 -#define VK_NONE_1A 0x1A -#define VK_ESCAPE 0x1B -#define VK_NONE_1C 0x1C -#define VK_NONE_1D 0x1D -#define VK_NONE_1E 0x1E -#define VK_NONE_1F 0x1F -#define VK_SPACE 0x20 -#define VK_PRIOR 0x21 -#define VK_NEXT 0x22 -#define VK_END 0x23 -#define VK_HOME 0x24 -#define VK_LEFT 0x25 -#define VK_UP 0x26 -#define VK_RIGHT 0x27 -#define VK_DOWN 0x28 -#define VK_SELECT 0x29 -#define VK_PRINT 0x2A -#define VK_EXECUTE 0x2B -#define VK_SNAPSHOT 0x2C -#define VK_INSERT 0x2D -#define VK_DELETE 0x2E -#define VK_HELP 0x2F -#define VK_0 0x30 -#define VK_1 0x31 -#define VK_2 0x32 -#define VK_3 0x33 -#define VK_4 0x34 -#define VK_5 0x35 -#define VK_6 0x36 -#define VK_7 0x37 -#define VK_8 0x38 -#define VK_9 0x39 -#define VK_NONE_3B 0x3B -#define VK_NONE_3C 0x3C -#define VK_NONE_3D 0x3D -#define VK_NONE_3E 0x3E -#define VK_NONE_3F 0x3F -#define VK_NONE_40 0x40 -#define VK_A 0x41 -#define VK_B 0x42 -#define VK_C 0x43 -#define VK_D 0x44 -#define VK_E 0x45 -#define VK_F 0x46 -#define VK_G 0x47 -#define VK_H 0x48 -#define VK_I 0x49 -#define VK_J 0x4A -#define VK_K 0x4B -#define VK_L 0x4C -#define VK_M 0x4D -#define VK_N 0x4E -#define VK_O 0x4F -#define VK_P 0x50 -#define VK_Q 0x51 -#define VK_R 0x52 -#define VK_S 0x53 -#define VK_T 0x54 -#define VK_U 0x55 -#define VK_V 0x56 -#define VK_W 0x57 -#define VK_X 0x58 -#define VK_Y 0x59 -#define VK_Z 0x5A -#define VK_NONE_5B 0x5B -#define VK_NONE_5C 0x5C -#define VK_NONE_5D 0x5D -#define VK_NONE_5E 0x5E -#define VK_NONE_5F 0x5F -#define VK_NUMPAD0 0x60 -#define VK_NUMPAD1 0x61 -#define VK_NUMPAD2 0x62 -#define VK_NUMPAD3 0x63 -#define VK_NUMPAD4 0x64 -#define VK_NUMPAD5 0x65 -#define VK_NUMPAD6 0x66 -#define VK_NUMPAD7 0x67 -#define VK_NUMPAD8 0x68 -#define VK_NUMPAD9 0x69 -#define VK_MULTIPLY 0x6A -#define VK_ADD 0x6B -#define VK_SEPARATOR 0x6C -#define VK_SUBTRACT 0x6D -#define VK_DECIMAL 0x6E -#define VK_DIVIDE 0x6F -#define VK_F1 0x70 -#define VK_F2 0x71 -#define VK_F3 0x72 -#define VK_F4 0x73 -#define VK_F5 0x74 -#define VK_F6 0x75 -#define VK_F7 0x76 -#define VK_F8 0x77 -#define VK_F9 0x78 -#define VK_F10 0x79 -#define VK_F11 0x7A -#define VK_F12 0x7B -#define VK_F13 0x7C -#define VK_F14 0x7D -#define VK_F15 0x7E -#define VK_F16 0x7F -#define VK_F17 0x80 -#define VK_F18 0x81 -#define VK_F19 0x82 -#define VK_F20 0x83 -#define VK_F21 0x84 -#define VK_F22 0x85 -#define VK_F23 0x86 -#define VK_F24 0x87 -#define VK_NONE_88 0x88 -#define VK_NONE_89 0x89 -#define VK_NONE_8A 0x8A -#define VK_NONE_8B 0x8B -#define VK_NONE_8C 0x8C -#define VK_NONE_8D 0x8D -#define VK_NONE_8E 0x8E -#define VK_NONE_8F 0x8F -#define VK_NUMLOCK 0x90 -#define VK_SCROLL 0x91 -#define VK_NONE_92 0x92 -#define VK_NONE_93 0x93 -#define VK_NONE_94 0x94 -#define VK_NONE_95 0x95 -#define VK_NONE_96 0x96 -#define VK_NONE_97 0x97 -#define VK_NONE_98 0x98 -#define VK_NONE_99 0x99 -#define VK_NONE_9A 0x9A -#define VK_NONE_9B 0x9B -#define VK_NONE_9C 0x9C -#define VK_NONE_9D 0x9D -#define VK_NONE_9E 0x9E -#define VK_NONE_9F 0x9F -#define VK_NONE_A0 0xA0 -#define VK_NONE_A1 0xA1 -#define VK_NONE_A2 0xA2 -#define VK_NONE_A3 0xA3 -#define VK_NONE_A4 0xA4 -#define VK_NONE_A5 0xA5 -#define VK_NONE_A6 0xA6 -#define VK_NONE_A7 0xA7 -#define VK_NONE_A8 0xA8 -#define VK_NONE_A9 0xA9 -#define VK_NONE_AA 0xAA -#define VK_NONE_AB 0xAB -#define VK_NONE_AC 0xAC -#define VK_NONE_AD 0xAD -#define VK_NONE_AE 0xAE -#define VK_NONE_AF 0xAF -#define VK_NONE_B0 0xB0 -#define VK_NONE_B1 0xB1 -#define VK_NONE_B2 0xB2 -#define VK_NONE_B3 0xB3 -#define VK_NONE_B4 0xB4 -#define VK_NONE_B5 0xB5 -#define VK_NONE_B6 0xB6 -#define VK_NONE_B7 0xB7 -#define VK_NONE_B8 0xB8 -#define VK_NONE_B9 0xB9 -#define VK_NONE_BA 0xBA -#define VK_NONE_BB 0xBB -#define VK_NONE_BC 0xBC -#define VK_NONE_BD 0xBD -#define VK_NONE_BE 0xBE -#define VK_NONE_BF 0xBF -#define VK_NONE_C0 0xC0 -#define VK_NONE_C1 0xC1 -#define VK_NONE_C2 0xC2 -#define VK_NONE_C3 0xC3 -#define VK_NONE_C4 0xC4 -#define VK_NONE_C5 0xC5 -#define VK_NONE_C6 0xC6 -#define VK_NONE_C7 0xC7 -#define VK_NONE_C8 0xC8 -#define VK_NONE_C9 0xC9 -#define VK_NONE_CA 0xCA -#define VK_NONE_CB 0xCB -#define VK_NONE_CC 0xCC -#define VK_NONE_CD 0xCD -#define VK_NONE_CE 0xCE -#define VK_NONE_CF 0xCF -#define VK_NONE_D0 0xD0 -#define VK_NONE_D1 0xD1 -#define VK_NONE_D2 0xD2 -#define VK_NONE_D3 0xD3 -#define VK_NONE_D4 0xD4 -#define VK_NONE_D5 0xD5 -#define VK_NONE_D6 0xD6 -#define VK_NONE_D7 0xD7 -#define VK_NONE_D8 0xD8 -#define VK_NONE_D9 0xD9 -#define VK_NONE_DA 0xDA -#define VK_NONE_DB 0xDB -#define VK_NONE_DC 0xDC -#define VK_NONE_DD 0xDD -#define VK_NONE_DE 0xDE -#define VK_NONE_DF 0xDF -#define VK_NONE_E0 0xE0 -#define VK_NONE_E1 0xE1 -#define VK_NONE_E2 0xE2 -#define VK_NONE_E3 0xE3 -#define VK_NONE_E4 0xE4 -#define VK_NONE_E5 0xE5 -#define VK_NONE_E6 0xE6 -#define VK_NONE_E7 0xE7 -#define VK_NONE_E8 0xE8 -#define VK_NONE_E9 0xE9 -#define VK_NONE_EA 0xEA -#define VK_NONE_EB 0xEB -#define VK_NONE_EC 0xEC -#define VK_NONE_ED 0xED -#define VK_NONE_EE 0xEE -#define VK_NONE_EF 0xEF -#define VK_NONE_F0 0xF0 -#define VK_NONE_F1 0xF1 -#define VK_NONE_F2 0xF2 -#define VK_NONE_F3 0xF3 -#define VK_NONE_F4 0xF4 -#define VK_NONE_F5 0xF5 -#define VK_NONE_F6 0xF6 -#define VK_NONE_F7 0xF7 -#define VK_NONE_F8 0xF8 -#define VK_NONE_F9 0xF9 -#define VK_NONE_FA 0xFA -#define VK_NONE_FB 0xFB -#define VK_NONE_FC 0xFC -#define VK_NONE_FD 0xFD -#define VK_NONE_FE 0xFE -#define VK_NONE_FF 0xFF - -#define VK_UPLEFT VK_HOME -#define VK_UPRIGHT VK_PRIOR -#define VK_DOWNLEFT VK_END -#define VK_DOWNRIGHT VK_NEXT -#define VK_ALT VK_MENU - -enum { - // - // Define all the KA types as variations of the VK types. This is - // so the KA functions will work properly under windows 95. - // - KA_NONE = 0, - KA_MORE = 1, - KA_SETBKGDCOL = 2, - KA_SETFORECOL = 6, - KA_FORMFEED = 12, - KA_SPCTAB = 20, - KA_SETX = 25, - KA_SETY = 26, - - KA_SPACE = 32, /* */ - KA_EXCLAMATION, /* ! */ - KA_DQUOTE, /* " */ - KA_POUND, /* # */ - KA_DOLLAR, /* $ */ - KA_PERCENT, /* % */ - KA_AMPER, /* & */ - KA_SQUOTE, /* ' */ - KA_LPAREN, /* ( */ - KA_RPAREN, /* ) */ - KA_ASTERISK, /* * */ - KA_PLUS, /* + */ - KA_COMMA, /* , */ - KA_MINUS, /* - */ - KA_PERIOD, /* . */ - KA_SLASH, /* / */ - - KA_0, KA_1, KA_2, KA_3, KA_4, KA_5, KA_6, KA_7, KA_8, KA_9, - KA_COLON, /* : */ - KA_SEMICOLON, /* ; */ - KA_LESS_THAN, /* < */ - KA_EQUAL, /* = */ - KA_GREATER_THAN, /* > */ - KA_QUESTION, /* ? */ - - KA_AT, /* @ */ - KA_A, /* A */ - KA_B, /* B */ - KA_C, /* C */ - KA_D, /* D */ - KA_E, /* E */ - KA_F, /* F */ - KA_G, /* G */ - KA_H, /* H */ - KA_I, /* I */ - KA_J, /* J */ - KA_K, /* K */ - KA_L, /* L */ - KA_M, /* M */ - KA_N, /* N */ - KA_O, /* O */ - - KA_P, /* P */ - KA_Q, /* Q */ - KA_R, /* R */ - KA_S, /* S */ - KA_T, /* T */ - KA_U, /* U */ - KA_V, /* V */ - KA_W, /* W */ - KA_X, /* X */ - KA_Y, /* Y */ - KA_Z, /* Z */ - KA_LBRACKET, /* [ */ - KA_BACKSLASH, /* \ */ - KA_RBRACKET, /* ] */ - KA_CARROT, /* ^ */ - KA_UNDERLINE, /* _ */ - - KA_GRAVE, /* ` */ - KA_a, /* a */ - KA_b, /* b */ - KA_c, /* c */ - KA_d, /* d */ - KA_e, /* e */ - KA_f, /* f */ - KA_g, /* g */ - KA_h, /* h */ - KA_i, /* i */ - KA_j, /* j */ - KA_k, /* k */ - KA_l, /* l */ - KA_m, /* m */ - KA_n, /* n */ - KA_o, /* o */ - - KA_p, /* p */ - KA_q, /* q */ - KA_r, /* r */ - KA_s, /* s */ - KA_t, /* t */ - KA_u, /* u */ - KA_v, /* v */ - KA_w, /* w */ - KA_x, /* x */ - KA_y, /* y */ - KA_z, /* z */ - KA_LBRACE, /* { */ - KA_BAR, /* | */ - KA_RBRACE, /* ] */ - KA_TILDA, /* ~ */ - - KA_ESC = VK_ESCAPE | WWKEY_VK_BIT, - KA_EXTEND = VK_ESCAPE | WWKEY_VK_BIT, - KA_RETURN = VK_RETURN | WWKEY_VK_BIT, - KA_BACKSPACE = VK_BACK | WWKEY_VK_BIT, - KA_TAB = VK_TAB | WWKEY_VK_BIT, - KA_DELETE = VK_DELETE | WWKEY_VK_BIT, /* */ - KA_INSERT = VK_INSERT | WWKEY_VK_BIT, /* */ - KA_PGDN = VK_NEXT | WWKEY_VK_BIT, /* */ - KA_DOWNRIGHT = VK_NEXT | WWKEY_VK_BIT, - KA_DOWN = VK_DOWN | WWKEY_VK_BIT, /* */ - KA_END = VK_END | WWKEY_VK_BIT, /* */ - KA_DOWNLEFT = VK_END | WWKEY_VK_BIT, - KA_RIGHT = VK_RIGHT | WWKEY_VK_BIT, /* */ - KA_KEYPAD5 = VK_SELECT | WWKEY_VK_BIT, /* NUMERIC KEY PAD <5> */ - KA_LEFT = VK_LEFT | WWKEY_VK_BIT, /* */ - KA_PGUP = VK_PRIOR | WWKEY_VK_BIT, /* */ - KA_UPRIGHT = VK_PRIOR | WWKEY_VK_BIT, - KA_UP = VK_UP | WWKEY_VK_BIT, /* */ - KA_HOME = VK_HOME | WWKEY_VK_BIT, /* */ - KA_UPLEFT = VK_HOME | WWKEY_VK_BIT, - KA_F12 = VK_F12 | WWKEY_VK_BIT, - KA_F11 = VK_F11 | WWKEY_VK_BIT, - KA_F10 = VK_F10 | WWKEY_VK_BIT, - KA_F9 = VK_F9 | WWKEY_VK_BIT, - KA_F8 = VK_F8 | WWKEY_VK_BIT, - KA_F7 = VK_F7 | WWKEY_VK_BIT, - KA_F6 = VK_F6 | WWKEY_VK_BIT, - KA_F5 = VK_F5 | WWKEY_VK_BIT, - KA_F4 = VK_F4 | WWKEY_VK_BIT, - KA_F3 = VK_F3 | WWKEY_VK_BIT, - KA_F2 = VK_F2 | WWKEY_VK_BIT, - KA_F1 = VK_F1 | WWKEY_VK_BIT, - KA_LMOUSE = VK_LBUTTON | WWKEY_VK_BIT, - KA_RMOUSE = VK_RBUTTON | WWKEY_VK_BIT, - - KA_SHIFT_BIT = WWKEY_SHIFT_BIT, - KA_CTRL_BIT = WWKEY_CTRL_BIT, - KA_ALT_BIT = WWKEY_ALT_BIT, - KA_RLSE_BIT = WWKEY_RLS_BIT, - - // - // Define all the KN types as variations of the KA types. This is - // so the KN functions will work properly under windows 95. - // - KN_NONE = 0, - KN_GRAVE = KA_GRAVE, - KN_1 = KA_1, - KN_2 = KA_2, - KN_3 = KA_3, - KN_4 = KA_4, - KN_5 = KA_5, - KN_6 = KA_6, - KN_7 = KA_7, - KN_8 = KA_8, - KN_9 = KA_9, - KN_0 = KA_0, - KN_MINUS = KA_MINUS, /* - */ - KN_EQUAL = KA_EQUAL, /* = */ - - KN_BACKSPACE = KA_BACKSPACE, - - KN_TAB = KA_TAB, /* */ - KN_Q = KA_q, - KN_W = KA_w, - KN_E = KA_e, - KN_R = KA_r, - KN_T = KA_t, - KN_Y = KA_y, - KN_U = KA_u, - KN_I = KA_i, - KN_O = KA_o, - KN_P = KA_p, - KN_LBRACKET = KA_LBRACKET, /* [ */ - KN_RBRACKET = KA_RBRACKET, /* ] */ - KN_BACKSLASH = KA_BACKSLASH, /* \ */ - - - KN_A = KA_a, - KN_S = KA_s, - KN_D = KA_d, - KN_F = KA_f, - KN_G = KA_g, - KN_H = KA_h, - KN_J = KA_j, - KN_K = KA_k, - KN_L = KA_l, - KN_SEMICOLON = KA_SEMICOLON, /* ; */ - KN_SQUOTE = KA_SQUOTE, /* ' */ - KN_BACKSLASH2 = KA_BACKSLASH, - KN_RETURN = KA_RETURN, - KN_Z = KA_z, - KN_X = KA_x, - KN_C = KA_c, - KN_V = KA_v, - KN_B = KA_b, - KN_N = KA_n, - KN_M = KA_m, - KN_COMMA = KA_COMMA, /* , */ - KN_PERIOD = KA_PERIOD, /* . */ - KN_SLASH = KA_SLASH, /* / */ - KN_SPACE = KA_SPACE, - KN_LMOUSE = KA_LMOUSE, - KN_RMOUSE = KA_RMOUSE, - - KN_HOME = KA_HOME, /* num key pad 7 */ - KN_UPLEFT = KA_UPLEFT, - KN_LEFT = KA_LEFT, /* num key pad 4 */ - KN_END = KA_END, /* num key pad 1 */ - KN_DOWNLEFT = KA_DOWNLEFT, - - KN_KEYPAD_SLASH = KA_SLASH, /* num key pad / */ - KN_UP = KA_UP, /* num key pad 8 */ - KN_CENTER = KA_KEYPAD5, /* num key pad 5 */ - KN_DOWN = KA_DOWN, /* num key pad 2 */ - KN_INSERT = KA_INSERT, /* num key pad 0 */ - KN_KEYPAD_ASTERISK= KA_ASTERISK, /* num key pad * */ - KN_PGUP = KA_PGUP, /* num key pad 9 */ - KN_UPRIGHT = KA_UPRIGHT, - KN_RIGHT = KA_RIGHT, /* num key pad 6 */ - KN_PGDN = KA_PGDN, /* num key pad 3 */ - KN_DOWNRIGHT = KA_DOWNRIGHT, - KN_DELETE = KA_DELETE, /* num key pad . */ - - KN_KEYPAD_MINUS = KA_MINUS, /* num key pad - */ - KN_KEYPAD_PLUS = KA_PLUS, /* num key pad + */ - - - KN_KEYPAD_RETURN = KA_RETURN, /* num key pad */ - - KN_ESC = KA_ESC, - KN_F1 = KA_F1, - KN_F2 = KA_F2, - KN_F3 = KA_F3, - KN_F4 = KA_F4, - KN_F5 = KA_F5, - KN_F6 = KA_F6, - KN_F7 = KA_F7, - KN_F8 = KA_F8, - KN_F9 = KA_F9, - KN_F10 = KA_F10, - KN_F11 = KA_F11, - KN_F12 = KA_F12, - - KN_PRNTSCRN = VK_PRINT | WWKEY_VK_BIT, - KN_CAPSLOCK = VK_CAPITAL | WWKEY_VK_BIT, - KN_SCROLLLOCK = VK_SCROLL | WWKEY_VK_BIT, /* */ - KN_PAUSE = VK_PAUSE | WWKEY_VK_BIT, /* */ - KN_LSHIFT = VK_SHIFT | WWKEY_VK_BIT, - KN_RSHIFT = VK_SHIFT | WWKEY_VK_BIT, - KN_LCTRL = VK_CONTROL | WWKEY_VK_BIT, - KN_RCTRL = VK_CONTROL | WWKEY_VK_BIT, - KN_LALT = VK_MENU | WWKEY_VK_BIT, - KN_RALT = VK_MENU | WWKEY_VK_BIT, - KN_E_INSERT = VK_INSERT | WWKEY_VK_BIT, - KN_E_DELETE = VK_DELETE | WWKEY_VK_BIT, - KN_E_LEFT = VK_LEFT | WWKEY_VK_BIT, /* extended */ - KN_E_HOME = VK_HOME | WWKEY_VK_BIT, /* extended */ - KN_E_END = VK_END | WWKEY_VK_BIT, /* extended */ - KN_E_UP = VK_UP | WWKEY_VK_BIT, /* extended */ - KN_E_DOWN = VK_DOWN | WWKEY_VK_BIT, /* extended */ - KN_E_PGUP = VK_PRIOR | WWKEY_VK_BIT, /* extended */ - KN_E_PGDN = VK_NEXT | WWKEY_VK_BIT, /* extended */ - KN_E_RIGHT = VK_RIGHT | WWKEY_VK_BIT, /* extended */ - KN_NUMLOCK = VK_NUMLOCK | WWKEY_VK_BIT, /* */ - - KN_SHIFT_BIT = WWKEY_SHIFT_BIT, - KN_CTRL_BIT = WWKEY_CTRL_BIT | WWKEY_VK_BIT, - KN_ALT_BIT = WWKEY_ALT_BIT | WWKEY_VK_BIT, - KN_RLSE_BIT = WWKEY_RLS_BIT, - KN_BUTTON = WWKEY_BTN_BIT, -}; - - -extern WWKeyboardClass *_Kbd; - - -/* -** The following routines provide some compatability with the old westwood -** library. -*/ -int Check_Key(void); -int Check_Key_Num(void); -int Get_Key_Num(void); -int Get_Key(void); -int KN_To_KA(int key); -void Clear_KeyBuffer(void); -int Key_Down(int key); -int KN_To_VK(int key); - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.INC b/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.INC deleted file mode 100644 index 58e521f..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/KEYBOARD.INC +++ /dev/null @@ -1,126 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : KEYBOARD.INC * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : July 12, 1994 * -;* * -;* Last Update : July 12, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Contains all the defines used by the keyboard interrupt for assembly * -;* includes. * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -TRUE EQU 1 ; numerical true -FALSE EQU 0 ; numerical false -DEBUG EQU 1 - -MAX_X_PIXEL EQU 319 -MAX_Y_PIXEL EQU 199 - - -KN_RESERVED1 EQU 14 -KN_RESERVED2 EQU 45 -KN_RESERVED3 EQU 56 - - -; these two are reserved for AMIGA open and close. -KN_LCOMM EQU 59 -KN_RCOMM EQU 63 - -KN_LMOUSE EQU 65 -KN_RMOUSE EQU 66 -KN_JBUTTON1 EQU 67 -KN_JBUTTON2 EQU 68 -KN_J_UP EQU 69 -KN_J_RIGHT EQU 70 -KN_J_DOWN EQU 71 -KN_J_LEFT EQU 72 - -KN_LEFT EQU 92 -KN_UPLEFT EQU 91 -KN_UP EQU 96 -KN_UPRIGHT EQU 101 -KN_RIGHT EQU 102 -KN_DOWNRIGHT EQU 103 -KN_DOWN EQU 98 -KN_DOWNLEFT EQU 93 -KN_CENTER EQU 97 - -KN_INSERT EQU 99 -KN_DELETE EQU 104 - -KN_RETURN EQU 43 -KN_SPACE EQU 61 -KN_KEYPAD_RETURN EQU 108 - - -; these two are reserved for AMIGA K left and right paren -KN_KLPAREN EQU 87 -KN_KRPAREN EQU 88 - - -KN_NUMLOCK EQU 90 - -KN_SCROLLOCK EQU 125 ; key ignored by the logging system - -KN_MOUSE_MOVE EQU 45 ; Indicate a mouse move (for playback of logged data) - -; ---------------------------------------------------------------- -; flags used in Keyflags to customize keystroke interrupt. - -REPEATON EQU 0001H ; 1:all makes into buffer, 0:only 1st make -TRACKEXT EQU 0002H ; 1:Home != keypad Home, 0:Home=keypad Home -FILTERONLY EQU 0004H ; 1:Normal BIOS operation with filter -CTRLSON EQU 0008H ; 1:pass scroll lock sequence into BIOS -CTRLALTTURBO EQU 0010H ; 1:Allow turbo up and down in application -CTRLCON EQU 0020H ; 1:pass stop code to BIOS -SCROLLLOCKON EQU 0040H ; 1:pass scroll lock key into BIOS -PAUSEON EQU 0080H ; 1:pass the pause key and seq to BIOS -BREAKON EQU 0100H ; 1:pass the ctrl break seq to BIOS -NONUMLOCK EQU 0200H ; 1:do NOT remap keypad to numbers -TASKSWITCHABLE EQU 0400H ; 1:allows task switching keys thru ALT-TAB, - ; ALT-ESC,CTRL-ESC -PASSBREAKS EQU 0800H ; 1:Pass all break codes to keyboard buffer. -KEYMOUSE EQU 1000H ; 1:Numeric keypad moves mouse -SIMLBUTTON EQU 2000H ; 1:have space and enter keys simulate Left -DEBUGINT EQU 4000H ; mouse button when KEYMOUSE is set - - -SHIFTPRESS EQU 001H ; bit 0 for shift key pressed -CTRLPRESS EQU 002H ; bit 1 for ctrl key pressed -ALTPRESS EQU 004H ; bit 2 for alt key pressed -KEYRELEASE EQU 008H ; bit 3 for key released -NOTKEYRELEASE EQU 0F7H ; not of key released - -CAPSLOCK EQU 00001H ; bit 0 for caps locked -NUMLOCK EQU 00002H ; bit 1 for num locked - - - -CLEARISR EQU 020H ; value to clear In Service Register -DOS EQU 021H -INTCHIP0 EQU 020H ; 8259 interrupt chip controller 0 -KEYCTRL EQU 061H ; control bits for KB sense data -KEYDATA EQU 060H ; keyboard scan code port diff --git a/code/TIBERIANDAWN/WIN32LIB/KEYSTRUC.INC b/code/TIBERIANDAWN/WIN32LIB/KEYSTRUC.INC deleted file mode 100644 index f230404..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/KEYSTRUC.INC +++ /dev/null @@ -1,159 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : KEYSTRUC.INC * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : July 13, 1994 * -;* * -;* Last Update : July 13, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -STRUC KeyboardType - SoundOn DW ? ; toggled by alt S - MusicOn DW ? ; toggled by alt M - KeyFlags DD ? ; all but repeat for now - Break DW ? - KeyMouseMove DB 6 DUP(?) - ScreenEdge DW 18 DUP (?) - Bits DB 8 DUP (?) - CondPassKey DW 17 DUP (?) - CondPassCond DW 17 DUP (?) - EscRoutine DD ? - ExtCodes DB 16 DUP (?) - ExtNums DB 16 DUP (?) - ExtRemap DB 16 DUP (?) - ExtRemapEnd DB ? - ExtKeyboard DB ? - KeyBuffer DW 128 DUP(?) ; set to empty - KeyBufferHead DD ? ; set to first entry - KeyBufferTail DD ? ; set to head for empty buffer - KeyLock DW ? ; num and caps lock bits - KeyNums DB 89 DUP (?) - KeysCapsLock DB 16 DUP (?) - KeysNumLock DB 16 DUP (?) - KeysUpDown DB 16 DUP (?) - KeyStream DB 16 DUP (?) - PassCount DW ? - KeyStreamIndex DW ? - LastKeyE0 DB ? - LastKeyE1 DB ? - PassAlways DB 10 DUP (?) - PassAlwaysEnd DB ? ; invalid code to END PassAlways - CtrlFlags DB ? - Buffer DW ? - Time DW ? - XYAdjust DB 26 DUP (?) - EdgeConv DW 16 DUP (?) - MouseUpdate DW ? - MouseX DD ? - LocalMouseX DW ? - MouseY DD ? - LocalMouseY DW ? - IsExtKey DB ? - ExtIndex DW ? - - KeyOldRMI DD ? ; The origianl RM interrupt seg:off. - KeyOldPMIOffset DD ? ; The origianl PM interrupt offset - KeyOldPMISelector DD ? ; The original PM interrupt segment. - - KeyCodeOffset DW ? ; Offset of the code in the RM stuff. - CallKeyRMIntOffset DW ? ; Offset of function to call DOS timer interrupt. - CallKeyRMIntAddr DD ? ; PM address of CallRealIntOffset for speed. - PMIssuedKeyInt DD ? ; did Protected mode pass this through? - - BrkOldRMI DD ? ; The origianl RM interrupt seg:off. - BrkOldPMIOffset DD ? ; The origianl PM interrupt offset - BrkOldPMISelector DD ? ; The original PM interrupt segment. - - BrkCodeOffset DW ? ; Offset of the code in the RM stuff. - CallBrkRMIntOffset DW ? ; Offset of function to call DOS timer interrupt. - CallBrkRMIntAddr DD ? ; PM address of CallRealIntOffset for speed. - PMIssuedBrkInt DD ? ; did Protected mode pass this through? - KeyIntDisabled DD ? - - DbgOldPMIOffset DD ? ; The origianl PM interrupt offset - DbgOldPMISelector DD ? ; The original PM interrupt segment. - - ;--------------------------------------------------------------------------- - ; Begin definition of Mouse Specific Variables for real mode - ;--------------------------------------------------------------------------- - Button DB ? ; current value of the mouse button - MDisabled DB ? ; Is the mouse driver disabled - MInput DB ? ; Defaults to mouse input allowed. - Adjust DW ? ; flag to adjust coordinates if necessary - MouseStepX DW ? ; step values if the mouse moves at - MouseStepY DW ? ; more than one pixel at a time - MouseOffsetX DW ? ; Fractional step values used if a mouse - MouseOffsetY DW ? ; moves at less than one pixel at a time - MState DD ? ; Tracks if mouse is hidden (TRUE) or not (FALSE) - MouseXOld DW ? ; Holds last MouseX and MouseY to determine if - MouseYOld DW ? ; mouse needs to be redrawn - MCState DW ? ; Tracks if mouse conditional hidden (TRUE) or not - MouseCXLeft DD ? ; Conditional hide mouse left x position - MouseCYUpper DD ? ; Conditional hide mouse top y position - MouseCXRight DD ? ; Conditional hide mouse right x position - MouseCYLower DD ? ; Conditional hide mouse lower y position - MouseCursor DD ? ; Pointer to the mouse cursor to draw - MouseCursorSize DW ? ; Size of mouse cursor draw area - MouseBuffer DD ? ; Pointer to buffer mouse is saved in - MouseXHot DD ? ; Offset to mouse's x hot spot - MouseYHot DD ? ; Offset to mouse's y hot spot - MouseBuffX DD ? ; X position background was saved at - MouseBuffY DD ? ; Y position background was saved at - MouseBuffW DD ? ; Width of the region saved for mouse - MouseBuffH DD ? ; Height of the region saved for mouse - MouseWidth DD ? ; Mouse cursor theoretical width - MouseHeight DD ? ; Mouse cursor theoretical height - MouseCodeOffset DW ? ; Offset to the real mode code offset - MouseRight DD ? ; Right hand side of the screen - MouseBottom DD ? ; Bottom of the screen - - - ShadowPtr dw ? - DrawMousePtr dw ? - - VGAMouseDraw dw ? - VGAMouseShadow dw ? - - VESAMouseDraw dw ? - VESAMouseShadow dw ? - - VesaPtr dd ? - VesaBankTable DD 8 dup (?) - Adjust_XPos dd ? - Adjust_YPos dd ? - - -ENDS - -; InitFlags that are set to have a fully functional interrupt. -IF_ALLOC_RM equ 1 ; Allocation of RM was successful. -IF_SET_VECTORS equ 2 ; Vectors have been set. -IF_LOCKED_PM_CODE equ 4 ; Locked PM code for DPMI. -IF_LOCKED_PM_DATA equ 8 ; Locked PM code for DPMI. -IF_RATE_CHANGE equ 10 ; Timer rate was changed. -IF_FUNCTIONAL equ 20 ; Timer is in and functional. -IF_LOCKED_RM_CODE equ 40 diff --git a/code/TIBERIANDAWN/WIN32LIB/LOAD.CPP b/code/TIBERIANDAWN/WIN32LIB/LOAD.CPP deleted file mode 100644 index 1a10558..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/LOAD.CPP +++ /dev/null @@ -1,375 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: g:/library/wwlib32/file/rcs/load.cpp 1.4 1994/04/22 12:42:21 scott_bowen Exp $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : LIBRARY * - * * - * File Name : LOAD.C * - * * - * Programmer : Christopher Yates * - * * - * Last Update : September 17, 1993 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Load_Uncompress -- Load and uncompress the given file. * - * Uncompress_Data -- Uncompress standard CPS buffer. * - * Load_Data -- Loads a data file from disk. * - * Load_Alloc_Data -- Loads and allocates buffer for a file. * - * Write_Data -- Writes a block of data as a file to disk. * - * Uncompress_Data -- Uncompresses data from one buffer to another. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "iff.h" -#include "file.h" -#include -#include -#include -#include - - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -/*************************************************************************** - * LOAD_DATA -- Loads a data file from disk. * - * * - * This routine will load a data file from disk. It does no translation* - * on the data. * - * * - * INPUT: name -- Pointer to ASCII filename of the data file. * - * * - * ptr -- Buffer to load the data file into. * - * * - * size -- Maximum size of the buffer (in bytes). * - * * - * OUTPUT: Returns with the number of bytes read. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/24/1991 JLB : Created. * - *=========================================================================*/ -unsigned long __cdecl Load_Data(char const *name, void *ptr, unsigned long size) -{ - int fd; - - fd = Open_File(name, READ); - size = Read_File(fd, ptr, size); - Close_File(fd); - return(size); -} - - -/*************************************************************************** - * WRITE_DATA -- Writes a block of data as a file to disk. * - * * - * This routine will write a block of data as a file to the disk. It * - * is the compliment of Load_Data. * - * * - * INPUT: name -- Name of the file to create. * - * * - * ptr -- Pointer to the block of data to write. * - * * - * size -- Size of the data block to be written. * - * * - * OUTPUT: Returns with the number of bytes actually written. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/05/1992 JLB : Created. * - *=========================================================================*/ -unsigned long __cdecl Write_Data(char const *name, void *ptr, unsigned long size) -{ - int fd; - - fd = Open_File(name, WRITE); - size = Write_File(fd, ptr, size); - Close_File(fd); - return(size); -} - - -/*************************************************************************** - * LOAD_ALLOC_DATA -- Loads and allocates buffer for a file. * - * * - * The routine will allocate a buffer and load the specified file into * - * it. The kind of memory used for the buffer is determined by the * - * memory allocation flags passed in. * - * * - * INPUT: name -- Name of the file to load. * - * * - * flags -- Memory allocation flags to use when allocating. * - * * - * OUTPUT: Returns with a pointer to the buffer that contains the file's * - * data. * - * * - * WARNINGS: A memory error could occur if regular memory flags are * - * specified. If XMS memory is specified, then this routine * - * could likely return NULL. * - * * - * HISTORY: * - * 05/28/1992 JLB : Created. * - *=========================================================================*/ -void * __cdecl Load_Alloc_Data(char const *name, MemoryFlagType flags) -{ - int fd; // Working file handle. - unsigned long size; // Size of the file to load. - void *buffer; // Buffer to hold the file. - - fd = Open_File(name, READ); - size = File_Size(fd); - buffer = Alloc(size, flags); - if (buffer) { - Read_File(fd, buffer, size); - } - Close_File(fd); - return(buffer); -} - - -/*************************************************************************** - * LOAD_UNCOMPRESS -- Load and uncompress the given file. * - * * - * INPUT: char * - file name to uncompress * - * GraphicBufferClass& - to load the source data into * - * GraphicBufferClass& - for the picture * - * void * - ptr for header uncompressed data * - * * - * OUTPUT: unsigned long size of uncompressed data * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1991 CY : Created. * - * 06/26/1991 JLB : Handles load & uncompress to same buffer. * - *=========================================================================*/ -unsigned long __cdecl Load_Uncompress(char const *file, BufferClass& uncomp_buff, BufferClass& dest_buff, void *reserved_data) -{ - int fd; // Source file handle. - unsigned int isize=0; // Size of the file. - unsigned int skipsize; // Size of the skip data bytes. - void *uncomp_ptr; // Source buffer pointer. - char *newuncomp_ptr; // Adjusted source pointer. - - - uncomp_ptr = uncomp_buff.Get_Buffer(); // get a pointer to buffer - - /*======================================================================*/ - /* Read the file into the uncompression buffer. */ - /*======================================================================*/ - - fd = Open_File(file, READ); // Open up the file to read from - Read_File(fd, (char *) &isize, 2L); // Read the file size - Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in. - isize -= 8; // Remaining data in file. - - /*======================================================================*/ - /* Check for and read in the skip data block. */ - /*======================================================================*/ - - skipsize = *(((short *)uncomp_ptr) + 3); - - if (reserved_data && skipsize) { - Read_File(fd, reserved_data, (unsigned long) skipsize); - } else { - Seek_File(fd, skipsize, SEEK_CUR); - } - - *( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value. - isize -= skipsize; - - /*======================================================================*/ - /* If the source and dest buffer are the same, we adjust the pointer so */ - /* that the compressed data is loaded into the end of the buffer. In */ - /* this way the uncompress code can write to the same buffer. */ - /*======================================================================*/ - newuncomp_ptr = (char *)Add_Long_To_Pointer(uncomp_buff.Get_Buffer(), uncomp_buff.Get_Size() - (isize+8L)); - - /*======================================================================*/ - /* Duplicate the header bytes. */ - /*======================================================================*/ - Mem_Copy(uncomp_ptr,newuncomp_ptr,8); - - /*======================================================================*/ - /* Read in the main compressed part of the file. */ - /*======================================================================*/ - Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize); - Close_File(fd); - - /*======================================================================*/ - /* Uncompress the file into the destination buffer (which may very well */ - /* be the source buffer). */ - /*======================================================================*/ - return(Uncompress_Data(newuncomp_ptr, dest_buff.Get_Buffer())); -} -#if(0) -/*************************************************************************** - * LOAD_UNCOMPRESS -- Load and uncompress the given file. * - * * - * INPUT: char *file name to uncompress, BuffType uncomp_buff to load * - * the source data into, BuffType dest_buff for the picture, * - * void *reserved_data pointer for header uncompressed data * - * * - * OUTPUT: unsigned long size of uncompressed data * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/28/1991 CY : Created. * - * 06/26/1991 JLB : Handles load & uncompress to same buffer. * - *=========================================================================*/ -unsigned long __cdecl Load_Uncompress(char const *file, BuffType uncomp_buff, BuffType dest_buff, void *reserved_data) -{ - int fd; // Source file handle. - unsigned int isize; // Size of the file. - unsigned int skipsize; // Size of the skip data bytes. - void *uncomp_ptr; // Source buffer pointer. - char *newuncomp_ptr; // Adjusted source pointer. - - - uncomp_ptr = Get_Buff(uncomp_buff); /* Get pointer to uncomp buffer */ - - /* Read the file into the uncomp_buff */ - - fd = Open_File(file, READ); - Read_File(fd, (char *) &isize, 2L); /* Read the file size */ - #if(AMIGA) - isize = Reverse_Word(isize); - #endif - - Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in. - isize -= 8; // Remaining data in file. - - /* - ** Check for and read in the skip data block. - */ - - skipsize = *(((short*)uncomp_ptr) + 3); - #if(AMIGA) - skipsize = Reverse_Word(skipsize); - #endif - - if (reserved_data && skipsize) { - Read_File(fd, reserved_data, (unsigned long) skipsize); - } else { - Seek_File(fd, skipsize, SEEK_CUR); - } - *( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value. - isize -= skipsize; - - /* - ** If the source and dest buffer are the same, we - ** adjust the pointer so that the compressed data is - ** loaded into the end of the buffer. In this way the - ** uncompress code can write to the same buffer. - */ - #if(IBM) - newuncomp_ptr = (char *)Add_Long_To_Pointer(Get_Buff(uncomp_buff), PageArraySize[uncomp_buff] - (isize+8L)); - #else - newuncomp_ptr = Get_Buff(uncomp_buff); - newuncomp_ptr += PageArraySize[uncomp_buff] - ((isize+10) & 0xFFFE); - #endif - - /* - ** Duplicate the header bytes. - */ - Mem_Copy(uncomp_ptr,newuncomp_ptr,8); - - /* - ** Read in the main compressed part of the file. - */ - Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize); - Close_File(fd); - - return(Uncompress_Data(newuncomp_ptr, Get_Buff(dest_buff))); -} - -#endif -/*************************************************************************** - * Uncompress_Data -- Uncompresses data from one buffer to another. * - * * - * This routine takes data from a compressed file (sans the first two * - * size bytes) and uncompresses it to a destination buffer. The source * - * data MUST have the CompHeaderType at its start. * - * * - * INPUT: src -- Source compressed data pointer. * - * * - * dst -- Destination (paragraph aligned) pointer. * - * * - * OUTPUT: Returns with the size of the uncompressed data. * - * * - * WARNINGS: If LCW compression is used, the destination buffer must * - * be paragraph aligned. * - * * - * HISTORY: * - * 09/17/1993 JLB : Created. * - *=========================================================================*/ -unsigned long __cdecl Uncompress_Data(void const *src, void *dst) -{ - unsigned int skip; // Number of leading data to skip. - CompressionType method; // Compression method used. - unsigned long uncomp_size=NULL; - - if (!src || !dst) return(NULL); - - /* - ** Interpret the data block header structure to determine - ** compression method, size, and skip data amount. - */ - uncomp_size = ((CompHeaderType*)src)->Size; - #if(AMIGA) - uncomp_size = Reverse_Long(uncomp_size); - #endif - skip = ((CompHeaderType*)src)->Skip; - #if(AMIGA) - skip = Reverse_Word(skip); - #endif - method = (CompressionType) ((CompHeaderType*)src)->Method; - src = Add_Long_To_Pointer((void *)src, (long)sizeof(CompHeaderType) + (long)skip); - - switch (method) { - - default: - case NOCOMPRESS: - Mem_Copy((void *) src, dst, uncomp_size); - break; - - case HORIZONTAL: -#if LIB_EXTERNS_RESOLVED - RLE_Uncompress((void *) src, dst, uncomp_size); -#endif - break; - - case LCW: - LCW_Uncompress((void *) src, (void *) dst, (unsigned long) uncomp_size); - break; - - } - - return(uncomp_size); -} - - diff --git a/code/TIBERIANDAWN/WIN32LIB/LOADFONT.CPP b/code/TIBERIANDAWN/WIN32LIB/LOADFONT.CPP deleted file mode 100644 index 87cd7f6..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/LOADFONT.CPP +++ /dev/null @@ -1,137 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : LOADFONT.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 6, 1991 * - * * - * Last Update : June 27, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Load_Font -- Loads a font from disk. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "font.h" -#include -#include -#include - -#if(IBM) -#include -#include - -#include - -int FontXSpacing = 0; -int FontYSpacing = 0; -void const *FontPtr = NULL; -char FontWidth = 8; -char FontHeight = 8; - -// only font.c and set_font.c use the following -char *FontWidthBlockPtr = NULL; - - - -/*************************************************************************** - * LOAD_FONT -- Loads a font from disk. * - * * - * This loads a font from disk. This function must be called as a * - * precursor to calling Set_Font(). You need only call this function * - * once per desired font at the beginning of your code, but AFTER * - * Prog_Init() is called. * - * * - * INPUT: name - Pointer to font name to use (eg. "topaz.font") * - * * - * fontsize - Size in points of the font loaded. * - * * - * OUTPUT: Pointer to font data or NULL if unable to load. * - * * - * WARNINGS: Some system memory is grabbed by this routine. * - * * - * HISTORY: * - * 4/10/91 BS : 2.0 compatibily * - * 6/09/91 JLB : IBM and Amiga compatability. * - * 11/27/1991 JLB : Uses file I/O routines for disk access. * - * 01/29/1992 DRD : Modified to use new font format. * - * 02/01/1992 DRD : Added font file verification. * - * 06/29/1994 SKB : modified for 32 bit library * - *=========================================================================*/ -void * __cdecl Load_Font(char const *name) -{ - char valid; - int fh; // DOS file handle for font file. - unsigned short size; // Size of the data in the file (-2); - char *ptr = NULL; // Pointer to newly loaded font. - - - - fh=Open_File(name,READ); - if ( fh>=0 ){ - if ( Read_File(fh, (char *) &size, 2) != 2) return(NULL); - - ptr = (char *) Alloc(size , MEM_NORMAL ); - *(short *)ptr = size; - Read_File(fh, ptr + 2, size - 2); - Close_File(fh); - } else { - return ((void*)errno); - } - - - -#ifdef cuts - if (Find_File(name)) { - fh = Open_File(name, READ); - if (Read_File(fh, (char *) &size, 2) != 2) return(NULL); - - ptr = (char *) Alloc(size, MEM_NORMAL); - *(short *)ptr = size; - Read_File(fh, ptr + 2, size - 2); - Close_File(fh); - } else { - return (NULL); - } -#endif - - // - // verify that the file loaded is a valid font file. - // - - valid = FALSE; - if (*(ptr + 2) == 0) { // no compression - if (*(ptr + 3) == 5) { // currently only 5 data blocks are used. - valid = TRUE; - } - } - - if ( !valid ) { - return (NULL); - } - - return(ptr); -} - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/LOADPAL.CPP b/code/TIBERIANDAWN/WIN32LIB/LOADPAL.CPP deleted file mode 100644 index e6d7487..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/LOADPAL.CPP +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Load_Palette * - * * - * File Name : LOADPAL.CPP * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : April 25, 1994 * - * * - * Last Update : April 27, 1994 [BR] * - * * - *-------------------------------------------------------------------------* - * Note: This module contains dependencies upon the file I/O system, * - * specifically Load_Data(). * - *-------------------------------------------------------------------------* - * Functions: * - * Load_Palette -- Loads a palette file into the given palette buffer. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* -********************************* Includes ********************************** -*/ -//#include -#include "wwstd.h" -#include "iff.h" -#include "palette.h" - -/* -********************************* Constants ********************************* -*/ - -/* -********************************** Globals ********************************** -*/ - -/* -******************************** Prototypes ********************************* -*/ - -/*************************************************************************** - * Load_Palette -- Loads a palette file into the given palette buffer. * - * * - * INPUT: * - * BYTE * file_name - name of the file to load. * - * BYTE * palette_pointer - pointer to palette buffer. * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/20/1991 BS : Created. * - * 04/27/1994 BR : Converted to 32-bit * - *=========================================================================*/ -void __cdecl Load_Palette(char *palette_file_name, void *palette_pointer) -{ - #if(IBM) - Load_Data(palette_file_name, palette_pointer, 768); - #else - Load_Data(palette_file_name, palette_pointer, (ULONG)(2<. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : MCGAPRIM.INC * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : January 16, 1995 * -;* * -;* Last Update : January 16, 1995 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -; Externs from REGIONSZ.ASM module of the MCGAPRIM library -GLOBAL MCGA_Size_Of_Region :NEAR - -; Externs from GETPIX.ASM module of the MCGAPRIM library -GLOBAL MCGA_Get_Pixel :NEAR - -; Externs from VGETPIX.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Get_Pixel :NEAR - -; Externs from PUTPIX.ASM module of the MCGAPRIM library -GLOBAL MCGA_Put_Pixel :NEAR - -; Externs from VPUTTPIX.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Put_Pixel :NEAR - -; Externs from CLEAR.ASM module of the MCGAPRIM library -GLOBAL MCGA_Clear :NEAR - -; Externs from VCLEAR.ASM module of the MCGA/SVGAPRIM library -GLOBAL Vesa_Clear :NEAR -; Externs from BITBLIT.ASM module of the MCGAPRIM library -GLOBAL Linear_Blit_To_Linear :NEAR - -; Externs from VBITBLIT.ASM module of the MCGA/SVGAPRIM library -GLOBAL Linear_Blit_To_Vesa :NEAR -GLOBAL Vesa_Blit_To_Linear :NEAR -GLOBAL Vesa_Blit_To_Vesa :NEAR - -; Externs from TOBUFF.ASM module of the MCGAPRIM library -GLOBAL MCGA_To_Buffer :NEAR - -; Externs from VTOBUFF.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_To_Buffer :NEAR - -; Externs from TOPAGE.ASM module of the MCGAPRIM library -GLOBAL MCGA_Buffer_To_Page :NEAR - -; Externs from VTOPAGE.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Buffer_To_Page :NEAR - -; Externs from SCALE.ASM module of the MCGAPRIM library -GLOBAL Linear_Scale_To_Linear :NEAR - -; Externs from VSCALE.ASM module of the SVGA/MCGAPRIM library -GLOBAL Linear_Scale_To_Vesa :NEAR -GLOBAL Vesa_Scale_To_Linear :NEAR -GLOBAL Vesa_Scale_To_Vesa :NEAR - -; Externs from TXTPRNT.ASM module of the MCGAPRIM library -GLOBAL MCGA_Print :NEAR - -; Externs from VTXTPRNT.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Print :NEAR - -;*-------------------------------------------------------------------------* -;* Define MCGA only assembly GLOBALS * -;*-------------------------------------------------------------------------* - -; Externs from DRAWLINE.ASM module of the MCGAPRIM library -GLOBAL MCGA_Draw_Line :NEAR - -; Externs from FILLQUAD.ASM module of the MCGAPRIM library -GLOBAL MCGA_Fill_Quad :NEAR - -; Externs from FILLRECT.ASM module of the MCGAPRIM library -GLOBAL MCGA_Fill_Rect :NEAR - -; Externs from REMAP.ASM module of the MCGAPRIM library -GLOBAL MCGA_Remap :NEAR - -; Externs from STAMP.ASM module of the MCGAPRIM library -GLOBAL MCGA_Draw_Stamp :NEAR - -GLOBAL get_clip : NEAR - -struc RECTANGLE - x0 dd ? - y0 dd ? - x1 dd ? - y1 dd ? -ends RECTANGLE - - - - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/MEM.CPP b/code/TIBERIANDAWN/WIN32LIB/MEM.CPP deleted file mode 100644 index ca04864..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MEM.CPP +++ /dev/null @@ -1,1086 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : MEM.C * - * * - * Programmer : Joe L. Bostic * - * Scott K. Bowen * - * * - * Start Date : March 31, 1993 * - * * - * Last Update : September 8, 1994 [IML] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Mem_Free -- Free a block of memory from system. * - * Mem_Alloc -- Allocate a block of memory from the special memory pool. * - * Mem_Init -- Initialize the private memory allocation pool. * - * Mem_Reference -- Updates the reference time for the specified memory blo* - * Mem_Find -- Returns with pointer to specified memory block. * - * Mem_Find_Oldest -- Returns with the memory block with the oldest time st* - * Mem_Free_Oldest -- Find and free the oldest memory block. * - * Mem_Avail -- Returns the amount of free memory available in the cache.* - * Mem_Cleanup -- Performes a garbage collection on the memory cache. * - * MemNode_Unlink -- Unlinks a node from the cache. * - * MemNode_Insert -- Inserts a node into a cache chain. * - * Mem_Largest_Avail -- Largest free block available. * - * Mem_Lock_Block -- Locks a block so that it cannot be moved in cleanup.* - * Mem_In_Use -- Makes it so a block will never be returned as oldest* - * Mem_Pool_Size -- Returns total amount of memory in pool. * - * Mem_Get_ID -- Returns ID of node. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include "wwmem.h" -#include - -#include -//#include - -#define DEBUG_FILL FALSE - -//////////////////////////////////////////////////////////////////////////// - - - -/******************************************************************************* -** A allocated block may have one of three meanings in the Time field. The first -** is the time stamp of the last time it was referenced. The other two values -** are defined below. MEM_BLOCK_IN_USE means that it will never be returned as the -** oldest since there is no valid time stamp. LOCKED_BLOCK has the same meaning as -** MEM_BLOCK_IN_USE with the added feature that the block will not be moved in a -** Mem_Cleanup(). Therefore, there may be some fragmentation after the cleanup -** if any blocks are LOCKED. It would be good practice to seldomly lock blocks, -** for instance, only when a sample is being played. -** WARNING: If these values change to anything else, logic will need to be changed -** in Mem_Find_Oldest since it relies on these being small values. -*/ -#define MEM_BLOCK_IN_USE 0x00 -#define MEM_BLOCK_LOCKED 0x01 - -/* -** Each block of memory in the pool is headed by this structure. -*/ -typedef struct MemChain { - struct MemChain *Next; // Pointer to next memory chain node. - struct MemChain *Prev; // Pointer to previous memory chain node. - unsigned long ID; // ID number of block. - unsigned short Time; // TickCount of latest reference. - unsigned long Size; // Size of memory block (in paragraphs). -} MemChain_Type; - - -/* -** Holding tank memory management data. -*/ -typedef struct MemPool { - MemChain_Type *FreeChain; // Pointer to first node in free chain. - MemChain_Type *UsedChain; // Pointer to first node in used chain. - unsigned long FreeMem; // Current amount of free ram (in paragraphs). - unsigned long TotalMem; // Total quantity of memory. - long pad2; -} MemPool_Type; - - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - -PRIVATE void MemNode_Unlink(MemPool_Type *pool, int freechain, MemChain_Type *node); -PRIVATE void MemNode_Insert(MemPool_Type *pool, int freechain, MemChain_Type *node, unsigned int size, unsigned long id, int merge); - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - - -/*************************************************************************** - * Mem_Init -- Initialize the private memory allocation pool. * - * * - * This routine is used to initialize the private memory allocation * - * pool. * - * * - * INPUT: buffer -- Pointer to the buffer that is the allocation pool. * - * * - * size -- Size of the buffer in bytes. * - * * - * OUTPUT: TRUE/FALSE; Was it initialized successfully? * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 03/31/1993 JLB : Created. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -int Mem_Init(void *buffer, long size) -{ - MemChain_Type *mem; // Working memory chain node. - MemPool_Type *pool; // Memory pool control structure. - - /* - ** The buffer is rounded down to the nearest paragraph. - */ - size = size & 0xFFFFFFF0L; - - if (!buffer || !size) return(FALSE); - - /* - ** Initialize the pool control structure. - */ - pool = (MemPool_Type *)buffer; - pool->FreeMem = (size - sizeof(MemPool_Type)) >> 4; - pool->UsedChain = NULL; - pool->TotalMem = pool->FreeMem; - mem = pool->FreeChain = (MemChain_Type *) (pool + 1); - - /* - ** Initialize the free memory chain. - */ - mem->Next = NULL; - mem->Prev = NULL; - mem->Size = pool->FreeMem; - mem->ID = -1; - mem->Time = 0; - - return(TRUE); -} - - -/*************************************************************************** - * Mem_Alloc -- Allocate a block of memory from the special memory pool. * - * * - * This routine will allocate a block of memory from the special * - * memory allocation pool. * - * * - * INPUT: poolptr -- Pointer to the memory pool base address. * - * * - * size -- The size of the memory block to allocate. * - * * - * id -- ID number to give this memory block. * - * * - * OUTPUT: Returns with a pointer to the allocated block. If there was * - * insufficient room, then NULL is returned. * - * * - * WARNINGS: Be sure to check for the NULL return case. * - * * - * HISTORY: * - * 03/31/1993 JLB : Created. * - * 08/06/1993 JLB : Optimized for low memory caches. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -void *Mem_Alloc(void *poolptr, long lsize, unsigned long id) -{ - MemPool_Type *pool; - MemChain_Type *node; // Pointer to current memory node. - unsigned int remainder=0; // Remaining bytes that are still free. - int found; - unsigned int size; // Paragraph size of allocation. - - - /* - ** If there is no free memory then the allocation will - ** always fail. - */ - if (!poolptr || !lsize) return(NULL); - pool = (MemPool_Type *) poolptr; - - /* - ** Allocations are forced to be paragraph sized. - */ - lsize += sizeof(MemChain_Type); // Account for header. - lsize = (lsize + 0x0FL) & 0xFFFFFFF0L; - size = lsize >> 4; - - /* - ** If the total free is less than the size of the desired allocation, - ** then we KNOW that an allocation will fail -- just return. - */ - if (pool->TotalMem < size) { - return(NULL); - } - - /* - ** Walk down free chain looking for the first block that will - ** accomodate the allocation. - */ - node = pool->FreeChain; - found = FALSE; - while (!found && node) { - - /* - ** Fetch free memory chunk block and see if it is big enough. - */ - if (node->Size >= size) { - found = TRUE; - break; - } - node = node->Next; - } - if (!found) { - return(NULL); - } - - /* - ** Determine if this allocation would split the block. - */ - remainder = node->Size - size; - - /* - ** If only a very small free chunk would remain, just tack it on - ** to the current allocation. - */ - if (remainder <= 2) { - remainder = 0; - size = node->Size; - } - - /* - ** Remove the primary block from the free memory list. - */ - MemNode_Unlink(pool, TRUE, node); - - /* - ** If a smaller block remains, then link it back into - ** the free memory list. - */ - if (remainder) { - MemNode_Insert(pool, TRUE, (MemChain_Type *)Add_Long_To_Pointer(node, (long)size << 4), remainder, -1, FALSE); - } - - /* - ** Link in the allocated node into the used memory list. - */ - MemNode_Insert(pool, FALSE, node, size, id, FALSE); - - /* - ** Reflect the change to the total free count. - */ - pool->FreeMem -= size; - - /* - ** Return a pointer to the block of allocated memory just past - ** the header. - */ - -#if DEBUG_FILL - memset(node + 1, id, (size-1) << 4); -#endif - return((void *) (node + 1)); -} - - -/*************************************************************************** - * Mem_Free -- Free a block of memory from system. * - * * - * This routine will free a block of memory from the special memory * - * buffer. * - * * - * INPUT: poolptr -- Pointer to the memory pool base address. * - * * - * buffer -- Pointer to memory block to free. * - * * - * OUTPUT: TRUE/FALSE; Was the deallocation successful? * - * * - * WARNINGS: Be sure to only pass in to this routine a buffer that was * - * returned from Mem_Alloc(). * - * * - * HISTORY: * - * 03/31/1993 JLB : Created. * - * 08/06/1993 JLB : Optimized for low memory caches. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -int Mem_Free(void *poolptr, void *buffer) -{ - MemPool_Type *pool; // pointer to structure. - MemChain_Type *node; // Copy of current memory node. - unsigned int size; // Size of the block being freed. - - /* - ** One can't free what isn't there. - */ - if (!buffer || !poolptr) { - return(FALSE); - } - pool = (MemPool_Type *) poolptr; - - /* - ** The node pointer is actually back a bit from the "normal" pointer. - */ - node = (MemChain_Type *) buffer; - node--; - - /* - ** Get pointer to actual allocated node and unlink it from the used - ** memory chain. - */ - size = node->Size; - MemNode_Unlink(pool, FALSE, node); - MemNode_Insert(pool, TRUE, node, size, -1, TRUE); - - /* - ** Reflect the new free memory into the total memory count. - */ - pool->FreeMem += size; - - return(TRUE); -} - - -/*************************************************************************** - * Mem_Reference -- Updates the reference time for the specified memory blo* - * * - * This routine is used to update the memory reference time for the * - * specified memory node. Typically, this is called every time a * - * memory block is used in order to make sure the memory block time * - * tracking (Last Recently Used) system works properly. * - * * - * INPUT: node -- Pointer to memory block returned from Mem_Find. * - * * - * OUTPUT: none * - * * - * WARNINGS: The node pointer must be valid. For maximum safety this * - * routine should be called right after Mem_Find(). * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -void Mem_Reference(void *node) -{ - MemChain_Type *nodeptr; // Pointer of current memory node. - - if (!node) return; - - // Get to the node header. - nodeptr = (MemChain_Type *) node; - nodeptr--; - - nodeptr->Time = (unsigned short)(TickCount.Time() >> 4); - -} - - -/*************************************************************************** - * MEM_LOCK_BLOCK -- Locks a block so that it cannot be moved in cleanup. * - * By marking a memory block in use, the memory system will never return* - * it as the oldest memory block. It also makes it so that the block * - * will never be moved during a Cleanup process. * - * * - * INPUT: node -- Pointer to memory block returned from Mem_Find. * - * * - * OUTPUT: none * - * * - * WARNINGS: If one or more blocks are locked in a heap, Mem_Avail might * - * not equal Mem_Largest_Avail after a call to Mem_Cleanup. * - * * - * HISTORY: * - * 04/15/1994 SKB : Created. * - *=========================================================================*/ -void Mem_Lock_Block(void *node) -{ - MemChain_Type *nodeptr; // Pointer of current memory node. - - if (!node) return; - - // Get to the node header. - nodeptr = (MemChain_Type *) node; - nodeptr--; - nodeptr->Time = MEM_BLOCK_LOCKED; -} - - -/*************************************************************************** - * MEM_IN_USE -- Makes it so a block will never be returned as oldest * - * By marking a memory block in use, the memory system will never return* - * it as the oldest memory block. It still can be moved in the Cleanup * - * code. * - * * - * INPUT: node -- Pointer to memory block returned from Mem_Find. * - * * - * OUTPUT: none * - * * - * WARNINGS: Mem_Find_Oldest() will return NULL if only IN_USE blocks are * - * in memory. * - * HISTORY: * - * 04/15/1994 SKB : Created. * - *=========================================================================*/ -void Mem_In_Use(void *node) -{ - MemChain_Type *nodeptr; // Pointer of current memory node. - - if (!node) return; - - // Get to the node header. - nodeptr = (MemChain_Type *) node - 1; - nodeptr->Time = MEM_BLOCK_IN_USE; -} - - -/*************************************************************************** - * Mem_Find -- Returns with pointer to specified memory block. * - * * - * Use this routine to convert a memory ID value into an actual memory * - * pointer. It sweeps through all of the 'cached' memory blocks and * - * returns with the matching block pointer. * - * * - * INPUT: poolptr -- Pointer to the memory cache block. * - * * - * id -- The ID of the block desired. * - * * - * OUTPUT: Returns with the pointer to the memory block. If NULL is * - * returned then the desired block is not in the memory cache. * - * * - * WARNINGS: This routine may return NULL if the memory block is not * - * present in the cache. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 08/06/1993 JLB : Optimized for low memory caches. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -void *Mem_Find(void *poolptr, unsigned long id) -{ - MemPool_Type *pool; // pointer to structure. - MemChain_Type *node; // Working node structure. - - if (!poolptr) return(NULL); - - pool = (MemPool_Type *) poolptr; - - /* - ** Cannot free a node that is not on the UsedChain list. - */ - if (!pool->UsedChain) { - return(NULL); - } - - /* - ** Sweep through entire allocation chain to find - ** the one with the matching ID. - */ - node = pool->UsedChain; - while (node) { - - if (node->ID == id) { - return(node + 1); - } - node = node->Next; - } - return(NULL); -} - - -/*************************************************************************** - * MEM_GET_ID -- Returns ID of node. * - * * - * INPUT: void *node - pointer to node. * - * * - * OUTPUT: The ID of the node that was supplied by user during Mem_Alloc().* - * * - * WARNINGS: pointer to node must be one that Mem_Alloc or * - * Mem_Find returned. ** - * * - * HISTORY: * - * 04/18/1994 SKB : Created. * - *=========================================================================*/ -unsigned long Mem_Get_ID(void *node) -{ - MemChain_Type *nodeptr; // Pointer of current memory node. - - if (!node) return (0L); - - // Get to the node header. - nodeptr = (MemChain_Type *) node - 1; - return (nodeptr->ID); -} - - -/*************************************************************************** - * Mem_Find_Oldest -- Returns with the memory block with the oldest time st* - * * - * Use this routine to find the memory block with the oldest time stamp * - * value. Typically, this is used when freeing memory blocks in the * - * cache in order to make room for a new memory block. * - * * - * INPUT: poolptr -- Pointer to the memory cache. * - * * - * OUTPUT: Returns with the pointer to the oldest memory block. If NULL * - * is returned, then the memory cache is empty. * - * * - * WARNINGS: This routine could return NULL. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 08/06/1993 JLB : Optimized for low memory caches. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - * 04/15/1994 SKB : Handle time wrap, locked blocks, and no_refenece blocks* - *=========================================================================*/ -void *Mem_Find_Oldest(void *poolptr) -{ - MemChain_Type *node; // Working node pointer. - MemChain_Type *oldnode; // Pointer to oldest block. - unsigned int oldtime; // Time of oldest block. - unsigned int basetime; // Time to mark our base time with. - unsigned int time; // basetime + time of node. - - if (!poolptr) return(NULL); - - /* - ** Sweep through entire allocation chain to find - ** the oldest referenced memory block. - */ - oldnode = NULL; - oldtime = 0; - node = ((MemPool_Type*) poolptr)->UsedChain; - - basetime = (unsigned int)(TickCount.Time() >> 4); - - while (node) { - - /* - ** Don't allow MEM_BLOCK_IN_USE or MEM_BLOCK_LOCKED to be returned. - */ - if (node->Time > MEM_BLOCK_LOCKED) { - - /* - ** Adjust time for wrap around (after about 5 hrs). - ** times less then the base time will wrap up high while - ** and times greater then base time will then be lower since - ** any time greater has been on the thing a long time. - */ - time = node->Time - basetime ; - - if (time < oldtime || !oldnode) { - oldtime = time; - oldnode = node; - } - } - node = node->Next; - } - - /* - ** Return with the value that matches the pointer that - ** was allocated by the system previously. - */ - if (oldnode) { - oldnode++; - } - return(oldnode); -} - - -/*************************************************************************** - * Mem_Free_Oldest -- Find and free the oldest memory block. * - * * - * This routine is used to free the oldest memory block in the memory * - * cache. This routine is typcially used in order to create more room * - * in the cache for a new allocation. * - * * - * INPUT: poolptr -- Pointer to the memory cache. * - * * - * OUTPUT: Returns with the node that it freed. Although this node is * - * is no longer valid, it may be used to mark that pointer as * - * invalid in the main code. * - * * - * WARNINGS: If this routine returns NULL, then no memory was freed. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -void *Mem_Free_Oldest(void *poolptr) -{ - MemChain_Type *node; // Copy of pointer to oldest node. - - if (!poolptr) return(NULL); - node = (MemChain *) Mem_Find_Oldest(poolptr); - if (Mem_Free(poolptr, node)) { - return(node); - } - return(NULL); -} - -/*************************************************************************** - * MEM_POOL_SIZE -- Returns total amount of memory in pool. * - * * - * INPUT: poolptr -- Pointer to the memory cache. * - * * - * OUTPUT: long total size of pool. i.e. largest possible allocation if * - * no memory was allocated. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/18/1994 SKB : Created. * - *=========================================================================*/ -long Mem_Pool_Size(void *poolptr) -{ - MemPool_Type *pool; // Memory pool control structure. - long memtotal; // Total amount of memory free. - - if (!poolptr) return(NULL); - pool = (MemPool_Type *) poolptr; - - memtotal = ((long)pool->TotalMem) << 4; - memtotal -= sizeof(MemChain_Type); - memtotal = MAX(memtotal, (long)0); - return(memtotal); -} - -/*************************************************************************** - * Mem_Avail -- Returns the amount of free memory available in the cache. * - * * - * This routine examines the memory cache and returns the amount of * - * free memory available. This memory total MAY be fragmented but * - * after Mem_Cleanup() is called, an allocation of the amount returned * - * by this function is guaranteed. * - * * - * INPUT: poolptr -- Pointer to the memory cache. * - * * - * OUTPUT: Returns the largest allocation possible from the memory cache. * - * * - * WARNINGS: The value returned may represent the FRAGMENTED total * - * amount of memory free in the cache. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -long Mem_Avail(void *poolptr) -{ - MemPool_Type *pool; // Memory pool control structure. - long memtotal; // Total amount of memory free. - - if (!poolptr) return(NULL); - pool = (MemPool_Type *) poolptr; - - memtotal = ((long)pool->FreeMem) << 4; - memtotal -= sizeof(MemChain_Type); - //memtotal -= sizeof(MemChain_Type) + 15; - memtotal = MAX(memtotal, (long)0); - return(memtotal); -} - - -/*************************************************************************** - * MEM_LARGEST_AVAIL -- Largest free block available. * - * This routine examines the free node list to find the largest block * - * available. User can Mem_Alloc() this return size successfully. * - * * - * INPUT: poolptr -- Pointer to the memory cache. * - * * - * OUTPUT: Returns largest allocation currently possible from the cache. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/15/1994 SKB : Created. * - *=========================================================================*/ -long Mem_Largest_Avail(void *poolptr) -{ - MemChain_Type *node; // Pointer to current memory node. - unsigned int size; - long truesize; - - /* - ** Make sure that it is a buffer. - */ - if (!poolptr) return(NULL); - - /* - ** Go through the entire free chain looking for the largest block. - */ - node = ((MemPool_Type *)poolptr)->FreeChain; - size = 0; - while (node) { - - /* - ** Fetch free memory chunk block and see if it is big enough. - */ - if (node->Size >= size) { - size = node->Size; - } - node = node->Next; - } - - truesize = (long)size << 4; - truesize -= sizeof(MemChain_Type); - truesize = MAX(truesize, 0L); - return (truesize); -} - - -/*************************************************************************** - * Mem_Cleanup -- Performs a garbage collection on the memory cache. * - * * - * This routine is used to coalesce all adjacent free blocks of * - * memory in the specified cache. As a result, all previous pointers * - * provided by Mem_Find() are invalidated. This routine consumes a * - * fair amount of time and should be called as infrequently as * - * possible. * - * * - * INPUT: poolptr -- Pointer to the memory cache. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine takes a significant amount of time! * - * If there are locked block in memory, the pool may still * - * be fragmented. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 08/06/1993 JLB : Updated for low memory caches. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -void Mem_Cleanup(void *poolptr) -{ - MemPool_Type *pool; // Memory pool control structure. - MemChain_Type *free, // Pointer to first free area. - *cur; // Pointer to first used block that is after free. - unsigned long size; - unsigned long freesize;// Size of free heap at the end of the block. - - if (!poolptr) return; - - /* - ** Fetch working copy of pool control structure. - */ - pool = (MemPool_Type *) poolptr; - - /* - ** Basic parameter and condition legality checks. If the memory pool - ** has no free space, no free blocks, or no allocated blocks, then - ** memory cleanup is unnecessary -- just exit. - */ - if (!pool->FreeMem || !pool->FreeChain || !pool->UsedChain) return; - - freesize = pool->FreeMem; - free = pool->FreeChain; - pool->FreeChain = NULL; - cur = pool->UsedChain; - while (TRUE) { - - /* - ** Setup pointers so that free points to the first free block and cur - ** points to the next used block after the free block. - */ - while (cur < free && cur) { - cur = cur->Next; - } - - // All used blocks are at the front of the free. We are done. - if (!cur) { - break; - } - - /* - ** Do not allow a locked block to be moved. - */ - if (cur->Time == MEM_BLOCK_LOCKED) { - /* - ** Figure the size of the new free block that we are creating. - ** Subtract off the total block size. - ** Add the node to the free list. - */ - size = (char *) cur - (char *) free; - size >>= 4; - freesize -= size; - MemNode_Insert(pool, TRUE, free, (unsigned int) size, -1, FALSE); - - /* - ** Time to find a new free position to start working from. - ** Cur will be in the position just following. - */ - free = (MemChain_Type *) Add_Long_To_Pointer(cur, (unsigned long)cur->Size << 4); - cur = cur->Next; - while (free == cur) { - free = (MemChain_Type *) Add_Long_To_Pointer(cur, (unsigned long)cur->Size << 4); - cur = cur->Next; - } - - // All used blocks are at the front of the free. We are done. - if (!cur) { - break; - } - } else { - - // Copy the block up. - size = (unsigned long)cur->Size << 4; - Mem_Copy(cur, free, size); - cur = free; - - // Change pointers of surrounding blocks. - if (cur->Next) { - cur->Next->Prev = cur; - } - if (cur->Prev) { - cur->Prev->Next = cur; - } else { - pool->UsedChain = cur; - } - - // Change to next new free area. - free = (MemChain_Type *) Add_Long_To_Pointer(cur, size); - } - } - - /* - ** Now build the single free chunk. - */ - MemNode_Insert(pool, TRUE, free, freesize, -1, FALSE); -} - - -/*************************************************************************** - * MemNode_Unlink -- Unlinks a node from the cache. * - * * - * A private routine the actually unlinks a memory block from the * - * memory cache. It doesn't perform a complete update of the memory * - * cache. * - * * - * INPUT: pool -- Pointer to the memory cache header (copy in real * - * memory). * - * * - * freechain-- Is the block part of the free memory chain? * - * * - * node -- Pointer to the node that will be unlinked. * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine doesn't update memory totals. It is a support * - * function. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - * 04/13/1994 SKB : Update for 32 bit library, removed XMS calls, * - * optimized for low memory only. * - *=========================================================================*/ -PRIVATE void MemNode_Unlink(MemPool_Type *pool, int freechain, MemChain_Type *node) -{ - MemChain_Type *other; // Copy of node data to unlink. - MemChain_Type **chain; // A pointer to one of the chains pointer. - - /* - ** Check for parameter validity. - */ - if (!pool || !node) return; - - /* - ** Setup working pointer for the particular chain desired. - */ - if (freechain) { - chain = &pool->FreeChain; - } else { - chain = &pool->UsedChain; - } - - /* - ** Make adjustments to the previous node. If the pointer - ** to the previous node is NULL then this indicates the - ** first node in the list and thus the chain pointer needs - ** to be updated instead. - */ - if (node->Prev) { - other = node->Prev; - other->Next = node->Next; - } else { - *chain = node->Next; - } - - if (node->Next) { - other = node->Next; - other->Prev = node->Prev; - } -} - - -/*************************************************************************** - * MemNode_Insert -- Inserts a node into a cache chain. * - * * - * This routine is used to add a node to a cache chain. Since nodes * - * do not contain double links, they must be placed in sequence. * - * * - * INPUT: pool -- Pointer to memory pool (must be in real memory). * - * * - * freechain-- Is the node to be inserted into the free chain? * - * * - * node -- Pointer to the node to insert. * - * * - * size -- Size of the memory block (in paragraphs). * - * * - * id -- The ID number to associate with this block. * - * * - * merge -- Merge inserted block with adjacent blocks. * - * * - * OUTPUT: return * - * * - * WARNINGS: This is a support routine. * - * * - * HISTORY: * - * 08/06/1993 JLB : Created. * - *=========================================================================*/ -PRIVATE void MemNode_Insert(MemPool_Type *pool, int freechain, MemChain_Type *node, unsigned int size, unsigned long id, int merge) -{ - MemChain_Type **chain; // Pointer to chain that will be linked. - MemChain_Type *prev, // Successor node pointer. - *next; // Predecessor node pointer. - int doit=TRUE; // Link the node into the list. - - - /* - ** Determine if the parameters are valid. - */ - if (!pool || !node || !size) return; - - /* - ** Setup working pointer for the particular chain desired. - */ - if (freechain) { - chain = &pool->FreeChain; - } else { - chain = &pool->UsedChain; - } - - /* - ** Handle the "no node in list" condition (easiest). - */ - if (!*chain) { - node->Next = NULL; - node->Prev = NULL; - node->Size = size; - node->Time = (unsigned short)(TickCount.Time() >> 4); - node->ID = id; - *chain = node; - return; - } - - /* - ** Sweep through the memory chain looking for a likely spot - ** to insert the new node. It will stop with "next" pointing - ** to the node to come after the block to be inserted and "prev" - ** will point to the node right before. - */ - prev = NULL; - next = *chain; - while (next && (next < node)) { - - /* - ** Move up the memory chain. - */ - prev = next; - next = next->Next; - } - - /* - ** Coallescing of adjacent blocks (if requested). - */ - if (merge) { - - /* - ** If the previous block is touching the block to insert - ** then merely adjust the size of the previous block and - ** that is all that is necessary. - */ - if (prev) { - if (((char *)prev + ((long)prev->Size << 4)) == ((char *) node)) { - prev->Size += size; - size = prev->Size; - node = prev; - prev = prev->Prev; - doit = FALSE; - } - } - - /* - ** If the following block is touching the block to insert - ** then remove the following block and increase the size of - ** the original insertion block by the size of the other - ** block. - */ - if (next) { - if (((char *)node + ((long)size << 4)) == (char *)next) { - - if (!doit) { - - /* - ** If the node was already merged with the previous block - ** then merely increase the previous block's size - ** and adjust it's next pointer appropriately. - */ - node->Size += next->Size; - node->Next = next->Next; - next = next->Next; - } else { - - /* - ** Increase the size of the current block and adjust - ** the "next" pointer so that it gets fixed up - ** accordingly. - */ - size += next->Size; - next = next->Next; - } - } - } - } - -#if DEBUG_FILL - if (doit) { - memset(node + 1, 0xFF, (size - 1) << 4); - } else { - memset(node + 1, 0xFF, (node->Size - 1) << 4); - } -#endif - - /* - ** Fixup the node pointers. - */ - if (prev) { - prev->Next = node; - }else{ - *chain = node; - } - - if (next) { - next->Prev = node; - } - - if (doit) { - node->Prev = prev; - node->Next = next; - node->Size = size; - node->Time = (unsigned short)(TickCount.Time() >> 4); - node->ID = id; - } -} - - - - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/MEMFLAG.H b/code/TIBERIANDAWN/WIN32LIB/MEMFLAG.H deleted file mode 100644 index ce47d10..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MEMFLAG.H +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Memory System * - * * - * File Name : MEMFLAG.H * - * * - * Programmer : Jeff Wilson * - * * - * Start Date : April 4, 1994 * - * * - * Last Update : September 8, 1994 [IML] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef MEMFLAG_H -#define MEMFLAG_H -// Memory Flags -/* -** Memory allocation flags. These are the flags that are passed into Alloc -** in order to control the type of memory allocated. -*/ -typedef enum { - MEM_NORMAL = 0x0000, // Default memory (normal). - MEM_NEW = 0x0001, // Called by the operator new and was overloaded. - MEM_CLEAR = 0x0002, // Clear memory before returning. - MEM_REAL = 0x0004, // Clear memory before returning. - MEM_TEMP = 0x0008, // Clear memory before returning. - MEM_LOCK = 0x0010, // Lock the memory that we allocated -} MemoryFlagType; - - -/* -** Prototypes for VMPAGEIN.ASM -*/ -extern "C"{ - void __cdecl Force_VM_Page_In (void *buffer, int length); -} - -/*=========================================================================*/ -/* The following prototypes are for the file: ALLOC.CPP */ -/*=========================================================================*/ - -void * operator new(size_t size, MemoryFlagType flag); -void * operator new[] (size_t size, MemoryFlagType flag); -void *Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags); -void Free(void const *pointer); -void DPMI_Lock(VOID const *ptr, long const size); -void DPMI_Unlock(void const *ptr, long const size); -void *Resize_Alloc(void *original_ptr, unsigned long new_size_in_bytes); -long Ram_Free(MemoryFlagType flag); -long Heap_Size(MemoryFlagType flag); -long Total_Ram_Free(MemoryFlagType flag); - -//PG_TO_FIX -//#pragma option -Jgd - -inline void * operator new(size_t size, MemoryFlagType flag) -{ - return(Alloc(size, flag)); -} -inline void * operator new[] (size_t size, MemoryFlagType flag) -{ - return(Alloc(size, flag)); -} - -//#pragma option -Jgd - -/*=========================================================================*/ -/* The following prototypes are for the file: MEM_COPY.ASM */ -/*=========================================================================*/ - -extern "C" { - void __cdecl Mem_Copy(void const *source, void *dest, unsigned long bytes_to_copy); -} - - -inline void *Add_Long_To_Pointer(void const *ptr, long size) -{ - return ((void *) ( (char const *) ptr + size)); -} - -extern void (*Memory_Error)(void); -extern void (*Memory_Error_Exit)(char *string); - -extern unsigned long MinRam; // Record of least memory at worst case. -extern unsigned long MaxRam; // Record of total allocated at worst case. - - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/MISC.H b/code/TIBERIANDAWN/WIN32LIB/MISC.H deleted file mode 100644 index 9c3a0a4..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MISC.H +++ /dev/null @@ -1,268 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : 32 bit library * - * * - * File Name : MISC.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MISC_H -#define MISC_H - -#define WIN32_LEAN_AND_MEAN // eliminates unecessary definitions in windows.h -#ifndef _WIN32 // Denzil 6/2/98 Watcom 11.0 complains without this check -#define _WIN32 -#endif // _WIN32 -#include -#include -#include - -extern LPDIRECTDRAWSURFACE PaletteSurface; - -/*========================= C++ Routines ==================================*/ - - -/*=========================================================================*/ -/* The following prototypes are for the file: DDRAW.CPP */ -/*=========================================================================*/ -void Process_DD_Result(HRESULT result, int display_ok_msg); -BOOL Set_Video_Mode(HWND hwnd, int w, int h, int bits_per_pixel); -void Reset_Video_Mode(void); -unsigned Get_Free_Video_Memory(void); -void Wait_Blit(void); -unsigned Get_Video_Hardware_Capabilities(void); - -extern "C" void Wait_Vert_Blank(void); -extern "C" void Set_DD_Palette (void *palette); - -/* -** Pointer to function to call if we detect a focus loss -*/ -extern void (*Misc_Focus_Loss_Function)(void); -/* -** Pointer to function to call if we detect a surface restore -*/ -extern void (*Misc_Focus_Restore_Function)(void); - - -/* - * Flags returned by Get_Video_Hardware_Capabilities - */ -/* Hardware blits supported? */ -#define VIDEO_BLITTER 1 - -/* Hardware blits asyncronous? */ -#define VIDEO_BLITTER_ASYNC 2 - -/* Can palette changes be synced to vertical refresh? */ -#define VIDEO_SYNC_PALETTE 4 - -/* Is the video cards memory bank switched? */ -#define VIDEO_BANK_SWITCHED 8 - -/* Can the blitter do filled rectangles? */ -#define VIDEO_COLOR_FILL 16 - -/* Is there no hardware assistance avaailable at all? */ -#define VIDEO_NO_HARDWARE_ASSIST 32 - - - -/* - * Definition of surface monitor class - * - * This class keeps track of all the graphic buffers we generate in video memory so they - * can be restored after a focus switch. -*/ - -#define MAX_SURFACES 20 - -class SurfaceMonitorClass { - - public: - - SurfaceMonitorClass(); - - void Add_DD_Surface (LPDIRECTDRAWSURFACE); - void Remove_DD_Surface (LPDIRECTDRAWSURFACE); - BOOL Got_Surface_Already (LPDIRECTDRAWSURFACE); - void Restore_Surfaces (void); - void Set_Surface_Focus ( BOOL in_focus ); - void Release(void); - - BOOL SurfacesRestored; - - private: - - LPDIRECTDRAWSURFACE Surface[MAX_SURFACES]; - BOOL InFocus; - -}; - -extern SurfaceMonitorClass AllSurfaces; //List of all direct draw surfaces - - -/*=========================================================================*/ -/* The following variables are declared in: DDRAW.CPP */ -/*=========================================================================*/ -extern LPDIRECTDRAW DirectDrawObject; -extern LPDIRECTDRAW2 DirectDraw2Interface; -extern HWND MainWindow; -extern BOOL SystemToVideoBlits; -extern BOOL VideoToSystemBlits; -extern BOOL SystemToSystemBlits; -extern BOOL OverlappedVideoBlits; // Can video driver blit overlapped regions? - -/*=========================================================================*/ -/* The following prototypes are for the file: EXIT.CPP */ -/* Prog_End Must be supplied by the user program in startup.cpp */ -/*=========================================================================*/ -VOID __cdecl Prog_End(const char *why = NULL, bool fatal = false); // Added why and fatal parameters. ST - 6/27/2019 10:10PM -VOID __cdecl Exit(INT errorval, const BYTE *message, ...); - -/*=========================================================================*/ -/* The following prototypes are for the file: DELAY.CPP */ -/*=========================================================================*/ -void Delay(int duration); -void Vsync(void); - - -/*=========================================================================*/ -/* The following prototypes are for the file: FINDARGV.CPP */ -/*=========================================================================*/ - -BYTE __cdecl Find_Argv(BYTE const *str); - -/*=========================================================================*/ -/* The following prototypes are for the file: LIB.CPP */ -/*=========================================================================*/ -char *Find_Argv(char const *str); -void Mono_Mem_Dump(void const *databuf, int bytes, int y); -void Convert_RGB_To_HSV(unsigned int r, unsigned int g, unsigned int b, unsigned int *h, unsigned int *s, unsigned int *v); -void Convert_HSV_To_RGB(unsigned int h, unsigned int s, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b); - - -/*=========================================================================*/ -/* The following prototypes are for the file: VERSION.CPP */ -/*=========================================================================*/ - -BYTE __cdecl Version(VOID); - - -/*=========================================================================*/ -/* The following prototypes are for the file: IRANDOM.CPP */ -/*=========================================================================*/ -int IRandom(int minval, int maxval); - - -/*========================= Assembly Routines ==============================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/*=========================================================================*/ -/* The following prototypes are for the file: RANDOM.ASM */ -/*=========================================================================*/ - -unsigned char __cdecl Random(void); -int __cdecl Get_Random_Mask(int maxval); - -/*=========================================================================*/ -/* The following prototype is for the file: SHAKESCR.ASM */ -/*=========================================================================*/ - -void __cdecl Shake_Screen(int shakes); - -/*=========================================================================*/ -/* The following prototypes are for the file: REVERSE.ASM */ -/*=========================================================================*/ - -long __cdecl Reverse_Long(long number); -short __cdecl Reverse_Short(short number); -long __cdecl Swap_Long(long number); -#if (0) -/*=========================================================================*/ -/* The following prototype is for the file: FACING8.ASM */ -/*=========================================================================*/ - -int __cdecl Desired_Facing8(int x1, int y1, int x2, int y2); - -/*=========================================================================*/ -/* The following prototype is for the file: FACING16.ASM */ -/*=========================================================================*/ - -int __cdecl Desired_Facing16(int x1, int y1, int x2, int y2); - -/*=========================================================================*/ -/* The following prototype is for the file: FACINGFF.ASM */ -/*=========================================================================*/ - -int __cdecl Desired_Facing256(int x1, int y1, int x2, int y2); - -/*=========================================================================*/ -/* The following prototype is for the file: FADING.ASM */ -/*=========================================================================*/ -#endif - -void * __cdecl Build_Fading_Table(void const *palette, void const *dest, long int color, long int frac); -/*=========================================================================*/ -/* The following prototype is for the file: CRC.ASM */ -/*=========================================================================*/ - -long __cdecl Calculate_CRC(void *buffer, long length); - -/*=========================================================================*/ -/* The following prototypes are for the file: DETPROC.ASM */ -/*=========================================================================*/ - -extern WORD __cdecl Processor(void); -extern WORD __cdecl Operating_System(void); -extern unsigned long random ( unsigned long mod ) ; -//extern void randomize ( void ) ; - -extern int __cdecl Clip_Rect ( int * x , int * y , int * dw , int * dh , - int width , int height ) ; -extern int __cdecl Confine_Rect ( int * x , int * y , int dw , int dh , - int width , int height ) ; - - - -/*=========================================================================*/ -/* The following prototypes are for the file: OPSYS.ASM */ -/*=========================================================================*/ - -extern WORD OperationgSystem; - -#ifdef __cplusplus -} -#endif - -/*=========================================================================*/ - -#endif // MISC_H diff --git a/code/TIBERIANDAWN/WIN32LIB/MODEMREG.H b/code/TIBERIANDAWN/WIN32LIB/MODEMREG.H deleted file mode 100644 index 4e3b81a..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MODEMREG.H +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -#ifndef WIN32 -#define WIN32 -#ifndef _WIN32 // Denzil 6/2/98 Watcom 11.0 complains without this check -#define _WIN32 -#endif // _WIN32 -#endif //WIN32 -#include - - - -class ModemRegistryEntryClass { - - public: - - ModemRegistryEntryClass (int modem_number); - ~ModemRegistryEntryClass (void); - - - char *Get_Modem_Name (void) { return (ModemName); } - - char *Get_Modem_Device_Name (void) { return (ModemDeviceName); } - - char *Get_Modem_Error_Correction_Enable (void) { return (ErrorCorrectionEnable); } - - char *Get_Modem_Error_Correction_Disable (void) { return (ErrorCorrectionDisable); } - - char *Get_Modem_Compression_Enable (void) { return (CompressionEnable); } - - char *Get_Modem_Compression_Disable (void) { return (CompressionDisable); } - - char *Get_Modem_Hardware_Flow_Control (void) { return (HardwareFlowControl); } - - char *Get_Modem_No_Flow_Control (void) { return (HardwareFlowControl); } - - private: - - char *ModemName; - char *ModemDeviceName; - char *ErrorCorrectionEnable; - char *ErrorCorrectionDisable; - char *CompressionEnable; - char *CompressionDisable; - char *HardwareFlowControl; - char *NoFlowControl; - -}; - - - - - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/MONO.H b/code/TIBERIANDAWN/WIN32LIB/MONO.H deleted file mode 100644 index 5b0cf89..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MONO.H +++ /dev/null @@ -1,181 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\monoc.h_v 2.16 06 Sep 1995 16:29:02 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : MONO.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 2, 1994 * - * * - * Last Update : July 2, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef MONOC_H -#define MONOC_H - - -class MonoClass { - /* - ** This is a private structure that is used to control which characters - ** are used when a box is drawn. Line drawing on the monochrome screen is - ** really made up of characters. This specifies which characters to use. - */ - typedef struct { - unsigned char UpperLeft; - unsigned char TopEdge; - unsigned char UpperRight; - unsigned char RightEdge; - unsigned char BottomRight; - unsigned char BottomEdge; - unsigned char BottomLeft; - unsigned char LeftEdge; - } BoxDataType; - - /* - ** Each cell is constructed of the actual character that is displayed and the - ** attribute to use. This character pair is located at every position on the - ** display (80 x 25). Since this cell pair can be represented by a "short" - ** integer, certain speed optimizations are taken in the monochrome drawing - ** code. - */ - typedef struct { - char Character; // Character to display. - char Attribute; // Attribute. - } CellType; - - /* - ** These private constants are used in the various monochrome operations. - */ - enum MonoClassPortEnums { - CONTROL_PORT=0x03B4, // CRTC control register. - DATA_PORT=0x03B5, // CRTC data register. - COLUMNS=80, // Number of columns. - LINES=25, // Number of lines. - SIZE_OF_PAGE=LINES*COLUMNS*sizeof(CellType), // Entire page size. - DEFAULT_ATTRIBUTE=0x02 // Normal white on black color attribute. - }; - - public: - enum MonoClassPageEnums { - MAX_MONO_PAGES=16, // Maximum RAM pages on mono card. - SEGMENT=0xB000 // Monochrome screen segment. - }; - - /* - ** These are the various box styles that may be used. - */ - typedef enum BoxStyleType { - SINGLE, // Single thickness. - DOUBLE_HORZ, // Double thick on the horizontal axis. - DOUBLE_VERT, // Double thick on the vertical axis. - DOUBLE, // Double thickness. - - COUNT - } BoxStyleType; - - MonoClass(void); - ~MonoClass(void); - - static void Enable(void) {Enabled = 1;}; - static void Disable(void) {Enabled = 0;}; - static int Is_Enabled(void) {return Enabled;}; - static MonoClass * Get_Current(void) {return PageUsage[0];}; - - void Draw_Box(int x, int y, int w, int h, char attrib=DEFAULT_ATTRIBUTE, BoxStyleType thick=SINGLE); - void Set_Default_Attribute(char attrib) {Attrib = attrib;}; - void Clear(void); - void Set_Cursor(int x, int y); - void Print(char const *text); - void Print(int text); - void Printf(char const *text, ...); - void Printf(int text, ...); - void Text_Print(char const *text, int x, int y, char attrib=DEFAULT_ATTRIBUTE); - void Text_Print(int text, int x, int y, char attrib=DEFAULT_ATTRIBUTE); - void View(void); - int Get_X(void) const {return X;}; - int Get_Y(void) const {return Y;}; - - /* - ** Handles deep copies for the mono class objects. This performs what is essentially - ** a screen copy. - */ - MonoClass & operator = (MonoClass const & ); - - /* - ** This merely makes a duplicate of the mono object into a newly created mono - ** object. - */ - MonoClass (MonoClass const &); - - private: - char X; // Cursor X position. - char Y; // Cursor Y position. - char Attrib; // Normal attribute to use if none specified. - char Page; // The current page to write to. - - /* - ** Helper functions to help with display operations. - */ - int Offset(int x=0, int y=0) const {return (SIZE_OF_PAGE*Page) + sizeof(CellType)*(x + (y*COLUMNS));}; - void Scroll(int lines); - void Store_Cell(CellType &cell, int x, int y) { - *(CellType *)((long)MonoSegment + Offset(x, y)) = cell; - }; - - /* - ** This is the segment/selector of the monochrome screen. - */ - static void * MonoSegment; - - /* - ** This the the arrays of characters used for drawing boxes. - */ - static BoxDataType const CharData[4]; - - /* - ** This array contains pointers to the monochrome objects that are assigned - ** to each of the monochrome pages. As the monochrome pages are made visible, - ** they can be shuffled around between the actual locations. The first entry - ** in this table is the one that is visible. - */ - static MonoClass * PageUsage[MAX_MONO_PAGES]; - - /* - ** If this is true, then monochrome output is allowed. It defaults to false - ** so that monochrome output must be explicitly enabled. - */ - static int Enabled; -}; - -void Mono_Set_Cursor(int x, int y); -int Mono_Printf(char const *string, ...); -void Mono_Clear_Screen(void); -void Mono_Text_Print(void const *text, int x, int y, int attrib); -void Mono_Draw_Rect(int x, int y, int w, int h, int attrib, int thick); -void Mono_Print(void const *text); -int Mono_X(void); -int Mono_Y(void); - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/MORPHPAL.CPP b/code/TIBERIANDAWN/WIN32LIB/MORPHPAL.CPP deleted file mode 100644 index e140d32..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MORPHPAL.CPP +++ /dev/null @@ -1,173 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : wwlib32 * - * * - * File Name : PALTOPAL.CPP * - * * - * Programmer : Bill Randolph * - * * - * Start Date : May 2, 1994 * - * * - * Last Update : May 2, 1994 [BR] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Morph_Palette -- morphs a palette from source to destination * - * Palette_To_Palette -- morph src palette to a dst palette * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* -********************************* Includes ********************************** -*/ -#include "wwstd.h" -#include "palette.h" -#include "timer.h" - -/* -********************************* Constants ********************************* -*/ -#define SCALE(a,b,c) (((((long)(a)<<8) / (long)(b) ) * (unsigned long)(c)) >>8) - - -/* -********************************** Globals ********************************** -*/ - -/* -******************************** Prototypes ********************************* -*/ - -PRIVATE int __cdecl Palette_To_Palette(void *src_palette, void *dst_palette, unsigned long current_time, unsigned long delay); - - -/*************************************************************************** - * Morph_Palette -- morphs a palette from source to destination * - * * - * INPUT: * - * void *src_pal - starting palette * - * void *dst_pal - ending palette * - * unsigned int delay - time delay in 60ths of a second * - * void *callback - user-defined callback, NULL if none * - * * - * OUTPUT: * - * none. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/02/1994 BR : Created. * - *=========================================================================*/ -void cdecl Morph_Palette (void *src_pal, void *dst_pal, unsigned int delay, - void (*callback) (void) ) -{ - int result; - unsigned long pal_start = TickCount.Time(); - extern void (*cb_ptr) ( void ) ; // callback function pointer - -// (void *)cb_ptr = callback; - cb_ptr = callback ; - - /*===================================================================*/ - /* Make sure that we don't go too fast but also make sure we keep */ - /* processing the morph palette if we have one. */ - /*===================================================================*/ - while (1) { - if (src_pal && dst_pal) { - result = Palette_To_Palette (src_pal, dst_pal, - (TickCount.Time() - pal_start), (unsigned long)delay); - if (!result) - break; - - if (callback) { - (*cb_ptr)(); - } - } - } - - return; - -} /* end of Morph_Palette */ - - -/*************************************************************************** - * Palette_To_Palette -- morph src palette to a dst palette * - * * - * Creates & sets a palette that's in-between 'src_palette' & * - * 'dst_palette'; how close it is to dst_palette is based on how close * - * 'current_time' is to 'delay'. 'current_time' & 'delay' are based on * - * 0 being the start time. * - * * - * INPUT: void *src_palette = palette we want to morph from * - * void *dst_palette = palette we want to morph to * - * long current_time = time we started morph pal * - * long delay = time we want the morph to take* - * * - * OUTPUT: int if the time had elapsed and no chages were * - * necessary this routine returns FALSE * - * otherwise it will always return TRUE (this * - * was necessary to detect the end of the ice * - * effect. * - * * - * HISTORY: * - * 05/24/1993 MC : Created. * - *=========================================================================*/ -PRIVATE int cdecl Palette_To_Palette(void *src_palette, void *dst_palette, - unsigned long current_time, unsigned long delay) -{ - char colour; - char diff; - int chgval; - int lp; - int change; - static char palette[768]; - char *src_pal = (char*)src_palette; - char *dst_pal = (char*)dst_palette; - - /*======================================================================*/ - /* Loop through each RGB value attempting to change it to the correct */ - /* color. */ - /*======================================================================*/ - for (change = lp = 0; lp < 768; lp++) { - if (current_time < delay ) { - diff = dst_pal[lp] & (char)63; - diff -= src_pal[lp] & (char)63; - if (diff) - change = TRUE; - chgval = SCALE(diff, delay, current_time); - colour = src_pal[lp] & (char)63; - colour +=(char)chgval; - } - else { - colour = dst_pal[lp] & (char)63; - change = FALSE; - } - palette[lp] = colour; - } - /*======================================================================*/ - /* Set the palette to the color that we created. */ - /*======================================================================*/ - Set_Palette(palette); - return(change); - -} /* end of Palette_To_Palette */ - - -/*************************** End of morphpal.cpp ***************************/ - - diff --git a/code/TIBERIANDAWN/WIN32LIB/MOUSE.H b/code/TIBERIANDAWN/WIN32LIB/MOUSE.H deleted file mode 100644 index b40d07e..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MOUSE.H +++ /dev/null @@ -1,123 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - * * - * Project Name : Westwood 32 Bit Library * - * * - * File Name : MOUSE.H * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 12/12/95 * - * * - * Last Update : December 12, 1995 [PWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WW_MOUSE_H -#define WW_MOUSE_H - -#include - -class WWMouseClass { - public: - WWMouseClass(GraphicViewPortClass *scr, int mouse_max_width, int mouse_max_height); - ~WWMouseClass(); - void *Set_Cursor(int xhotspot, int yhotspot, void *cursor); - void Process_Mouse(void); - void Hide_Mouse(void); - void Show_Mouse(void); - void Conditional_Hide_Mouse(int x1, int y1, int x2, int y2); - void Conditional_Show_Mouse(void); - int Get_Mouse_State(void); - int Get_Mouse_X(void); - int Get_Mouse_Y(void); - void Get_Mouse_XY(int &x, int &y); - // - // The following two routines can be used to render the mouse onto a graphicbuffer - // other than the hidpage. - // - void Draw_Mouse(GraphicViewPortClass *scr); - void Erase_Mouse(GraphicViewPortClass *scr, int forced = FALSE); - - void Block_Mouse(GraphicBufferClass *buffer); - void Unblock_Mouse(GraphicBufferClass *buffer); - void Set_Cursor_Clip(void); - void Clear_Cursor_Clip(void); - - private: - enum { - CONDHIDE = 1, - CONDHIDDEN = 2, - }; - void Low_Hide_Mouse(void); - void Low_Show_Mouse(int x, int y); - - char *MouseCursor; // pointer to the mouse cursor in memory - int MouseXHot; // X hot spot of the current mouse cursor - int MouseYHot; // Y hot spot of the current mouse cursor - int CursorWidth; // width of the mouse cursor in pixels - int CursorHeight; // height of the mouse cursor in pixels - - char *MouseBuffer; // pointer to background buffer in memory - int MouseBuffX; // pixel x mouse buffer was preserved at - int MouseBuffY; // pixel y mouse buffer was preserved at - int MaxWidth; // maximum width of mouse background buffer - int MaxHeight; // maximum height of mouse background buffer - - int MouseCXLeft; // left x pos if conditional hide mouse in effect - int MouseCYUpper; // upper y pos if conditional hide mouse in effect - int MouseCXRight; // right x pos if conditional hide mouse in effect - int MouseCYLower; // lower y pos if conditional hide mouse in effect - char MCFlags; // conditional hide mouse flags - char MCCount; // nesting count for conditional hide mouse - - GraphicViewPortClass *Screen; // pointer to the surface mouse was init'd with - char * PrevCursor; // pointer to previous cursor shape - int MouseUpdate; - int State; - - char *EraseBuffer; // Buffer which holds background to restore to hidden page - int EraseBuffX; // X position of the hidden page background - int EraseBuffY; // Y position of the hidden page background - int EraseBuffHotX; // X position of the hidden page background - int EraseBuffHotY; // Y position of the hidden page background - - int EraseFlags; // Records whether mutex has been released - - CRITICAL_SECTION MouseCriticalSection; // Control for mouse re-enterancy - unsigned TimerHandle; - -}; - -extern "C" { - void __cdecl Mouse_Shadow_Buffer(void *thisptr, GraphicViewPortClass *srcdst, void *buffer, int x, int y, int hotx, int hoty, int store); - void __cdecl Draw_Mouse(void *thisptr, GraphicViewPortClass *srcdst, int x, int y); - void * __cdecl ASM_Set_Mouse_Cursor(void * thisptr, int hotspotx, int hotspoty, VOID *cursor); -}; - -void Hide_Mouse(void); -void Show_Mouse(void); -void Conditional_Hide_Mouse(int x1, int y1, int x2, int y2); -void Conditional_Show_Mouse(void); -int Get_Mouse_State(void); -void *Set_Mouse_Cursor(int hotx, int hoty, void *cursor); -int Get_Mouse_X(void); -int Get_Mouse_Y(void); - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/MOUSE.INC b/code/TIBERIANDAWN/WIN32LIB/MOUSE.INC deleted file mode 100644 index c8031cb..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MOUSE.INC +++ /dev/null @@ -1,64 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*********************************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : MOUSE.INC * -;* * -;* Programmer : Philip W. Gorrow * -;* * -;* Start Date : 12/12/95 * -;* * -;* Last Update : December 12, 1995 [PWG] * -;* * -;*---------------------------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -STRUC MouseType -MouseCursor DD ? ; pointer to the mouse cursor in memory -MouseXHot DD ? ; X hot spot of the current mouse cursor -MouseYHot DD ? ; Y hot spot of the current mouse cursor -CursorWidth DD ? ; Width of mouse cursor in pixels -CursorHeight DD ? ; Height of the mouse cursor in pixels - -MouseBuffer DD ? ; pointer to background buffer in memory -MouseBuffX DD ? ; pixel x mouse buffer was preserved at -MouseBuffY DD ? ; pixel y mouse buffer was preserved at -MaxWidth DD ? ; Maximum possible width of the background buffer -MaxHeight DD ? ; Maximum possible height of the background buffer - -MouseCXLeft DD ? ; left hand x position if conditional hide mouse in effect -MouseCYUpper DD ? ; upper y position if conditional hide mouse in effect -MouseCXRight DD ? ; right hand x position if conditional hide mouse in effect -MouseCYLower DD ? ; lower y position if conditional hide mouse in effect -MCFlags DB ? ; conditional hide mouse flags -MCCount DB ? ; nesting count for conditional hide mouse - -Screen DD ? ; pointer to the surface mouse was init'd with -PrevCursor DD ? ; pointer to the prev cursor shape -MouseUpdate DD ? ; is the mouse being currently updated -State DD ? - -EraseBuffer DD ? -EraseBuffX DD ? -EraseBuffY DD ? -EraseBuffHotX DD ? -EraseBuffHotY DD ? -EraseFlags DD ? -ENDS diff --git a/code/TIBERIANDAWN/WIN32LIB/MOUSEWW.CPP b/code/TIBERIANDAWN/WIN32LIB/MOUSEWW.CPP deleted file mode 100644 index bdb952b..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/MOUSEWW.CPP +++ /dev/null @@ -1,720 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*********************************************************************************************** - * * - * Project Name : Westwood 32 bit Library * - * * - * File Name : MOUSE.CPP * - * * - * Programmer : Philip W. Gorrow * - * * - * Start Date : 12/12/95 * - * * - * Last Update : December 12, 1995 [PWG] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * WWMouseClass::WWMouseClass -- Constructor for the Mouse Class * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "mouse.h" -#include - -static WWMouseClass *_Mouse=NULL; -void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 ); -extern bool GameInFocus; - - -/*********************************************************************************************** - * MOUSECLASS::MOUSECLASS -- Constructor for the Mouse Class * - * * - * INPUT: GraphicViewPortClass * screen - pointer to screen mouse is created for * - * * - * OUTPUT: none * - * * - * HISTORY: * - * 12/12/1995 PWG : Created. * - *=============================================================================================*/ -WWMouseClass::WWMouseClass(GraphicViewPortClass *scr, int mouse_max_width, int mouse_max_height) -{ - MouseCursor = new char[mouse_max_width * mouse_max_height]; - MouseXHot = 0; - MouseYHot = 0; - CursorWidth = 0; - CursorHeight = 0; - - MouseBuffer = new char[mouse_max_width * mouse_max_height]; - MouseBuffX = -1; - MouseBuffY = -1; - MaxWidth = mouse_max_width; - MaxHeight = mouse_max_height; - - MouseCXLeft = 0; - MouseCYUpper = 0; - MouseCXRight = 0; - MouseCYLower = 0; - MCFlags = 0; - MCCount = 0; - - Screen = scr; - PrevCursor = NULL; - MouseUpdate = 0; - State = 1; - timeBeginPeriod ( 1000/ 60); - - InitializeCriticalSection (&MouseCriticalSection); - // - // Install the timer callback event handler - // - - EraseBuffer = new char[mouse_max_width * mouse_max_height]; - EraseBuffX = -1; - EraseBuffY = -1; - EraseBuffHotX = -1; - EraseBuffHotY = -1; - EraseFlags = FALSE; - - _Mouse = this; - - // Add TIME_KILL_SYNCHRONOUS flag. ST - 2/13/2019 5:07PM - //TimerHandle = timeSetEvent( 1000/60 , 1 , ::Process_Mouse, 0 , TIME_PERIODIC); - //TimerHandle = timeSetEvent( 1000/60 , 1 , ::Process_Mouse, 0 , TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); // Removed. ST - 2/13/2019 5:12PM - - /* - ** Force the windows mouse pointer to stay withing the graphic view port region - */ - Set_Cursor_Clip(); -} - -WWMouseClass::~WWMouseClass() -{ - MouseUpdate++; - - if (MouseCursor) delete[] MouseCursor; - if (MouseBuffer) delete[] MouseBuffer; - if (TimerHandle) { - timeKillEvent(TimerHandle); - TimerHandle = 0; //ST - 2/13/2019 5:12PM - } - timeEndPeriod (1000/60); - DeleteCriticalSection(&MouseCriticalSection); - - /* - ** Free up the windows mouse pointer movement - */ - Clear_Cursor_Clip(); -} - - -void Block_Mouse(GraphicBufferClass *buffer) -{ - if (_Mouse){ - _Mouse->Block_Mouse(buffer); - } -} - - -void Unblock_Mouse(GraphicBufferClass *buffer) -{ - if (_Mouse){ - _Mouse->Unblock_Mouse(buffer); - } -} - - - -void WWMouseClass::Block_Mouse(GraphicBufferClass *buffer) -{ - if (buffer == Screen->Get_Graphic_Buffer()){ - EnterCriticalSection(&MouseCriticalSection); - } -} - - -void WWMouseClass::Unblock_Mouse(GraphicBufferClass *buffer) -{ - if (buffer == Screen->Get_Graphic_Buffer()){ - LeaveCriticalSection(&MouseCriticalSection); - } -} - - - - - -void WWMouseClass::Set_Cursor_Clip(void) -{ -#if (0) // Not needed. ST - 1/3/2019 2:18PM - if (Screen){ - RECT region; - - region.left = 0; - region.top = 0; - region.right = Screen->Get_Width(); - region.bottom = Screen->Get_Height(); - - ClipCursor(®ion); - } -#endif -} - - - -void WWMouseClass::Clear_Cursor_Clip(void) -{ -#if (0) - ClipCursor(NULL); -#endif -} - - - -void WWMouseClass::Process_Mouse(void) -{ -//ST - 1/3/2019 10:50AM - return; -#if (0) - POINT pt; // define a structure to hold current cursor pos - - // - // If the mouse is currently hidden or it has not been installed, then we - // have no need to redraw the mouse. - // - if (!Screen || !_Mouse || State > 0 || MouseUpdate || EraseFlags || !GameInFocus) - return; - - // - // Make sure there are no conflicts with other - // threads that may try and lock the screen buffer - // - //Block_Mouse(Screen->Get_Graphic_Buffer()); - - // - // If the screen is already locked by another thread then just exit - // - if (Screen->Get_LockCount()!=0){ - //Unblock_Mouse(Screen->Get_Graphic_Buffer()); - return; - } - - // - // Get the mouse's current real cursor position - // - GetCursorPos(&pt); // get the current cursor position - // - // If the mouse has moved then we are responsible to redraw the mouse - // - if (pt.x != MouseBuffX || pt.y != MouseBuffY) { - // - // If we can't lock the surface we need to draw to, we cannot update - // the mouse. - // - if (Screen->Lock()) { - // - // Erase the old mouse by dumping the mouses shadow buff - // to the screen (if its position had ever been recorded). - // - Low_Hide_Mouse(); - - // - // Verify that the mouse has not gone into a conditional hiden area - // If it has, mark it as being in one. - // - if (MCFlags & CONDHIDE && pt.x >= MouseCXLeft && pt.x <= MouseCXRight && pt.y >= MouseCYUpper && pt.y <= MouseCYLower) { - MCFlags |= CONDHIDDEN; - } - - // - // Show the mouse if we are allowed to. - // - if (!(MCFlags & CONDHIDDEN)) { - Low_Show_Mouse(pt.x, pt.y); - } - // - // Finally unlock the destination surface as we have sucessfully - // updated the mouse. - // - Screen->Unlock(); - } - } - - // - // Allow other threads to lock the screen again - // - //Unblock_Mouse(Screen->Get_Graphic_Buffer()); -#endif -} - -void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor) -{ -//ST - 1/3/2019 10:50AM - xhotspot; - yhotspot; - cursor; - return cursor; - -#if (0) - - // - // If the pointer to the cursor we got is invalid, or its the same as the - // currently set cursor then just return. - if (!cursor || cursor == PrevCursor) - return(cursor); - - // - // Wait until we have exclusive access to our data - // - MouseUpdate++; - // - // Since we are updating the mouse we need to hide the cursor so we - // do not get some sort of weird transformation. - // - Hide_Mouse(); - // - // Now convert the shape to a mouse cursor with the given hotspots and - // set it as our current mouse. - // - void *retval = ASM_Set_Mouse_Cursor(this, xhotspot, yhotspot, cursor); - // - // Show the mouse which will force it to appear with the new shape we - // have assigned. - // - Show_Mouse(); - // - // We are done updating the mouse cursor so on to bigger and better things. - // - MouseUpdate--; - // - // Return the previous mouse cursor which as conveniantly passed back by - // Asm_Set_Mouse_Cursor. - // - return(retval); -#endif -} - -void WWMouseClass::Low_Hide_Mouse() -{ -//ST - 1/3/2019 10:50AM -#if (0) - if (!State) { - if (MouseBuffX != -1 || MouseBuffY != -1) { - if (Screen->Lock()){ - Mouse_Shadow_Buffer(this, Screen, MouseBuffer, MouseBuffX, MouseBuffY, MouseXHot, MouseYHot, 0); - Screen->Unlock(); - } - } - MouseBuffX = -1; - MouseBuffY = -1; - } -#endif - State++; -} -void WWMouseClass::Hide_Mouse() -{ - MouseUpdate++; - Low_Hide_Mouse(); - MouseUpdate--; -} - - -void WWMouseClass::Low_Show_Mouse(int x, int y) -{ - // - // If the mouse is already visible then just ignore the problem. - // - if (State == 0) return; - // - // Make the mouse a little bit more visible - // - State--; - -//ST - 1/3/2019 10:50AM -#if (0) - - // - // If the mouse is completely visible then draw it at its current - // position. - // - if (!State) { - // - // Try to lock the screen til we sucessfully get a lock. - // - if (Screen->Lock()){ - // - // Save off the area behind the mouse. - // - Mouse_Shadow_Buffer(this, Screen, MouseBuffer, x, y, MouseXHot, MouseYHot, 1); - // - // Draw the mouse in its new location - // - ::Draw_Mouse(this, Screen, x, y); - // - // Save off the positions that we saved the buffer from - // - MouseBuffX = x; - MouseBuffY = y; - // - // Unlock the screen and lets get moving. - // - Screen->Unlock(); - } - } -#endif -} - -void WWMouseClass::Show_Mouse() -{ - POINT pt; - GetCursorPos(&pt); - - MouseUpdate++; - Low_Show_Mouse(pt.x, pt.y); - MouseUpdate--; -} - -void WWMouseClass::Conditional_Hide_Mouse(int x1, int y1, int x2, int y2) -{ - POINT pt; - - MouseUpdate++; - - // - // First of all, adjust all the coordinates so that they handle - // the fact that the hotspot is not necessarily the upper left - // corner of the mouse. - // - x1 -= (CursorWidth - MouseXHot); - x1 = MAX(0, x1); - y1 -= (CursorHeight - MouseYHot); - y1 = MAX(0, y1); - x2 += MouseXHot; - x2 = MIN(x2, Screen->Get_Width()); - y2 += MouseYHot; - y2 = MIN(y2, Screen->Get_Height()); - - // The mouse could be in one of four conditions. - // 1) The mouse is visible and no conditional hide has been specified. - // (perform normal region checking with possible hide) - // 2) The mouse is hidden and no conditional hide as been specified. - // (record region and do nothing) - // 3) The mouse is visible and a conditional region has been specified - // (expand region and perform check with possible hide). - // 4) The mouse is already hidden by a previous conditional. - // (expand region and do nothing) - // - // First: Set or expand the region according to the specified parameters - if (!MCCount) { - MouseCXLeft = x1; - MouseCYUpper = y1; - MouseCXRight = x2; - MouseCYLower = y2; - } else { - MouseCXLeft = MIN(x1, MouseCXLeft); - MouseCYUpper = MIN(y1, MouseCYUpper); - MouseCXRight = MAX(x2, MouseCXRight); - MouseCYLower = MAX(y2, MouseCYLower); - } - // - // If the mouse isn't already hidden, then check its location against - // the hiding region and hide if necessary. - // - if (!(MCFlags & CONDHIDDEN)) { - GetCursorPos(&pt); - if (MouseBuffX >= MouseCXLeft && MouseBuffX <= MouseCXRight && MouseBuffY >= MouseCYUpper && MouseBuffY <= MouseCYLower) { - Low_Hide_Mouse(); - MCFlags |= CONDHIDDEN; - } - } - // - // Record the fact that a conditional hide was called and then exit - // - // - MCFlags |= CONDHIDE; - MCCount++; - MouseUpdate--; - -} -void WWMouseClass::Conditional_Show_Mouse(void) -{ - MouseUpdate++; - - // - // if there are any nested hides then dec the count - // - if (MCCount) { - MCCount--; - // - // If the mouse is now not hidden and it had actually been - // hidden before then display it. - // - if (!MCCount) { - if (MCFlags & CONDHIDDEN) { - Show_Mouse(); - } - MCFlags = 0; - } - } - - MouseUpdate--; -} - - -void WWMouseClass::Draw_Mouse(GraphicViewPortClass *scr) -{ - scr; - return; -//ST - 1/3/2019 10:50AM -#if (0) - - POINT pt; - - if (State != 0) return; - MouseUpdate++; - // - // Get the position that the mouse is currently located at - // - GetCursorPos(&pt); - if (MCFlags & CONDHIDE && pt.x >= MouseCXLeft && pt.x <= MouseCXRight && pt.y >= MouseCYUpper && pt.y <= MouseCYLower) { - Hide_Mouse(); - MCFlags |= CONDHIDDEN; - } else { - // - // If the mouse is already visible then just ignore the problem. - // - EraseFlags = TRUE; - - // - // Try to lock the screen - dont do video stuff if we cant. - // - if (scr->Lock()){ - // - // Save off the area behind the mouse into two different buffers, one - // which will be used to restore the mouse and the other which will - // be used to restore the hidden surface when we get a chance. - // - Mouse_Shadow_Buffer(this, scr, EraseBuffer, pt.x, pt.y, MouseXHot, MouseYHot, 1); - memcpy(MouseBuffer, EraseBuffer, MaxWidth * MaxHeight); - // - // Draw the mouse in its new location - // - ::Draw_Mouse(this, scr, pt.x, pt.y); - // - // Save off the positions that we saved the buffer from - // - EraseBuffX = pt.x; - MouseBuffX = pt.x; - EraseBuffY = pt.y; - MouseBuffY = pt.y; - EraseBuffHotX = MouseXHot; - EraseBuffHotY = MouseYHot; - // - // Unlock the screen and lets get moving. - // - scr->Unlock(); - } - } - - MouseUpdate--; -#endif -} - -void WWMouseClass::Erase_Mouse(GraphicViewPortClass *scr, int forced) -{ -//ST - 1/3/2019 10:50AM - scr; - forced; - return; -#if (0) - // - // If we are forcing the redraw of a mouse we already managed to - // restore then just get outta here. - // - if (forced && EraseBuffX == -1 && EraseBuffY == -1) return; - - MouseUpdate++; - - // - // If this is not a forced call, only update the mouse is we can legally - // lock the buffer. - // - if (!forced) { -#if(0) - if (scr->Lock()) { - // - // If the surface has not already been restore then restore it and erase the - // restoration coordinates so we don't accidentally do it twice. - // - if (EraseBuffX != -1 || EraseBuffY != -1) { - Mouse_Shadow_Buffer(this, scr, EraseBuffer, EraseBuffX, EraseBuffY, 0); - EraseBuffX = -1; - EraseBuffY = -1; - } - // - // We are done writing to the buffer so unlock it. - // - scr->Unlock(); - } -#endif - } else { - // - // If the surface has not already been restore then restore it and erase the - // restoration coordinates so we don't accidentally do it twice. - // - if (EraseBuffX != -1 || EraseBuffY != -1) { - if (scr->Lock()){ - Mouse_Shadow_Buffer(this, scr, EraseBuffer, EraseBuffX, EraseBuffY, EraseBuffHotX, EraseBuffHotY, 0); - scr->Unlock(); - } - EraseBuffX = -1; - EraseBuffY = -1; - } - } - MouseUpdate--; - EraseFlags = FALSE; -#endif -} - -int WWMouseClass::Get_Mouse_State(void) -{ - return(State); -} -/*********************************************************************************************** - * WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels * - * * - * INPUT: none * - * * - * OUTPUT: int - returns the mouses current x position in pixels * - * * - * HISTORY: * - * 10/17/1995 PWG : Created. * - *=============================================================================================*/ -int WWMouseClass::Get_Mouse_X(void) -{ - POINT pt; - GetCursorPos(&pt); - return(pt.x); -} - - -/*********************************************************************************************** - * WWKeyboardClass::Get_Mouse_Y -- returns the mouses current y position in pixels * - * * - * INPUT: none * - * * - * OUTPUT: int - returns the mouses current y position in pixels * - * * - * HISTORY: * - * 10/17/1995 PWG : Created. * - *=============================================================================================*/ -int WWMouseClass::Get_Mouse_Y(void) -{ - POINT pt; - GetCursorPos(&pt); - return(pt.y); -} - -/*********************************************************************************************** - * WWKeyboardClass::Get_Mouse_XY -- Returns the mouses x,y position via reference vars * - * * - * INPUT: int &x - variable to return the mouses x position in pixels * - * int &y - variable to return the mouses y position in pixels * - * * - * OUTPUT: none - output is via reference variables * - * * - * HISTORY: * - * 10/17/1995 PWG : Created. * - *=============================================================================================*/ -void WWMouseClass::Get_Mouse_XY(int &x, int &y) -{ - POINT pt; - - GetCursorPos(&pt); - x = pt.x; - y = pt.y; -} - -//#pragma off(unreferenced) - -void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 ) -{ - static BOOL in_mouse_callback = false; - - if (_Mouse && !in_mouse_callback) { - in_mouse_callback = TRUE; - _Mouse->Process_Mouse(); - in_mouse_callback = FALSE; - } -} -//#pragma on(unreferenced) - -void Hide_Mouse(void) -{ - if (!_Mouse) return; - _Mouse->Hide_Mouse(); -} - -void Show_Mouse(void) -{ - if (!_Mouse) return; - _Mouse->Show_Mouse(); -} - -void Conditional_Hide_Mouse(int x1, int y1, int x2, int y2) -{ - if (!_Mouse) return; - _Mouse->Conditional_Hide_Mouse(x1, y1, x2, y2); -} - -void Conditional_Show_Mouse(void) -{ - if (!_Mouse) return; - _Mouse->Conditional_Show_Mouse(); -} - -int Get_Mouse_State(void) -{ - if (!_Mouse) return(0); - return(_Mouse->Get_Mouse_State()); -} - -void *Set_Mouse_Cursor(int hotx, int hoty, void *cursor) -{ - if (!_Mouse) return(0); - return(_Mouse->Set_Cursor(hotx,hoty,cursor)); -} - -extern int DLLForceMouseX; -extern int DLLForceMouseY; - - -int Get_Mouse_X(void) -{ - if (DLLForceMouseX >= 0) { - return DLLForceMouseX; - } - if (!_Mouse) return(0); - return(_Mouse->Get_Mouse_X()); -} - -int Get_Mouse_Y(void) -{ - if (DLLForceMouseY >= 0) { - return DLLForceMouseY; - } - - if (!_Mouse) return(0); - return(_Mouse->Get_Mouse_Y()); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/NEWDEL.CPP b/code/TIBERIANDAWN/WIN32LIB/NEWDEL.CPP deleted file mode 100644 index 4a49788..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/NEWDEL.CPP +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Memory system. * - * * - * File Name : NEWDEL.CPP * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : June 21, 1994 * - * * - * Last Update : October 20, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * operator NEW -- Overides the global new function. * - * operator delete -- Overides the global delete function. * - * operator NEW[] -- Overides the array version of new. * - * operator delete[] -- Overides the array version of delete[] * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "wwmem.h" - - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - - -/*************************************************************************** - * OPERATOR NEW -- Overides the global new function. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - *=========================================================================*/ -void * operator new(size_t size) -{ - return (Alloc((unsigned long) size, MEM_NEW)); -} - - -/*************************************************************************** - * OPERATOR NEW[] -- Overides the array version of new. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - *=========================================================================*/ -void * operator new[](size_t size) -{ - return (Alloc((unsigned long) size, MEM_NEW)); -} - - -/*************************************************************************** - * OPERATOR DELETE -- Overides the global delete function. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 06/21/1994 SKB : Created. * - *=========================================================================*/ -void operator delete(void *ptr) -{ - Free(ptr); -} - -/*************************************************************************** - * OPERATOR DELETE[] -- Overides the array version of delete[] * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/20/1994 SKB : Created. * - *=========================================================================*/ -void operator delete[](void *ptr) -{ - Free(ptr); -} - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/NYBBTB.INC b/code/TIBERIANDAWN/WIN32LIB/NYBBTB.INC deleted file mode 100644 index 48444c4..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/NYBBTB.INC +++ /dev/null @@ -1,56 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;**************************************************************************** -;* bNybbleTablexxxx - ADPCM Lookup table for nybbles -;**************************************************************************** - - align 4 - -bNybbleTableLow DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - - align 4 - -bNybbleTableHigh DB 00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2 - DB 01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2 - DB 02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2 - DB 03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2 - DB 04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2 - DB 05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2 - DB 06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2 - DB 07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2 - DB 08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2 - DB 09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2 - DB 0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2 - DB 0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2 - DB 0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2 - DB 0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2 - DB 0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2 - DB 0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2 diff --git a/code/TIBERIANDAWN/WIN32LIB/PALETTE.CPP b/code/TIBERIANDAWN/WIN32LIB/PALETTE.CPP deleted file mode 100644 index 3c8b924..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/PALETTE.CPP +++ /dev/null @@ -1,381 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : WWLIB * - * * - * File Name : PALETTE.C * - * * - * Programmer : BILL STOKES * - * * - * Start Date : 6/20/91 * - * * - * Last Update : August 2, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Note: This module contains dependencies upon the video system, * - * specifically Get_Video_Mode(). * - *-------------------------------------------------------------------------* - * Functions: * - * Set_Palette -- sets the current palette * - * Set_Palette_Color -- Set a color number in a palette to the data. * - * Fade_Palette_To -- Fades the current palette into another * - * Determine_Bump_Rate -- determines desired bump rate for fading * - * Bump_Palette -- increments the palette one step, for fading * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* -********************************* Includes ********************************** -*/ -//#include - -#include "palette.h" -#include "timer.h" -#include "wwstd.h" - - -/* -********************************* Constants ********************************* -*/ - -/* -********************************** Globals ********************************** -*/ -extern "C" extern unsigned char CurrentPalette[]; /* in pal.asm */ - -/* -******************************** Prototypes ********************************* -*/ - -PRIVATE void __cdecl Determine_Bump_Rate(void *palette, int delay, short *ticks, short *rate); -PRIVATE BOOL __cdecl Bump_Palette(void *palette1, unsigned int step); - -/* -******************************** Code ********************************* -*/ - -/*************************************************************************** - * Set_Palette -- sets the current palette * - * * - * INPUT: * - * void *palette - palette to set * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/25/1994 SKB : Created. * - * 04/27/1994 BR : Converted to 32-bit * - *=========================================================================*/ -void __cdecl Set_Palette(void *palette) -{ - - #if(IBM) - Set_Palette_Range(palette); - #else - Copy_Palette(palette,CurrentPalette); - LoadRGB4(&Main_Screen->ViewPort,palette,32L); - LoadRGB4(AltVPort,palette,32L); - #endif - -} /* end of Set_Palette */ - - -/*************************************************************************** - * Set_Palette_Color -- Set a color number in a palette to the data. * - * * - * * - * INPUT: * - * void *palette - palette to set color in * - * int color - which color index to set * - * void *data - RGB data for color * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/25/1994 SKB : Created. * - * 04/27/1994 BR : Converted to 32-bit * - *=========================================================================*/ -void __cdecl Set_Palette_Color(void *palette, int color, void *data) -{ - /* - ---------------------- Return if 'palette' is NULL ----------------------- - */ - if (!palette) return; - - /* - ------------------- Change the color & set the palette ------------------- - */ - #if(IBM) - memcpy(&((unsigned char *)palette)[color * RGB_BYTES], data, RGB_BYTES); - Set_Palette_Range(palette); - #else - palette[color] = *(unsigned short*)data; - Set_Palette(palette); - #endif - -} /* end of Set_Palette */ - - -/*************************************************************************** - * Fade_Palette_To -- Fades the current palette into another * - * * - * This will allow the palette to fade from current palette into the * - * palette that was passed in. This can be used to fade in and fade out. * - * * - * INPUT: * - * char *palette1 - this is the palette to fade to. * - * unsigned int delay - fade with this timer count down * - * void *callback - user-defined callback function * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 06/20/1991 BS : Created. * - *=========================================================================*/ -void Fade_Palette_To(void *palette1, unsigned int delay, void (*callback)() ) -{ - BOOL changed; // Flag that palette has changed this tick. - short jump; // Gun values to jump per palette set. - unsigned long timer; // Tick count timer used for timing. - short ticksper; // The ticks (fixed point) per bit jump. - int tickaccum; - - - extern void (*cb_ptr)(void); // callback function pointer - -// (void *)cb_ptr = callback; - cb_ptr = callback; - - /* - ---------------------- Return if 'palette1' is NULL ---------------------- - */ - if (!palette1) - return; - - /* - --------------------------- Get the bump rate ---------------------------- - */ - Determine_Bump_Rate(palette1, delay, &ticksper, &jump); - - tickaccum = 0; // init accumulated elapsed time - timer = TickCount.Time(); // timer = current time - do { - changed = FALSE; - - tickaccum += ticksper; // tickaccum = time of next change * 256 - timer += (tickaccum >> 8); // timer = time of next change (rounded) - tickaccum &= 0x0FF; // shave off high byte, keep roundoff bits - - changed = Bump_Palette(palette1, jump); // increment palette - - /* - .................. Wait for time increment to elapse .................. - */ - if (changed) { - while (TickCount.Time() < (int)timer) { - /* - ................. Update callback while waiting ................. - */ - if (callback) { -#if LIB_EXTERNS_RESOLVED - Sound_Callback(); // should be removed! -#endif - (*cb_ptr)(); - } - } - } - -#if LIB_EXTERNS_RESOLVED - Sound_Callback(); // should be removed! -#endif - if (callback) { - (*cb_ptr)(); - } - } while (changed); - -} /* end of Fade_Palette_To */ - - -/*************************************************************************** - * Determine_Bump_Rate -- determines desired bump rate for fading * - * * - * INPUT: * - * unsigned char *palette - palette to fade to * - * int delay - desired time delay in 60ths of a second * - * short *ticks - output: loop ticks per color jump * - * short *rate - output: color gun increment rate * - * * - * OUTPUT: * - * none * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/27/1994 BR : Converted to 32-bit * - * 08/02/1994 SKB : Made private * - *=========================================================================*/ -PRIVATE void __cdecl Determine_Bump_Rate(void *palette, int delay, short *ticks, - short *rate) -{ - int gun1; // Palette 1 gun value. - int gun2; // Palette 2 gun value. - int diff; // Maximum color gun difference. - int tp; // Temporary tick accumulator. - int index; // Color gun working index. - long t; // Working tick intermediate value. - int adiff; // Absolute difference between guns. - - /* - ------------------------ Find max gun difference ------------------------- - */ - diff = 0; - for (index = 0; index < PALETTE_BYTES; index++) { - gun1 = ((unsigned char *)palette)[index]; - gun2 = CurrentPalette[index]; - adiff = ABS(gun1-gun2); - diff = MAX(diff, adiff); - } - - /*------------------------------------------------------------------------ - ticks = (total time delay ) / (max gun diff) - The value is computed based on (delay * 256), for fixed-point math; - the lower bits represent the leftover from the division; 'ticks' is - returned still shifted, so the low bits can be used to accumulate the - time more accurately; the caller must shift the accumulated value down - 8 bits to determine the actual elapsed time! - ------------------------------------------------------------------------*/ - t = ((long)delay) << 8; - if (diff) { - t /= diff; - t = MIN((long)t, (long)0x7FFF); - } - *ticks = (short)t; - - /*------------------------------------------------------------------------ - Adjust the color gun rate value if the time to fade is faster than can - reasonably be performed given the palette change, ie if (ticks>>8)==0, - and thus less than 1/60 of a second - ------------------------------------------------------------------------*/ - tp = *ticks; - *rate = 1; - while (*rate <= diff && *ticks < 256) { - *ticks += tp; - *rate += 1; - } - -} /* end of Determine_Bump_Rate */ - - -/*************************************************************************** - * Bump_Palette -- increments the palette one step, for fading * - * * - * INPUT: * - * palette1 - palette to fade towards * - * step - max step amount, determined by Determine_Bump_Rate * - * * - * OUTPUT: * - * FALSE = no change, TRUE = changed * - * * - * WARNINGS: * - * * - * HISTORY: * - * 04/27/1994 BR : Created. * - * 08/02/1994 SKB : Made private * - *=========================================================================*/ -#if(IBM) -PRIVATE BOOL __cdecl Bump_Palette(void *palette1, unsigned int step) -{ - BOOL changed=FALSE; // Flag that palette has changed this tick. - int index; // Index to DAC register gun. - int gun1,gun2; // Palette 1 gun value. - unsigned char palette[PALETTE_BYTES]; // copy of current palette - - /* - ---------------------- Return if 'palette1' is NULL ---------------------- - */ - if (!palette1) - return (FALSE); - - - /* - ------------------------ Copy the current palette ------------------------ - */ - memcpy(palette, CurrentPalette, 768); - - /* - ----------------------- Loop through palette bytes ----------------------- - */ - for (index = 0; index < PALETTE_BYTES; index++) { - gun1 = ((unsigned char *)palette1)[index]; - gun2 = palette[index]; - - /* - ............. If the colors match, go on to the next one .............. - */ - if (gun1 == gun2) continue; - - changed = TRUE; - - /* - .................. Increment current palette's color .................. - */ - if (gun2 < gun1) { - gun2 += step; - gun2 = MIN(gun2, gun1); // make sure we didn't overshoot it - } - /* - .................. Decrement current palette's color .................. - */ - else { - gun2 -= step; - gun2 = MAX(gun2, gun1); // make sure we didn't overshoot it - } - - palette[index] = (unsigned char)gun2; - } - - /* - ----------------- Set current palette to the new palette ----------------- - */ - if (changed) { - Set_Palette(&palette[0]); - } - - return (changed); - -} /* end of Bump_Palette */ - -#else - - /* This is already implemented in asm on the Amiga */ - -#endif - -void (*cb_ptr)(void); // callback function pointer - -/**************************** End of palette.cpp ***************************/ - - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/PALETTE.H b/code/TIBERIANDAWN/WIN32LIB/PALETTE.H deleted file mode 100644 index 6087d0d..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/PALETTE.H +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Palette 32bit Library. * -;* * -;* File Name : PALETTE.H * -;* * -;* Programmer : Scott K. Bowen * -;* * -;* Start Date : April 25, 1994 * -;* * -;* Last Update : April 27, 1994 [BRR] * -;* * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef PALETTE_H -#define PALETTE_H - -#include -/* -********************************* Constants ********************************* -*/ -#define RGB_BYTES 3 -#define PALETTE_SIZE 256 -#define PALETTE_BYTES 768 - -/* -******************************** Prototypes ********************************* -*/ -/* --------------------------------- Palette.cpp -------------------------------- -*/ -void __cdecl Set_Palette(void *palette); -void __cdecl Set_Palette_Color(void *palette, int color, void *data); -void Fade_Palette_To(void *palette1, unsigned int delay, void (*callback)() ); - -/* --------------------------------- loadpal.cpp -------------------------------- -*/ -void __cdecl Load_Palette(char *palette_file_name, void *palette_pointer); - -/* -------------------------------- morphpal.cpp -------------------------------- -*/ -void __cdecl Morph_Palette (void *src_palette, void *dst_palette, unsigned int delay, - void *callback); - -/* ----------------------------------- pal.asm ---------------------------------- -*/ -#ifdef __cplusplus -extern "C" { -#endif - -extern void __cdecl Set_Palette_Range(void *palette); -extern BOOL __cdecl Bump_Color(void *palette, int changable, int target); - -#ifdef __cplusplus -} -#endif -extern "C" extern unsigned char CurrentPalette[]; /* in pal.asm */ - - -#endif // PALETTE_H - -/***************************** End of palette.h ****************************/ diff --git a/code/TIBERIANDAWN/WIN32LIB/PLAYCD.H b/code/TIBERIANDAWN/WIN32LIB/PLAYCD.H deleted file mode 100644 index 0c5a68d..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/PLAYCD.H +++ /dev/null @@ -1,306 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : WWLIB * - * * - * File Name : PLAYCD.H * - * * - * Programmer : STEVE WETHERILL * - * * - * Start Date : 5/13/94 * - * * - * Last Update : June 4, 1994 [SW] * - * * - *-------------------------------------------------------------------------*/ - -#ifndef PLAYCD_H -#define PLAYCD_H - - -#ifdef NOT_FOR_WIN95 -/* ==================================================================== */ -/* Defines */ -/* ==================================================================== */ - -#define CHLEFT 0 -#define CHRIGHT 1 -#define CHBOTH 2 - -#define AUDIO_START_MIN 1 -#define AUDIO_START_SEC 44 - -typedef struct { - unsigned short seg ; - unsigned short sel ; - } SEGSEL ; - - - - -extern "C" int DPMI_real_alloc ( UINT , SEGSEL * , USHORT * ) ; -extern "C" int DPMI_real_free ( SEGSEL ) ; -extern "C" void DPMI_real_intr ( int , union REGS * , struct SREGS * ); -extern "C" void DPMI_real_call ( void * funct , union REGS * , struct SREGS * ); - - - - -/* ==================================================================== */ -/* Data structures */ -/* ==================================================================== */ - -// Audio Track Info request block - -struct TinfoType { - UBYTE Length; - UBYTE SubCd; - UBYTE Command; - UWORD Status; - UBYTE Rsvd[8]; - UBYTE MDescr; - - UWORD TrnsAdOff; - UWORD TrnsAdSeg; - - UWORD CntTrns; - UWORD StSect; - - UWORD VolIDOff; - UWORD VolIDSeg; - - UBYTE TrInfo; - UBYTE Track; - ULONG Start; - UBYTE TrCtrl; -}; - -// Audio Track Status Control Block - -struct StatType { - UBYTE Length; - UBYTE SubCd; - UBYTE Command; - UWORD Status; - UBYTE Rsvd[8]; - UBYTE MDescr; - - UWORD TrnsAdOff; - UWORD TrnsAdSeg; - - UWORD CntTrns; - UWORD StSect; - - UWORD VolIDOff; - UWORD VolIDSeg; - - UBYTE StatInfo; - UWORD Stat; - ULONG Start; - ULONG End; - }; - -// Audio Track Volume control block - -struct VolmType { - UBYTE Length; - UBYTE SubCd; - UBYTE Command; - UWORD Status; - UBYTE Rsvd[8]; - UBYTE MDescr; - - UWORD TrnsAdOff; - UWORD TrnsAdSeg; - - UWORD CntTrns; - UWORD StSect; - - UWORD VolIDOff; - UWORD VolIDSeg; - - UBYTE TrInfo; - UBYTE In0; - UBYTE Vol0; - UBYTE In1; - UBYTE Vol1; - UBYTE In2; - UBYTE Vol2; - UBYTE In3; - UBYTE Vol3; - }; - -// Audio Track Play request block - -struct PlayType { - UBYTE Length; - UBYTE SubCd; - UBYTE Command; - UWORD Status; - UBYTE Rsvd[8]; - UBYTE AddrMd; - ULONG Start; - ULONG CntSect; - }; - - -// Audio Track Stop request block - -struct StopType { - UBYTE Length; - UBYTE SubCd; - UBYTE Command; - UWORD Status; - UBYTE Rsvd[8]; - }; - -#endif //NOT_FOR_WIN95 - -/*************************************************************************** - * GetCDClass -- object which will return logical CD drive * - * * - * HISTORY: * - * 06/04/1994 SW : Created. * - *=========================================================================*/ - -#define MAX_CD_DRIVES 26 -#define NO_CD_DRIVE -1 - -class GetCDClass { - -protected: - - int CDDrives[MAX_CD_DRIVES]; //Array containing CD drive letters - int CDCount; //Number of available CD drives - int CDIndex; - -public: - - - GetCDClass(VOID); // This is the default constructor - ~GetCDClass(VOID); // This is the destructor - - inline int Get_First_CD_Drive(void); - inline int Get_Next_CD_Drive(void); - inline int Get_Number_Of_Drives(void) {return (CDCount);}; - -}; - - - -/*********************************************************************************************** - * GCDC::Get_Next_CD_Drive -- return the logical drive number of the next CD drive * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Logical drive number of a cd drive or -1 if none * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/21/96 3:50PM ST : Created * - *=============================================================================================*/ -inline int GetCDClass::Get_Next_CD_Drive(void) -{ - if (CDCount){ - if (CDIndex == CDCount) CDIndex = 0; - return (CDDrives[CDIndex++]); - }else{ - return (-1); - } -} - - - -/*************************************************************************** - * GCDC::Get_First_CD_Drive -- return the number of the first CD drive * - * * - * * - * * - * INPUT: * - * none * - * OUTPUT: * - * logical drive number * - * WARNINGS: * - * * - * HISTORY: * - * 05/26/1994 SW : Created. * - * 12/4/95 ST : fixed for Win95 * - *=========================================================================*/ -inline int GetCDClass::Get_First_CD_Drive(void) -{ - CDIndex = 0; - return (Get_Next_CD_Drive()); -} - - - - - - -/*************************************************************************** - * RedBookClass -- adds red book functionality * - * * - * this class inherits from GetCDClass and adds red book play functionality* - * * - * * - * HISTORY: * - * 06/04/1994 SW : Created. * - *=========================================================================*/ - -#ifdef NOT_FOR_WIN95 -class RedBookClass : public GetCDClass { - -private: - - SEGSEL Tinfo_addrp; - SEGSEL Stat_addrp; - SEGSEL Stop_addrp; - SEGSEL Volm_addrp; - SEGSEL Play_addrp; - - StopType Stop; - PlayType Play; - VolmType Volm; - StatType Stat; - TinfoType Tinfo; - -public: - - RedBookClass(VOID); // This is the default constructor - ~RedBookClass(VOID); // This is the destructor - - ULONG RedToHS(ULONG i); - ULONG MSFtoRed(UBYTE m, UBYTE s, UBYTE f); - VOID FullCDVolume(UBYTE chan); - VOID PlayTrack(UWORD track); - VOID Play_CD_MSL(UWORD min_sec, UWORD len); - VOID PlayMSF(UBYTE startM, UBYTE startS, UBYTE startF, - UBYTE endM, UBYTE endS, UBYTE endF, UBYTE chan); - UWORD CheckCDMusic(VOID); - VOID StopCDMusic(VOID); - -}; - -#endif //NOT_FOR_WIN95 -/***************************** End of Playcd.h ****************************/ - -#endif // PLAYCD_H - diff --git a/code/TIBERIANDAWN/WIN32LIB/PROFILE.H b/code/TIBERIANDAWN/WIN32LIB/PROFILE.H deleted file mode 100644 index bc20add..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/PROFILE.H +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Library profiler * - * * - * File Name : PROFILE.H * - * * - * Programmer : Steve Tall * - * * - * Start Date : 11/17/95 * - * * - * Last Update : November 20th 1995 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * * - * New System * - * ~~~~~~~~~~~ * - * * - * The new profiler system creates a seperate thread and then starts a timer off there. The * - * timer in the second thread uses GetThreadContext to sample the IP address of each user * - * thread. This system has the advantage of being able to sample what is happening in all the * - * threads we own not just the main thread. Another advantage is that it doesnt require a * - * major recompilation. * - * The disadvantage is that we dont really know what is going on when the IP is outside the * - * scope of our threads - We could be in direct draw, direct sound or even something like the * - * VMM and there is no way to tell. * - * * - * * - * * - * Old System * - * ~~~~~~~~~~~ * - * * - * The profiler works by using the function prologue and epilogue hooks available in Watcom * - * to register the current functions address in a global variable and then sampling the * - * contents of the variable using a windows timer which runs at up to 1000 samples per second.* - * * - * Compile the code to be sampled with the -ep and -ee flags to enable the prologue (__PRO) * - * and epilogue (__EPI) calls to be generated. * - * At the beginning of the section to be profiled (just before main loop normally) call the * - * Start_Profiler function to start sampling. At the end of the section, call Stop_Profiler * - * which will stop the timer and write the profile data to disk in the PROFILE.BIN file. * - * * - * Use PROFILE.EXE to view the results of the session. * - * * - * The addition of prologue and epilogue code will slow down the product and the profiler * - * allocates a huge buffer for data so it should not be linked in unless it is going to be * - * used. * - * * - * The advantage of the prologue/epilogue approach is that all samples represent valid * - * addresses within our code so we get valid results we can use even when the IP is in system * - * code. * - * * - * * - *---------------------------------------------------------------------------------------------* - * * - * Functions: * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#define MAX_PROFILE_TIME 60*1 //1 minute(s) @ 14.4 Mb per hour -#define PROFILE_RATE 1000 //samples per sec (max 1000) - - -/* - * Defines for choosing between the old and new profiler system - * -*/ - -#define OLD_PROFILE_SYSTEM 1 -#define NEW_PROFILE_SYSTEM 2 - -//#define PROFILE_SYSTEM OLD_PROFILE_SYSTEM -#define PROFILE_SYSTEM NEW_PROFILE_SYSTEM - - - -extern "C"{ - void __cdecl Profile_Init(void); - void __cdecl Profile_End(void); - void __cdecl Start_Profiler(void); - void __cdecl Stop_Profiler(void); -} - diff --git a/code/TIBERIANDAWN/WIN32LIB/PROFILE.INC b/code/TIBERIANDAWN/WIN32LIB/PROFILE.INC deleted file mode 100644 index ec99294..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/PROFILE.INC +++ /dev/null @@ -1,41 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - - -;USE_PROFILER =1 - - -macro prologue -Ifdef USE_PROFILER - global __PRO:near - - call __PRO -endif ;USE_PROFILER -endm - - - -macro epilogue -ifdef USE_PROFILER - global __EPI:near - - push ebp - call __EPI - pop ebp -endif ;USE_PROFILER -endm - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/RAWFILE.H b/code/TIBERIANDAWN/WIN32LIB/RAWFILE.H deleted file mode 100644 index 460c362..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/RAWFILE.H +++ /dev/null @@ -1,254 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\rawfile.h_v 2.15 06 Sep 1995 16:29:30 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : RAWFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : October 18, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * RawFileClass::File_Name -- Returns with the filename associate with the file object. * - * RawFileClass::RawFileClass -- Default constructor for a file object. * - * RawFileClass::Is_Open -- Checks to see if the file is open or not. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef RAWFILE_H -#define RAWFILE_H - -#ifndef WIN32 -#define WIN32 1 -#ifndef _WIN32 // Denzil 6/2/98 Watcom 11.0 complains without this check -#define _WIN32 -#endif // _WIN32 -#endif -#include - -//#include -#include -#include -#include -//#include -#include "wwfile.h" - -#ifdef NEVER - /* - ** This is a duplicate of the error numbers. The error handler for the RawFileClass handles - ** these errors. If the error routine is overridden and additional errors are defined, then - ** use numbers starting with 100. Note that these errors here are listed in numerical order. - ** These errors are defined in the standard header file "ERRNO.H". - */ - EZERO, // Non-error. - EINVFNC, // Invalid function number. - ENOFILE, // File not found. - ENOENT=ENOFILE, // No such file or directory. - ENOPATH, // Path not found. - EMFILE, // Too many open files. - EACCES, // Permission denied. - EBADF, // Bad file number. - ECONTR, // Memory blocks destroyed. - ENOMEM, // Not enough core memory. - EINVMEM, // Invalid memory block address. - EINVENV, // Invalid environment. - EINVFMT, // Invalid format. - EINVACC, // Invalid access code. - EINVDAT, // Invalid data. - EFAULT, // Unknown error. - EINVDRV, // Invalid drive specified. - ENODEV=EINVDRV, // No such device. - ECURDIR, // Attempt to remove CurDir. - ENOTSAM, // Not same device. - ENMFILE, // No more files. - EINVAL, // Invalid argument. - E2BIG, // Argument list too long. - ENOEXEC, // exec format error. - EXDEV, // Cross-device link. - ENFILE, // Too many open files. - ECHILD, // No child process. - ENOTTY, // not used - ETXTBSY, // not used - EFBIG, // not used - ENOSPC, // No space left on device. - ESPIPE, // Illegal seek. - EROFS, // Read-only file system. - EMLINK, // not used - EPIPE, // Broken pipe. - EDOM, // Math argument. - ERANGE, // Result too large. - EEXIST, // File already exists. - EDEADLOCK, // Locking violation. - EPERM, // Operation not permitted. - ESRCH, // not used - EINTR, // Interrupted function call. - EIO, // Input/output error. - ENXIO, // No such device or address. - EAGAIN, // Resource temporarily unavailable. - ENOTBLK, // not used - EBUSY, // Resource busy. - ENOTDIR, // not used - EISDIR, // not used - EUCLEAN, // not used -#endif - -/* -** This is the definition of the raw file class. It is derived from the abstract base FileClass -** and handles the interface to the low level DOS routines. This is the first class in the -** chain of derived file classes that actually performs a useful function. With this class, -** I/O is possible. More sophisticated features, such as packed files, CD-ROM support, -** file caching, and XMS/EMS memory support, are handled by derived classes. -** -** Of particular importance is the need to override the error routine if more sophisticated -** error handling is required. This is more than likely if greater functionality is derived -** from this base class. -*/ -class RawFileClass : public FileClass -{ - public: - - /* - ** This is a record of the access rights used to open the file. These rights are - ** used if the file object is duplicated. - */ - int Rights; - - RawFileClass(char const *filename); - RawFileClass(void); - RawFileClass (RawFileClass const & f); - RawFileClass & operator = (RawFileClass const & f); - virtual ~RawFileClass(void) {if (Allocated && Filename) free((char *)Filename);}; - - virtual char const * File_Name(void) const; - virtual char const * Set_Name(char const *filename); - virtual int Create(void); - virtual int Delete(void); - virtual int Is_Available(int forced=false); - virtual int Is_Open(void) const; - virtual int Open(char const *filename, int rights=READ); - virtual int Open(int rights=READ); - virtual long Read(void *buffer, long size); - virtual long Seek(long pos, int dir=SEEK_CUR); - virtual long Size(void); - virtual long Write(void const *buffer, long size); - virtual void Close(void); - virtual void Error(int error, int canretry = false, char const * filename=NULL); - virtual void Set_Buffer_Size(int size); - - - protected: - - /* - ** This function returns the largest size a low level DOS read or write may - ** perform. Larger file transfers are performed in chunks of this size or less. - */ - long Transfer_Block_Size(void) {return (long)((unsigned)UINT_MAX)-16L;}; - - private: - - /* - ** This is the low level DOS handle. A -1 indicates an empty condition. - */ - int Handle; - - /* - ** This points to the filename as a NULL terminated string. It may point to either a - ** constant or an allocated string as indicated by the "Allocated" flag. - */ - char const *Filename; - - /* - ** Filenames that were assigned as part of the construction process - ** are not allocated. It is assumed that the filename string is a - ** constant in that case and thus making duplication unnecessary. - ** This value will be non-zero if the filename has be allocated - ** (using strdup()). - */ - unsigned Allocated:1; -}; - - -/*********************************************************************************************** - * RawFileClass::File_Name -- Returns with the filename associate with the file object. * - * * - * Use this routine to determine what filename is associated with this file object. If no * - * filename has yet been assigned, then this routing will return NULL. * - * * - * INPUT: none * - * * - * OUTPUT: Returns with a pointer to the file name associated with this file object or NULL * - * if one doesn't exist. * - * * - * WARNINGS: none * - * * - * HISTORY: * -;* 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline char const * RawFileClass::File_Name(void) const -{ - return Filename; -} - -/*********************************************************************************************** - * RawFileClass::RawFileClass -- Default constructor for a file object. * - * * - * This constructs a null file object. A null file object has no file handle or filename * - * associated with it. In order to use a file object created in this fashion it must be * - * assigned a name and then opened. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * -;* 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline RawFileClass::RawFileClass(void) : Filename(0) -{ - Handle = -1; - Allocated = false; -} - -/*********************************************************************************************** - * RawFileClass::Is_Open -- Checks to see if the file is open or not. * - * * - * Use this routine to determine if the file is open. It returns true if it is. * - * * - * INPUT: none * - * * - * OUTPUT: bool; Is the file open? * - * * - * * - * WARNINGS: none * - * * - * HISTORY: * -;* 10/18/1994 JLB : Created. * - *=============================================================================================*/ -inline int RawFileClass::Is_Open(void) const -{ - return (Handle != -1); -} - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/REGIONSZ.CPP b/code/TIBERIANDAWN/WIN32LIB/REGIONSZ.CPP deleted file mode 100644 index cafd161..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/REGIONSZ.CPP +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB 32 * - * * - * File Name : REGIONSZ.CPP * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : November 3, 1994 * - * * - * Last Update : November 3, 1994 [PWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Size_Of_Region -- Calculates the size of a given region * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - - -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - - -/*************************************************************************** - * SIZE_OF_REGION -- Calculates the size of a given region * - * * - * INPUT: int width - the width of the region * - * int height - the height of the region * - * * - * OUTPUT: long - the size of the region * - * * - * HISTORY: * - * 11/03/1994 PWG : Created. * - *=========================================================================*/ -long Size_Of_Region(int width, int height) -{ - return(width * height); -} diff --git a/code/TIBERIANDAWN/WIN32LIB/REMAP.ASM b/code/TIBERIANDAWN/WIN32LIB/REMAP.ASM deleted file mode 100644 index 99356cf..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/REMAP.ASM +++ /dev/null @@ -1,172 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : REMAP.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : July 1, 1994 * -;* * -;* Last Update : July 1, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -INCLUDE ".\drawbuff.inc" -INCLUDE ".\gbuffer.inc" - - -CODESEG - - PROC Buffer_Remap C NEAR - USES eax,ebx,ecx,edx,esi,edi - - ;*=================================================================== - ;* Define the arguements that our function takes. - ;*=================================================================== - ARG this_object:DWORD - ARG x0_pixel:DWORD - ARG y0_pixel:DWORD - ARG region_width:DWORD - ARG region_height:DWORD - ARG remap :DWORD - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - local x1_pixel : DWORD - local y1_pixel : DWORD - local win_width : dword - local counter_x : dword - - - cmp [ remap ] , 0 - jz ??real_out - -; Clip Source Rectangle against source Window boundaries. - mov esi , [ this_object ] ; get ptr to src - xor ecx , ecx - xor edx , edx - mov edi , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register - mov ebx , [ x0_pixel ] - mov eax , [ x0_pixel ] - add ebx , [ region_width ] - shld ecx , eax , 1 - mov [ x1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi,[ ( GraphicViewPort esi) . GVPHeight ] ; get height into register - mov ebx , [ y0_pixel ] - mov eax , [ y0_pixel ] - add ebx , [ region_height ] - shld ecx , eax , 1 - mov [ y1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz ??real_out - or al , dl - jz ??do_remap - - test cl , 1000b - jz ??scr_left_ok - mov [ x0_pixel ] , 0 - -??scr_left_ok: - test cl , 0010b - jz ??scr_bottom_ok - mov [ y0_pixel ] , 0 - -??scr_bottom_ok: - test dl , 0100b - jz ??scr_right_ok - mov eax , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register - mov [ x1_pixel ] , eax -??scr_right_ok: - test dl , 0001b - jz ??do_remap - mov eax , [ (GraphicViewPort esi) . GVPHeight ] ; get width into register - mov [ y1_pixel ] , eax - - -??do_remap: - cld - mov edi , [ (GraphicViewPort esi) . GVPOffset ] - mov eax , [ (GraphicViewPort esi) . GVPXAdd ] - mov ebx , [ x1_pixel ] - add eax , [ (GraphicViewPort esi) . GVPWidth ] - add eax , [ (GraphicViewPort esi) . GVPPitch ] - mov esi , eax - mul [ y0_pixel ] - add edi , [ x0_pixel ] - sub ebx , [ x0_pixel ] - jle ??real_out - add edi , eax - sub esi , ebx - - mov ecx , [ y1_pixel ] - sub ecx , [ y0_pixel ] - jle ??real_out - mov eax , [ remap ] - mov [ counter_x ] , ebx - xor edx , edx - -??outer_loop: - mov ebx , [ counter_x ] -??inner_loop: - mov dl , [ edi ] - mov dl , [ eax + edx ] - mov [ edi ] , dl - inc edi - dec ebx - jnz ??inner_loop - add edi , esi - dec ecx - jnz ??outer_loop - - - - -??real_out: - ret - - ENDP Buffer_Remap - - END diff --git a/code/TIBERIANDAWN/WIN32LIB/SET_FONT.CPP b/code/TIBERIANDAWN/WIN32LIB/SET_FONT.CPP deleted file mode 100644 index ed11342..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/SET_FONT.CPP +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : SET_FONT.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 6, 1991 * - * * - * Last Update : June 29, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Set_Font -- Changes the default text printing font. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include "font.h" -#include - - - -/*************************************************************************** - * SET_FONT -- Changes the default text printing font. * - * * - * This routine will change the default text printing font for all * - * text output. It handles updating the system where necessary. * - * * - * INPUT: fontptr -- Pointer to the font to change to. * - * * - * OUTPUT: Returns with a pointer to the previous font. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 09/06/1991 JLB : Created. * - * 09/17/1991 JLB : Fixed return value bug. * - * 01/31/1992 DRD : Modified to use new font format. * - * 06/29/1994 SKB : modified for 32 bit library * - *=========================================================================*/ -void * __cdecl Set_Font(void const *fontptr) -{ - void *oldfont; - char const *blockptr; - - oldfont = (void *) FontPtr; - - if (fontptr) { - FontPtr = (void *) fontptr; - - /* - ** Inform the system about the new font. - */ - - FontWidthBlockPtr = (char*)fontptr + *(unsigned short *)((char*)fontptr + FONTWIDTHBLOCK); - blockptr = (char*)fontptr + *(unsigned short *)((char*)fontptr + FONTINFOBLOCK); - FontHeight = *(blockptr + FONTINFOMAXHEIGHT); - FontWidth = *(blockptr + FONTINFOMAXWIDTH); - //Draw_Char_Setup(); - -#if FALSE - WindowLines = WinH / FontHeight; - WindowWidth = WinW << 3; - WindowColumns = WindowWidth / FontWidth; -#endif - } - - return(oldfont); -} diff --git a/code/TIBERIANDAWN/WIN32LIB/SHAPE.H b/code/TIBERIANDAWN/WIN32LIB/SHAPE.H deleted file mode 100644 index ce686dd..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/SHAPE.H +++ /dev/null @@ -1,187 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB32 * - * * - * File Name : SHAPE.H * - * * - * Programmer : Bill Randolph * - * * - * Start Date : May 25, 1994 * - * * - * Last Update : September 14, 1994 [IML] * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef SHAPE_H -#define SHAPE_H - -#ifndef GBUFFER_H -#include "gbuffer.h" -#endif -/* -*********************************** Types *********************************** -*/ -/* ---------------------------- Shape creation flags ---------------------------- -*/ -typedef enum { - MAKESHAPE_NORMAL = 0x0000, // 256-color compressed shape - MAKESHAPE_COMPACT = 0x0001, // 16-color shape (with built-in color table) - MAKESHAPE_NOCOMP = 0x0002, // Uncompressed shape - MAKESHAPE_VARIABLE = 0x0004 // <16-color shape -} MakeShapeFlags_Type; - -inline MakeShapeFlags_Type operator|(MakeShapeFlags_Type a, MakeShapeFlags_Type b) -{return static_cast(static_cast(a) | static_cast(b));} - -inline MakeShapeFlags_Type operator&(MakeShapeFlags_Type a, MakeShapeFlags_Type b) -{return static_cast(static_cast(a) & static_cast(b));} - -inline MakeShapeFlags_Type operator~(MakeShapeFlags_Type a) -{return static_cast(~static_cast(a));} - - -/*--------------------------------------------------------------------------- -Shape drawing flags: -- The low byte is for coordinate transformations. -- The high byte is for drawing effects. ----------------------------------------------------------------------------*/ -typedef enum { - SHAPE_NORMAL = 0x0000, // Standard shape - SHAPE_HORZ_REV = 0x0001, // Flipped horizontally - SHAPE_VERT_REV = 0x0002, // Flipped vertically - SHAPE_SCALING = 0x0004, // Scaled (WORD scale_x, WORD scale_y) - SHAPE_VIEWPORT_REL = 0x0010, // Coords are window-relative - SHAPE_WIN_REL = 0x0010, // Coordinates are window relative instead of absolute. - SHAPE_CENTER = 0x0020, // Coords are based on shape's center pt - SHAPE_BOTTOM = 0x0040, // Y coord is based on shape's bottom pt - SHAPE_FADING = 0x0100, // Fading effect (void * fading_table, - // WORD fading_num) - SHAPE_PREDATOR = 0x0200, // Transparent warping effect - SHAPE_COMPACT = 0x0400, // Never use this bit - SHAPE_PRIORITY = 0x0800, // Use priority system when drawing - SHAPE_GHOST = 0x1000, // Shape is drawn ghosted - SHAPE_SHADOW = 0x2000, - SHAPE_PARTIAL = 0x4000, - SHAPE_COLOR = 0x8000 // Remap the shape's colors - // (void * color_table) -} ShapeFlags_Type; - -inline ShapeFlags_Type operator|(ShapeFlags_Type a, ShapeFlags_Type b) -{return static_cast(static_cast(a) | static_cast(b));} - -inline ShapeFlags_Type operator&(ShapeFlags_Type a, ShapeFlags_Type b) -{return static_cast(static_cast(a) & static_cast(b));} - -inline ShapeFlags_Type operator~(ShapeFlags_Type a) -{return static_cast(~static_cast(a));} - - -/* -------------------------------- Shape header -------------------------------- -*/ -typedef struct { - unsigned short ShapeType; // 0 = normal, 1 = 16 colors, - // 2 = uncompressed, 4 = <16 colors - unsigned char Height; // Height of the shape in scan lines - unsigned short Width; // Width of the shape in bytes - unsigned char OriginalHeight; // Original height of shape in scan lines - unsigned short ShapeSize; // Size of the shape, including header - unsigned short DataLength; // Size of the uncompressed shape (just data) - unsigned char Colortable[16]; // Optional color table for compact shape -} Shape_Type; - -/* -------------------------------- Shape block --------------------------------- -*/ -//#pragma warning (push, 4200) -#pragma warning (disable : 4200) -typedef struct { - unsigned short NumShapes; // number of shapes in the block - long Offsets[]; // array of offsets to shape data - // (offsets within the shape block, with - // 0 being the first offset value, not the - // start of the shape block) -} ShapeBlock_Type; -//#pragma warning (pop) - -/* -******************************** Prototypes ********************************* -*/ - -/* --------------------------------- prioinit.c --------------------------------- -*/ - -extern "C" { -extern void *MaskPage; -extern void *BackGroundPage; -extern long _ShapeBufferSize; -extern char *_ShapeBuffer; -} - - -void __cdecl Init_Priority_System (GraphicBufferClass *mask, - GraphicBufferClass *back); - - -/* --------------------------------- drawshp.asm -------------------------------- -*/ - -extern "C" { -int Draw_Shape(GraphicViewPortClass *gvp, void const *shape, LONG x, LONG y, LONG flags, ...); -} - -/* ----------------------------------- shape.c ---------------------------------- -*/ -short __cdecl Get_Shape_Data(void const *shape, int data); -int __cdecl Extract_Shape_Count(void const *buffer); -void * __cdecl Extract_Shape(void const *buffer, int shape); -int __cdecl Restore_Shape_Height(void *shape); -int __cdecl Set_Shape_Height(void const *shape, int newheight); - -extern "C" { -int __cdecl Get_Shape_Width(void const *shape); -int __cdecl Get_Shape_Height(void const *shape); -int __cdecl Get_Shape_Original_Height(void const *shape); -int __cdecl Get_Shape_Uncomp_Size(void const *shape); -} - - -/* -------------------------------- setshape.asm -------------------------------- -*/ -extern "C" { -void __cdecl Set_Shape_Buffer(void const *buffer, int size); -} -/* -------------------------------- shapeinf.asm -------------------------------- -*/ -int __cdecl Get_Shape_Flags(void const *shape); -int __cdecl Get_Shape_Size(void const *shape); -int __cdecl Get_Shape_Scaled_Width(void const *shape, int scale); -int __cdecl Get_Shape_Scaled_Height(void const *shape, int scale); - -#endif // SHAPE_H - -/****************************** End of shape.h *****************************/ - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/SHAPE.INC b/code/TIBERIANDAWN/WIN32LIB/SHAPE.INC deleted file mode 100644 index f1cb250..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/SHAPE.INC +++ /dev/null @@ -1,212 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : WWLIB32 * -;* * -;* File Name : SHAPE.INC * -;* * -;* Programmer : Scott Bowen * -;* * -;* Start Date : May 25, 1994 * -;* * -;* Last Update : September 14, 1994 [IML] * -;* * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * -;****************************** Equates ************************************ -; - - - - - - -;............................ Shape Types .................................. -; -TRUE equ 1 ; Boolean 'true' value -FALSE equ 0 ; Boolean 'false' value - -MAKESHAPE_NORMAL EQU 0 ; 256-color compressed shape -MAKESHAPE_COMPACT EQU 1 ; 16-color shape (built-in color table) -MAKESHAPE_NOCOMP EQU 2 ; non-wwcomped shape -MAKESHAPE_VARIABLE EQU 4 ; <16-color shape with variable # - ; of colors (ColorTable[0] = # of colors) -; old names: -;COLOR_SHAPE EQU 1 ; flag which determines a color shape -;NORM_SHAPE EQU 2 ; flag that indicates non wwcomped shp -;NORM_SHAPE_16 EQU 4 ; flag that tells us if we have a variable sized table - ; variable sized table -; -;........................................................................... -; Drawing flags: -; The low byte is for coordinate transformations. -; The high byte is for drawing effects. -;........................................................................... -; -SHAPE_NORMAL EQU 0000h ; no options; just a copy -SHAPE_HORZ_REV EQU 0001h ; reverse horizontally -SHAPE_VERT_REV EQU 0002h ; reverse vertically -SHAPE_SCALING EQU 0004h ; scale -SHAPE_VIEWPORT_REL EQU 0010h ; viewport-relative coordinates -SHAPE_CENTER EQU 0020h ; use centered coordinates -SHAPE_BOTTOM EQU 0040h ; Y coord is based on shape bottom pt -SHAPE_FADING EQU 0100h ; fading effect shape -SHAPE_PREDATOR EQU 0200h ; predator effect shape -SHAPE_COMPACT EQU 0400h ; shape is in 16 colors -SHAPE_PRIORITY EQU 0800h ; priority draw shape -SHAPE_GHOST EQU 1000h ; ghosting effect -SHAPE_SHADOW EQU 2000h ; shadow effect -SHAPE_PARTIAL EQU 4000h ; partial predator effect -SHAPE_COLOR EQU 8000h ; use alternative color table effect - -SHAPE_EFFECTS EQU 03F00h ; shape effect flags - -; -;.......................... Shadow Effect .................................. -; -SHADOW_COL EQU 00FFh ; magic number for shadows - -;......................... Priority System ................................. -; -CLEAR_UNUSED_BITS EQU 0007h ; and with 0000-0111 to clear - ; non-walkable high bit and - ; scaling id bits -NON_WALKABLE_BIT EQU 0080h ; and with 1000-0000 to clear all - ; but non-walkable bit -; -;......................... Predator Effect ................................. -; -PRED_MASK EQU 0007h ; mask used for predator pixel puts - -;--------------------------------------------------------------------------- -; This table is a list of the local stack variables in the function -; Draw_Shape. Many other functions in other modules access these variables -; on the stack. Since the BP is not changed when these other functions are -; called by Draw_Shape (possibly indirectly), they can also access these -; stack varibles. When adding or removing from the table, one must be very -; careful to change the offsets. -;--------------------------------------------------------------------------- -;.......................... proc addresses ................................. -LSkipRout EQU DWORD PTR ebp - 04h ;DWORD pointer to the skip routine -RSkipRout EQU DWORD PTR ebp - 08h ;DWORD pointer to the skip routine -DrawRout EQU DWORD PTR ebp - 0Ch ;DWORD pointer to the draw routine -;........................ optional arguments ............................... -ColorTable EQU DWORD PTR ebp - 10h ;DWORD ptr to the shapes color table -FadingTable EQU DWORD PTR ebp - 14h ;DWORD ptr to the fading table - -FadingNum EQU DWORD PTR ebp - 18h ;DWORD number of times to fade -IsTranslucent EQU DWORD PTR ebp - 1Ch ;DWORD ptr to is_translucent table -Translucent EQU DWORD PTR ebp - 20h ;DWORD ptr to actual translucent tbl -PriLevel EQU BYTE PTR ebp - 24h ;BYTE priority level of the object -ScaleX EQU DWORD PTR ebp - 28h ;DWORD the x increment to scale by -ScaleY EQU DWORD PTR ebp - 2Ch ;DWORD the y increment to scale by -ShadowingTable EQU DWORD PTR ebp - 30h ;DWORD ptr to the shadowing table -;........................ Shape header values .............................. -ShapeType EQU DWORD PTR ebp - 34h ;DWORD shape type -ShapeWidth EQU DWORD PTR ebp - 38h ;DWORD shape's unscaled width -ShapeHeight EQU DWORD PTR ebp - 3Ch ;DWORD shape's unscaled height -UncompDataLen EQU DWORD PTR ebp - 40h ;DWORD uncompressed data length -ShapeData EQU DWORD PTR ebp - 44h ;DWORD pointer to shape data -;...................... Scaled shape dimensions ............................ -ScaledWidth EQU DWORD PTR ebp - 48h ;DWORD shape's scaled width -ScaledHeight EQU DWORD PTR ebp - 4Ch ;DWORD shape's scaled height -;...................... Pixel clipping variables ........................... -LeftClipPixels EQU DWORD PTR ebp - 50h ;DWORD # left-clipped pixels -RightClipPixels EQU DWORD PTR ebp - 54h ;DWORD # right-clipped pixels -TopClipPixels EQU DWORD PTR ebp - 58h ;DWORD # top-clipped pixels -BotClipPixels EQU DWORD PTR ebp - 5Ch ;DWORD # bottom-clipped pixels -PixelWidth EQU DWORD PTR ebp - 60h ;DWORD drawable area in pixels -PixelHeight EQU DWORD PTR ebp - 64h ;DWORD drawable area in pixels -;......................... Drawing variables ............................... -NumColors EQU DWORD PTR ebp - 68h ;DWORD # colors for 16-color shapes -StartDraw EQU DWORD PTR ebp - 6Ch ;DWORD offset of drawing start pos -NextLine EQU DWORD PTR ebp - 70h ;DWORD offset of next drawing line -LeftClipBytes EQU DWORD PTR ebp - 74h ;DWORD # left-clipped bytes -XTotal EQU DWORD PTR ebp - 78h ;DWORD accumulated x-pixels -XTotalInit EQU DWORD PTR ebp - 7Ch ;DWORD initial roundoff for XTotal -YTotal EQU DWORD PTR ebp - 80h ;DWORD accumulated y-pixels -HeightCount EQU DWORD PTR ebp - 84h ;DWORD ht counter for drawing lines -LineStart EQU DWORD PTR ebp - 88h ;DWORD address of start of line -WidthCount EQU DWORD PTR ebp - 8Ch ;DWORD counts down # bytes skipped -StashReg EQU DWORD PTR ebp - 90h ;DWORD temp variable for draw routines -MaskAdjust EQU DWORD PTR ebp - 94h ;DWORD priority buffer offset -BackAdjust EQU DWORD PTR ebp - 98h ;DWORD background buffer offset -StashECX EQU DWORD PTR ebp - 9Ch ;DWORD temp variable for ECX register -StashEDX EQU DWORD PTR ebp -0A0h ;DWORD temp variable for EDX register - -Local_Size EQU 00A4h ; Amt of data on stack: 4+last offset - -;****************************** Declarations ******************************* -;--------------------------------------------------------------------------- -; Global variables used by the shape routines, defined in drawshp.asm -;--------------------------------------------------------------------------- -GLOBAL C ShapeBuffer:DWORD -GLOBAL C ShapeBufferSize:DWORD -GLOBAL C _MaskPage:DWORD -GLOBAL C _BackGroundPage:DWORD -GLOBAL C PredCount:DWORD -GLOBAL C PredTable:BYTE -GLOBAL C PredValue:DWORD -GLOBAL C PartialPred:DWORD -GLOBAL C PartialCount:DWORD -GLOBAL C Flags:DWORD - -;--------------------------------------------------------------------------- -; External tables that are defined in ds_table.asm. -;--------------------------------------------------------------------------- -GLOBAL LSkipTable:DWORD -GLOBAL RSkipTable:DWORD -GLOBAL DrawTable:DWORD - -;------------------------------------------------------------------------------ -; Public functions, declared in the order they appear in the function tables. -;-------------------------------------------------------------------------------- -GLOBAL C Not_Supported:NEAR -; LSkipTable: -GLOBAL Left_Skip:NEAR ; ds_ls -GLOBAL Left_Reverse_Skip:NEAR ; ds_lrs -GLOBAL Left_Skip:NEAR ; ds_ls -GLOBAL Left_Reverse_Skip:NEAR ; ds_lrs -GLOBAL Left_Scale_Skip:NEAR ; ds_lss -GLOBAL Left_Scale_Reverse_Skip:NEAR ; ds_lsrs -GLOBAL Left_Scale_Skip:NEAR ; ds_lss -GLOBAL Left_Scale_Reverse_Skip:NEAR ; ds_lsrs - -; RSkipTable: -GLOBAL Right_Skip:NEAR ; ds_rs -GLOBAL Right_Reverse_Skip:NEAR ; ds_rrs -GLOBAL Right_Skip:NEAR ; ds_rs -GLOBAL Right_Reverse_Skip:NEAR ; ds_rrs -GLOBAL Right_Scale_Skip:NEAR ; ds_rss -GLOBAL Right_Scale_Reverse_Skip:NEAR ; ds_rsrs -GLOBAL Right_Scale_Skip:NEAR ; ds_rss -GLOBAL Right_Scale_Reverse_Skip:NEAR ; ds_rsrs - -; DrawTable: -GLOBAL Draw_Normal:NEAR ; ds_dn -GLOBAL Draw_Reverse:NEAR ; ds_dr -GLOBAL Draw_Normal:NEAR ; ds_dn -GLOBAL Draw_Reverse:NEAR ; ds_dr -GLOBAL Draw_Scale:NEAR ; ds_ds -GLOBAL Draw_Scale_Reverse:NEAR ; ds_dsr -GLOBAL Draw_Scale:NEAR ; ds_ds -GLOBAL Draw_Scale_Reverse:NEAR ; ds_dsr - - -;************************* End of shape.inc ******************************** - diff --git a/code/TIBERIANDAWN/WIN32LIB/SOUND.H b/code/TIBERIANDAWN/WIN32LIB/SOUND.H deleted file mode 100644 index ff72582..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/SOUND.H +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : SOUND.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : September 1, 1993 * - * * - * Last Update : September 1, 1993 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef SOUND_H -#define SOUND_H - -//#define HMI_DRIVER TRUE -//#include "sos.h" -#include "soscomp.h" -#include "dsound.h" - -/* -** Maximum number of sound effects that may run at once. -*/ -#define MAX_SFX 5 - -/* -** Size of temp HMI low memory staging buffer. -*/ -#define SECONDARY_BUFFER_SIZE (1024*32) - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/SOUNDINT.H b/code/TIBERIANDAWN/WIN32LIB/SOUNDINT.H deleted file mode 100644 index 76171df..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/SOUNDINT.H +++ /dev/null @@ -1,289 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Westwood 32 bit Library * - * * - * File Name : SOUNDINT.H * - * * - * Programmer : Phil W. Gorrow * - * * - * Start Date : June 23, 1995 * - * * - * Last Update : June 23, 1995 [PWG] * - * * - * This file is the include file for the Westwood Sound Sytem defines and * - * routines that are handled in an interrupt. - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "sound.h" - -/* -** Defines for true and false. These are included because we do not allow -** the sound int to include any of the westwood standard headers. If we -** did, there might be too much temptation to call another library function. -** this would be bad, because then that function would not be locked. -*/ -#define FALSE 0 -#define TRUE 1 - -/* -** Define the different type of sound compression avaliable to the westwood -** library. -*/ -typedef enum { - SCOMP_NONE=0, // No compression -- raw data. - SCOMP_WESTWOOD=1, // Special sliding window delta compression. - SCOMP_SONARC=33, // Sonarc frame compression. - SCOMP_SOS=99 // SOS frame compression. -} SCompressType; - -/* -** This is the safety overrun margin for the sonarc compressed -** data frames. This value should be equal the maximum 'order' times -** the maximum number of bytes per sample. It should be evenly divisible -** by 16 to aid paragraph alignment. -*/ -#define SONARC_MARGIN 32 - - -/* -** Define the sample control structure which helps us to handle feeding -** data to the sound interrupt. -*/ -#pragma pack(1); -typedef struct { - /* - ** This flags whether this sample structure is active or not. - */ - unsigned Active; - //unsigned Active:1; - - /* - ** This flags whether the sample is loading or has been started. - */ - //unsigned Loading:1; - unsigned Loading; - - /* - ** This semaphore ensures that simultaneous update of this structure won't - ** occur. This is necessary since both interrupt and regular code can modify - ** this structure. - */ - //unsigned DontTouch:1; - unsigned DontTouch; - - /* - ** If this sample is really to be considered a score rather than - ** a sound effect, then special rules apply. These largely fall into - ** the area of volume control. - */ - //unsigned IsScore:1; - unsigned IsScore; - - /* - ** This is the original sample pointer. It is used to control the sample based on - ** pointer rather than handle. The handle method is necessary when more than one - ** sample could be playing simultaneously. The pointer method is necessary when - ** the dealing with a sample that may have stopped behind the programmer's back and - ** this occurance is not otherwise determinable. It is also used in - ** conjunction with original size to unlock a sample which has been DPMI - ** locked. - */ - void const *Original; - long OriginalSize; - - /* - ** These are pointers to the double buffers. - */ - LPDIRECTSOUNDBUFFER PlayBuffer; - - /* - ** Variable to keep track of the playback rate of this buffer - */ - int PlaybackRate; - - /* - ** Variable to keep track of the sample type ( 8 or 16 bit ) of this buffer - */ - int BitSize; - - /* - ** Variable to keep track of the stereo ability of this buffer - */ - int Stereo; - - /* - ** The number of bytes in the buffer that has been filled but is not - ** yet playing. This value is normally the size of the buffer, - ** except for the case of the last bit of the sample. - */ - LONG DataLength; - - /* - ** This is the buffer index for the low buffer that - ** has been filled with data but not yet being - ** played. - */ -// short int Index; - - /* - ** Pointer into the play buffer for writing the next - ** chunk of sample to - ** - */ - VOID *DestPtr; - - /* - ** This flag indicates that there is more source data - ** to copy to the play buffer - ** - */ - BOOL MoreSource; - - /* - ** This flag indicates that the entire sample fitted inside the - ** direct sound secondary buffer - ** - */ - BOOL OneShot; - - /* - ** Pointer to the sound data that has not yet been copied - ** to the playback buffers. - */ - VOID *Source; - - /* - ** This is the number of bytes remaining in the source data as - ** pointed to by the "Source" element. - */ - LONG Remainder; - - /* - ** Object to use with Enter/LeaveCriticalSection - ** - */ - CRITICAL_SECTION AudioCriticalSection; - - /* - ** Samples maintain a priority which is used to determine - ** which sounds live or die when the maximum number of - ** sounds are being played. - */ - int Priority; - - /* - ** This is the handle as returned by sosDIGIStartSample function. - */ - short int Handle; - - /* - ** This is the current volume of the sample as it is being played. - */ - int Volume; - int Reducer; // Amount to reduce volume per tick. - - /* - ** This is the compression that the sound data is using. - */ - SCompressType Compression; - short int TrailerLen; // Number of trailer bytes in buffer. - BYTE Trailer[SONARC_MARGIN]; // Maximum number of 'order' samples needed. - - - DWORD Pitch; - WORD Flags; - - /* - ** This flag indicates whether this sample needs servicing. - ** Servicing entails filling one of the empty low buffers. - */ - short int Service; - - /* - ** This flag is TRUE when the sample has stopped playing, - ** BUT there is more data available. The sample must be - ** restarted upon filling the low buffer. - */ - BOOL Restart; - - /* - ** Streaming control handlers. - */ - BOOL (*Callback)(short int id, short int *odd, VOID **buffer, LONG *size); - VOID *QueueBuffer; // Pointer to continued sample data. - LONG QueueSize; // Size of queue buffer attached. - short int Odd; // Block number tracker (0..StreamBufferCount-1). - int FilePending; // Number of buffers already filled ahead. - long FilePendingSize; // Number of bytes in last filled buffer. - - /* - ** The file variables are used when streaming directly off of the - ** hard drive. - */ - int FileHandle; // Streaming file handle (ERROR = not in use). - VOID *FileBuffer; // Temporary streaming buffer (allowed to be freed). - /* - ** The following structure is used if the sample if compressed using - ** the sos 16 bit compression Codec. - */ - - _SOS_COMPRESS_INFO sosinfo; - - -} SampleTrackerType; - - -typedef struct LockedData { - unsigned int DigiHandle; // = -1; - BOOL ServiceSomething; // = FALSE; - long MagicNumber; // = 0xDEAF; - VOID *UncompBuffer; // = NULL; - long StreamBufferSize; // = (2*SECONDARY_BUFFER_SIZE)+128; - short StreamBufferCount; // = 32; - SampleTrackerType SampleTracker[MAX_SFX]; - unsigned int SoundVolume; - unsigned int ScoreVolume; - BOOL _int; -} LockedDataType; - -extern LockedDataType LockedData; -#pragma pack(4); - -void Init_Locked_Data(void); -long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size); -long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, short int *trailersize); -VOID far __cdecl maintenance_callback(VOID); -VOID __cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid); -void far HMI_TimerCallback(void); -void *Audio_Add_Long_To_Pointer(void const *ptr, long size); -void DPMI_Unlock(VOID const *ptr, long const size); -extern "C" { - void __cdecl Audio_Mem_Set(void const *ptr, unsigned char value, long size); -// void Mem_Copy(void *source, void *dest, unsigned long bytes_to_copy); - long __cdecl Decompress_Frame(void * source, void * dest, long size); - int __cdecl Decompress_Frame_Lock(void); - int __cdecl Decompress_Frame_Unlock(void); - int __cdecl sosCODEC_Lock(void); - int __cdecl sosCODEC_Unlock(void); - void __GETDS(void); -} diff --git a/code/TIBERIANDAWN/WIN32LIB/STAMP.INC b/code/TIBERIANDAWN/WIN32LIB/STAMP.INC deleted file mode 100644 index c629e23..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/STAMP.INC +++ /dev/null @@ -1,56 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -; This is the control structure at the start of a loaded icon set. It must match -; the structure in ICONSET.C! This structure MUST be a multiple of 16 bytes long. - -ifdef NO_WAY_THIS_WILL_BE_DEFINED_HAHAHAHA - - STRUC IControl_Type -Width DW ? ; Width in pixels (per icon). -Height DW ? ; Height in pixels (per icon). -Count DW ? ; Number of icons in this set. -Allocated DW ? ; Was this iconset allocated? -Size DD ? ; Size of entire iconset memory block. -Icons DD ? ; Offset from buffer start to icon data. -Palettes DD ? ; Offset from buffer start to palette data. -Remaps DD ? ; Offset from buffer start to remap index data. -TransFlag DD ? ; Offset for transparency flag data. -Map DD ? ; Icon map offset. - ENDS - -else - - - STRUC IControl_Type - -Width DW ? ; Width in pixels (per icon). -Height DW ? ; Height in pixels (per icon). -Count DW ? ; Number of icons in this set. -Allocated DW ? ; Was this iconset allocated? -MapWidth DW ? -MapHeight DW ? -Size DD ? ; Size of entire iconset memory block. -Icons DD ? ; Offset from buffer start to icon data. -Palettes DD ? ; Offset from buffer start to palette data. -Remaps DD ? ; Offset from buffer start to remap index data. -TransFlag DD ? ; Offset for transparency flag data. -ColorMap DD ? -Map DD ? ; Icon map offset. - ENDS - -endif - -ICON256 EQU 1 diff --git a/code/TIBERIANDAWN/WIN32LIB/STRUCTS.H b/code/TIBERIANDAWN/WIN32LIB/STRUCTS.H deleted file mode 100644 index 995ebb5..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/STRUCTS.H +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB32 Examples * - * * - * File Name : STRUCTS.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - diff --git a/code/TIBERIANDAWN/WIN32LIB/SVGAPRIM.INC b/code/TIBERIANDAWN/WIN32LIB/SVGAPRIM.INC deleted file mode 100644 index 33813ca..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/SVGAPRIM.INC +++ /dev/null @@ -1,74 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : SVGAPRIM.INC * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : December 8, 1994 * -;* * -;* Last Update : December 8, 1994 [PWG] * -;* * -;*-------------------------------------------------------------------------* - -; Externs from VIDEO.CPP module of the VIDEO library -GLOBAL BankTable :DWORD -GLOBAL VesaFunc :DWORD -GLOBAL XRes :DWORD -GLOBAL YRes :DWORD -GLOBAL CurrentMode :DWORD -global cpu_video_page :dword -global cpu_page_limit :dword - - -; Externs from VESA.ASM module of the SVGAPRIM library -GLOBAL Vesa_Asm_Set_Win :NEAR -GLOBAL Vesa_Asm_Next_Win :NEAR - -; Externs from VGETPIX.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Get_Pixel :NEAR - -; Externs from VPUTTPIX.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Put_Pixel :NEAR - - -; Externs from VCLEAR.ASM module of the MCGA/SVGAPRIM library -GLOBAL Vesa_Clear :NEAR - -; Externs from VBITBLIT.ASM module of the MCGA/SVGAPRIM library -GLOBAL Linear_Blit_To_Vesa :NEAR -GLOBAL Vesa_Blit_To_Linear :NEAR -GLOBAL Vesa_Blit_To_Vesa :NEAR - -; Externs from VTOBUFF.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_To_Buffer :NEAR - -; Externs from VTOPAGE.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Buffer_To_Page :NEAR - -; Externs from VSCALE.ASM module of the SVGA/MCGAPRIM library -GLOBAL Linear_Scale_To_Vesa :NEAR -GLOBAL Vesa_Scale_To_Linear :NEAR -GLOBAL Vesa_Scale_To_Vesa :NEAR - - -; Externs from VSCALE.ASM module of the SVGA/MCGAPRIM library -GLOBAL Vesa_Print :NEAR diff --git a/code/TIBERIANDAWN/WIN32LIB/TILE.H b/code/TIBERIANDAWN/WIN32LIB/TILE.H deleted file mode 100644 index f6a5056..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/TILE.H +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Part of the TILE Library * - * * - * File Name : TILE.H * - * * - * Programmer : Barry W. Green * - * * - * Start Date : February 2, 1995 * - * * - * Last Update : February 2, 1995 [BWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TILE_H -#define TILE_H - -/*=========================================================================*/ -/* The following prototypes are for the file: ICONSET.CPP */ -/*=========================================================================*/ -void * Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize); -void Free_Icon_Set(void const *iconset); -long Get_Icon_Set_Size(void const *iconset); -int Get_Icon_Set_Width(void const *iconset); -int Get_Icon_Set_Height(void const *iconset); -void * Get_Icon_Set_Icondata(void const *iconset); -void * Get_Icon_Set_Trans(void const *iconset); -void * Get_Icon_Set_Remapdata(void const *iconset); -void * Get_Icon_Set_Palettedata(void const *iconset); -int Get_Icon_Set_Count(void const *iconset); -void * Get_Icon_Set_Map(void const *iconset); - - - -#if (1) -/* -** This is the control structure at the start of a loaded icon set. It must match -** the structure in WWLIB.I! This structure MUST be a multiple of 16 bytes long. -*/ - -// C&C version of struct -typedef struct { - short Width; // Width of icons (pixels). - short Height; // Height of icons (pixels). - short Count; // Number of (logical) icons in this set. -// BOOL Allocated; // Was this iconset allocated? - short Allocated; // Was this iconset allocated? - long Size; // Size of entire iconset memory block. - unsigned char *Icons; // Offset from buffer start to icon data. - long Palettes; // Offset from buffer start to palette data. - long Remaps; // Offset from buffer start to remap index data. - long TransFlag; // Offset for transparency flag table. - unsigned char *Map; // Icon map offset (if present). -} IControl_Type; - - -#else - -// RA version of struct -typedef struct { - short Width; // Width of icons (pixels). - short Height; // Height of icons (pixels). - short Count; // Number of (logical) icons in this set. - short Allocated; // Was this iconset allocated? - short MapWidth; // Width of map (in icons). - short MapHeight; // Height of map (in icons). - long Size; // Size of entire iconset memory block. - long Icons; // Offset from buffer start to icon data. -// unsigned char * Icons; // Offset from buffer start to icon data. - long Palettes; // Offset from buffer start to palette data. - long Remaps; // Offset from buffer start to remap index data. - long TransFlag; // Offset for transparency flag table. - long ColorMap; // Offset for color control value table. - long Map; // Icon map offset (if present). -// unsigned char * Map; // Icon map offset (if present). -} IControl_Type; - -#endif - - -#endif //TILE_H diff --git a/code/TIBERIANDAWN/WIN32LIB/TIMER.CPP b/code/TIBERIANDAWN/WIN32LIB/TIMER.CPP deleted file mode 100644 index fb1cc38..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/TIMER.CPP +++ /dev/null @@ -1,200 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Temp timer for 32bit lib * - * * - * File Name : TIMER.CPP * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : July 6, 1994 * - * * - * Last Update : May 3, 1995 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * TC::Time -- Return the time on the timer. * - * TC::TimerClass -- Construct a timer class object. * - * TC::Stop -- Stop the timer. * - * TC::Start -- Start a timer. * - * TC::Set -- Set the time of a timer. * - * TC::Reset -- Clear the timer. * - * TimerClass::Time -- Get the current time of timer. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include "timer.H" -#include -#include - - -///////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////// Code //////////////////////////////////////// - -/*************************************************************************** - * TC::TIMERCLASS -- Construct a timer class object. * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - *=========================================================================*/ -TimerClass::TimerClass(BaseTimerEnum timer, BOOL on) -{ - Accumulated = 0; - Started = 0; - - TickType=timer; - - if (on && TimerSystemOn) Start(); -} - - - - -/*********************************************************************************************** - * TC:Get_Ticks -- return the number of ticks on the system or user timers * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: tick count * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/5/95 4:17PM ST : Created * - *=============================================================================================*/ - -long TimerClass::Get_Ticks ( void ) - -{ - if ( WindowsTimer ){ - switch ( TickType ){ - - case BT_SYSTEM : - return ( WindowsTimer->Get_System_Tick_Count() ); - - case BT_USER : - return ( WindowsTimer->Get_User_Tick_Count() ); - - } - } - return 0; -} - - - -/*************************************************************************** - * TIMERCLASS::TIME -- Get the current time of timer. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/03/1995 SKB : Created. * - *=========================================================================*/ -long TimerClass::Time(void) -{ - if (Started) { - long ticks = Get_Ticks(); - Accumulated += ticks - (Started-1); - Started = ticks+1; - } - return(Accumulated); -} - - -/*************************************************************************** - * TC::STOP -- Stop the timer. * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - *=========================================================================*/ -long TimerClass::Stop(void) -{ - long time = Time(); - Started = 0; - return(time); -} - - -/*************************************************************************** - * TC::START -- Start a timer. * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - *=========================================================================*/ -long TimerClass::Start(void) -{ - if (!Started) { - Started = Get_Ticks()+1; - } - return(Time()); -} - - -/*************************************************************************** - * TC::SET -- Set the time of a timer. * - * * - * * - * * - * INPUT: long value to set timer at. * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - * 05/03/1995 SKB : If start return Start since it returns Time * - *=========================================================================*/ -long TimerClass::Set(long value, BOOL start) -{ - Started = 0; - Accumulated = value; - if (start) return (Start()); - return(Time()); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/TIMER.H b/code/TIBERIANDAWN/WIN32LIB/TIMER.H deleted file mode 100644 index fb5d986..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/TIMER.H +++ /dev/null @@ -1,198 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Timer Class Functions * - * * - * File Name : TIMER.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : July 6, 1994 * - * * - * Last Update : July 12, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef TIMER_H -#define TIMER_H - - -#ifndef WIN32 -#define WIN32 1 -#ifndef _WIN32 // Denzil 6/2/98 Watcom 11.0 complains without this check -#define _WIN32 -#endif // _WIN32 -#endif -#include -#include - -/*=========================================================================*/ -/* The following prototypes are for the file: TIMERA.ASM */ -/*=========================================================================*/ - -////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////// Externs ///////////////////////////////////////////// -extern BOOL TimerSystemOn; -extern HANDLE TimerThreadHandle; //Handle of timer thread -extern int InTimerCallback; //true if we are currently in a callback - - -/*=========================================================================*/ -typedef enum BaseTimerEnum { - BT_SYSTEM, // System timer (60 / second). - BT_USER // User controllable timer (? / second). -} BaseTimerEnum; - -class TimerClass { - public: - // Constructor. Timers set before low level init has been done will not - // be able to be 'Started' or 'on' until timer system is in place. - TimerClass(BaseTimerEnum timer=BT_SYSTEM, BOOL start=FALSE); - - // No destructor. - ~TimerClass(void){} - - // - long Set(long value, BOOL start=TRUE); // Set initial timer value. - long Stop(void); // Pause timer. - long Start(void); // Resume timer. - long Reset(BOOL start=TRUE); // Reset timer to zero. - long Time(void); // Fetch current timer value. - - protected: - long Started; // Time last started (0 == not paused). - long Accumulated; // Total accumulated ticks. - - private: -// long (*Get_Ticks)(void); // System timer fetch. - BaseTimerEnum TickType; - long Get_Ticks (void); -}; - - -inline long TimerClass::Reset(BOOL start) -{ - return(Set(0, start)); -} - - -class CountDownTimerClass : private TimerClass { - public: - // Constructor. Timers set before low level init has been done will not - // be able to be 'Started' or 'on' until timer system is in place. - CountDownTimerClass(BaseTimerEnum timer, long set, int on=FALSE); - CountDownTimerClass(BaseTimerEnum timer=BT_SYSTEM, int on=FALSE); - - // No destructor. - ~CountDownTimerClass(void){} - - // Public functions - long Set(long set, BOOL start=TRUE); // Set count down value. - long Reset(BOOL start=TRUE); // Reset timer to zero. - long Stop(void); // Pause timer. - long Start(void); // Resume timer. - long Time(void); // Fetch current count down value. - - protected: - long DelayTime; // Ticks remaining before countdown timer expires. -}; - -inline long CountDownTimerClass::Stop(void) -{ - TimerClass::Stop(); - return(Time()); -} - -inline long CountDownTimerClass::Start(void) -{ - TimerClass::Start(); - return(Time()); -} - -inline long CountDownTimerClass::Reset(BOOL start) -{ - return (TimerClass::Reset(start)); -} - - - - -class WinTimerClass { - - public: - WinTimerClass ( UINT freq=60 , BOOL partial=0 ); - ~WinTimerClass(); - - void Update_Tick_Count ( void ); - unsigned Get_System_Tick_Count ( void ); - unsigned Get_User_Tick_Count ( void ); - - private: - - unsigned TimerHandle; //Handle for windows timer event - unsigned Frequency; //Frequency of our windows timer in ticks per second - - unsigned TrueRate; //True rate of clock. (only use word) - unsigned SysTicks; //Tick count of timer. - unsigned UserTicks; //Tick count of timer. - unsigned UserRate; //Desired rate of timer. - - -}; - - -extern WinTimerClass *WindowsTimer; - - - - - - - - -////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////// externs ////////////////////////////////////////// -#ifndef FUNCTION_H -extern TimerClass TickCount; -#endif -extern CountDownTimerClass CountDown; - -////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////// Prototypes ////////////////////////////////////////// - -extern "C" { - long __cdecl Get_System_Tick_Count(void); - long __cdecl Get_User_Tick_Count(void); - void far __cdecl Timer_Interrupt_Func(void); -// long Get_Num_Interrupts(unsigned int realmode); - void __cdecl Disable_Timer_Interrupt(void); - void __cdecl Enable_Timer_Interrupt(void); -} - -/*=========================================================================*/ -/* The following prototypes are for the file: TIMER.CPP */ -/*=========================================================================*/ -BOOL __cdecl Init_Timer_System(unsigned int freq, int partial = FALSE); -BOOL __cdecl Remove_Timer_System(VOID); - - -#endif // TIMER_H - diff --git a/code/TIBERIANDAWN/WIN32LIB/TIMERDWN.CPP b/code/TIBERIANDAWN/WIN32LIB/TIMERDWN.CPP deleted file mode 100644 index 90fea6e..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/TIMERDWN.CPP +++ /dev/null @@ -1,123 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Temp timer for 32bit lib * - * * - * File Name : TIMER.CPP * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : July 6, 1994 * - * * - * Last Update : July 12, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * CDTC::Time -- Return the time on the timer. * - * CDTC::Stop -- Stop the timer. * - * CDTC::Start -- Start a timer. * - * CDTC::DownTimerClass -- Construct a timer class object. * - * CDTC::Set -- Set the time of a timer. * - * CDTC::Reset -- Clear the timer. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include "timer.H" - -///////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////// Defines ///////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////// Code //////////////////////////////////////// - - -/*************************************************************************** - * TC::CountDownTimerClass -- Construct a timer class object. * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - *=========================================================================*/ -CountDownTimerClass::CountDownTimerClass(BaseTimerEnum timer, long set, int on) - :TimerClass(timer, on) -{ - Set(set, on); -} - -CountDownTimerClass::CountDownTimerClass(BaseTimerEnum timer, int on) - :TimerClass(timer, FALSE) -{ - DelayTime = 0; - if (on) Start(); -} - - -/*************************************************************************** - * CDTC::TIME -- Return the time on the timer. * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - *=========================================================================*/ -long CountDownTimerClass::Time() -{ - long ticks = DelayTime - TimerClass::Time(); - - if (ticks < 0) { - ticks = 0; - } - return(ticks); -} - - -/*************************************************************************** - * CDTC::SET -- Set the time of a timer. * - * * - * * - * * - * INPUT: ULONG value to set timer at. * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/12/1994 SKB : Created. * - *=========================================================================*/ -long CountDownTimerClass::Set(long value, BOOL start) -{ - DelayTime = value; - TimerClass::Reset(start); - return(Time()); -} - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/TIMERINI.CPP b/code/TIBERIANDAWN/WIN32LIB/TIMERINI.CPP deleted file mode 100644 index 6cca626..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/TIMERINI.CPP +++ /dev/null @@ -1,312 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Temp timer for 32bit lib * - * * - * File Name : TIMERINI.CPP * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : July 6, 1994 * - * * - * Last Update : July 6, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Init_Timer_System -- Initialize the WW timer system. * - * Remove_Timer_System -- Removes the timer system. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include -#include "timer.H" -#include -#include - -///////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////// Defines ///////////////////////////////////// - -#define COPY_FROM_MEM TRUE - -///////////////////////////////////////////////////////////////////////////////// -////////////////////////////// timera.asm functions////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif - -extern BOOL Install_Timer_Interrupt(VOID *bin_ptr, UINT rm_size, UINT freq, BOOL partial); -extern BOOL Remove_Timer_Interrupt(VOID); - -#ifdef __cplusplus -} -#endif - -///////////////////////////////////////////////////////////////////////////////// -/////////////////////////////// Global Data ///////////////////////////////////// - -BOOL TimerSystemOn = FALSE; - -// Global timers that the library or user can count on existing. -TimerClass TickCount(BT_SYSTEM); -CountDownTimerClass CountDown(BT_SYSTEM, 0); - - -// Prototype for timer callback -void CALLBACK Timer_Callback ( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 ); - -HANDLE TimerThreadHandle = 0; //Handle of timer thread -int InTimerCallback = 0; //Flag to say if we are in a timer callback - -///////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////// Code //////////////////////////////////////// - - - -#pragma warning (disable : 4996) - - -/*************************************************************************** - * WinTimerClass::WinTimerClass -- Initialize the WW timer system. * - * * - * * - * INPUT: UINT : user timer frequency. * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/5/95 3:47PM : ST Created. * - *=========================================================================*/ -WinTimerClass::WinTimerClass (UINT freq, BOOL partial) -{ - BOOL success; - - // - // Inform windows that we want a higher than normal - // timer resolution - // -#ifdef __SW_EP - timeBeginPeriod(1000/PROFILE_RATE); - Frequency = PROFILE_RATE; -#else - timeBeginPeriod ( 1000/freq ); - Frequency = freq; -#endif - - - // - // Install the timer callback event handler - // - //TimerHandle = timeSetEvent ( 1000/freq , 1 , Timer_Callback , 0 , TIME_PERIODIC); - // Add TIME_KILL_SYNCHRONOUS flag. ST - 2/13/2019 5:07PM - TimerHandle = timeSetEvent ( 1000/freq , 1 , Timer_Callback , 0 , TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); - TimerSystemOn = success = ( TimerHandle !=0 ); - - if (success) { - if (!partial) { - WindowsTimer=this; - TickCount.Start(); - } - }else{ - char error_str [128]; - sprintf (error_str, "Error - timer system failed to start. Error code %d\n", GetLastError()); - OutputDebugString(error_str); - } -} - - - -/*************************************************************************** - * WinTimerClass::~WinTimerClass -- Removes the timer system. * - * * - * * - * INPUT: NONE. * - * * - * OUTPUT: BOOL was it removed successfuly * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/5/95 3:47PM : ST Created. * - *=========================================================================*/ -WinTimerClass::~WinTimerClass( void ) -{ - - if ( TimerHandle ){ - timeKillEvent ( TimerHandle ); - TimerHandle = 0; //ST - 2/13/2019 5:12PM - } - - TimerSystemOn = FALSE; - timeEndPeriod ( 1000/Frequency ); -} - - - - - -/*********************************************************************************************** - * Timer_Callback -- Main timer callback. Equivalent to a timer interrupt handler * - * * - * * - * * - * INPUT: uint timer ID * - * uint reserved * - * long 0 (application defined) * - * long reserved * - * long reserved * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/5/95 3:19PM ST : Created * - *=============================================================================================*/ - - -void CALLBACK Timer_Callback (UINT , UINT , DWORD , DWORD , DWORD) -{ - //CONTEXT context; - - InTimerCallback++; - - // Removed. ST - 2/13/2019 5:11PM - //if (!TimerThreadHandle){ - // DuplicateHandle (GetCurrentProcess(), GetCurrentThread() , GetCurrentProcess() ,&TimerThreadHandle , 0 , TRUE , DUPLICATE_SAME_ACCESS); - //} - - - if (WindowsTimer) { - WindowsTimer->Update_Tick_Count(); - } - InTimerCallback--; -} - - - - - - -/*********************************************************************************************** - * WinTimerClass::Update_Tick_Count -- update westwood timers * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/5/95 3:58PM ST : Created * - *=============================================================================================*/ - -void WinTimerClass::Update_Tick_Count ( void ) -{ -/* - * - * Increment westwood timers - * - */ - SysTicks++; - UserTicks++; - -} - - - - - - - - -/* -;*************************************************************************** -;* GET_NUM_INTERRUPTS -- Returns the number of interrupts that have occured* -;* * -;* INPUT: TRUE - returns num RM ints. * -;* FALSE - return num PM ints. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 07/12/1994 SKB : Created. * -;*=========================================================================* - PROC Get_Num_Interrupts C Near - USES esi - ARG realmode:DWORD - - mov esi,[RealModePtr] - cmp [realmode],0 - je ??prot_mode - mov eax,[(TimerType PTR esi).NumRMInts] - ret -??prot_mode: - mov eax,[(TimerType PTR esi).NumPMInts] - ret - - ENDP - */ - - - - -/*********************************************************************************************** - * WinTimerClass::Get_System_Tick_Count -- returns the system tick count * - * * - * INPUT: Nothing * - * * - * OUTPUT: tick count * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/5/95 4:02PM ST : Created * - *=============================================================================================*/ - -unsigned WinTimerClass::Get_System_Tick_Count ( void ) -{ - return ( SysTicks ); -} - - - -/*********************************************************************************************** - * WinTimerClass::Get_User_Tick_Count -- returns the user tick count * - * * - * INPUT: Nothing * - * * - * OUTPUT: tick count * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/5/95 4:02PM ST : Created * - *=============================================================================================*/ - -unsigned WinTimerClass::Get_User_Tick_Count ( void ) -{ - return ( UserTicks ); -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/TOBUFF.ASM b/code/TIBERIANDAWN/WIN32LIB/TOBUFF.ASM deleted file mode 100644 index b210cf3..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/TOBUFF.ASM +++ /dev/null @@ -1,294 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Westwood 32 bit Library * -;* * -;* File Name : TOBUFFER.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : June 8, 1994 * -;* Last Update : Feb 10, 1995 [jrj] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* VVC::TOBUFFER -- Copies a virtual viewport to a linear buffer * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -;IDEAL -;P386 -;MODEL USE32 FLAT -;LOCALS ?? -.model flat - - -TRANSP equ 0 - - -;INCLUDE "drawbuff.inc" -INCLUDE gbuffer.inc - - -;CODESEG -.code - - -;*************************************************************************** -;* VIVC::TOBUFFER -- Copies a virtual viewport to a linear buffer * -;* * -;* INPUT: BYTE * dest - buffer to copy to * -;* size - size of the buffer to copy to * -;* x_pixel - x pixel on viewport to copy from * -;* y_pixel - y pixel on viewport to copy from * -;* pixel_width - the width of copy region * -;* pixel_height - the height of copy region * -;* * -;* OUTPUT: none * -;* * -;* WARNINGS: Coordinates and dimensions will be adjusted if they exceed * -;* the boundaries. In the event that no adjustment is * -;* possible this routine will abort. If the size of the * -;* region to copy exceeds the size passed in for the buffer * -;* the routine will automatically abort. * -;* * -;* HISTORY: * -;* 06/15/1994 PWG : Created. * -;*=========================================================================* -Buffer_To_Buffer proc C public USES ebx ecx edx esi edi this_object:DWORD, x_pixel:DWORD, y_pixel:DWORD, pixel_width:DWORD, pixel_height:DWORD, dest:DWORD, buffer_size:DWORD - - ;PROC Buffer_To_Buffer C near - ;USES ebx,ecx,edx,esi,edi - - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ;ARG this_object:DWORD ; this is a class member function - ;ARG x_pixel:DWORD ; Page X pixel coordinate. - ;ARG y_pixel:DWORD ; Page Y pixel coordinate. - ;ARG pixel_width:DWORD ; Width of region in pixels. - ;ARG pixel_height:DWORD ; Height of region in pixels. - ;ARG dest:DWORD ; the buffer to copy to - ;ARG buffer_size:DWORD ; the size of the buffer - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL x1_pixel :dword - LOCAL y1_pixel :dword - LOCAL dest_x1 : dword - LOCAL dest_y1 : dword - LOCAL dest_ajust_width:DWORD - LOCAL scr_ajust_width:DWORD - ;LOCAL dest_area : dword - -; Clip dest Rectangle against source Window boundaries. - - mov [ dest_x1 ] , 0 - mov [ dest_y1 ] , 0 - - mov esi , [ this_object ] ; get ptr to dest - xor ecx , ecx - xor edx , edx - mov edi , [esi].GraphicViewPort.GVPWidth ; get width into register - mov ebx , [ x_pixel ] - mov eax , [ x_pixel ] - add ebx , [ pixel_width ] - shld ecx , eax , 1 - mov [ x1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - mov edi,[esi].GraphicViewPort.GVPHeight ; get height into register - mov ebx , [ y_pixel ] - mov eax , [ y_pixel ] - add ebx , [ pixel_height ] - shld ecx , eax , 1 - mov [ y1_pixel ] , ebx - inc edi - shld edx , ebx , 1 - sub eax , edi - sub ebx , edi - shld ecx , eax , 1 - shld edx , ebx , 1 - - xor cl , 5 - xor dl , 5 - mov al , cl - test dl , cl - jnz real_out - or al , dl - jz do_blit - - test cl , 1000b - jz scr_left_ok - mov eax , [ x_pixel ] - neg eax - mov [ x_pixel ] , 0 - mov [ dest_x1 ] , eax - -scr_left_ok: - test cl , 0010b - jz scr_bottom_ok - mov eax , [ y_pixel ] - neg eax - mov [ y_pixel ] , 0 - mov [ dest_y1 ] , eax - -scr_bottom_ok: - test dl , 0100b - jz scr_right_ok - mov eax , [esi].GraphicViewPort.GVPWidth ; get width into register - mov [ x1_pixel ] , eax -scr_right_ok: - test dl , 0001b - jz do_blit - mov eax , [esi].GraphicViewPort.GVPHeight ; get width into register - mov [ y1_pixel ] , eax - -do_blit: - - cld - - mov eax , [esi].GraphicViewPort.GVPXAdd - add eax , [esi].GraphicViewPort.GVPWidth - add eax , [esi].GraphicViewPort.GVPPitch - mov esi , [esi].GraphicViewPort.GVPOffset - - mov ecx , eax - mul [ y_pixel ] - add esi , [ x_pixel ] - add esi , eax - - add ecx , [ x_pixel ] - sub ecx , [ x1_pixel ] - mov [ scr_ajust_width ] , ecx - - mov edi , [ dest ] - mov eax , [ pixel_width ] - sub eax , [ x1_pixel ] - add eax , [ x_pixel ] - mov [ dest_ajust_width ] , eax - - mov eax , [ dest_y1 ] - mul [ pixel_width ] - add eax , [ dest_x1 ] - add edi , eax - - mov edx , [ y1_pixel ] - mov eax , [ x1_pixel ] - sub edx , [ y_pixel ] - jle real_out - sub eax , [ x_pixel ] - jle real_out - - mov ebx , [ pixel_width ] - imul ebx , edx - cmp ebx , [ buffer_size ] - jg real_out - - -; ******************************************************************** -; Forward bitblit only - -IF TRANSP - cmp [ transp ] , 0 - jnz forward_Blit_trans -ENDIF - -; the inner loop is so efficient that -; the optimal consept no longer apply because -; the optimal byte have to by a number greather than 9 bytes - cmp eax , 10 - jl forward_loop_bytes - -forward_loop_dword: - mov ecx , edi - mov ebx , eax - neg ecx - and ecx , 3 - sub ebx , ecx - rep movsb - mov ecx , ebx - shr ecx , 2 - rep movsd - mov ecx , ebx - and ecx , 3 - rep movsb - add esi , [ scr_ajust_width ] - add edi , [ dest_ajust_width ] - dec edx - jnz forward_loop_dword - ret - -forward_loop_bytes: - mov ecx , eax - rep movsb - add esi , [ scr_ajust_width ] - add edi , [ dest_ajust_width ] - dec edx ; decrement the height - jnz forward_loop_bytes - ret - - -IF TRANSP - -forward_Blit_trans: - mov ecx , eax - and ecx , 01fh - lea ecx , [ ecx + ecx * 4 ] - neg ecx - shr eax , 5 - lea ecx , [ transp_reference + ecx * 2 ] - mov [ y1_pixel ] , ecx - -forward_loop_trans: - mov ecx , eax - jmp [ y1_pixel ] -forward_trans_line: - REPT 32 - local transp_pixel - mov bl , [ esi ] - test bl , bl - jz transp_pixel - mov [ edi ] , bl - transp_pixel: - inc esi - inc edi - ENDM - transp_reference: - dec ecx - jge forward_trans_line - add esi , [ scr_ajust_width ] - add edi , [ dest_ajust_width ] - dec edx - jnz forward_loop_trans - ret -ENDIF - -real_out: - ret - -;ENDP Buffer_To_Buffer -Buffer_To_Buffer endp - -END \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/VIDEO.H b/code/TIBERIANDAWN/WIN32LIB/VIDEO.H deleted file mode 100644 index 223d4e6..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/VIDEO.H +++ /dev/null @@ -1,216 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : 32 bit library * - * * - * File Name : VIDEO.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef VIDEO_H -#define VIDEO_H - -#ifndef WWSTD_H -#include "wwstd.h" -#endif - -/*=========================================================================*/ -/* The machine can be in one of the following graphic modes. The global */ -/* GraphicMode is set to one of these values. */ -/*=========================================================================*/ -#define CGA_MODE 4 // DOS 320x200 4 color mode -#define TGA_MODE 9 // TANDY 320x200 16 color mode -#define EGA_MODE 13 // DOS 320x200 16 color mode -#define MCGA_MODE 0x13 // DOS 320x200 256 color mode -#define VGA_MODE 0x13 // DOS 320x200 256 color mode -#define EEGA_MODE 14 // DOS 640x400 16 color mode -#define ETGA_MODE 9 // TANDY 640x400 16 color mode -#define HGA_MODE 7 // DOS 768x400 2 color mode -#define TXT_MODE 3 // DOS plain old color text mode -#define VESA_640X400_256 0x100 // VESA 640x400 256 color mode -#define VESA_640X480_256 0x101 // VESA 640x480 256 color mode -#define VESA_800X600_256 0x103 // VESA 800x600 256 color mode -#define VESA_1024X768_256 0x105 // VESA 1024x768 256 color mode -#define VESA_1280X400_256 0x107 // VESA 1280x400 256 color mode -#define VESA_TEXT_80X60 0x108 // VESA 80x60 text mode -#define VESA_TEXT_132X25 0x109 // VESA 132x25 text mode -#define VESA_TEXT_132X60 0x10C // VESA 132x60 text mode -#define RESET_MODE -1 -#define UNINITIALIZED_MODE -1 -#define VESA_MIN VESA_640X400_256 -#define VESA_MAX VESA_TEXT_132X60 - -/*=========================================================================*/ -/* Define the maximum number of bank entries */ -/*=========================================================================*/ -#define MAX_BANK_ENTRIES ((1280L*1024L)/65536L) - - -/*=========================================================================* - * VesaInfoType - General info about this VESA implementation * - * (Filled in by VESA BIOS Function 0) * - * * - * Signature - Will always be 'VESA' * - * Version - Version # * - * OEMString - OEM ID string * - * Capabilities - Not defined by VESA yet * - * AvailModes - List of available modes; terminated with -1 (0xffff) * - * TotalMemory - ??? * - * Reserved - Pads structure to 256 bytes total * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -typedef struct { - char Signature[4]; - short Version; - REALPTR OEMString; - long Capabilities; - REALPTR AvailModes; - short TotalMemory; - char Reserved[236]; -} VesaInfoType; - -#endif //NOT_FOR_WIN95 - -/*=========================================================================* - * VesaModeInfoType - Info about this VESA mode * - * (Filled in by VESA BIOS Function 1) * - * * - * Attributes - bit 0: 1 = mode is supported * - * bit 1: 1 = optional info available * - * bit 2: 1 = std BIOS output funcs valid in this mode * - * bit 3: 0 = monochrome, 1 = color * - * bit 4: 0 = text mode, 1 = graphics * - * WinA_Attributes - bit 0 = win exists, bit 1=readable, bit 2= writable * - * WinB_Attributes - bit 0 = win exists, bit 1=readable, bit 2= writable * - * WinGranularity - smallest address boundary window can be placed upon; * - * size is in KB (ie 64, 32, 4) * - * WinSize - size of windows in KB (ie 64, 32) * - * WinA_Segment - location of Window A in CPU space (usually 0xa000) * - * WinB_Segment - location of Window B in CPU space (usually 0xb000) * - * WinFunc - address of window-setting function (This is provided * - * as an alternative to Int 10 for speed.) * - * BytesPerScanline - # bytes per scan line * - * * - * Optional info (available if bit 1 of Attributes is set): * - * * - * XRes - X-resolution * - * YRes - Y-resolution * - * XCharSize - Horizontal size of char cell * - * YCharSize - Vertical size of char cell * - * NumPlanes - # of memory planes (???) * - * BitsPerPixel - # bites per pixel * - * NumBanks - # of banks (ie planes) * - * MemoryModel - 00h = Text mode * - * 01h = CGA mode * - * 02h = Hercules * - * 03h = 4 plane planar mode * - * 04h = packed pixel mode (1 byte/pixel) * - * 05h = non-chain 4, 256-color mode * - * 06-0Fh = * - * 10-FFh = OEM-specific * - * BankSize - Bank size in KB * - *=========================================================================*/ -#ifdef NOT_FOR_WIN95 -typedef struct { - short Attributes; - char WinA_Attributes; - char WinB_Attributes; - short WinGranularity; - short WinSize; - short WinA_Segment; - short WinB_Segment; - REALPTR WinFunc; - short BytesPerScanline; - short XRes; - short YRes; - char XCharSize; - char YCharSize; - char NumPlanes; - char BitsPerPixel; - char NumBanks; - char MemoryModel; - char BankSize; - char NumInputPages; - char Reserved; - char RedMaskSize; - char RedFieldPosition; - char GreenMaskSize; - char GreenFieldPosition; - char BlueMaskSize; - char BlueFieldPosition; - char RsvdMaskSize; - char RsvdFieldPosition; - char DirectColorModeInfo; - char pad[216]; -} VesaModeInfoType; - -extern REALPTR VesaFunc; - -#endif //NOT_FOR_WIN95 - - -extern "C" { -extern int GraphicMode; -extern long XRes; -extern long YRes; - -extern long BankTable []; -extern unsigned long RMVesaVector ; -extern unsigned long RMVesaRegs ; -} - -/*=========================================================================*/ -/* The following prototypes are for the file: VIDEO.CPP */ -/*=========================================================================*/ - -extern "C" int Set_Video_Mode(int mode); -int Get_Video_Mode(void); -void Update_Video_Mode (void) ; -void Vesa_Info(void); -void Vesa_Set_Window(long grain_num); -int Get_Original_Video_Mode(void); -void Set_Original_Video_Mode(int mode); - -/*=========================================================================*/ -/* The following prototypes are for the file: INITDLAY.CPP */ -/*=========================================================================*/ - -extern VOID Init_Delay(VOID); -extern BOOL VertBlank; - -/*=========================================================================*/ -/* The following prototypes are for the file: VERTBLNK.ASM */ -/*=========================================================================*/ - -extern "C" { - extern WORD Get_Vert_Blank(VOID); - extern VOID Wait_Vert_Blank(BOOL blank); -} - -/*=========================================================================*/ - -#endif // VIDEO_H \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/WINCOMM.H b/code/TIBERIANDAWN/WIN32LIB/WINCOMM.H deleted file mode 100644 index 5d26049..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WINCOMM.H +++ /dev/null @@ -1,454 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer/ WW Library * - * * - * File Name : WINCOMM.H * - * * - * Programmer : Steve Tall * - * * - * Start Date : 1/10/96 * - * * - * Last Update : January 10th 1996 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * * - * These classes was created to replace the greenleaf comms functions used in C&C DOS with * - * WIN32 API calls. * - * * - *---------------------------------------------------------------------------------------------* - * * - * Functions: * - * * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#ifndef WIN32 -#define WIN32 -#define _WIN32 -#endif //WIN32 -#include - -typedef enum WinCommDialMethodType { - WC_TOUCH_TONE = 0, - WC_PULSE -} WinCommDialMethodType; - - - -#define COMMSUCCESS 0 -#define ASTIMEOUT -10 -#define COMMUSERABORT -16 - - -/* -** The size of our serial buffer within the class. -** -** !!!!!! THIS MUST BE A POWER OF 2 !!!!!! -** -*/ -#define SIZE_OF_WINDOWS_SERIAL_BUFFER 2048 - - - -/* -** WinModemClass. -** -** This class provides access to modems under Win95. The functions are designed to be more or less -** drop in replacements for the Grenleaf comms functions. -*/ - -class WinModemClass -{ - - public: - - WinModemClass (void); //WinModemClass Contructor - virtual ~WinModemClass (void); //WinModemClass Destructor - - - /* - ** Serial port open should be called to get a handle to the COM port - ** This needs to be called first as other class members rely on the handle - ** - ** Replacement for Greenleaf function: PortOpenGreenleafFast - */ - //virtual HANDLE Serial_Port_Open (int port, int baud, int parity, int wordlen, int stopbits); - virtual HANDLE Serial_Port_Open (char *device_name, int baud, int parity, int wordlen, int stopbits, int flowcontrol); - - /* - ** This function releases the COM port handle and should be called after - ** communications have finished - ** - ** Replacement for Greenleaf function: PortClose - */ - void Serial_Port_Close (void); - - /* - ** This member copies any bytes from the internal class serial buffer - ** into your user buffer. - ** - ** Replacement for Greenleaf function: ReadBuffer - */ - int Read_From_Serial_Port (unsigned char *dest_ptr, int buffer_len); - - /* - ** Write chars to the serial port - ** - ** Replacement for Greenleaf function: WriteBuffer - */ - void Write_To_Serial_Port (unsigned char *buffer, int length); - - /* - ** Wait for the outgoing buffer to empty - */ - void Wait_For_Serial_Write (void); - - /* - ** Set the dial type to DIAL_TOUCH_TONE or DIAL_PULSE - ** - ** Replacement for Greenleaf function: HMSetDiallingMethod - */ - virtual void Set_Modem_Dial_Type (WinCommDialMethodType method); - - /* - ** Get the status of the modem control lines - ** Possible flags are: CTS_SET DSR_SET RI_SET & CD_SET - ** - ** Replacement for Greenleaf function: GetModemStatus - */ - virtual unsigned Get_Modem_Status (void); - - /* - ** Set the DTR line to the given state - ** - ** Replacement for Greenleaf function: SetDtr - */ - virtual void Set_Serial_DTR (BOOL state); - - /* - ** Get the result code from the modem after issuing an 'AT' command - ** - ** Replacement for Greenleaf function: HMInputLine - */ - virtual int Get_Modem_Result (int delay, char *buffer, int buffer_len); - - /* - ** Issue a dial command to the modem. - ** Use Set_Modem_Dial_Type to select pulse or tone dial - ** - ** Replacement for Greenleaf function: HMDial - */ - virtual void Dial_Modem (char *dial_number); - - /* - ** Send a command to the modem. This is usually an 'AT' command. - ** Function will optionally retry until 'OK' is received. - */ - virtual int Send_Command_To_Modem (char *command, char terminator, char *buffer, int buflen, int delay, int retries); - - /* - ** Sets a pointer to a function that will be called for each incoming serial char - ** - ** Replacement for Greenleaf function: HMSetUpEchoRoutine - */ - virtual void Set_Echo_Function (void(*func)(char c)); - - /* - ** Sets a pointer to a function that will be called if ESC is pressed during a dial - ** - ** Replacement for Greenleaf function: HMSetUpAbortKey - */ - virtual void Set_Abort_Function (int (*func)(void)); - - /* - ** Member to allow access to the serial port handle - */ - HANDLE Get_Port_Handle(void); - - /* - ** Status vars for debugging purposes - */ - int FramingErrors; - int IOErrors; - int BufferOverruns; - int InBufferOverflows; - int ParityErrors; - int OutBufferOverflows; - int InQueue; - int OutQueue; - - /* - ** Modem send result codes - */ - enum SendModemEnum { - MODEM_CMD_TIMEOUT = 0, - MODEM_CMD_OK, - MODEM_CMD_0, - MODEM_CMD_ERROR - }; - - - /* - ** Enums for modem status flags - */ - enum { - CTS_SET = 0x10, - DSR_SET = 0x20, - RI_SET = 0x40, - CD_SET = 0x80 - }; - - - protected: - - - /* - ** Copy incoming data from the windows file buffer into the internal class buffer - */ - BOOL Read_Serial_Chars(void); - - /* - ** Pointer to the internal class circular buffer for incoming data - */ - unsigned char *SerialBuffer; - - /* - ** Overlap object for asyncronous reads from the serial port - */ - OVERLAPPED ReadOverlap; - - /* - ** Overlap object for asyncronous writes to the serial port - */ - OVERLAPPED WriteOverlap; - - /* - ** Flag that there is no outstanding incoming data in the windows buffer - */ - BOOL WaitingForSerialCharRead; - - /* - ** Flag that we are waiting for the last write to port operation to complete - */ - BOOL WaitingForSerialCharWrite; - - /* - ** Head and Tail pointers for our internal serial buffer - */ - int SerialBufferReadPtr; - int SerialBufferWritePtr; - - /* - ** Windows handle to the COM port device - */ - HANDLE PortHandle; - - /* - ** Dialing method - DIAL_TOUCH_TONE or DIAL_PULSE - */ - WinCommDialMethodType DialingMethod; - - /* - ** Pointer to function for echoing incoming data - can be NULL - */ - void (*EchoFunction)(char c); - - /* - ** Pointer to function for aborting when ESC pressed - can be NULL - */ - int (*AbortFunction)(void); - - /* - ** Serial buffer for asyncronous reads - */ - char TempSerialBuffer[SIZE_OF_WINDOWS_SERIAL_BUFFER]; -}; - - - - - - - - - - -/* -** WinNullModemClass. -** -** This class provides access to serial ports under Win95. The functions are designed to be more or less -** drop in replacements for the Grenleaf comms functions. -** -** This class just overloads the WinModemClass members that arent required for direct serial communications -** via a 'null modem' cable. -*/ -class WinNullModemClass : public WinModemClass -{ - - public: - - virtual inline void Set_Modem_Dial_Type (int){}; - virtual inline unsigned Get_Modem_Status (void){return (0);}; - virtual inline void Set_Serial_DTR (BOOL){}; - virtual inline int Get_Modem_Result (int, char*, int){return(0);}; - virtual inline void Dial_Modem (char*){}; - virtual inline int Send_Command_To_Modem (char*, char, char*, int, int, int){return (0);}; - virtual inline void Set_Echo_Function (void(*)(char)){}; - virtual inline void Set_Abort_Function (int(*)(void)){}; - -}; - - -extern WinModemClass *SerialPort; - - - - - - - - - -// -// -// This bit swiped from the SDK because its not in the Watcom headers yet -// -// - -/************************************************************************ -* * -* mcx.h -- This module defines the 32-Bit Windows MCX APIs * -* * -* Copyright (c) 1990-1995, Microsoft Corp. All rights reserved. * -* * -************************************************************************/ - -#ifndef _MCX_H_ -#define _MCX_H_ - -typedef struct _MODEMDEVCAPS { - DWORD dwActualSize; - DWORD dwRequiredSize; - DWORD dwDevSpecificOffset; - DWORD dwDevSpecificSize; - - // product and version identification - DWORD dwModemProviderVersion; - DWORD dwModemManufacturerOffset; - DWORD dwModemManufacturerSize; - DWORD dwModemModelOffset; - DWORD dwModemModelSize; - DWORD dwModemVersionOffset; - DWORD dwModemVersionSize; - - // local option capabilities - DWORD dwDialOptions; // bitmap of supported values - DWORD dwCallSetupFailTimer; // maximum in seconds - DWORD dwInactivityTimeout; // maximum in seconds - DWORD dwSpeakerVolume; // bitmap of supported values - DWORD dwSpeakerMode; // bitmap of supported values - DWORD dwModemOptions; // bitmap of supported values - DWORD dwMaxDTERate; // maximum value in bit/s - DWORD dwMaxDCERate; // maximum value in bit/s - - // Variable portion for proprietary expansion - BYTE abVariablePortion [1]; -} MODEMDEVCAPS, *PMODEMDEVCAPS, *LPMODEMDEVCAPS; - -typedef struct _MODEMSETTINGS { - DWORD dwActualSize; - DWORD dwRequiredSize; - DWORD dwDevSpecificOffset; - DWORD dwDevSpecificSize; - - // static local options (read/write) - DWORD dwCallSetupFailTimer; // seconds - DWORD dwInactivityTimeout; // seconds - DWORD dwSpeakerVolume; // level - DWORD dwSpeakerMode; // mode - DWORD dwPreferredModemOptions; // bitmap - - // negotiated options (read only) for current or last call - DWORD dwNegotiatedModemOptions; // bitmap - DWORD dwNegotiatedDCERate; // bit/s - - // Variable portion for proprietary expansion - BYTE abVariablePortion [1]; -} MODEMSETTINGS, *PMODEMSETTINGS, *LPMODEMSETTINGS; - -// Dial Options -#define DIALOPTION_BILLING 0x00000040 // Supports wait for bong "$" -#define DIALOPTION_QUIET 0x00000080 // Supports wait for quiet "@" -#define DIALOPTION_DIALTONE 0x00000100 // Supports wait for dial tone "W" - -// SpeakerVolume for MODEMDEVCAPS -#define MDMVOLFLAG_LOW 0x00000001 -#define MDMVOLFLAG_MEDIUM 0x00000002 -#define MDMVOLFLAG_HIGH 0x00000004 - -// SpeakerVolume for MODEMSETTINGS -#define MDMVOL_LOW 0x00000000 -#define MDMVOL_MEDIUM 0x00000001 -#define MDMVOL_HIGH 0x00000002 - -// SpeakerMode for MODEMDEVCAPS -#define MDMSPKRFLAG_OFF 0x00000001 -#define MDMSPKRFLAG_DIAL 0x00000002 -#define MDMSPKRFLAG_ON 0x00000004 -#define MDMSPKRFLAG_CALLSETUP 0x00000008 - -// SpeakerMode for MODEMSETTINGS -#define MDMSPKR_OFF 0x00000000 -#define MDMSPKR_DIAL 0x00000001 -#define MDMSPKR_ON 0x00000002 -#define MDMSPKR_CALLSETUP 0x00000003 - -// Modem Options -#define MDM_COMPRESSION 0x00000001 -#define MDM_ERROR_CONTROL 0x00000002 -#define MDM_FORCED_EC 0x00000004 -#define MDM_CELLULAR 0x00000008 -#define MDM_FLOWCONTROL_HARD 0x00000010 -#define MDM_FLOWCONTROL_SOFT 0x00000020 -#define MDM_CCITT_OVERRIDE 0x00000040 -#define MDM_SPEED_ADJUST 0x00000080 -#define MDM_TONE_DIAL 0x00000100 -#define MDM_BLIND_DIAL 0x00000200 -#define MDM_V23_OVERRIDE 0x00000400 - -#endif /* _MCX_H_ */ - - - - - - - - - - - - - - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/WINDOWS.CPP b/code/TIBERIANDAWN/WIN32LIB/WINDOWS.CPP deleted file mode 100644 index b31d434..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WINDOWS.CPP +++ /dev/null @@ -1,973 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: g:/library/source/rcs/./windows.c 1.12 1994/05/20 15:35:25 joe_bostic Exp $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : LIBRARY * - * * - * File Name : WINDOWS.C * - * * - * Programmer : Everyone * - * * - * Last Update : February 3, 1992 [DRD] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Change_New_Window -- Combined Change_Window and New_Window. * - * Change_Window -- Changes the 'current' window in the system. * - * Fetch_Char -- Gets one undipthonged char from input. * - * Flush_Line -- Outputs the accumulate text line to screen. * - * In_Char -- Stores (un-dipped) character(s) from input to buffer. * - * New_Window -- Clears the current window to the background color. * - * Set_More_Off -- Turns the 'more' prompting off. * - * Set_More_On -- Turns the 'more' prompting on. * - * Set_More_Prompt -- Adjusts the more prompt text for default routine * - * Standard_More_Prompt -- Default more prompt code for Window_Print * - * Window_Int_Print -- Prints an integer to the window. * - * Window_Print -- Displays and wraps text into a window. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include -#include -#include -#include -#include -#include "ww_win.h" -#include -#include -#include - -PRIVATE void Scroll_Window(void); -PRIVATE void Flush_Line(void); -PRIVATE void In_Char(char *str); -PRIVATE char Fetch_Char(void); - - -PRIVATE int ScrollCounter = 0; // Count of the lines displayed before a pause. -PRIVATE char Line[84]; // Staging line buffer. -PRIVATE int Pos; // Char Position of next free character. -PRIVATE int PPos; // Pixel position of next free character. -PRIVATE int WPos; // Char position in window. -PRIVATE char *MainSource; -PRIVATE char *AltSource; -PRIVATE char Char[2]; -PRIVATE char Stack; -PRIVATE char WordWrapFlag = FALSE; // flag for a word wrap. - -PRIVATE int MoreSpace = 7; -PRIVATE int MoreFColor = 0; -PRIVATE int MoreBColor = 0; - - -int WindowColumns=40; -int WindowLines=25; -int WindowWidth=40; -unsigned int WinB=0; -unsigned int WinC=1; -unsigned int WinX=0; -unsigned int WinY=0; -unsigned int WinCx=0; -unsigned int WinCy=0; -unsigned int WinH=25; -unsigned int WinW=40; -unsigned int Window=0; - -int MoreOn = TRUE; -char *TXT_MoreText = "--More--"; -void (*Window_More_Ptr)(char const *,int,int,int) = Standard_More_Prompt; - -extern GraphicViewPortClass *LogicPage; -/*************************************************************************** - * STANDARD_MORE_PROMPT -- Default more prompt code for Window_Print * - * * - * This is the standard "" prompting code that is used by * - * Window_Print when a page is full of text and a pause is desired * - * before the next page of text is printed. This function is called * - * through the Window_More_Ptr global. * - * * - * INPUT: prompt -- Pointer to ASCII text that will be window printed * - * at the right margin. * - * * - * space -- The number of spaces to allow for the 'more' text. * - * * - * fcolor -- The foreground color to use for the 'more' text. * - * * - * bcolor -- The background oclor to use for the 'more' text. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1991 JLB : Created. * - *=========================================================================*/ -void Standard_More_Prompt(char const *prompt, int space, int fcolor, int bcolor) -{ - int x, y, moresize; - - moresize = (space - 1) * (FontWidth+FontXSpacing); - x = ((WinX+WinW) << 3) - moresize; - //y = WinY + ((WinH/FontHeight)-1)*FontHeight; - y = WinY + (WinCy-1) * (FontHeight+FontYSpacing); - - // Default "more" prompter. - LogicPage->Print(prompt, x, y, fcolor ? fcolor : WindowList[Window][WINDOWBCOL], bcolor ? bcolor : WindowList[Window][WINDOWFCOL]); -//BG if (LogicPage == SEENPAGE) { -//BG Window_Show_Mouse(); -//BG } - - // PWG - have to figure out how to do this in windows library - -// Clear_KeyBuffer(); -// Get_Key(); - -//BG if (LogicPage == SEENPAGE) { -//BG Window_Hide_Mouse(Window); -//BG } - - // Erase the more prompt prompt. - // Text_Print(prompt, x, y, WinB, WinB); - LogicPage->Fill_Rect(x, y, x + moresize - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB); -} - - -/*************************************************************************** - * SET_MORE_PROMPT -- Adjusts the more prompt text for default routine * - * * - * Use this routine to control the text of the "" prompt that * - * the default more prompt routine uses. This can be useful for * - * foreign language translations. * - * * - * INPUT: prompt -- Pointer to ASCII text that will be window printed * - * at the right margin. * - * * - * space -- The number of spaces to allow for the 'more' text. * - * * - * fcolor -- The foreground color to use for the 'more' text. * - * * - * bcolor -- The background color to use for the 'more' text. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/29/1991 JLB : Created. * - *=========================================================================*/ -void Set_More_Prompt(char const *prompt, int space, int fcolor, int bcolor) -{ - if (prompt) { - TXT_MoreText = (char*)prompt; - MoreSpace = space; - MoreFColor = fcolor; - MoreBColor = bcolor; - } - else { - TXT_MoreText = ""; - MoreSpace = 7; - MoreFColor = MoreBColor = 0; - } -} - - -/*************************************************************************** - * SET_MORE_ON -- Turns the 'more' prompting on. * - * * - * Use this routine to turn on the 'more' prompting that Window_Print * - * does. If you have a custom more function pointer, then that * - * routine will be called, otherwise the library default 'more' prompt * - * will be utilized. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -void Set_More_On(void) -{ - MoreOn = TRUE; - ScrollCounter = 0; -} - - -/*************************************************************************** - * SET_MORE_OFF -- Turns the 'more' prompting off. * - * * - * This routine will turn the 'more' prompting that Window_Print does * - * off. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -void Set_More_Off(void) -{ - MoreOn = FALSE; -} - - -/*************************************************************************** - * CHANGE_WINDOW -- Changes the 'current' window in the system. * - * * - * Use this routine to change the 'current' window. The current window * - * is used in Window_Print and some other graphic output routines. * - * * - * INPUT: windnum -- The window number to change to. * - * * - * OUTPUT: Returns with the previously current window. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -int Change_Window(int windnum) -{ - int oldwindow; - int *data; - - oldwindow = Window; - Window = windnum; - data = &WindowList[windnum][0]; - - WinX = *data++; - WinY = *data++; - WinW = *data++; - WinH = *data++; - WinC = *data++; - WinB = *data++; - WinCx = *data++; - WinCy = *data++; - ScrollCounter = 0; - WPos = WinCx / (FontWidth+FontXSpacing); - WindowLines = (WinH-FontYSpacing) / (FontHeight+FontYSpacing); - WindowWidth = WinW << 3; - WindowColumns = WindowWidth / (FontWidth+FontXSpacing); - return (oldwindow); -} - - -/*************************************************************************** - * CHANGE_NEW_WINDOW -- Combined Change_Window and New_Window. * - * * - * This is a combo-routine. It merely combines the Change_Window * - * with the New_Window routines. It will save some (small) code if * - * you use this routine instead of the two function calls. * - * * - * INPUT: window -- Window number to change to and clear. * - * * - * OUTPUT: Returns with the previously current window. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -int Change_New_Window(int windnum) -{ - int oldwindow; - - oldwindow = Change_Window(windnum); - New_Window(); - return(oldwindow); -} - - -/*************************************************************************** - * NEW_WINDOW -- Clears the current window to the background color. * - * * - * This routine clears the current window to the background color. It * - * is used in preparation to Window_Print because it ensures a clean * - * 'slate' for the text. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -void New_Window(void) -{ - int x,y,w,h; - - x = WinX << 3; - y = WinY; - w = (WinX + WinW) << 3; - h = WinY + WinH; - - LogicPage->Fill_Rect(x, y, w - 1, h - 1, (unsigned char)WinB); - - WinCx = WPos = 0; - WinCy = 0; - ScrollCounter = 0; -} - - -/*************************************************************************** - * WINDOW_INT_PRINT -- Prints an integer to the window. * - * * - * Use this routine to print an integer to the window. This routine * - * as all other Window printing routines will handle word wrap. * - * * - * INPUT: num -- The integer to convert to ASCII and print. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -void Window_Int_Print(int num) -{ - Window_Print("%d", num); -} - - -/*************************************************************************** - * WINDOW_PRINT -- Displays and wraps text into a window. * - * * - * This is the general purpos text output routine that will handle * - * word wrap within a window. It is useful for displaying arbitrary * - * text. This routine will handle dipthonged text and as such it * - * can be quite useful in saving memory. * - * * - * INPUT: string -- String to print. This can be of ANY length and * - * can even contain some formatting codes. The * - * codes supported are: * - * * - * KA_SETX Forces the cursor X position to the value * - * specified. * - * * - * KA_SETY Forces the cursor Y position to the value * - * specified. * - * * - * KA_MORE Causes an immediate "" prompt * - * regardless of the scroll situation. * - * * - * KA_RETURN Breaks line and continues output at the * - * left edge of following line. * - * * - * * - * KA_FORMFEED Clears the window and continues printing at * - * the upper left corner. * - * * - * KA_SETBKGDCOL Set the background color with the color * - * specified by the following byte. * - * * - * * - * KA_SETFORECOL Set the foreground color with the color * - * specified by the following byte. * - * * - * KA_TAB Move the cursor over to the next tabstop. * - * Tabstops are set every 8 columns. * - * * - * KA_SPCTAB Insert spaces until the cursor is positioned * - * at the next tabstop. * - * * - * %s Replace the "%s" with the text pointed to * - * by the pointer argument passed to the * - * routine (follows same method a printf). * - * * - * %d Replace the "%d" with an integer ASCII * - * number of the int passed to the routine. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - * 07/29/1991 JLB : Added MORE, SETX, and SETY * - *=========================================================================*/ -void Window_Print(char const string[], ...) -{ - int oldcx, x, y; // Scratch variables. - char c; // Current character. - char buffer[10]; // Working %d buffer. - int old_c, old_b; // Original window colors. - va_list arg; // Argument list var. - - - va_start(arg, string); - - WordWrapFlag = FALSE; // initialize word wrap flag. - Pos = PPos = 0; - Line[0] = '\0'; - Char[0] = Char[1] = 0; - MainSource = (char*)&string[0]; - AltSource = NULL; - old_c = WinC; - old_b = WinB; - -//BG if (LogicPage == SEENPAGE) { -//BG Window_Hide_Mouse(Window); -//BG } - - while (TRUE) { - - c = Fetch_Char(); - - if (!c) break; // Exit on NULL character. - - /* - ** Substitution commands only work if not already expanding a - ** string. - */ - if (!AltSource) { - if (c == '%') { - switch(tolower(Char[0])) { - case 's': - AltSource = va_arg(arg, char*); - if (AltSource) { - Stack = Char[1]; - Char[0] = Char[1] = '\0'; - c = Fetch_Char(); - } - break; - - case 'd': - AltSource = buffer; - sprintf(buffer, "%d", va_arg(arg, int)); - Stack = Char[1]; - Char[0] = Char[1] = '\0'; - c = Fetch_Char(); - break; - - default: - break; - } - } - } - - switch(c) { - -#if(FALSE) - // these are the positions of foreign language characters - /* - ** These are characters that shouldn't be window printed because - ** they are currently reserved. - */ - case KA_CTRL_C: - case KA_CTRL_D: - case KA_CTRL_E: - case KA_CTRL_G: - case KA_CTRL_J: - case KA_CTRL_K: - case KA_CTRL_N: - case KA_CTRL_O: - case KA_CTRL_P: - case KA_CTRL_Q: - case KA_CTRL_R: - case KA_CTRL_T: - case KA_CTRL_U: - case KA_CTRL_V: - case KA_CTRL_W: - case KA_CTRL_Z: - case KA_CTRL_BACKSLASH: - case KA_CTRL_CARROT: - case KA_CTRL_UNDERLINE: - break; -#endif - /* - ** Force cursor column to specified X value. - */ - case KA_SETX: - Flush_Line(); - WPos = Fetch_Char(); - WPos = MAX(0, WPos); - - // WPos is max width char position - - WPos = MIN(WindowColumns-1, WPos); - WinCx = WPos * (FontWidth+FontXSpacing); - break; - - /* - ** Force the cursor to specified Y value. - */ - case KA_SETY: - Flush_Line(); - WinCy = Fetch_Char(); - //WinCy = MAX(0, WinCy); - WinCy = MIN((long)WindowLines-1, (long)WinCy); - break; - - /* - ** Force a "" prompt. - */ - case KA_MORE: - Flush_Line(); - if (Window_More_Ptr) { -//BG if (LogicPage == SEENPAGE) Window_Show_Mouse(); - Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor); -//BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window); - } - break; - - /* - ** Clear and home the window cursor. This is the same - ** as New_Window(). - */ - case KA_FORMFEED: - New_Window(); - break; - - /* - ** Move cursor to start of next line. - */ - case KA_RETURN: - Flush_Line(); - ScrollCounter++; - WinCx = 0; - -#if(FALSE) - if (WinCy >= WindowLines-1) { - Scroll_Window(); - } - else { - WinCy++; - } -#else - WinCy++; -#endif - - break; - - /* - ** Set the background color. - */ - case KA_SETBKGDCOL: - Flush_Line(); - WinB = Fetch_Char(); - break; - - /* - ** Set the foreground color. - */ - case KA_SETFORECOL: - Flush_Line(); - WinC = Fetch_Char(); - break; - - /* - ** Move cursor to next column. - */ - case KA_TAB: - Flush_Line(); - WPos = ((WPos + 8) & 0xFFF8) - 1; - if (WPos >= WindowColumns) { - WPos = 0; - } - WinCx = WPos * (FontWidth+FontXSpacing); - break; - - /* - ** Tab to specified column but add spaces. - */ - case KA_SPCTAB: - Flush_Line(); - oldcx = WinCx; - x = WinX << 3; - y = WinY + (WinCy * (FontHeight+FontYSpacing)); - WPos = ((WPos + 8) & 0xFFF8) - 1; - - if (WPos >= WindowColumns) { - WinCx = WPos = 0; - - // Fill_Rect instead of printing spaces - - LogicPage->Fill_Rect(x + oldcx, y, - x + WindowWidth - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB); - - ScrollCounter++; - WinCy++; - } - else { - WinCx = WPos * (FontWidth+FontXSpacing); - - // Fill_Rect instead of printing spaces - - LogicPage->Fill_Rect(x + oldcx, y, - x + WinCx - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB); - } - break; - - /* - ** next character is a extended value 1-127, but 128 is added - ** for a value 129-255 - */ - case KA_EXTEND: - c = 127; - - // NOTE: this falls thru to the default case DO NOT MOVE!!!!! - - - /* - ** next character is a literal value 1-127, except 13 - */ -// case KA_LITERAL: -// if (c != (char) 127) { // check if fell thru from extend case -// c = 0; // set to zero for literal case -// } -// c += Fetch_Char(); - - // NOTE: this falls thru to the default case DO NOT MOVE!!!!! - - - /* - ** Normal character output. - */ - default: - PPos += Char_Pixel_Width(c); // get pixel location of next char - Line[Pos++] = c; - Line[Pos] = '\0'; - - if (WinCx + PPos > (unsigned)WindowWidth) { - Flush_Line(); - } - break; - } - } - - /* - ** If there is text still pending, then display it before exiting. - */ - if (Pos) Flush_Line(); - - /* - ** Record changes in the cursor position. - */ - WindowList[Window][WINDOWCURSORX] = WinCx; - WindowList[Window][WINDOWCURSORY] = WinCy; - - /* - ** Restore the window colors to their original values. - */ - WindowList[Window][WINDOWFCOL] = WinC = old_c; - WindowList[Window][WINDOWBCOL] = WinB = old_b; - -//BG if (LogicPage == SEENPAGE) { -//BG Window_Show_Mouse(); -//BG } - - va_end(arg); -} - - -/*************************************************************************** - * SCROLL_WINDOW -- Scrolls the text window up one line. * - * * - * This will scroll the text window up one line. It will handle any * - * pausing for "more" if the MoreOn flag is set. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: This routine assumes that the LogicPage is the SEENPAGE. * - * If this is not the case, the program may appear to hang * - * if a "more" prompt is generated. * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -PRIVATE void Scroll_Window(void) -{ - int y; // Top pixel row of bottom line of window. - - /* - ** Possibly prompt for more text. - */ - if (ScrollCounter >= WindowLines-1 && MoreOn) { - ScrollCounter = 0; - - if (Window_More_Ptr) { -//BG if (LogicPage == SEENPAGE) Window_Show_Mouse(); - Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor); -//BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window); - } - } - - /* - ** Scroll the window up one line. - */ - y = ((WinH / (FontHeight+FontYSpacing)) - 1) * (FontHeight+FontYSpacing); - LogicPage->Blit(*LogicPage,WinX<<3, WinY + (FontHeight+FontYSpacing), WinX<<3, WinY, WinW<<3, WinH - (FontHeight+FontYSpacing) ); - LogicPage->Fill_Rect(WinX<<3, - WinY + y, - ((WinX+WinW)<<3) - 1, - WinY + WinH - 1, - (unsigned char)WinB); -} - - -/*************************************************************************** - * FLUSH_LINE -- Outputs the accumulate text line to screen. * - * * - * This will display the accumlated text line to the screen. It will * - * handle breaking the text line at an appropriate position. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -PRIVATE void Flush_Line(void) -{ - int breakit, breaksize, breakwidth; - int x, y; // Coordinates of text print. - int breakpoint; // Point to break the line (if possible). - char breakchar; // Break replace character. - int index; // Backward moving index var. - - /* - ** There could be a held and this is implied by the cursor Y position - ** beyond the bottom of the window. If this is the case, then scroll the - ** window and proceed with the line flush. - */ - while (WinCy >= (unsigned)WindowLines /*&& Pos > 0*/) { - Scroll_Window(); - if (WinCy >= (unsigned)WindowLines) WinCy--; - } - //if (WinCy >= WindowLines) WinCy = WindowLines-1; - - x = (WinX<<3) + WinCx; - y = WinY + (WinCy*(FontHeight+FontYSpacing)); - - breakwidth = WindowWidth; -// if (ScrollCounter >= WindowLines - 1 && MoreOn) { -// breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width -// } - - /* - ** Try to break the line at the last space IF the line has reached the edge - ** of the window. - */ - breakpoint = Pos; - breaksize = PPos; - if (WinCx + breaksize > (unsigned)breakwidth) { - - /* - ** Since the text WILL spill past the edge of the window, determine the - ** point where the break should occur. If this line is ready for the - ** prompt, then breaking must account for the text. - */ - if (ScrollCounter >= WindowLines - 1 && MoreOn) { - breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width - } - breakwidth -= WinCx; - - breakit = 0; - for (index = breakpoint - 1; index > 0; index--) { - breakchar = Line[index]; - breaksize -= Char_Pixel_Width(breakchar); - - // only once, find largest text that can fit on the line - if (!breakit) { - // was this the char that went past the right edge - if (breaksize <= breakwidth) { - breakit = index; // save this position if there is no spaces - } - } - - // after largest text is found then look for a space to break on - if (breakit && breakchar == KA_SPACE) { - breakpoint = index; - WordWrapFlag = FALSE; // word will start at beginning of next line - break; - } - } - - /* - ** Exception: When the current text buffer cannot be broken at a logical - ** place AND the text is starting past the left margin, THEN there is - ** an implied break between the previous text output and this one. - ** Output the current text on the next line left margin. - */ - if (!index) { - if (WinCx && !WordWrapFlag) { - breakpoint = breaksize = 0; // Continue text on next line. - WordWrapFlag = TRUE; // indicate a word continuation. - } - else { - breakpoint = breakit; // Just print as much as possible. - } - } - } - - breakchar = Line[breakpoint]; - Line[breakpoint] = '\0'; - - LogicPage->Print(Line, x, y, WinC, WinB); - WinCx += breaksize; // add size of text string printed. - - Line[breakpoint] = breakchar; - if (breakchar == KA_SPACE) { // take out a space between words. - breakpoint++; - } - - // take out another space for double spacing after end of sentence. - if (Line[breakpoint] == KA_SPACE) { - breakpoint++; - } - - strcpy(Line, &Line[breakpoint]); - Pos = strlen(Line); - PPos = String_Pixel_Width(Line); - - /* - ** If at this point there is still text in the buffer, then flushing has - ** not been completed. Scroll to next line and repeat the text flushing - ** process. - */ - if (Pos || WinCx >= (unsigned)WindowWidth) { - WinCx = WPos = 0; - #if(FALSE) - if (WinCy >= WindowLines-1) { - Scroll_Window(); - } else { - WinCy++; - } - #else - WinCy++; - #endif - Flush_Line(); - ScrollCounter++; // must be done after flush line for correct counting - } -} - - -/*************************************************************************** - * IN_CHAR -- Stores (un-dipped) character(s) from input to buffer. * - * * - * Use this routine to fetch the next character from the input stream. * - * If the character was dipthonged, then it will be broken into its * - * component ASCII characters and stored in the specified location. * - * This is the core character stream reading code. * - * * - * INPUT: str -- char pointer to the position to store the character(s)* - * fetched from the input stream. * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -PRIVATE void In_Char(char *str) -{ - char c; // Character to return. - char next; // Following character (if any). - - c = next = '\0'; - - /* - ** Fetch a raw byte from the input stream. - */ - if (AltSource) { - if (*AltSource == '\0') { - AltSource = NULL; - c = Stack; - } else { - c = *AltSource++; - } - } - - if (!c && MainSource) { - if (*MainSource == '\0') { - MainSource = NULL; - } else { - c = *MainSource++; - } - } - - /* - ** Convert a dipthong character into it's component - ** ASCII characters. - */ - if (c & 0x80) { - c &= 0x7F; - next = c & (char)0x07; - c = (char)((c & (char)0x78) >> 3); - - next = Dipthong[c][next]; // Dipthong character. - c = Common[c]; // Common character. - } - - *str++ = c; - *str = next; -} - - -/*************************************************************************** - * FETCH_CHAR -- Gets one undipthonged char from input. * - * * - * This routine will fetch one character from the input stream. The * - * character has already been un-dipthonged. It is a straight ASCII * - * character. This routine ensures that if the next character in the * - * input stream needs to be examined, it is available in Char[0]. * - * * - * INPUT: none * - * * - * OUTPUT: Returns next character in the input stream (ASCII). If NULL * - * is returned, then this indicates the end of the input stream. * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 07/25/1991 JLB : Created. * - *=========================================================================*/ -PRIVATE char Fetch_Char(void) -{ - char c; // Character to return. - - if (!Char[0]) { - In_Char(&Char[0]); - } - - c = Char[0]; - Char[0] = Char[1]; - Char[1] = '\0'; - - if (!Char[0]) { - In_Char(&Char[0]); - } - - return (c); -} - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/WINHIDE.CPP b/code/TIBERIANDAWN/WIN32LIB/WINHIDE.CPP deleted file mode 100644 index 93680de..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WINHIDE.CPP +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: g:/library/source/rcs/./winhide.c 1.10 1994/05/20 15:35:50 joe_bostic Exp $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Dune * - * * - * File Name : WINHIDE.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : May 30, 1991 * - * * - * Last Update : August 16, 1991 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Window_Hide_Mouse -- Hides the mouse when it enters a window. * - * Window_Show_Mouse -- Shows the mouse after Window_Hide_Mouse hides it.* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include -#include -#include "ww_win.h" - - -#if(IBM) -/*************************************************************************** - * WINDOW_HIDE_MOUSE -- Hides the mouse when it enters a window. * - * * - * This is an intelligent form of Conditional_Hide_Mouse(). It will * - * hide the mouse if it enters the specified window (see the * - * WindowList global). * - * * - * INPUT: window - Window number. * - * * - * OUTPUT: none * - * * - * WARNINGS: Just like Conditional_Hide_Mouse(), this function is NOT * - * nestable. * - * * - * HISTORY: * - * 04/26/1991 JLB : Created. * - *=========================================================================*/ -void Window_Hide_Mouse(int window) -{ - int x,y,w,h; - - x = WindowList[window][WINDOWX]<<3; - y = WindowList[window][WINDOWY]; - w = WindowList[window][WINDOWWIDTH]<<3; - h = WindowList[window][WINDOWHEIGHT]; -// Conditional_Hide_Mouse(x,y,x+w-1,y+h-1); -} - - -/*************************************************************************** - * WINDOW_SHOW_MOUSE -- Shows the mouse after Window_Hide_Mouse hides it. * - * * - * This routines will show the mouse after Window_Hide_Mouse has hidden * - * it. * - * * - * INPUT: none * - * * - * OUTPUT: none * - * * - * WARNINGS: none * - * * - * HISTORY: * - * 05/22/1991 JLB : Created. * - *=========================================================================*/ -void Window_Show_Mouse(void) -{ -// Conditional_Show_Mouse(); -} -#endif - - - diff --git a/code/TIBERIANDAWN/WIN32LIB/WRITEPCX.CPP b/code/TIBERIANDAWN/WIN32LIB/WRITEPCX.CPP deleted file mode 100644 index d3681b4..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WRITEPCX.CPP +++ /dev/null @@ -1,177 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : iff * - * * - * File Name : WRITEPCX.CPP * - * * - * Programmer : Julio R. Jerez * - * * - * Start Date : May 2, 1995 * - * * - * Last Update : May 2, 1995 [JRJ] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * int Save_PCX_File (char* name, GraphicViewPortClass& pic, char* palette)* - *= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -#include -#include "filepcx.h" -#include -static void Write_Pcx_ScanLine ( int file_handle , int scansize , unsigned char * ptr ); - - -/*************************************************************************** - * WRITE_PCX_FILE -- Write the data in ViewPort to a pcx file * - * * - * * - * * - * INPUT: name is a NULL terminated string of the fromat [xxxx.pcx] * - * pic is a pointer to a GraphicViewPortClass or to a * - * GraphicBufferClass holding the picture. * - * palette is a pointer the the memry block holding the color * * - * palette of the picture. * - * * - * OUTPUT: FALSE if the function fails zero otherwise * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/04/1995 JRJ : Created. * - * 08/01/1995 SKB : Copy the palette so it is not modified. * - *=========================================================================*/ -int Write_PCX_File (char* name, GraphicViewPortClass& pic, unsigned char* palette ) -{ - unsigned char palcopy[256 * 3]; - unsigned i ; - //unsigned width ; - int file_handle ; - int VP_Scan_Line ; - char * ptr ; - RGB * pal ; - GraphicBufferClass * Graphic_Buffer ; - PCX_HEADER header = { 10 , 5 , 1 , 8 , 0 , 0 , 319 , 199 , - 320 , 200 , { 0 } , 0 , 1 , 320 , 1 , {0} } ; - - // Open file name - file_handle = Open_File ( name , WRITE ) ; - if ( file_handle == WW_ERROR ) return FALSE ; - - - header.width = pic.Get_Width() - 1 ; - header.height = pic.Get_Height() - 1 ; - header.byte_per_line = pic.Get_Width() ; - Write_File ( file_handle, & header , sizeof (PCX_HEADER)) ; - - VP_Scan_Line = pic.Get_Width() + pic.Get_XAdd(); - Graphic_Buffer = pic.Get_Graphic_Buffer() ; - ptr = ( char * ) Graphic_Buffer->Get_Buffer() ; - ptr += ( (pic.Get_YPos() * VP_Scan_Line) + pic.Get_XPos() ); - - for ( i = 0 ; i < (unsigned)header.height + 1 ; i ++ ) - Write_Pcx_ScanLine ( file_handle , header.byte_per_line, (unsigned char*)ptr + i * VP_Scan_Line ) ; - - Mem_Copy(palette, palcopy, 256 * 3); - pal = ( RGB * ) palcopy ; - for ( i = 0 ; i < 256 ; i ++ ) { - pal -> red <<= 2 ; - pal -> green <<= 2 ; - pal -> blue <<= 2 ; - pal ++ ; - } - i = 0x0c ; - Write_File ( file_handle, & i , 1 ) ; - Write_File ( file_handle, palcopy , 256 * sizeof (RGB) ) ; - Close_File (file_handle) ; - return 0 ; -} - - - - -/*************************************************************************** - * WRITE_PCX_SCANLINE -- function to write a single pcx scanline to a file * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/04/1995 JRJ : Created. * - *=========================================================================*/ - -#define POOL_SIZE 2048 -#define WRITE_CHAR(x) { \ - * file_ptr ++ = x ; \ - if ( file_ptr >= & pool [ POOL_SIZE ] ) { \ - Write_File ( file_handle, pool , POOL_SIZE ) ; \ - file_ptr = pool ; \ - } } - - -void Write_Pcx_ScanLine ( int file_handle , int scansize , unsigned char * ptr ) -{ - unsigned i ; - unsigned rle ; - unsigned color ; - unsigned last ; - unsigned char * file_ptr ; - unsigned char pool [ POOL_SIZE ] ; - - file_ptr = pool ; - last = * ptr ; - rle = 1 ; - - for ( i = 1 ; i < (unsigned)scansize ; i ++ ) { - color = 0xff & * ++ ptr ; - if ( color == last ) { - rle ++ ; - if ( rle == 63 ) { - WRITE_CHAR ( 255 ) ; - WRITE_CHAR ( color ) ; - rle = 0 ; - } - } else { - if ( rle ) { - if ( rle == 1 && ( 192 != ( 192 & last ))) { - WRITE_CHAR ( last ) ; - } else { - WRITE_CHAR ( rle | 192 ) ; - WRITE_CHAR ( last ) ; - } - } - last = color ; - rle = 1 ; - } - } - if ( rle ) { - if ( rle == 1 && ( 192 != ( 192 & last ))) { - WRITE_CHAR ( last ) ; - } else { - WRITE_CHAR ( rle | 192 ) ; - WRITE_CHAR ( last) ; - } - } - - Write_File ( file_handle, pool , ( int ) file_ptr - ( int ) pool ) ; -} diff --git a/code/TIBERIANDAWN/WIN32LIB/WSA.CPP b/code/TIBERIANDAWN/WIN32LIB/WSA.CPP deleted file mode 100644 index 3dcc2f9..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WSA.CPP +++ /dev/null @@ -1,1153 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: g:/library/source/rcs/./wsa.c 1.16 1994/05/20 15:35:27 joe_bostic Exp $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Library Animation System * - * * - * File Name : WSA.C * - * * - * Programmer : Michael Legg * - * * - * Start Date : November 20, 1991 * - * * - *-------------------------------------------------------------------------* - * There are many different ways that the user can use the WSA library * - * module. The options are as follows : * - * * - * System Allocation vs User Buffer - The user may request that the * - * system allocate the needed buffer from the heap or the user may * - * pass his own buffer in for the animator to use. * - * * - * Resident vs File based - If there is enough RAM, the user may put the * - * entire animation into RAM for fastest animations. If there is * - * not enouph RAM, the system will automatically make it so each * - * frame will be read off disk when needed. * - * * - * Direct to Page vs Use of a user buffer -- Noramally Direct to page * - * is the best method both in speed and in RAM need to hold anim. * - * One may want to use the write to user buffer method if they * - * are using the animation in a non sequencial order. * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Animate_Frame -- Displays a frame of a given animation * - * Get_Animation_Frame_Count -- Return Number of frames in an animation. * - * Get_Animation_X -- Gets the x from an animation * - * Get_Animation_Y -- Gets the y from an animation * - * Get_Animation_Width -- Gets the width from an animation * - * Get_Animation_Height -- The height of the animation we are processing * - * Apply_Delta -- Copies frame into delta buffer, then applies to target * - * Close_Animation -- Close the animation, freeing the space if necessary* - * Get_File_Frame_Offset -- Get offset of a delta frame from animate file* - * Get_Resident_Frame_Offset -- Gets frame offset of animate file in RAM * - * Open_Animation -- Opens an animation file and reads into buffer * - *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -#include -#include "wsa.h" -#include -#include -#include -#include -//#include -#include - -// -// WSA animation header allocation type. -// If we need more then 8 flags for the flags variable, we can combine -// USER_ALLOCATED with SYS_ALLOCATED and combine FILE with RESIDENT. -// -#define WSA_USER_ALLOCATED 0x01 -#define WSA_SYS_ALLOCATED 0x02 -#define WSA_FILE 0x04 -#define WSA_RESIDENT 0x08 -#define WSA_TARGET_IN_BUFFER 0x10 -#define WSA_LINEAR_ONLY 0x20 -#define WSA_FRAME_0_ON_PAGE 0x40 -#define WSA_AMIGA_ANIMATION 0x80 -#define WSA_PALETTE_PRESENT 0x100 -#define WSA_FRAME_0_IS_DELTA 0x200 - -// These are used to call Apply_XOR_Delta_To_Page_Or_Viewport() to setup flags parameter. If -// These change, make sure and change their values in lp_asm.asm. -#define DO_XOR 0x0 -#define DO_COPY 0x01 -#define TO_VIEWPORT 0x0 -#define TO_PAGE 0x02 - - - - -typedef struct { - unsigned short current_frame; - unsigned short total_frames; - unsigned short pixel_x; - unsigned short pixel_y; - unsigned short pixel_width; - unsigned short pixel_height; - unsigned short largest_frame_size; - char *delta_buffer; - char *file_buffer; - char file_name[ 13 ]; - short flags; - // New fields that animate does not know about below this point. SEE EXTRA_charS_ANIMATE_NOT_KNOW_ABOUT - short file_handle; - unsigned long anim_mem_size; -} SysAnimHeaderType; - -// NOTE:"THIS IS A BAD THING. SINCE sizeof(SysAnimHeaderType) CHANGED, THE ANIMATE.EXE -// UTILITY DID NOT KNOW I UPDATED IT, IT ADDS IT TO largest_frame_size BEFORE SAVING -// IT TO THE FILE. THIS MEANS I HAVE TO ADD THESE charS ON NOW FOR IT TO WORK. -#define EXTRA_charS_ANIMATE_NOT_KNOW_ABOUT (sizeof(short) + sizeof(unsigned long)) - - -// -// Header structure for the file. -// NOTE: The 'total_frames' field is used to differentiate between Amiga and IBM -// animations. Amiga animations have the HIGH bit set. -// -typedef struct { - unsigned short total_frames; - unsigned short pixel_x; - unsigned short pixel_y; - unsigned short pixel_width; - unsigned short pixel_height; - unsigned short largest_frame_size; - short flags; - unsigned long frame0_offset; - unsigned long frame0_end; - /* unsigned long data_seek_offset, unsigned short frame_size ... */ -} WSA_FileHeaderType; - -#define WSA_FILE_HEADER_SIZE ( sizeof(WSA_FileHeaderType) - (2 * sizeof(unsigned long)) ) - -/*=========================================================================*/ -/* The following PRIVATE functions are in this file: */ -/*=========================================================================*/ - -PRIVATE unsigned long Get_Resident_Frame_Offset( char *file_buffer, int frame ); -PRIVATE unsigned long Get_File_Frame_Offset( int file_handle, int frame, int palette_adjust); -PRIVATE BOOL Apply_Delta(SysAnimHeaderType *sys_header, int curr_frame, char *dest_ptr, int dest_w); -/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - - -/*************************************************************************** - * OPEN_ANIMATION -- Opens an animation file and reads into buffer * - * * - * INPUT: char *file_name of animation sequence file. * - * char *user_buffer pointer if one exists (NULL ok) * - * unsigned long user_buffer_size if known (NULL ok) * - * WSAOpenType user_flags - flags on how to open. * - * unsigned char *palette - pointer to palette space for return (NULL ok) * - * * - * OUTPUT: void *pointer to animation data. Must be used for all * - * other WSA calls. * - * * - * WARNINGS: May return NULL, please check. * - * * - * HISTORY: * - * 11/26/1991 SB : Created. * - *=========================================================================*/ -void * __cdecl Open_Animation(char const *file_name, char *user_buffer, long user_buffer_size, WSAOpenType user_flags, unsigned char *palette) -{ - int fh, anim_flags; - int palette_adjust; - unsigned int offsets_size; - unsigned int frame0_size; - long target_buffer_size, delta_buffer_size, file_buffer_size; - long max_buffer_size, min_buffer_size; - char *sys_anim_header_buffer; - char *target_buffer; - char *delta_buffer, *delta_back; - SysAnimHeaderType *sys_header; - WSA_FileHeaderType file_header; - - /*======================================================================*/ - /* Open the file to get the header information */ - /*======================================================================*/ - - anim_flags = 0; - fh = Open_File(file_name, READ); - Read_File(fh, (char *) &file_header, sizeof(WSA_FileHeaderType)); - - /*======================================================================*/ - /* If the file has an attached palette then if we have a valid palette */ - /* pointer we need to read it in. */ - /*======================================================================*/ - - if (file_header.flags & 1) { - anim_flags |= WSA_PALETTE_PRESENT; - palette_adjust = 768; - - if (palette != NULL) { - Seek_File(fh, sizeof(unsigned long) * (file_header.total_frames), SEEK_CUR); - Read_File(fh, palette, 768L); - } - - } else { - palette_adjust = 0; - } - - // Check for flag from ANIMATE indicating that this animation was - // created from a .LBM and a .ANM. These means that the first - // frame is a XOR Delta from a picture, not black. - if (file_header.flags & 2) { - anim_flags |= WSA_FRAME_0_IS_DELTA; - } - - - // Get the total file size minus the size of the first frame and the size - // of the file header. These will not be read in to save even more space. - file_buffer_size = Seek_File(fh, 0L, SEEK_END); - - if (file_header.frame0_offset) { - long tlong; - - tlong = file_header.frame0_end - file_header.frame0_offset; - frame0_size = (unsigned short) tlong; - } - else { - anim_flags |= WSA_FRAME_0_ON_PAGE; - frame0_size = 0; - } - - file_buffer_size -= palette_adjust + frame0_size + WSA_FILE_HEADER_SIZE; - - // We need to determine the buffer sizes required for the animation. At a - // minimum, we need a target buffer for the uncompressed frame and a delta - // buffer for the delta data. We may be able to make the file resident, - // so we will determine the file size. - // - // If the target buffer is in the user buffer - // Then figure its size - // and set the allocation flag - // Else size is zero. - // - if (user_flags & WSA_OPEN_DIRECT) { - target_buffer_size = 0L; - } - else { - anim_flags |= WSA_TARGET_IN_BUFFER; - target_buffer_size = (unsigned long) file_header.pixel_width * file_header.pixel_height; - } - - // NOTE:"THIS IS A BAD THING. SINCE sizeof(SysAnimHeaderType) CHANGED, THE ANIMATE.EXE - // UTILITY DID NOT KNOW I UPDATED IT, IT ADDS IT TO largest_frame_size BEFORE SAVING - // IT TO THE FILE. THIS MEANS I HAVE TO ADD THESE charS ON NOW FOR IT TO WORK. - delta_buffer_size = (unsigned long) file_header.largest_frame_size + EXTRA_charS_ANIMATE_NOT_KNOW_ABOUT; - min_buffer_size = target_buffer_size + delta_buffer_size; - max_buffer_size = min_buffer_size + file_buffer_size; - - // check to see if buffer size is big enough for at least min required - if (user_buffer && (user_buffer_size < min_buffer_size)) { - Close_File(fh); - return(NULL); - } - - // A buffer was not passed in, so do allocations - if (user_buffer == NULL) { - - // If the user wants it from the disk, then let us give it to him, - // otherwise, try to give a max allocation he can have. - if (user_flags & WSA_OPEN_FROM_DISK) { - user_buffer_size = min_buffer_size; - } - // else no buffer size, then try max configuration. - else if (!user_buffer_size) { - user_buffer_size = max_buffer_size; - } - // else if buffer specified is less then max needed, give min. - else if (user_buffer_size < max_buffer_size) { - user_buffer_size = min_buffer_size; - } - // otherwise we only want to alloc what we need. - else { - user_buffer_size = max_buffer_size; - } - - - // Check to see if enough RAM available for buffer_size. - if (user_buffer_size > Ram_Free(MEM_NORMAL)) { - - // If not enough room for even the min, return no buffer. - - if (min_buffer_size > Ram_Free(MEM_NORMAL)) { - Close_File(fh); - return(NULL); - } - - // Else make buffer size the min and allocate it. - user_buffer_size = min_buffer_size; - } - - // allocate buffer needed - user_buffer = (char *) Alloc(user_buffer_size, MEM_CLEAR); - - anim_flags |= WSA_SYS_ALLOCATED; - } - else { - // Check to see if the user_buffer_size should be min or max. - if ((user_flags & WSA_OPEN_FROM_DISK) || (user_buffer_size < max_buffer_size)) { - user_buffer_size = min_buffer_size; - } - else { - user_buffer_size = max_buffer_size; - } - anim_flags |= WSA_USER_ALLOCATED; - } - - - // Set the pointers to the RAM buffers - sys_anim_header_buffer = user_buffer; - target_buffer = (char *) Add_Long_To_Pointer(sys_anim_header_buffer, sizeof(SysAnimHeaderType)); - delta_buffer = (char *) Add_Long_To_Pointer(target_buffer, target_buffer_size); - - // Clear target buffer if it is in the user buffer. - if (target_buffer_size) { - memset( target_buffer, 0, (unsigned short) target_buffer_size ); - } - - // Poke data into the system animation header (start of user_buffer) - // current_frame is set to total_frames so that Animate_Frame() knows that - // it needs to clear the target buffer. - - sys_header = ( SysAnimHeaderType * ) sys_anim_header_buffer; - sys_header -> current_frame = - sys_header -> total_frames = file_header.total_frames; - sys_header -> pixel_x = file_header.pixel_x; - sys_header -> pixel_y = file_header.pixel_y; - sys_header -> pixel_width = file_header.pixel_width; - sys_header -> pixel_height = file_header.pixel_height; - sys_header -> anim_mem_size = user_buffer_size; - sys_header -> delta_buffer = delta_buffer; - sys_header -> largest_frame_size = - (unsigned short) (delta_buffer_size - sizeof(SysAnimHeaderType)); - - strcpy(sys_header->file_name, file_name); - - // Figure how much room the frame offsets take up in the file. - // Add 2 - one for the wrap around and one for the final end offset. - offsets_size = (file_header.total_frames + 2) << 2; - - // Can the user_buffer_size handle the maximum case buffer? - if ( user_buffer_size == max_buffer_size) { - - // - // set the file buffer pointer, - // Skip over the header information. - // Read in the offsets. - // Skip over the first frame. - // Read in remaining frames. - // - - sys_header->file_buffer = (char *)Add_Long_To_Pointer(delta_buffer,sys_header->largest_frame_size); - Seek_File( fh, WSA_FILE_HEADER_SIZE, SEEK_SET); - Read_File( fh, sys_header->file_buffer, offsets_size); - Seek_File( fh, frame0_size + palette_adjust, SEEK_CUR); - Read_File( fh, sys_header->file_buffer + offsets_size, - file_buffer_size - offsets_size); - - // - // Find out if there is an ending value for the last frame. - // If there is not, then this animation will not be able to - // loop back to the beginning. - // - if (Get_Resident_Frame_Offset( sys_header->file_buffer, sys_header->total_frames + 1)) - anim_flags |= WSA_RESIDENT; - else - anim_flags |= WSA_LINEAR_ONLY | WSA_RESIDENT; - } - else { // buffer cannot handle max_size of buffer - - if(Get_File_Frame_Offset( fh, sys_header->total_frames + 1, palette_adjust)) - anim_flags |= WSA_FILE; - else - anim_flags |= WSA_LINEAR_ONLY | WSA_FILE; -//// - sys_header->file_buffer = NULL; - } - - // Figure where to back load frame 0 into the delta buffer. - delta_back = (char *)Add_Long_To_Pointer(delta_buffer, - sys_header->largest_frame_size - frame0_size); - - // Read the first frame into the delta buffer and uncompress it. - // Then close it. - Seek_File( fh, WSA_FILE_HEADER_SIZE + offsets_size + palette_adjust, SEEK_SET); - Read_File( fh, delta_back, frame0_size); - - // We do not use the file handle when it is in RAM. - if (anim_flags & WSA_RESIDENT) { - sys_header -> file_handle = (short) -1; - Close_File(fh); - } - else { - sys_header -> file_handle = (short)fh; - } - - LCW_Uncompress(delta_back, delta_buffer, sys_header->largest_frame_size); - - // Finally set the flags, - sys_header->flags = (short)anim_flags; - - // return valid handle - return( user_buffer ); -} - - -/*************************************************************************** - * CLOSE_ANIMATION -- Close the animation, freeing the space if necessary. * - * * - * INPUT: void *handle to the animation data buffer * - * * - * OUTPUT: none * - * * - * WARNINGS: handle MUST have been returned by Open_Animation * - * * - * HISTORY: * - * 11/23/1991 ML : Created. * - *=========================================================================*/ -void __cdecl Close_Animation( void *handle ) -{ - SysAnimHeaderType *sys_header; - - // Assign our local system header pointer to the beginning of the handle space - sys_header = (SysAnimHeaderType *) handle; - - // Close the WSA file in it was disk based. - if (sys_header->flags & WSA_FILE) { - Close_File(sys_header->file_handle); - } - - // Check to see if the buffer was allocated OR the programmer provided the buffer - if (handle && sys_header->flags & WSA_SYS_ALLOCATED) { - Free(handle); - } -} - -/*************************************************************************** - * ANIMATE_FRAME -- Displays a frame of a given animation * - * * - * INPUT: void *handle to the animation. * - * int frame_number wanted to be displayed * - * int x_pixel position of left side of animation on page * - * int y_pixel position of top of animation on page * - * * - * OUTPUT: BOOL if successfull or not. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/27/1991 SB : Created. * - *=========================================================================*/ -//#pragma off (unreferenced) -BOOL __cdecl Animate_Frame(void *handle, GraphicViewPortClass& view, - int frame_number, int x_pixel, int y_pixel, - WSAType flags_and_prio, void *magic_cols, void *magic) -{ - SysAnimHeaderType *sys_header; // fix up the void pointer past in. - int curr_frame; // current frame we are on. - int total_frames; // number of frames in anim. - int distance; // distance to desired frame. - int search_dir; // direcion to search for desired frame. - int search_frames; // How many frames to search. - int loop; // Just a loop varible. - char *frame_buffer; // our destination. - BOOL direct_to_dest; // are we going directly to the destination? - int dest_width; // the width of the destination buffer or page. - - - // Assign local pointer to the beginning of the buffer where the system information - // resides - sys_header = (SysAnimHeaderType *)handle; - - // Get the total number of frames - total_frames = sys_header->total_frames; - - // Are the animation handle and the frame number valid? - if (!handle || (total_frames <= frame_number)) { - return FALSE; - } - - if (view.Lock()!=TRUE) return (FALSE); - - // Decide if we are going to a page or a viewport (part of a buffer). - dest_width = view.Get_Width() + view.Get_XAdd() + view.Get_Pitch(); - - // - // adjust x_pixel and y_pixel by system pixel_x and pixel_y respectively. - // - x_pixel += (short)sys_header->pixel_x; - y_pixel += (short)sys_header->pixel_y; - - // - // Check to see if we are using a buffer inside of the animation buffer or if - // it is being drawn directly to the destination page or buffer. - // - if (sys_header->flags & WSA_TARGET_IN_BUFFER) { - // Get a pointer to the frame in animation buffer. - frame_buffer = (char *)Add_Long_To_Pointer(sys_header, sizeof(SysAnimHeaderType)); - direct_to_dest = FALSE; - } - else { - frame_buffer = (char *)view.Get_Offset(); - frame_buffer += (y_pixel * dest_width) + x_pixel; - direct_to_dest = TRUE; - } - // - // If current_frame is equal to tatal_frames, then no animations have taken place - // so must uncompress frame 0 in delta buffer to the frame_buffer/page if it - // exists. - // - if (sys_header->current_frame == total_frames) { - - // Call apply delta telling it wether to copy or to xor depending on if the - // target is a page or a buffer. - - if (!(sys_header->flags & WSA_FRAME_0_ON_PAGE)) { - if (direct_to_dest) { - - // The last parameter says weather to copy or to XOR. If the - // first frame is a DELTA, then it must be XOR'd. A TRUE is - // copy while FALSE is XOR. - - Apply_XOR_Delta_To_Page_Or_Viewport(frame_buffer, sys_header->delta_buffer, - sys_header->pixel_width, dest_width, //dest_width - sys_header->pixel_width, - (sys_header->flags & WSA_FRAME_0_IS_DELTA)? DO_XOR : DO_COPY); - } - else { - Apply_XOR_Delta(frame_buffer, sys_header->delta_buffer); - } - } - sys_header->current_frame = 0; - } - - // - // Get the current frame - // If no looping aloud, are the trying to do it anyways? - // - curr_frame = sys_header->current_frame; -#if (FALSE) - // This is commented out since we will let them loop even though they should - // not - it will be slower. - if ( (sys_header->flags & WSA_LINEAR_ONLY) && (frame_number < cur_frame) ) { - view.Unlock(); - return FALSE; - } -#endif - - // Get absoulte distance from our current frame to the target frame - distance = ABS(curr_frame - frame_number); - - // Assume we are searching right - search_dir = 1; - - // Calculate the number of frames to search if we go right and wrap - - if (frame_number > curr_frame) { - search_frames = total_frames - frame_number + curr_frame; - - // Is going right faster than going backwards? - // Or are they trying to loop when the should not? - if ((search_frames < distance) && !(sys_header->flags & WSA_LINEAR_ONLY)) { - search_dir = -1; // No, so go left - } - else { - search_frames = distance; - } - } - else { - search_frames = total_frames - curr_frame + frame_number; - - // Is going right faster than going backwards? - // Or are they trying to loop when the should not? - if ((search_frames >= distance) || (sys_header->flags & WSA_LINEAR_ONLY)) { - search_dir = -1; // No, so go left - search_frames = distance; - } - } - - // Take care of the case when we are searching right (possibly right) - - if (search_dir > 0) { - for (loop = 0; loop < search_frames; loop++) { - - // Move the logical frame number ordinally right - curr_frame += search_dir; - - Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); - - // Adjust the current frame number, taking into consideration that we could - // have wrapped - - if (curr_frame == total_frames) { - curr_frame = 0; - } - } - } - else { - for (loop = 0; loop < search_frames; loop++) { - - // If we are going backwards and we are on frame 0, the delta to get - // to the last frame is the n + 1 delta (wrap delta) - - if (curr_frame == 0) { - curr_frame = total_frames; - } - - Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); - - curr_frame += search_dir; - } - } - - sys_header->current_frame = (short)frame_number; - - // If we did this all in a hidden buffer, then copy it to the desired page or viewport. - if (sys_header->flags & WSA_TARGET_IN_BUFFER) { -#if TRUE - - Buffer_To_Page(x_pixel, y_pixel, sys_header->pixel_width, sys_header->pixel_height, frame_buffer, view); - -#else - int flags = ((unsigned short)flags_and_prio & 0xFF00u) >> 12u; - int pri = flags_and_prio & 0x00FF; - - Buffer_Bitblit_To_LogicPage(x_pixel, y_pixel, sys_header->pixel_width, - sys_header->pixel_height, 0, flags, frame_buffer, pri, - magic_cols, magic); -#endif - } - - view.Unlock(); - return TRUE; -} -/*************************************************************************** - * ANIMATE_FRAME -- Displays a frame of a given animation * - * * - * INPUT: void *handle to the animation. * - * int frame_number wanted to be displayed * - * int x_pixel position of left side of animation on page * - * int y_pixel position of top of animation on page * - * * - * OUTPUT: BOOL if successfull or not. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/27/1991 SB : Created. * - *=========================================================================*/ -//#pragma argsused -#ifdef cuts -BOOL __cdecl Animate_Frame(void *handle, GraphicViewPortClass& view, - int frame_number, int x_pixel, int y_pixel, - WSAType flags_and_prio, void *magic_cols, void *magic) -{ - SysAnimHeaderType *sys_header; // fix up the void pointer past in. - int curr_frame; // current frame we are on. - int total_frames; // number of frames in anim. - int distance; // distance to desired frame. - int search_dir; // direcion to search for desired frame. - int search_frames; // How many frames to search. - int loop; // Just a loop varible. - char *frame_buffer; // our destination. - BOOL direct_to_dest; // are we going directly to the destination? - int dest_width; // the width of the destination buffer or page. - - // Assign local pointer to the beginning of the buffer where the system information - // resides - sys_header = (SysAnimHeaderType *)handle; - - // Get the total number of frames - total_frames = sys_header->total_frames; - - // Are the animation handle and the frame number valid? - if (!handle || (total_frames <= frame_number)) { - return FALSE; - } - - - // Decide if we are going to a page or a viewport (part of a buffer). - dest_width = view.Get_Width() + view.Get_XAdd(); - - // - // adjust x_pixel and y_pixel by system pixel_x and pixel_y respectively. - // - x_pixel += (short)sys_header->pixel_x; - y_pixel += (short)sys_header->pixel_y; - - // - // Check to see if we are using a buffer inside of the animation buffer or if - // it is being drawn directly to the destination page or buffer. - // - if (sys_header->flags & WSA_TARGET_IN_BUFFER) { - // Get a pointer to the frame in animation buffer. - frame_buffer = (char *)Add_Long_To_Pointer(sys_header, sizeof(SysAnimHeaderType)); - direct_to_dest = FALSE; - } - else { - frame_buffer = (char *)view.Get_Offset(); - frame_buffer += (y_pixel * dest_width) + x_pixel; - direct_to_dest = TRUE; - } - // - // If current_frame is equal to tatal_frames, then no animations have taken place - // so must uncompress frame 0 in delta buffer to the frame_buffer/page if it - // exists. - // - if (sys_header->current_frame == total_frames) { - - // Call apply delta telling it wether to copy or to xor depending on if the - // target is a page or a buffer. - - if (!(sys_header->flags & WSA_FRAME_0_ON_PAGE)) { - if (direct_to_dest) { - - // The last parameter says weather to copy or to XOR. If the - // first frame is a DELTA, then it must be XOR'd. A TRUE is - // copy while FALSE is XOR. - Apply_XOR_Delta_To_Page_Or_Viewport(frame_buffer, sys_header->delta_buffer, - sys_header->pixel_width, dest_width, //dest_width - sys_header->pixel_width, - (sys_header->flags & WSA_FRAME_0_IS_DELTA)? DO_XOR : DO_COPY); - } - else { - Apply_XOR_Delta(frame_buffer, sys_header->delta_buffer); - } - } - sys_header->current_frame = 0; - } - - // - // Get the current frame - // If no looping aloud, are the trying to do it anyways? - // - curr_frame = sys_header->current_frame; -#if (FALSE) - // This is commented out since we will let them loop even though they should - // not - it will be slower. - if ( (sys_header->flags & WSA_LINEAR_ONLY) && (frame_number < cur_frame) ) { - return FALSE; - } -#endif - - // Get absoulte distance from our current frame to the target frame - distance = ABS(curr_frame - frame_number); - - // Assume we are searching right - search_dir = 1; - - // Calculate the number of frames to search if we go right and wrap - - if (frame_number > curr_frame) { - search_frames = total_frames - frame_number + curr_frame; - - // Is going right faster than going backwards? - // Or are they trying to loop when the should not? - if ((search_frames < distance) && !(sys_header->flags & WSA_LINEAR_ONLY)) { - search_dir = -1; // No, so go left - } - else { - search_frames = distance; - } - } - else { - search_frames = total_frames - curr_frame + frame_number; - - // Is going right faster than going backwards? - // Or are they trying to loop when the should not? - if ((search_frames >= distance) || (sys_header->flags & WSA_LINEAR_ONLY)) { - search_dir = -1; // No, so go left - search_frames = distance; - } - } - - // Take care of the case when we are searching right (possibly right) - - if (search_dir > 0) { - for (loop = 0; loop < search_frames; loop++) { - - // Move the logical frame number ordinally right - curr_frame += search_dir; - - Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); - - // Adjust the current frame number, taking into consideration that we could - // have wrapped - - if (curr_frame == total_frames) { - curr_frame = 0; - } - } - } - else { - for (loop = 0; loop < search_frames; loop++) { - - // If we are going backwards and we are on frame 0, the delta to get - // to the last frame is the n + 1 delta (wrap delta) - - if (curr_frame == 0) { - curr_frame = total_frames; - } - - Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); - - curr_frame += search_dir; - } - } - - sys_header->current_frame = frame_number; - - // If we did this all in a hidden buffer, then copy it to the desired page or viewport. - if (sys_header->flags & WSA_TARGET_IN_BUFFER) { -#if TRUE - - Buffer_To_Page(x_pixel, y_pixel, sys_header->pixel_width, sys_header->pixel_height, frame_buffer, view); - -#else - int flags = ((unsigned short)flags_and_prio & 0xFF00u) >> 12u; - int pri = flags_and_prio & 0x00FF; - - Buffer_Bitblit_To_LogicPage(x_pixel, y_pixel, sys_header->pixel_width, - sys_header->pixel_height, 0, flags, frame_buffer, pri, - magic_cols, magic); -#endif - } - - - return TRUE; -} -#endif - - -/*************************************************************************** - * ANIMATE_FRAME_COUNT -- Return Number of frames in an animation. * - * * - * INPUT: void *handle to the animation. * - * * - * OUTPUT: int number of frames in animation. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 12/05/1991 SB : Created. * - *=========================================================================*/ -int __cdecl Get_Animation_Frame_Count(void *handle) -{ - SysAnimHeaderType *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return((short)sys_header->total_frames); -} - - -/*************************************************************************** - * GET_ANIM_X -- Gets the x from an animation * - * * - * * - * INPUT: void * to the animation that we are processing * - * * - * OUTPUT: int the x of the animation we are processing * - * * - * WARNINGS: * - * * - * HISTORY: * - * 07/03/1992 DRD : Created. * - *=========================================================================*/ -int __cdecl Get_Animation_X(void const *handle) -{ - SysAnimHeaderType const *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return(sys_header->pixel_x); -} - -/*************************************************************************** - * GET_ANIM_Y -- Gets the y from an animation * - * * - * * - * INPUT: void * to the animation that we are processing * - * * - * OUTPUT: int the y of the animation we are processing * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/14/1992 PWG : Created. * - *=========================================================================*/ -int __cdecl Get_Animation_Y(void const *handle) -{ - SysAnimHeaderType const *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return(sys_header->pixel_y); -} - -/*************************************************************************** - * GET_ANIM_WIDTH -- Gets the width from an animation * - * * - * * - * INPUT: void * to the animation that we are processing * - * * - * OUTPUT: int the width of the animation we are processing * - * * - * WARNINGS: * - * * - * HISTORY: * - * 10/14/1992 PWG : Created. * - *=========================================================================*/ -int __cdecl Get_Animation_Width(void const *handle) -{ - SysAnimHeaderType const *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return(sys_header->pixel_width); -} - -/*************************************************************************** - * GET_ANIM_HEIGHT -- The height of the animation we are processing * - * * - * INPUT: void * to the animation that we are processing * - * * - * OUTPUT: int the height of the animation we are processing * - * * - * HISTORY: * - * 10/14/1992 PWG : Created. * - *=========================================================================*/ -int __cdecl Get_Animation_Height(void const *handle) -{ - SysAnimHeaderType const *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return(sys_header->pixel_height); -} - - -/*************************************************************************** - * GET_ANIM_PALETTE -- Returns true if the anim had an attached palette * - * * - * INPUT: void * to the animation that we are processing * - * * - * OUTPUT: int True if the animation has a set palette. False if the * - * animation does not. * - * * - * HISTORY: * - * 10/14/1992 PWG : Created. * - *=========================================================================*/ -int __cdecl Get_Animation_Palette(void const *handle) -{ - SysAnimHeaderType const *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return(sys_header->flags & WSA_PALETTE_PRESENT); -} - - -/*************************************************************************** - * GET_ANIMATION_SIZE -- Return the amount of memory the animation is using* - * * - * * - * INPUT: void * to the animation that we are processing * - * * - * OUTPUT: unsigned long number of byte used by animation. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/23/1994 SKB : Created. * - *=========================================================================*/ -unsigned long __cdecl Get_Animation_Size(void const *handle) -{ - SysAnimHeaderType const *sys_header; - - if (!handle) { - return FALSE; - } - sys_header = (SysAnimHeaderType *) handle; - return(sys_header->anim_mem_size); -} - -/* :::::::::::::::::::::::::::: PRIVATE FUNCTIONS :::::::::::::::::::::::::::::: */ - - -/*************************************************************************** - * GET_RESIDENT_FRAME_OFFSET -- Gets frame offset of animate file in RAM * - * * - * INPUT: char *file_buffer in RAM of animation file. * - * int frame number that we need the offset of. * - * * - * OUTPUT: int offset of frame requested. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/26/1991 SB : Created. * - *=========================================================================*/ -PRIVATE unsigned long Get_Resident_Frame_Offset( char *file_buffer, int frame ) -{ - unsigned long frame0_size; - unsigned long *lptr; - - // If there is a frame 0, the calculate its size. - lptr = (unsigned long *) file_buffer; - - if (*lptr) { - frame0_size = lptr[1] - *lptr; - } else { - frame0_size = 0; - } - - // Return the offset into RAM for the frame. - lptr += frame; - if (*lptr) - return (*lptr - (frame0_size + WSA_FILE_HEADER_SIZE)); - else - return (0L); -} - - -/*************************************************************************** - * GET_FILE_FRAME_OFFSET -- Get offset of a delta frame from animate file. * - * * - * INPUT: int file_handle of animation file. * - * int frame number that we need the offset of. * - * * - * OUTPUT: int offset of frame requested. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/26/1991 SB : Created. * - *=========================================================================*/ -PRIVATE unsigned long Get_File_Frame_Offset( int file_handle, int frame, int palette_adjust) -{ - unsigned long offset; - - Seek_File(file_handle, (frame << 2) + WSA_FILE_HEADER_SIZE, SEEK_SET); - - if (Read_File(file_handle, (char *) &offset, sizeof(unsigned long)) != sizeof(unsigned long)) { - offset = 0L; - } - offset += palette_adjust; - return( offset ); -} - - -/*************************************************************************** - * APPLY_DELTA -- Copies frame into delta buffer, then applies to target * - * * - * INPUT: SysAnimHeaderType *sys_header - pointer to animation buffer.* - * int curr_frame - frame to put into target buffer. * - * * - * OUTPUT: BOOL - Return wether or not it worked. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 11/26/1991 SB : Created. * - *=========================================================================*/ -PRIVATE BOOL Apply_Delta(SysAnimHeaderType *sys_header, int curr_frame, char *dest_ptr, int dest_w) -{ - char *data_ptr, *delta_back; - int file_handle, palette_adjust; - unsigned long frame_data_size, frame_offset; - - - palette_adjust = ((sys_header->flags & WSA_PALETTE_PRESENT) ? 768 : 0); - delta_back = sys_header->delta_buffer; - - if (sys_header->flags & WSA_RESIDENT) { - // Get offset of the given frame in the resident file - // Get the size of the frame <- (frame+1 offset) - (offset) - // Point at the delta data - // figure offset to load data into end of delta buffer - // copy it into buffer - - frame_offset = Get_Resident_Frame_Offset(sys_header->file_buffer, curr_frame); - frame_data_size = Get_Resident_Frame_Offset(sys_header->file_buffer, curr_frame + 1) - frame_offset; - - data_ptr = (char *)Add_Long_To_Pointer(sys_header->file_buffer, frame_offset); - delta_back = (char *)Add_Long_To_Pointer(delta_back, - sys_header->largest_frame_size - frame_data_size); - - Mem_Copy( data_ptr, delta_back, frame_data_size ); - - } else if (sys_header -> flags & WSA_FILE) { - - // Open up file because not file not in RAM. - // Get offset of the given frame in the file on disk - // Get the size of the frame <- (frame+1 offset) - (offset) - // Return if Get_.._offset() failed. -- need error handling???? - // Seek to delta data. - // figure offset to load data into end of delta buffer - // Read it into buffer -- Return if correct amount not read.-- errors?? - - file_handle = sys_header->file_handle; - Seek_File(file_handle, 0L, SEEK_SET); - - frame_offset = Get_File_Frame_Offset(file_handle, curr_frame, palette_adjust); - frame_data_size = Get_File_Frame_Offset(file_handle, curr_frame + 1, palette_adjust) - frame_offset; - - if (!frame_offset || !frame_data_size) { - return(FALSE); - } - - Seek_File(file_handle, frame_offset, SEEK_SET); - delta_back = (char *)Add_Long_To_Pointer(delta_back, sys_header->largest_frame_size - frame_data_size); - - if (Read_File(file_handle, delta_back, frame_data_size) != frame_data_size) { - return(FALSE); - } - } - - // Uncompress data at end of delta buffer to the beginning of delta buffer. - // Find start of target buffer. - // Apply the XOR delta. - - LCW_Uncompress(delta_back, sys_header->delta_buffer, sys_header->largest_frame_size); - - if (sys_header->flags & WSA_TARGET_IN_BUFFER) { - Apply_XOR_Delta(dest_ptr, sys_header->delta_buffer); - } - else { - Apply_XOR_Delta_To_Page_Or_Viewport(dest_ptr, sys_header->delta_buffer, - sys_header->pixel_width, dest_w, DO_XOR); - } - - return(TRUE); -} - diff --git a/code/TIBERIANDAWN/WIN32LIB/WSA.H b/code/TIBERIANDAWN/WIN32LIB/WSA.H deleted file mode 100644 index 8cb0fd6..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WSA.H +++ /dev/null @@ -1,160 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : WSA 32bit LIbrary * - * * - * File Name : WSA.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : May 23, 1994 * - * * - * Last Update : May 25, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * Open_Animation -- file name and flags, system allocates buffer. * - * Open_Animation -- file name, flags, palette, system allocates buffer. * - * Open_Animation -- file_name, graphic buffer, flags. * - * Open_Animation -- file name, bufferclass, flags, palette. * - * Open_Animation -- filename, ptr, size, flags, no palette. * - * Animate_Frame -- Animate a frame to a page with magic colors. * - * Animate_Frame -- Animate a frame to a viewport with magic colors. * - * Animate_Frame -- Animate a frame to a page. * - * Animate_Frame -- Animate a frame to a viewport. * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WSA_H -#define WSA_H - -#ifndef WWSTD_H -#include "wwstd.h" -#endif - -#ifndef GBUFFER_H -#include "gbuffer.h" -#endif - -//lint -strong(AJX,WSAType) -typedef enum { - WSA_NORMAL, // Normal WSA animation - WSA_GHOST = 0x1000, // Or'd with the above flags to get ghosting - WSA_PRIORITY2 = 0x2000, // Copy using a priority (or in the priority) - WSA_TRANS = 0x4000, // Copy frame, ignoring transparent colors - WSA_PRIORITY = 0x8000 // Copy using a priority (or in the priority) -} WSAType; - - -//lint -strong(AJX,WSAOpenType) -typedef enum { - WSA_OPEN_FROM_MEM = 0x0000, // Try to load entire anim into memory. - WSA_OPEN_INDIRECT = 0x0000, // First animate to internal buffer, then copy to page/viewport. - WSA_OPEN_FROM_DISK = 0x0001, // Force the animation to be disk based. - WSA_OPEN_DIRECT = 0x0002, // Animate directly to page or viewport. - - // These next two have been added for the 32 bit library to give a better idea of what is - // happening. You may want to animate directly to the destination or indirectly to the - // destination by using the animations buffer. Indirecly is best if the dest is a seenpage - // and the animation is not linear or if the destination is modified between frames. - WSA_OPEN_TO_PAGE = WSA_OPEN_DIRECT , - WSA_OPEN_TO_BUFFER= WSA_OPEN_INDIRECT , - -} WSAOpenType; - -/*=========================================================================*/ -/* The following prototypes are for the file: WSA.CPP */ -/*=========================================================================*/ - -void * __cdecl Open_Animation(char const *file_name, char *user_buffer, long user_buffer_size, WSAOpenType user_flags, unsigned char *palette=NULL); -void __cdecl Close_Animation( void *handle ); -BOOL __cdecl Animate_Frame(void *handle, GraphicViewPortClass& view, - int frame_number, int x_pixel=0, int y_pixel=0, - WSAType flags_and_prio = WSA_NORMAL, void *magic_cols=NULL, void *magic=NULL); -int __cdecl Get_Animation_Frame_Count(void *handle); -BOOL __cdecl Animate_Frame(void *handle, VideoViewPortClass& view, - int frame_number, int x_pixel=0, int y_pixel=0, - WSAType flags_and_prio = WSA_NORMAL, void *magic_cols=NULL, void *magic=NULL); -int __cdecl Get_Animation_Frame_Count(void *handle); -int __cdecl Get_Animation_X(void const *handle); -int __cdecl Get_Animation_Y(void const *handle); -int __cdecl Get_Animation_Width(void const *handle); -int __cdecl Get_Animation_Height(void const *handle); -int __cdecl Get_Animation_Palette(void const *handle); -unsigned long __cdecl Get_Animation_Size(void const *handle); - - -/*************************************************************************** - * OPEN_ANIMATION -- file name, flags, palette, system allocates buffer. * - * * - * * - * INPUT: char *file_name - name of file to open. * - * WSAOpenType user_flags - flags on how to open. * - * unsigned char *palette - pointer to a palette buffer to fill. * - * * - * OUTPUT: void *pointer to animation data. Must be used for all * - * other WSA calls. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/24/1994 SKB : Created. * - *=========================================================================*/ -inline void * __cdecl Open_Animation(char *file_name, WSAOpenType user_flags, unsigned char *palette=NULL) -{ - return (Open_Animation(file_name, NULL, 0L, user_flags, palette)); -} - - -/*************************************************************************** - * OPEN_ANIMATION -- file_name, bufferclass, flags. * - * * - * * - * INPUT: char *file_name - name of file to open. * - * GraphicBufferClass - pointer to a buffer. * - * WSAOpenType user_flags - flags on how to open. * - * unsigned char *palette - pointer to a palette buffer to fill. * - * * - * OUTPUT: void *pointer to animation data. Must be used for all * - * other WSA calls. * - * * - * WARNINGS: * - * * - * HISTORY: * - * 05/24/1994 SKB : Created. * - *=========================================================================*/ -inline void * __cdecl Open_Animation(char *file_name, BufferClass& buffer, WSAOpenType user_flags, unsigned char *palette=NULL) -{ - return (Open_Animation(file_name, (char *)buffer.Get_Buffer(), buffer.Get_Size(), user_flags, palette)); -} - - -/*=========================================================================*/ -/* The following prototypes are for the file: LP_ASM.ASM */ -/*=========================================================================*/ - - -extern "C" { -unsigned int __cdecl Apply_XOR_Delta(char *source_ptr, char *delta_ptr); -void __cdecl Apply_XOR_Delta_To_Page_Or_Viewport(void *target, void *delta, int width, int nextrow, int copy); -} - - - -#endif // WSA_H - diff --git a/code/TIBERIANDAWN/WIN32LIB/WWFILE.H b/code/TIBERIANDAWN/WIN32LIB/WWFILE.H deleted file mode 100644 index d7dd406..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WWFILE.H +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\wwfile.h_v 2.14 06 Sep 1995 16:30:00 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : WWFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : August 8, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WWFILE_H -#define WWFILE_H - -#include - -#ifndef READ -#define READ _READ -#endif -#ifndef WRITE -#define WRITE _WRITE -#endif - -class FileClass -{ - public: - virtual ~FileClass(void) {}; - virtual char const * File_Name(void) const = 0; - virtual char const * Set_Name(char const *filename) = 0; - virtual int Create(void) = 0; - virtual int Delete(void) = 0; - virtual int Is_Available(int forced=false) = 0; - virtual int Is_Open(void) const = 0; - virtual int Open(char const *filename, int rights=READ) = 0; - virtual int Open(int rights=READ) = 0; - virtual long Read(void *buffer, long size) = 0; - virtual long Seek(long pos, int dir=SEEK_CUR) = 0; - virtual long Size(void) = 0; - virtual long Write(void const *buffer, long size) = 0; - virtual void Close(void) = 0; - - operator char const * () {return File_Name();}; -}; - -#endif diff --git a/code/TIBERIANDAWN/WIN32LIB/WWLIB32.H b/code/TIBERIANDAWN/WIN32LIB/WWLIB32.H deleted file mode 100644 index 88fe24e..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WWLIB32.H +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : WWLIB32 User include file * - * * - * File Name : WWLIB32.H * - * * - * Programmer : Scott K. Bowen * - * * - * Start Date : August 3, 1994 * - * * - * Last Update : August 3, 1994 [SKB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef WWLIB32_H -#define WWLIB32_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#endif // WWLIB32_H - - diff --git a/code/TIBERIANDAWN/WIN32LIB/WWMEM.H b/code/TIBERIANDAWN/WIN32LIB/WWMEM.H deleted file mode 100644 index 20bb06a..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WWMEM.H +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : Memory System * - * * - * File Name : MEM.H * - * * - * Programmer : Jeff Wilson * - * * - * Start Date : April 4, 1994 * - * * - * Last Update : September 8, 1994 [IML] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifndef WWMEM_H -#define WWMEM_H - -#include "wwstd.h" -#include "new.h" -#include "memflag.h" - -// Defines -//============== - - - - -/*=========================================================================*/ -/* The following prototypes are for the file: MEM.CPP */ -/*=========================================================================*/ - -int Mem_Init(void *buffer, long size); -void *Mem_Alloc(void *poolptr, long lsize, unsigned long id); -int Mem_Free(void *poolptr, void *buffer); -void Mem_Reference(void *node); -void Mem_Lock_Block(void *node); -void Mem_In_Use(void *node); -void *Mem_Find(void *poolptr, unsigned long id); -unsigned long Mem_Get_ID(void *node); -void *Mem_Find_Oldest(void *poolptr); -void *Mem_Free_Oldest(void *poolptr); -long Mem_Pool_Size(void *poolptr); -long Mem_Avail(void *poolptr); -long Mem_Largest_Avail(void *poolptr); -void Mem_Cleanup(void *poolptr); - - -#endif - diff --git a/code/TIBERIANDAWN/WIN32LIB/WWMEM.INC b/code/TIBERIANDAWN/WIN32LIB/WWMEM.INC deleted file mode 100644 index 954b433..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WWMEM.INC +++ /dev/null @@ -1,40 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Memory System * -;* * -;* File Name : WWMEM.INC * -;* * -;* Programmer : Ian M. Leslie * -;* * -;* Start Date : August 11, 1994 * -;* * -;* Last Update : August 17, 1994 [IML] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -MEM_NORMAL EQU 0000h ; Default memory (normal). -MEM_NEW EQU 0001h ; Called by the operator new and was overloaded. -MEM_CLEAR EQU 0002h ; - -GLOBAL @Alloc$qul14MemoryFlagType:PROC -GLOBAL @Free$qpv:PROC diff --git a/code/TIBERIANDAWN/WIN32LIB/WWSTD.H b/code/TIBERIANDAWN/WIN32LIB/WWSTD.H deleted file mode 100644 index 83ee8b9..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WWSTD.H +++ /dev/null @@ -1,224 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** - *************************************************************************** - * * - * Project Name : wwstd.h * - * * - * File Name : WWLIB.H * - * * - * Programmer : Jeff Wilson * - * * - * Start Date : March 1, 1994 * - * * - * Last Update : March 1, 1994 [] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WWSTD_H -#define WWSTD_H - - - -#include -#include - -#ifndef IBM -#define IBM TRUE -#endif - -#define WW_ERROR -1 - -#define PRIVATE static -#define PUBLIC /* Routines & data don't have a specifier */ - -#ifdef __cplusplus -#define __CPPARGS ... -#else -#define __CPPARGS -#endif - - - -#ifdef GET_SIZE -#undef GET_SIZE -#endif -#define GET_SIZE(a) ((sizeof(a) / sizeof(*a))) - -//PG_TO_FIX -//#pragma option -Jg -// Returns the absolute value of the number. -#ifdef ABS -#undef ABS -#endif -template T ABS(T a) -{ - return (a < 0) ? -a : a; -} -//int ABS(int); -//long ABS(long); - -// Returns the minimum of the two numbers. -#ifdef MIN -#undef MIN -#endif -template T MIN(T a, T b) -{ - return (b < a) ? b : a; -}; -//short MIN(short, short); -//int MIN(int, int); -//long MIN(long, long); - -// Returns the maximum of the two numbers. -#ifdef MAX -#undef MAX -#endif -template T MAX(T a, T b) -{ - return (b > a) ? b : a; -}; - -// Returns the low word of a long -#define LOW_WORD(a) ((unsigned short)((long)(a) & 0x0000FFFFL)) - -// Returns the high word of a long -#define HIGH_WORD(a) ((unsigned long)(a) >> 16) - -// Merges to shorts to become a long -#define MAKE_LONG(a,b) (((long)(a) << 16) | (long)((b)&0x0000FFFFL)) - -/* -** Macro allows our routines to act like -** sprintf etc.. -*/ -#ifdef AssembleTo -#undef AssembleTo -#endif - -#define AssembleTo(dest,fmt)\ -{\ - va_list argptr;\ - if (fmt != (dest))\ - {\ - va_start (argptr, fmt);\ - vsprintf ((dest), fmt, argptr);\ - va_end (argptr);\ - }\ -} - - -/* -** The type of processor running on this system as -** returned by Processor(). -*/ -#define PROC_80386 0 -#define PROC_80486 1 -#define PROC_PENTIUM 2 - - -// Inline Routines -//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ -// -// These Template functions are generally used -// by classes when they havce over loaded > and <. -// -#ifdef __cplusplus -template T Min(T a, T b) -{ - return (a inline T Max(T a, T b) -{ - return (a>b ? a : b); -} - -template T Abs(T a) -{ - return ((a<0) ? -(a) : a); -} - -template VOID minimize(T &a, T b) -{ - if( b VOID maximize(T &a, T b) -{ - if( b>a ) - a=b; -} -#endif - -/* -** Macros that control bit settings in a variable. -*/ -#define Bit_Flags_On(a,b) a |= (b) -#define Bit_Flags_Off(a,b) a &= (~(b)) -#define Bit_Flags_Value(a,b) (a & (b)) -#define Bit_Flags_Flip(a,b) a ^= (b) - -// Template replacements for the user defines above -#ifdef __cplusplus -template VOID BitFlagsOn(T &a, T b) -{ - a |= (b); -} - -template VOID BitFlagsOff(T &a, T b) -{ - a &= (~(b)); -} - -template T BitFlagsValue(T a, T b) -{ - return (a & (b)); -} - -template VOID BitFlagsFlip(T &a, T b) -{ - a ^= (b); -} -#endif - -typedef enum { - TBLACK, - PURPLE, - CYAN, - GREEN, - LTGREEN, - YELLOW, - PINK, - BROWN, - RED, - LTCYAN, - LTBLUE, - BLUE, - BLACK, - GREY, - LTGREY, - WHITE, - COLOR_PADDING=0x1000 -} ColorType; - - - -#endif //WWSTD_H \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/WW_WIN.H b/code/TIBERIANDAWN/WIN32LIB/WW_WIN.H deleted file mode 100644 index 7f87861..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/WW_WIN.H +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Part of the WINDOWS Library * - * * - * File Name : WINDOWS.H * - * * - * Programmer : Barry W. Green * - * * - * Start Date : February 16, 1995 * - * * - * Last Update : February 16, 1995 [BWG] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WINDOWS_H -#define WINDOWS_H - -/*=========================================================================*/ -/* The following prototypes are for the file: WINHIDE.CPP */ -/*=========================================================================*/ -void Window_Hide_Mouse(int window); -void Window_Show_Mouse(void); - -/*=========================================================================*/ -/* The following prototypes are for the file: WINDOWS.CPP */ -/*=========================================================================*/ -void Standard_More_Prompt(char const *prompt, int space, int fcolor, int bcolor); -void Set_More_Prompt(char const *prompt, int space, int fcolor, int bcolor); -void Set_More_On(void); -void Set_More_Off(void); -int Change_Window(int windnum); -int Change_New_Window(int windnum); -void New_Window(void); -void Window_Int_Print(int num); -void Window_Print(char const string[], ...); - -/* -** The WindowList[][8] array contains the following elements. Use these -** defines when accessing the WindowList. -*/ -typedef enum { - WINDOWX, // X byte position of left edge. - WINDOWY, // Y pixel position of top edge. - WINDOWWIDTH, // Width in bytes of the window. - WINDOWHEIGHT, // Height in pixels of the window. - WINDOWFCOL, // Default foreground color. - WINDOWBCOL, // Default background color. - WINDOWCURSORX, // Current cursor X position (in rows). - WINDOWCURSORY, // Current cursor Y position (in lines). - WINDOWPADDING=0x1000 -} WindowIndexType; - -extern int WindowList[][8]; -extern int WindowColumns; -extern int WindowLines; -extern int WindowWidth; -extern unsigned int WinB; -extern unsigned int WinC; -extern unsigned int WinX; -extern unsigned int WinY; -extern unsigned int WinCx; -extern unsigned int WinCy; -extern unsigned int WinH; -extern unsigned int WinW; -extern unsigned int Window; - -extern int MoreOn; -extern char *TXT_MoreText; - -extern void (*Window_More_Ptr)(char const *, int, int, int); - -#endif //WINDOWS_H - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/XORDELTA.ASM b/code/TIBERIANDAWN/WIN32LIB/XORDELTA.ASM deleted file mode 100644 index 79416fb..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/XORDELTA.ASM +++ /dev/null @@ -1,668 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - -; ************************************************************************** -; ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S * -; ************************************************************************** -; * * -; * Project Name : WSA Support routines * -; * * -; * File Name : XORDELTA.ASM * -; * * -; * Programmer : Scott K. Bowen * -; * * -; * Last Update :May 23, 1994 [SKB] * -; * * -; *------------------------------------------------------------------------* -; * Functions: * -;* Apply_XOR_Delta -- Apply XOR delta data to a buffer. * -;* Apply_XOR_Delta_To_Page_Or_Viewport -- Calls the copy or the XOR funti* -;* Copy_Delta_buffer -- Copies XOR Delta Data to a section of a page. * -;* XOR_Delta_Buffer -- Xor's the data in a XOR Delta format to a page. * -; * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* - -;IDEAL -;P386 -;MODEL USE32 FLAT -.model flat - - - -;LOCALS ?? - -; These are used to call Apply_XOR_Delta_To_Page_Or_Viewport() to setup flags parameter. If -; These change, make sure and change their values in wsa.cpp. -DO_XOR equ 0 -DO_COPY equ 1 -TO_VIEWPORT equ 0 -TO_PAGE equ 2 - -; -; Routines defined in this module -; -; -; UWORD Apply_XOR_Delta(UWORD page_seg, BYTE *delta_ptr); -; PUBLIC Apply_XOR_Delta_To_Page_Or_Viewport(UWORD page_seg, BYTE *delta_ptr, WORD width, WORD copy) -; -; PROC C XOR_Delta_Buffer -; PROC C Copy_Delta_Buffer -; - -externdef C Apply_XOR_Delta:NEAR -externdef C Apply_XOR_Delta_To_Page_Or_Viewport:NEAR - - - - ;CODESEG - .code - - -;*************************************************************************** -;* APPLY_XOR_DELTA -- Apply XOR delta data to a linear buffer. * -;* AN example of this in C is at the botton of the file commented out. * -;* * -;* INPUT: BYTE *target - destination buffer. * -;* BYTE *delta - xor data to be delta uncompress. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 05/23/1994 SKB : Created. * -;*=========================================================================* -Apply_XOR_Delta proc C public USES ebx ecx edx esi edi target:DWORD, delta:DWORD - - ;USES ebx,ecx,edx,edi,esi - ;ARG target:DWORD ; pointers. - ;ARG delta:DWORD ; pointers. - - ; Optimized for 486/pentium by rearanging instructions. - mov edi,[target] ; get our pointers into offset registers. - mov esi,[delta] - - cld ; make sure we go forward - xor ecx,ecx ; use cx for loop - -top_loop: - xor eax,eax ; clear out eax. - mov al,[esi] ; get delta source byte - inc esi - - test al,al ; check for a SHORTDUMP ; check al incase of sign value. - je short_run - js check_others - -; -; SHORTDUMP -; - mov ecx,eax ; stick count in cx - -dump_loop: - mov al,[esi] ;get delta XOR byte - xor [edi],al ; xor that byte on the dest - inc esi - inc edi - dec ecx - jnz dump_loop - jmp top_loop - -; -; SHORTRUN -; - -short_run: - mov cl,[esi] ; get count - inc esi ; inc delta source - -do_run: - mov al,[esi] ; get XOR byte - inc esi - -run_loop: - xor [edi],al ; xor that byte. - - inc edi ; go to next dest pixel - dec ecx ; one less to go. - jnz run_loop - jmp top_loop - -; -; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP -; - -check_others: - sub eax,080h ; opcode -= 0x80 - jnz do_skip ; if zero then get next word, otherwise use remainder. - - mov ax,[esi] - lea esi,[esi+2] ; get word code in ax - test ax,ax ; set flags. (not 32bit register so neg flag works) - jle not_long_skip - -; -; SHORTSKIP AND LONGSKIP -; -do_skip: - add edi,eax ; do the skip. - jmp top_loop - - -not_long_skip: - jz stop ; long count of zero means stop - sub eax,08000h ; opcode -= 0x8000 - test eax,04000h ; is it a LONGRUN (code & 0x4000)? - je long_dump - -; -; LONGRUN -; - sub eax,04000h ; opcode -= 0x4000 - mov ecx,eax ; use cx as loop count - jmp do_run ; jump to run code. - - -; -; LONGDUMP -; - -long_dump: - mov ecx,eax ; use cx as loop count - jmp dump_loop ; go to the dump loop. - -stop: - - ret - -Apply_XOR_Delta endp - - -;---------------------------------------------------------------------------- - - -;*************************************************************************** -;* APPLY_XOR_DELTA_To_Page_Or_Viewport -- Calls the copy or the XOR funtion. * -;* * -;* * -;* This funtion is call to either xor or copy XOR_Delta data onto a * -;* page instead of a buffer. The routine will set up the registers * -;* need for the actual routines that will perform the copy or xor. * -;* * -;* The registers are setup as follows : * -;* es:edi - destination segment:offset onto page. * -;* ds:esi - source buffer segment:offset of delta data. * -;* dx,cx,ax - are all zeroed out before entry. * -;* * -;* INPUT: * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 03/09/1992 SB : Created. * -;*=========================================================================* - - -Apply_XOR_Delta_To_Page_Or_Viewport proc C public USES ebx ecx edx esi edi target:DWORD, delta:DWORD, xwidth:DWORD, nextrow:DWORD, copy:DWORD - - ;USES ebx,ecx,edx,edi,esi - ;ARG target:DWORD ; pointer to the destination buffer. - ;ARG delta:DWORD ; pointer to the delta buffer. - ;ARG width:DWORD ; width of animation. - ;ARG nextrow:DWORD ; Page/Buffer width - anim width. - ;ARG copy:DWORD ; should it be copied or xor'd? - - - mov edi,[target] ; Get the target pointer. - mov esi,[delta] ; Get the destination pointer. - - xor eax,eax ; clear eax, later put them into ecx and edx. - - cld ; make sure we go forward - - mov ebx,[nextrow] ; get the amount to add to get to next row from end. push it later... - - mov ecx,eax ; use cx for loop - mov edx,eax ; use dx to count the relative column. - - push ebx ; push nextrow onto the stack for Copy/XOR_Delta_Buffer. - mov ebx,[xwidth] ; bx will hold the max column for speed compares - -; At this point, all the registers have been set up. Now call the correct function -; to either copy or xor the data. - - cmp [copy],DO_XOR ; Do we want to copy or XOR - je xorfunct ; Jump to XOR if not copy - call Copy_Delta_Buffer ; Call the function to copy the delta buffer. - jmp didcopy ; jump past XOR -xorfunct: - call XOR_Delta_Buffer ; Call funtion to XOR the deltat buffer. -didcopy: - pop ebx ; remove the push done to pass a value. - - ret - -Apply_XOR_Delta_To_Page_Or_Viewport ENDP -;---------------------------------------------------------------------------- - - -;*************************************************************************** -;* XOR_DELTA_BUFFER -- Xor's the data in a XOR Delta format to a page. * -;* This will only work right if the page has the previous data on it. * -;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. * -;* The registers must be setup as follows : * -;* * -;* INPUT: * -;* es:edi - destination segment:offset onto page. * -;* ds:esi - source buffer segment:offset of delta data. * -;* edx,ecx,eax - are all zeroed out before entry. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 03/09/1992 SB : Created. * -;*=========================================================================* - -XOR_Delta_Buffer proc C nextrow:DWORD - -top_loop2: - xor eax,eax ; clear out eax. - mov al,[esi] ; get delta source byte - inc esi - - test al,al ; check for a SHORTDUMP ; check al incase of sign value. - je short_run2 - js check_others2 - -; -; SHORTDUMP -; - mov ecx,eax ; stick count in cx - -dump_loop2: - mov al,[esi] ; get delta XOR byte - xor [edi],al ; xor that byte on the dest - inc esi - inc edx ; increment our count on current column - inc edi - cmp edx,ebx ; are we at the final column - jne end_col1 ; if not the jmp over the code - - sub edi,edx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row -end_col1: - - dec ecx - jnz dump_loop2 - jmp top_loop2 - -; -; SHORTRUN -; - -short_run2: - mov cl,[esi] ; get count - inc esi ; inc delta source - -do_run2: - mov al,[esi] ; get XOR byte - inc esi - -run_loop2: - xor [edi],al ; xor that byte. - - inc edx ; increment our count on current column - inc edi ; go to next dest pixel - cmp edx,ebx ; are we at the final column - jne end_col2 ; if not the jmp over the code - - sub edi,ebx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row -end_col2: - - - dec ecx - jnz run_loop2 - jmp top_loop2 - -; -; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP -; - -check_others2: - sub eax,080h ; opcode -= 0x80 - jnz do_skip2 ; if zero then get next word, otherwise use remainder. - - mov ax,[esi] ; get word code in ax - lea esi,[esi+2] - test ax,ax ; set flags. (not 32bit register so neg flag works) - jle not_long_skip2 - -; -; SHORTSKIP AND LONGSKIP -; -do_skip2: - sub edi,edx ; go back to beginning or row. - add edx,eax ; incriment our count on current row -recheck2: - cmp edx,ebx ; are we past the end of the row - jb end_col3 ; if not the jmp over the code - - sub edx,ebx ; Subtract width from the col counter - add edi,[nextrow] ; jump to start of next row - jmp recheck2 ; jump up to see if we are at the right row -end_col3: - add edi,edx ; get to correct position in row. - jmp top_loop2 - - -not_long_skip2: - jz stop2 ; long count of zero means stop - sub eax,08000h ; opcode -= 0x8000 - test eax,04000h ; is it a LONGRUN (code & 0x4000)? - je long_dump2 - -; -; LONGRUN -; - sub eax,04000h ; opcode -= 0x4000 - mov ecx,eax ; use cx as loop count - jmp do_run2 ; jump to run code. - - -; -; LONGDUMP -; - -long_dump2: - mov ecx,eax ; use cx as loop count - jmp dump_loop2 ; go to the dump loop. - -stop2: - - ret - - -XOR_Delta_Buffer ENDP - -;---------------------------------------------------------------------------- - - -;*************************************************************************** -;* COPY_DELTA_BUFFER -- Copies XOR Delta Data to a section of a page. * -;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. * -;* The registers must be setup as follows : * -;* * -;* INPUT: * -;* es:edi - destination segment:offset onto page. * -;* ds:esi - source buffer segment:offset of delta data. * -;* dx,cx,ax - are all zeroed out before entry. * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 03/09/1992 SB : Created. * -;*=========================================================================* -Copy_Delta_Buffer proc C nextrow:DWORD - - ;ARG nextrow:DWORD - -top_loop3: - xor eax,eax ; clear out eax. - mov al,[esi] ; get delta source byte - inc esi - - test al,al ; check for a SHORTDUMP ; check al incase of sign value. - je short_run3 - js check_others3 - -; -; SHORTDUMP -; - mov ecx,eax ; stick count in cx - -dump_loop3: - mov al,[esi] ; get delta XOR byte - - mov [edi],al ; store that byte on the dest - - inc edx ; increment our count on current column - inc esi - inc edi - cmp edx,ebx ; are we at the final column - jne end_col1_3 ; if not the jmp over the code - - sub edi,edx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row -end_col1_3: - - dec ecx - jnz dump_loop3 - jmp top_loop3 - -; -; SHORTRUN -; - -short_run3: - mov cl,[esi] ; get count - inc esi ; inc delta source - -do_run3: - mov al,[esi] ; get XOR byte - inc esi - -run_loop3: - mov [edi],al ; store the byte (instead of XOR against current color) - - inc edx ; increment our count on current column - inc edi ; go to next dest pixel - cmp edx,ebx ; are we at the final column - jne end_col2_3 ; if not the jmp over the code - - sub edi,ebx ; get our column back to the beginning. - xor edx,edx ; zero out our column counter - add edi,[nextrow] ; jump to start of next row -end_col2_3: - - - dec ecx - jnz run_loop3 - jmp top_loop3 - -; -; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP -; - -check_others3: - sub eax,080h ; opcode -= 0x80 - jnz do_skip3 ; if zero then get next word, otherwise use remainder. - - mov ax,[esi] ; get word code in ax - lea esi,[esi+2] - test ax,ax ; set flags. (not 32bit register so neg flag works) - jle not_long_skip3 - -; -; SHORTSKIP AND LONGSKIP -; -do_skip3: - sub edi,edx ; go back to beginning or row. - add edx,eax ; incriment our count on current row -recheck3: - cmp edx,ebx ; are we past the end of the row - jb end_col3_3 ; if not the jmp over the code - - sub edx,ebx ; Subtract width from the col counter - add edi,[nextrow] ; jump to start of next row - jmp recheck3 ; jump up to see if we are at the right row -end_col3_3: - add edi,edx ; get to correct position in row. - jmp top_loop3 - - -not_long_skip3: - jz stop3 ; long count of zero means stop - sub eax,08000h ; opcode -= 0x8000 - test eax,04000h ; is it a LONGRUN (code & 0x4000)? - je long_dump3 - -; -; LONGRUN -; - sub eax,04000h ; opcode -= 0x4000 - mov ecx,eax ; use cx as loop count - jmp do_run3 ; jump to run code. - - -; -; LONGDUMP -; - -long_dump3: - mov ecx,eax ; use cx as loop count - jmp dump_loop3 ; go to the dump loop. - -stop3: - - ret - -Copy_Delta_Buffer ENDP - -;---------------------------------------------------------------------------- - - END - - -;---------------------------------------------------------------------------- -; -;PUBLIC UWORD Apply_XOR_Delta(UWORD page_seg, BYTE *delta_ptr) -;{ -; -; register UWORD loop; -; BYTE opcode, xor_byte; -; UWORD bytes_to_uncompress = 64000U; -; -; -; /* Make our buffer pointer */ -; -; to = MK_FP(page_seg, 0); -; delta = Normalize_Pointer(delta_ptr); -; -; -; while (bytes_to_uncompress) { -; -; opcode = *delta++; -; -; -; /* Check for SHORTDUMP */ -; -; if (opcode > 0) { -; -; -; bytes_to_uncompress -= opcode; -; -; for (loop = 0; loop < opcode; loop++) { -; xor_byte = *delta++; -; *to++ ^= xor_byte; -; } -; continue; -; } -; -; /* Check for SHORTRUN */ -; -; if (opcode == 0) { -; -; word_count = *delta++; -; xor_byte = *delta++; -; -; bytes_to_uncompress -= word_count; -; -; for (loop = 0; loop < word_count; loop++) { -; *to++ ^= xor_byte; -; } -; continue; -; } -; -; /* By now, we know it must be a LONGDUMP, SHORTSKIP, or LONGSKIP */ -; -; opcode -= 0x80; -; -; -; /* Is it a SHORTSKIP? */ -; -; if (opcode != 0) { -; -; to += opcode; -; bytes_to_uncompress -= (WORD) opcode; -; continue; -; } -; -; -; word_count = *((UWORD *) delta)++; -; -; /* Is it a LONGSKIP? */ -; -; if ((WORD) word_count > 0) { -; -; to += word_count; -; bytes_to_uncompress -= (WORD) word_count; -; continue; -; } -; -; -; word_count -= 0x8000; -; -; /* Is it a LONGRUN? */ -; -; if (word_count & 0x4000) { -; -; word_count -= 0x4000; -; -; bytes_to_uncompress -= word_count; -; -; xor_byte = *delta++; -; -; for (loop = 0; loop < word_count; loop++) { -; *to++ ^= xor_byte; -; } -; continue; -; } -; -; -; /* It must be a LONGDUMP */ -; -; bytes_to_uncompress -= word_count; -; -; for (loop = 0; loop < word_count; loop++) { -; xor_byte = *delta++; -; *to++ ^= xor_byte; -; } -; } -; -; -; return(64000U); -;} -; - - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/_DIPTABL.CPP b/code/TIBERIANDAWN/WIN32LIB/_DIPTABL.CPP deleted file mode 100644 index d3cf784..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/_DIPTABL.CPP +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: g:/library/source/rcs/./_diptabl.c 1.11 1994/05/20 15:36:04 joe_bostic Exp $ */ -/*************************************************************************** - ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** - *************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : _DIPTABL.C * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : July 3, 1991 * - * * - * Last Update : July 3, 1991 [JLB] * - * * - *-------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -char Common[16]={' ','e','t','a','i','n','o','s','r','l','h','c','d','u','p','m'}; - -char Dipthong[16][8]={ - {'t','a','s','i','o',' ','w','b'}, - {' ','r','n','s','d','a','l','m'}, - {'h',' ','i','e','o','r','a','s'}, - {'n','r','t','l','c',' ','s','y'}, - {'n','s','t','c','l','o','e','r'}, - {' ','d','t','g','e','s','i','o'}, - {'n','r',' ','u','f','m','s','w'}, - {' ','t','e','p','.','i','c','a'}, - {'e',' ','o','i','a','d','u','r'}, - {' ','l','a','e','i','y','o','d'}, - {'e','i','a',' ','o','t','r','u'}, - {'e','t','o','a','k','h','l','r'}, - {' ','e','i','u',',','.','o','a'}, - {'n','s','r','c','t','l','a','i'}, - {'l','e','o','i','r','a','t','p'}, - {'e','a','o','i','p',' ','b','m'}, -}; - \ No newline at end of file diff --git a/code/TIBERIANDAWN/WIN32LIB/_FILE.H b/code/TIBERIANDAWN/WIN32LIB/_FILE.H deleted file mode 100644 index b5a35e9..0000000 --- a/code/TIBERIANDAWN/WIN32LIB/_FILE.H +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** -;*************************************************************************** -;* * -;* Project Name : Library - Filio header stuff. * -;* * -;* File Name : FILE.H * -;* * -;* Programmer : Scott K. Bowen * -;* * -;* Start Date : September 13, 1993 * -;* * -;* Last Update : April 11, 1994 * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef FILE_H -#include "file.h" -#endif - -#ifndef _FILE_H -#define _FILE_H - - -/*=========================================================================*/ -/* Fileio defines */ -/*=========================================================================*/ - -#define LIB_CDROM TRUE - -#define MODE_OLDFILE (O_RDONLY | O_BINARY) -#define MODE_NEWFILE (O_WRONLY | O_BINARY | O_CREAT | O_TRUNC) -#define MODE_READWRITE (O_RDWR | O_BINARY) - -#define FILEOPENERROR -1 -#define FILEOPEN(f,m) ibm_open(f, m, (((UWORD) m) == MODE_OLDFILE) ? S_IREAD : (S_IREAD | S_IWRITE)) - -#define FILECLOSE(fd) ibm_close(fd) -#define FILEREAD(f,b,n) ibm_read(f,b,(WORD)(n)) -#define FILEWRITE(f,b,n) ibm_write(f,b,(WORD)(n)) -#define FILESEEK(f,b,n) ibm_lseek(f, b, n) -#define FILEDELETE(f) ibm_unlink(f) -#define CHANGEDIR(p) ibm_chdir(p) - -#define FILENAMESIZE 13 -#define IO_CHUNK_SIZE 0xfff0UL - -/* -** Maximum number of file handles -*/ -#define TABLE_MAX 20 - - -/*=========================================================================*/ -/* The file handle table */ -/*=========================================================================*/ -typedef struct { - BOOL Empty; // Is this handle empty? - WORD Handle; // DOS file handle (0 = resident). - LONG Pos; // Current file position. - LONG Start; // Offset of file from pointer. - WORD Index; // FileData[] index. - WORD Mode; // Access mode (WW). - BYTE *Name; // File name pointer. -} FileHandleType; - - -/*=========================================================================*/ -/* The following prototypes are for the file: FILEIO.CPP */ -/*=========================================================================*/ - -WORD ibm_getdisk(VOID); -WORD ibm_setdisk(WORD drive); -WORD ibm_close(WORD handle); -WORD ibm_unlink(BYTE const *name); -LONG ibm_lseek(WORD handle, LONG offset, WORD where); -UWORD ibm_read(WORD handle, VOID *ptr, UWORD bytes); -UWORD ibm_write(WORD handle, VOID *ptr, UWORD bytes); -WORD ibm_open(BYTE const *name, UWORD mode, WORD attrib); -WORD ibm_chdir(BYTE const *path); - -/*=========================================================================*/ -/* The following prototypes are for the file: FILELIB.CPP */ -/*=========================================================================*/ - -WORD cdecl Do_Open_Error(FileErrorType errormsgnum, BYTE const *file_name); -VOID cdecl Do_IO_Error(FileErrorType errormsgnum, BYTE const *filename); -LONG cdecl Read_File_With_Recovery( WORD handle, VOID *buf, UWORD bytes ); -WORD cdecl Open_File_With_Recovery( BYTE const *file_name, UWORD mode ); -BOOL cdecl Cache_File(WORD index, WORD file_handle); - - -/*=========================================================================*/ -/* The following prototypes are for the file: DEVICES.ASM */ -/*=========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern VOID Get_Devices(VOID); -extern WORD Is_Device_Real(WORD device); - -#ifdef __cplusplus -} -#endif - -/*=========================================================================*/ -/* The following prototypes are for the file: DEVTABLE.ASM */ -/*=========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern VOID Init_Device_Table(BYTE *table); -extern WORD Max_Device(VOID); - - -#ifdef __cplusplus -} -#endif - - -/*=========================================================================*/ -/* The following prototypes are for the file: HARDERR.ASM */ -/*=========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern VOID Install_Hard_Error_Handler(VOID); -extern VOID Remove_Hard_Error_Handler(VOID); - -#ifdef __cplusplus -} -#endif - - -/*=========================================================================*/ -/* Globale variables in the fileio system. */ -/*=========================================================================*/ - -extern BYTE CallingDOSInt; -extern "C" extern BYTE MaxDevice,DefaultDrive; -extern BYTE MultiDriveSearch; -extern FileDataType *FileDataPtr; -extern FileHandleType FileHandleTable[TABLE_MAX]; -extern UWORD NumFiles; // Number of files, except PAK, in file table. -extern UWORD NumPAKFiles; // Number of PAK files in filetable. -extern VOID *FileCacheHeap; // Pointer to the cache in memory. -extern WORD DiskNumber; -extern WORD MaxDirNum; - - -/*=========================================================================*/ - - - -#endif // _FILE_H - - diff --git a/code/TIBERIANDAWN/WINASM.ASM b/code/TIBERIANDAWN/WINASM.ASM deleted file mode 100644 index 85283f2..0000000 --- a/code/TIBERIANDAWN/WINASM.ASM +++ /dev/null @@ -1,887 +0,0 @@ -; -; Copyright 2020 Electronic Arts Inc. -; -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -; software: you can redistribute it and/or modify it under the terms of -; the GNU General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. - -; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -; in the hope that it will be useful, but with permitted additional restrictions -; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -; distributed with this program. You should have received a copy of the -; GNU General Public License along with permitted additional restrictions -; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. - - -;*************************************************************************** -;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S I N C ** -;*************************************************************************** -;* * -;* Project Name : Command & Conquer * -;* * -;* File Name : WINSAM.ASM * -;* * -;* Programmer : Steve Tall * -;* * -;* Start Date : October 26th, 1995 * -;* * -;* Last Update : October 26th, 1995 [ST] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -IDEAL -P386 -MODEL USE32 FLAT - -global C _AbortModemFunctionPtr:dword -global C Memory_Error_Exit :dword -global C MouseQX :dword -global C MouseQY :dword - -global FastGetPortHardware_ :near -global FastSetPortHardware_ :near -global PortOpenGreenleafFast_ :near -global HMWaitForOK_ :near -global HMSetDialingMethod_ :near -global HMDial_ :near -global HMInputLine_ :near -global HMAnswer_ :near -global PortKillTime_ :near -global HMSendStringNoWait_ :near -global HMSetUpEchoRoutine_ :near -global HMSetUpAbortKey_ :near -global SetAbortModemFunctionPtr_:near -global Change8259Priority_ :near -global HMSendString_ :near -global C Stop_Execution :near - - -global _IPX_Initialise:near -global _ASM_IPX_Initialise:near - - - codeseg - -proc _ASM_IPX_Initialise near - - int 3 - jmp _IPX_Initialise - -endp - - - - -global _Int3:near -proc _Int3 near - ;int 3 - ret -endp - - -proc Stop_Execution C near - - nop - ret - -endp - - - -; -; Stuff needed from the shape library -; -; -; - - -INCLUDE "shape.inc" - - - - -;*************************************************************************** -;* ModeX_Blit -- Copy a 320x200 graphic view port to a modex screen * -;* * -;* * -;* INPUT: eax - graphic view port * -;* * -;* OUTPUT: none * -;* * -;* PROTO: extern "C" void ModeX_Blit (GraphicBufferClass *source); * -;* * -;* HISTORY: * -;* 10/26/1994 PWG : Created. * -;*=========================================================================* - -SEQUENCER =3c4h ; sequencer port -MAP_MASK =2 ; map mask register - - INCLUDE "gbuffer.inc" - global ModeX_Blit_:near - - -proc ModeX_Blit_ NEAR - - pushad - mov ebx,eax - - mov esi,[(GraphicViewPort ebx).GVPOffset] - mov eax,[(GraphicViewPort ebx).GVPXAdd] - add eax,[(GraphicViewPort ebx).GVPPitch] - mov edi,0a0000h - mov ebx,eax - - mov al,MAP_MASK - - mov ebp,200 - -??each_line_lp: mov ah,1 ;1st plane - push ebx - push esi - -??each_plane_lp:mov edx,SEQUENCER - out dx,ax - - push esi - push edi - push eax - - rept 10 - mov al,[esi] - mov bl,[esi+8] - mov cl,[esi+16] - mov dl,[esi+24] - mov ah,[esi+4] - mov bh,[esi+12] - mov ch,[esi+20] - mov dh,[esi+28] - shl ebx,16 - shl edx,16 - or ebx,eax - or edx,ecx - mov [edi],ebx - mov [edi+4],edx - add esi,32 - add edi,8 - endm - - pop eax - pop edi - pop esi - inc esi - shl ah,1 - cmp ah,16 - jl ??each_plane_lp - - - pop esi - pop ebx - lea esi,[esi+ebx+320] - add edi,80 - dec ebp - jnz ??each_line_lp - - popad - - ret - -endp ModeX_Blit_ - - - - - - -ifdef cuts - pushad - mov ebx,eax - - mov esi,[(GraphicViewPort ebx).GVPOffset] - mov eax,[(GraphicViewPort ebx).GVPXAdd] - add eax,[(GraphicViewPort ebx).GVPPitch] - mov edi,0a0000h - mov ebx,eax - - mov al,MAP_MASK - mov ah,1 ;1st plane - -??each_plane_lp:mov edx,SEQUENCER - out dx,ax - mov ebp,200 ;do 200 lines - push esi - push edi - -??each_line_lp: mov ecx,320/4 - -??each_pixel_lp:mov dl,[esi] - mov [edi],dl - add esi,4 - inc edi - dec ecx - jnz ??each_pixel_lp - - add esi,ebx - dec ebp - jnz ??each_line_lp - - pop edi - pop esi - inc esi - shl ah,1 - - cmp ah,16 - jl ??each_plane_lp -endif - - - - - - - - - - -proc FastGetPortHardware_ NEAR -endp - -proc FastSetPortHardware_ NEAR -endp - -proc PortOpenGreenleafFast_ NEAR -endp - -proc HMWaitForOK_ NEAR -endp - -proc HMSetDialingMethod_ NEAR -endp - -proc HMDial_ NEAR -endp - -proc HMInputLine_ NEAR -endp - -proc HMAnswer_ NEAR -endp - -proc PortKillTime_ NEAR -endp - -proc HMSendStringNoWait_ NEAR -endp - -proc HMSetUpEchoRoutine_ NEAR -endp - -proc HMSetUpAbortKey_ NEAR -endp - -proc SetAbortModemFunctionPtr_ NEAR -endp - -proc Change8259Priority_ NEAR -endp - -proc HMSendString_ NEAR -endp - - ret - - - - - - - - masm -; -; Change a DAC colour register directly -; -; register number in al -; -; bh=red bl=green cl=blue -; - -set_dac_col proc near - pushad - cli - push eax - mov dx,03dah - in al,dx - jmp @@1 -@@1: mov dx,03c8h - pop eax - out dx,al - jmp @@2 -@@2: inc dl - mov al,bh - out dx,al - jmp @@3 -@@3: mov al,bl - out dx,al - jmp @@4 -@@4: mov al,cl - out dx,al - jmp @@5 -@@5: sti - popad - ret -set_dac_col endp - - ideal - - -global Set_Palette_Register_:near - - -proc Set_Palette_Register_ near - - pushad - and cl,63 - mov bh,dl - and bh,63 - and bl,63 - call set_dac_col - popad - ret - -endp Set_Palette_Register_ - - - - - locals ?? - - - - ends - - dataseg - -LineBuffer dd 640 dup (?) - ends - - - - segment mycode page public use32 'code' ; Need stricter segment alignment - -global C Asm_Interpolate:near -global C Asm_Interpolate_Line_Double:near -global C Asm_Interpolate_Line_Interpolate:near -global C PaletteInterpolationTable:byte - - -;********************************************************************************************* -;* Asm_Interpolate -- interpolate a 320x200 buffer to a 640x400 screen * -;* * -;* INPUT: ptr to source buffer (320x200 image) * -;* ptr to dest buffer (640x400) * -;* height of source buffer * -;* width of source buffer * -;* width of dest buffer * -;* * -;* * -;* OUTPUT: none * -;* * -;* Warnings: * -;* * -;* HISTORY: * -;* 12/15/95 ST : Created. * -;*===========================================================================================* - -PROC Asm_Interpolate C near - - ARG src_ptr:dword - ARG dest_ptr:dword - ARG source_height:dword - ARG source_width:dword - ARG dest_width:dword - - LOCAL old_dest:dword - - pushad - - mov eax,[dest_ptr] - mov [old_dest],eax - - mov esi,[src_ptr] - -??each_line_loop: - mov ecx,[source_width] - sub ecx,2 - shr ecx,1 - mov edi,[old_dest] - jmp ??interpolate_loop - - align 32 -; -; convert 2 pixels of source into 4 pixels of destination -; so we can write to video memory with dwords -; -??interpolate_loop: - mov eax,[esi] - lea esi,[esi+2] - mov edx,eax - mov ebx,eax - and edx,65535 - ror ebx,8 - mov bl,[edx+PaletteInterpolationTable] - mov bh,ah - and eax,000ffff00h - ror ebx,8 - -;1st 3 pixels now in ebx - - shr eax,8 - mov bh,[eax+PaletteInterpolationTable] - ror ebx,16 - mov [edi],ebx - add edi,4 - - dec ecx - jnz ??interpolate_loop - -; do the last three pixels and a blank on the end of a row - xor eax,eax - mov ax,[esi] - mov [edi],al - inc edi - lea esi,[esi+2] - mov al,[eax+PaletteInterpolationTable] - mov [edi],al - inc edi - mov [edi],ah - inc edi - mov [byte edi],0 - - mov edi,[dest_width] - add [old_dest],edi - - dec [source_height] - jnz ??each_line_loop - - popad - ret - -endp Asm_Interpolate - - - - - - - - - - - - - - -PROC Asm_Interpolate_Line_Double C near - ARG src_ptr:dword - ARG dest_ptr:dword - ARG source_height:dword - ARG source_width:dword - ARG dest_width:dword - - LOCAL old_dest:dword - LOCAL width_counter:dword - LOCAL pixel_count:dword - - pushad - - mov eax,[dest_ptr] - mov [old_dest],eax - - mov esi,[src_ptr] - mov edi,[dest_ptr] - -??each_line_loop: - mov [width_counter],0 - mov ecx,[source_width] - sub ecx,2 - shr ecx,1 - mov [pixel_count],ecx - mov ecx,offset LineBuffer - mov edi,[old_dest] - jmp ??interpolate_loop - align 16 - -; convert 2 pixels of source into 4 pixels of destination -??interpolate_loop: - mov eax,[esi] - lea esi,[esi+2] - mov edx,eax - mov ebx,eax - and edx,65535 - ror ebx,8 - mov bl,[edx+PaletteInterpolationTable] - mov bh,ah - and eax,000ffff00h - ror ebx,8 - - ;1st 3 pixels now in ebx - shr eax,8 - mov bh,[eax+PaletteInterpolationTable] - ror ebx,16 - mov [edi],ebx - mov [ecx],ebx - add edi,4 - add ecx,4 - - dec [pixel_count] - jnz ??interpolate_loop - -; do the last three pixels and a blank - - xor eax,eax - mov ax,[esi] - mov [edi],al - mov [ecx],al - inc edi - inc ecx - lea esi,[esi+2] - mov al,[eax+PaletteInterpolationTable] - mov [edi],al - mov [ecx],al - inc edi - inc ecx - mov [edi],ah - mov [ecx],ah - inc edi - inc ecx - mov [byte edi],0 - mov [byte ecx],0 - - mov edi,[dest_width] - shr edi,1 - add [old_dest],edi - push esi - push edi - mov esi,offset LineBuffer - mov edi,[old_dest] - mov ecx,[source_width] - shr ecx,1 - rep movsd - pop edi - pop esi - add [old_dest],edi - mov edi,[old_dest] - - dec [source_height] - jnz ??each_line_loop - - popad - ret - -endp Asm_Interpolate_Line_Double - - - - - - - - - - ends - - dataseg - -TopLine dd 640 dup (?) -BottomLine dd 640 dup (?) - - - segment mycode page public use32 'code' ; Need stricter segment alignment - - -proc Interpolate_Single_Line C near - - ARG source_ptr:dword - ARG dest_ptr:dword - ARG source_width:dword - - pushad - - mov ecx,[source_width] - sub ecx,2 - shr ecx,1 - - mov esi,[source_ptr] - mov edi,[dest_ptr] - -??interpolate_loop: - mov eax,[esi] - lea esi,[esi+2] - mov edx,eax - mov ebx,eax - and edx,65535 - ror ebx,8 - mov bl,[edx+PaletteInterpolationTable] - mov bh,ah - and eax,000ffff00h - ror ebx,8 - - ;1st 3 pixels now in ebx - shr eax,8 - mov bh,[eax+PaletteInterpolationTable] - ror ebx,16 - mov [edi],ebx - add edi,4 - - dec ecx - jnz ??interpolate_loop - -; do the last three pixels and a blank - - xor eax,eax - mov ax,[esi] - mov [edi],al - inc edi - mov al,[eax+PaletteInterpolationTable] - mov [edi],al - inc edi - mov [edi],ah - inc edi - mov [byte edi],0 - - popad - ret - - -endp Interpolate_Single_Line - - -proc Interpolate_Between_Lines C near - - ARG source1:dword - ARG source2:dword - ARG destination:dword - ARG source_width:dword - - pushad - mov esi,[source1] - mov edi,[destination] - mov ebx,[source2] - xor eax,eax - mov ecx,[source_width] - add ecx,ecx - -??interpolate_each_pixel_loop: - mov al,[esi] - mov ah,[ebx] - inc esi - inc ebx - mov dl,[eax+PaletteInterpolationTable] - mov [edi],dl - inc edi - dec ecx - jnz ??interpolate_each_pixel_loop - - popad - ret - -endp Interpolate_Between_Lines - - - - -macro Lineswp - push [next_line] - push [last_line] - pop [next_line] - pop [last_line] -endm - - -PROC Asm_Interpolate_Line_Interpolate C near - - - ARG src_ptr:dword - ARG dest_ptr:dword - ARG source_lines:dword - ARG source_width:dword - ARG dest_width:dword - - LOCAL old_dest:dword - LOCAL pixel_count:dword - LOCAL next_line:dword - LOCAL last_line:dword - - pushad - - mov eax,[dest_ptr] - mov [old_dest],eax - - mov [next_line],offset TopLine - mov [last_line],offset BottomLine - mov ecx,[source_width] - shr ecx,1 - mov [pixel_count],ecx - shr [dest_width],1 - - call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width] - mov esi,[source_width] - Lineswp - add [src_ptr],esi - dec [source_lines] - - -??each_line_pair_loop: - call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width] - call Interpolate_Between_Lines C,[last_line],[next_line],offset LineBuffer,[source_width] - - mov esi,[last_line] - mov edi,[old_dest] - mov ecx,[pixel_count] - rep movsd - - mov edi,[old_dest] - mov esi,offset LineBuffer - add edi,[dest_width] - mov ecx,[pixel_count] - mov [old_dest],edi - rep movsd - - mov edi,[old_dest] - mov esi,[source_width] - add edi,[dest_width] - add [src_ptr],esi - mov [old_dest],edi - - Lineswp - dec [source_lines] - jnz ??each_line_pair_loop - - call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width] - mov esi,[next_line] - mov edi,[old_dest] - mov ecx,[pixel_count] - rep movsd - - popad - ret - - -endp Asm_Interpolate_Line_Interpolate - - ends mycode - - - - -global C Asm_Create_Palette_Interpolation_Table:near -global C InterpolationPalette:dword - - codeseg - - -proc Asm_Create_Palette_Interpolation_Table C near - - LOCAL palette_counter:dword - LOCAL first_palette:dword - LOCAL second_palette:dword - LOCAL dest_ptr:dword - LOCAL count:dword - LOCAL closest_colour:dword - LOCAL distance_of_closest:dword - - pushad - - mov [dest_ptr],0 - mov [palette_counter],256 - mov esi,[InterpolationPalette] - -??palette_outer_loop: - mov edi,[InterpolationPalette] - mov ecx,256 - -??palette_inner_loop: - mov bl,[esi] - add bl,[edi] - shr bl,1 - - mov bh,[esi+1] - add bh,[edi+1] - shr bh,1 - - mov dl,[esi+2] - add dl,[edi+2] - shr dl,1 - - mov [closest_colour],0 - mov [distance_of_closest],-1 - - push edi - push ecx - mov edi,[InterpolationPalette] - mov [count],0 - -??cmp_pal_lp: xor eax,eax - xor ecx,ecx - mov al,[edi] - sub al,bl - imul al - mov ecx,eax - mov al,[edi+1] - sub al,bh - imul al - add ecx,eax - mov al,[edi+2] - sub al,dl - imul al - add ecx,eax - - cmp ecx,[distance_of_closest] - ja ??end_cmp_lp - mov [distance_of_closest],ecx - mov eax,[count] - mov [closest_colour],eax - test ecx,ecx - jz ??got_perfect - -??end_cmp_lp: lea edi,[edi+3] - inc [count] - cmp [count],256 - jb ??cmp_pal_lp - - -??got_perfect: mov edi,[dest_ptr] - mov eax,[closest_colour] - mov [edi+PaletteInterpolationTable],al - inc [dest_ptr] - - pop ecx - pop edi - lea edi,[edi+3] - dec ecx - jnz ??palette_inner_loop - - lea esi,[esi+3] - dec [palette_counter] - jnz ??palette_outer_loop - - popad - ret - -endp Asm_Create_Palette_Interpolation_Table - - - - - DATASEG - -_AbortModemFunctionPtr dd 0 -Memory_Error_Exit dd 0 -MouseQX dd 0 -MouseQY dd 0 - -end diff --git a/code/TIBERIANDAWN/WINSTUB.CPP b/code/TIBERIANDAWN/WINSTUB.CPP deleted file mode 100644 index 62fe62a..0000000 --- a/code/TIBERIANDAWN/WINSTUB.CPP +++ /dev/null @@ -1,938 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - - -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Command & Conquer * - * * - * File Name : WINSTUB.CPP * - * * - * Programmer : Steve Tall * - * * - * Start Date : 10/04/95 * - * * - * Last Update : October 4th 1995 [ST] * - * * - *---------------------------------------------------------------------------------------------* - * Overview: * - * This file contains stubs for undefined externals when linked under Watcom for Win 95 * - * * - *---------------------------------------------------------------------------------------------* - * * - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "function.h" -#include "tcpip.h" - -void output(short,short) -{} - -bool InDebugger = false; -bool ReadyToQuit = false; - -#if (0) -/*************************************************************************** - * Extract_Shape_Count -- returns # of shapes in the given shape block * - * * - * The # of shapes in a shape block is the first WORD in the block, so * - * this is the value returned. * - * * - * INPUT: * - * buffer pointer to shape block, created with MAKESHPS.EXE * - * * - * OUTPUT: * - * # shapes in the block * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -int __cdecl Extract_Shape_Count(VOID const *buffer) -{ - ShapeBlock_Type *block = (ShapeBlock_Type *)buffer; - - return (block->NumShapes); - -} /* end of Extract_Shape_Count */ - - -/*************************************************************************** - * Extract_Shape -- Gets pointer to shape in given shape block * - * * - * INPUT: * - * buffer pointer to shape block, created with MAKESHPS.EXE * - * shape index of shape to get * - * * - * OUTPUT: * - * pointer to shape in the shape block * - * * - * WARNINGS: * - * none * - * * - * HISTORY: * - * 06/09/1992 JLB : Created. * - * 08/19/1993 SKB : Split drawshp.asm into several modules. * - * 05/25/1994 BR : Converted to 32-bit * - *=========================================================================*/ -VOID * __cdecl Extract_Shape(VOID const *buffer, int shape) -{ - ShapeBlock_Type *block = (ShapeBlock_Type*) buffer; - long offset; // Offset of shape data, from start of block - char *bytebuf = (char*) buffer; - - /* - ----------------------- Return if invalid argument ----------------------- - */ - if (!buffer || shape < 0 || shape >= block->NumShapes) - return(NULL); - - offset = block->Offsets[shape]; - - return(bytebuf + 2 + offset); - -} /* end of Extract_Shape */ -#endif //(0) - - - -unsigned long CCFocusMessage = WM_USER+50; //Private message for receiving application focus -extern void VQA_PauseAudio(void); -extern void VQA_ResumeAudio(void); - - -ThemeType OldTheme = THEME_NONE; - - -/*********************************************************************************************** - * Focus_Loss -- this function is called when a library function detects focus loss * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 2/1/96 2:10PM ST : Created * - *=============================================================================================*/ - -void Focus_Loss(void) -{ - if (SoundOn){ - if (OldTheme == THEME_NONE){ - OldTheme = Theme.What_Is_Playing(); - } - } - Theme.Stop(); - Stop_Primary_Sound_Buffer(); - if (WWMouse) WWMouse->Clear_Cursor_Clip(); -} - - -void Focus_Restore(void) -{ - Restore_Cached_Icons(); - Map.Flag_To_Redraw(true); - Start_Primary_Sound_Buffer(TRUE); - if (WWMouse) WWMouse->Set_Cursor_Clip(); - VisiblePage.Clear(); - HiddenPage.Clear(); -} - - - -/*********************************************************************************************** - * Check_For_Focus_Loss -- check for the end of the focus loss * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 2/2/96 10:49AM ST : Created * - *=============================================================================================*/ - -void Check_For_Focus_Loss(void) -{ - -// ST - 1/3/2019 10:40AM -#if (0) - static BOOL focus_last_time = 1; - MSG msg; - - if ( !GameInFocus ){ - Focus_Loss(); - while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD ) ){ - if( !GetMessage( &msg, NULL, 0, 0 ) ){ - return; - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (!focus_last_time && GameInFocus){ - - VQA_PauseAudio(); - CountDownTimerClass cd; - cd.Set(60*1); - - do { - while (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )) { - if( !GetMessage( &msg, NULL, 0, 0 ) ){ - return; - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - } while(cd.Time()); - VQA_ResumeAudio(); - //AllSurfaces.Restore_Surfaces(); - //VisiblePage.Clear(); - //HiddenPage.Clear(); - //Map.Flag_To_Redraw(true); - PostMessage (MainWindow, CCFocusMessage,0,0); - } - - focus_last_time = GameInFocus; -#endif -} - - - -extern BOOL InMovie; -#if (0) //PG_TO_FIX -long FAR PASCAL _export Windows_Procedure (HWND hwnd, UINT message, UINT wParam, LONG lParam) -{ - - int low_param = LOWORD(wParam); - - if (message == CCFocusMessage){ - Start_Primary_Sound_Buffer(TRUE); - if (!InMovie){ - Theme.Queue_Song(OldTheme); - OldTheme = THEME_NONE; - } - return(0); - } - - - switch ( message ){ - - case WM_MOUSEMOVE: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_RBUTTONDBLCLK: - Kbd.Message_Handler(hwnd, message, wParam, lParam); - return(0); - - case WM_DESTROY: - CCDebugString ("C&C95 - WM_DESTROY message received.\n"); - CCDebugString ("C&C95 - About to call Prog_End.\n"); - Prog_End(); - CCDebugString ("C&C95 - About to Invalidate_Cached_Icons.\n"); - Invalidate_Cached_Icons(); - CCDebugString ("C&C95 - About to release the video surfaces.\n"); - VisiblePage.Un_Init(); - HiddenPage.Un_Init(); - AllSurfaces.Release(); - if (!InDebugger){ - CCDebugString ("C&C95 - About to reset the video mode.\n"); - Reset_Video_Mode(); - } - CCDebugString ("C&C95 - About to stop the profiler.\n"); - Stop_Profiler(); - CCDebugString ("C&C95 - Posting the quit message.\n"); - PostQuitMessage( 0 ); - /* - ** If we are shutting down gracefully than flag that the message loop has finished. - ** If this is a forced shutdown (ReadyToQuit == 0) then try and close down everything - ** before we exit. - */ - if (ReadyToQuit){ - CCDebugString ("C&C95 - We are now ready to quit.\n"); - ReadyToQuit = 2; - }else{ - CCDebugString ("C&C95 - Emergency shutdown.\n"); - CCDebugString ("C&C95 - Shut down the network stuff.\n"); -#ifndef DEMO - Shutdown_Network(); -#endif - CCDebugString ("C&C95 - Kill the Winsock stuff.\n"); - if (Winsock.Get_Connected()) Winsock.Close(); - CCDebugString ("C&C95 - Call ExitProcess.\n"); - ExitProcess(0); - } - CCDebugString ("C&C95 - Clean & ready to quit.\n"); - return(0); - - case WM_ACTIVATEAPP: - GameInFocus=(BOOL)wParam; - if (!GameInFocus) { - Focus_Loss(); - } - AllSurfaces.Set_Surface_Focus (GameInFocus); - AllSurfaces.Restore_Surfaces(); -// if (GameInFocus){ -// Restore_Cached_Icons(); -// Map.Flag_To_Redraw(true); -// Start_Primary_Sound_Buffer(TRUE); -// if (WWMouse) WWMouse->Set_Cursor_Clip(); -// } - return(0); -#if (0) - case WM_ACTIVATE: - if (low_param == WA_INACTIVE){ - GameInFocus = FALSE; - Focus_Loss(); - } - return(0); -#endif //(0) - - case WM_SYSCOMMAND: - switch ( wParam ) { - - case SC_CLOSE: - /* - ** Windows sent us a close message. Probably in response to Alt-F4. Ignore it by - ** pretending to handle the message and returning 0; - */ - return (0); - - case SC_SCREENSAVE: - /* - ** Windoze is about to start the screen saver. If we just return without passing - ** this message to DefWindowProc then the screen saver will not be allowed to start. - */ - return (0); - } - break; - -#ifdef FORCE_WINSOCK - case WM_ACCEPT: - case WM_HOSTBYADDRESS: - case WM_HOSTBYNAME: - case WM_ASYNCEVENT: - case WM_UDPASYNCEVENT: - Winsock.Message_Handler(hwnd, message, wParam, lParam); - return (0); -#endif //FORCE_WINSOCK - } - - return (DefWindowProc (hwnd, message, wParam, lParam)); -} - -#endif - - - - - - - - -/*********************************************************************************************** - * Create_Main_Window -- opens the MainWindow for C&C * - * * - * * - * * - * INPUT: instance -- handle to program instance * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/10/95 4:08PM ST : Created * - *=============================================================================================*/ - -#define CC_ICON 1 -int ShowCommand; - -void Create_Main_Window ( HANDLE instance ,int command_show , int width , int height ) - -{ - MainWindow = NULL; - return; -#if (0) - HWND hwnd ; - WNDCLASS wndclass ; - // - // Register the window class - // - - wndclass.style = CS_HREDRAW | CS_VREDRAW ; - wndclass.lpfnWndProc = Windows_Procedure ; - wndclass.cbClsExtra = 0 ; - wndclass.cbWndExtra = 0 ; - wndclass.hInstance = instance ; - wndclass.hIcon = LoadIcon (instance, MAKEINTRESOURCE(CC_ICON)) ; - wndclass.hCursor = NULL; - wndclass.hbrBackground = NULL; - wndclass.lpszMenuName = "Command & Conquer"; //NULL - wndclass.lpszClassName = "Command & Conquer"; - - RegisterClass (&wndclass) ; - - - // - // Create our main window - // - hwnd = CreateWindowEx ( - WS_EX_TOPMOST, - "Command & Conquer", - "Command & Conquer", - WS_POPUP | WS_MAXIMIZE, - 0, - 0, - width, - height, - NULL, - NULL, - instance, - NULL ); - - ShowWindow (hwnd, command_show ); - ShowCommand = command_show; - UpdateWindow (hwnd); - SetFocus (hwnd); - MainWindow=hwnd; //Save the handle to our main window - hInstance = instance; - - CCFocusMessage = RegisterWindowMessage ("CC_GOT_FOCUS"); - - Audio_Focus_Loss_Function = &Focus_Loss; - Misc_Focus_Loss_Function = &Focus_Loss; - Misc_Focus_Restore_Function = &Focus_Restore; - Gbuffer_Focus_Loss_Function = &Focus_Loss; -#endif -} - -void Window_Dialog_Box(HANDLE hinst, LPCTSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc) -{ -#if (0) - MSG msg; - /* - ** Get rid of the Westwood mouse cursor because we are showing a - ** dialog box and we want to have the right windows cursor showing - ** for it. - */ - Hide_Mouse(); - ShowCursor(TRUE); - - /* - ** Pop up the dialog box and then run a standard message handler - ** until the dialog box is closed. - */ - - DialogBox(hinst, lpszTemplate, hwndOwner, dlgprc); - while (GetMessage(&msg, NULL, 0, 0) && !AllDone) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - /* - ** Restore the westwood mouse cursor and get rid of the windows one - ** because it is now time to restore back to the westwood way of - ** doing things. - */ - ShowCursor(FALSE); - Show_Mouse(); -#endif -} - - - -typedef struct tColourList { - - char Red; - char Green; - char Blue; -} ColourList; - -ColourList ColourLookup[9]={ - 0,0,0, - 63,0,0, - 0,63,0, - 0,0,63, - 63,0,63, - 63,63,0, - 0,63,63, - 32,32,32, - 63,63,63 -}; - - - - -int DebugColour=1; - - -extern "C" void Set_Palette_Register(int number,int red ,int green ,int blue); -//#pragma off (unreferenced) -void Colour_Debug (int call_number) -{ - //#if 0 - //if (DebugColour==call_number || !call_number){ - - //if (call_number){ - // Wait_Vert_Blank(); - //} - - // ST - 1/3/2019 10:43AM - //Set_Palette_Register (0,ColourLookup[call_number].Red , - // ColourLookup[call_number].Green, - // ColourLookup[call_number].Blue); - //} - //#endif -} - -//#pragma on (unreferenced) - - - - - -BOOL Any_Locked (void) -{ - if (SeenBuff.Get_LockCount() || - HidPage.Get_LockCount()){ - return (TRUE); - }else{ - return(FALSE); - } -} - - - - - - - -HANDLE DebugFile = INVALID_HANDLE_VALUE; - -/*********************************************************************************************** - * CCDebugString -- sends a string to the debugger and echos it to disk * - * * - * * - * * - * INPUT: string * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 10/28/96 12:48PM ST : Created * - *=============================================================================================*/ -void CCDebugString (char *string) -{ -#if (0) - - char outstr[256]; - - sprintf (outstr, "%s", string); - - DWORD actual; - if (DebugFile == INVALID_HANDLE_VALUE){ - DebugFile = CreateFile("debug.txt", GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - }else{ - DebugFile = CreateFile("debug.txt", GENERIC_WRITE, 0, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } - - if (DebugFile != INVALID_HANDLE_VALUE){ - SetFilePointer (DebugFile, 0, NULL, FILE_END); - WriteFile(DebugFile, outstr, strlen(outstr)+1, &actual, NULL); - CloseHandle (DebugFile); - } - - OutputDebugString (string); - -#else - - string = string; - -#endif - -} - - - - - - - - - - - - - - -// -// Miscellaneous stubs. Mainly for multi player stuff -// -// -// - -//IPXAddressClass::IPXAddressClass(void) { -// int i; -// i++; -//} -//int IPXManagerClass::Num_Connections(void){ return (0); } -//int IPXManagerClass::Connection_ID( int ) { return (0); } -//IPXAddressClass * IPXManagerClass::Connection_Address( int ) { return ((IPXAddressClass*)0); } -//char * IPXManagerClass::Connection_Name( int ) { return ((char*)0); } -//int IPXAddressClass::Is_Broadcast() { return (0); } -//int IPXManagerClass::Send_Global_Message( void *, int, int, IPXAddressClass * ) { return (0); } -//int IPXManagerClass::Service() { return (0); } -//int IPXManagerClass::Get_Global_Message( void *, int *, IPXAddressClass *, short unsigned * ) { return (0); } -//int IPXAddressClass::operator ==( IPXAddressClass & ) { return (0); } -//IPXManagerClass::IPXManagerClass( int, int, int, int, short unsigned, short unsigned ) {} -//IPXManagerClass::~IPXManagerClass() { -// int i; -// i++; -// } -//int IPXManagerClass::Delete_Connection( int ) { return (0); } -//IPXAddressClass::IPXAddressClass( char unsigned *, char unsigned * ){} -//void IPXManagerClass::Set_Socket( short unsigned ){} -//int IPXManagerClass::Is_IPX() { return (0); } -//int IPXManagerClass::Init() { return (0); } -//void IPXAddressClass::Get_Address( char unsigned *, char unsigned * ){} -//void IPXManagerClass::Set_Bridge( char unsigned * ){} -//int IPXManagerClass::Global_Num_Send() { return (0); } -//void IPXManagerClass::Set_Timing( long unsigned, long unsigned, long unsigned ){} -//unsigned long IPXManagerClass::Global_Response_Time() { return (0); } -//int IPXManagerClass::Create_Connection( int, char *, IPXAddressClass * ) { return (0); } -//int IPXAddressClass::operator !=( IPXAddressClass & ) { return (0); } -//int IPXManagerClass::Send_Private_Message( void *, int, int, int ) { return (0); } -//int IPXManagerClass::Get_Private_Message( void *, int *, int * ) { return (0); } -//int IPXManagerClass::Connection_Index( int ) { return (0); } -//void IPXManagerClass::Reset_Response_Time(){} -//long unsigned IPXManagerClass::Response_Time() { return (0); } -//int IPXManagerClass::Private_Num_Send( int ) { return (0); } - -//_VQAHandle * VQA_Alloc(void){ return ((_VQAHandle *)0); } -//void VQA_Init( _VQAHandle *, long ( *)()) {} -//long VQA_Open( _VQAHandle *, char const *, _VQAConfig * ) { return (0); } -//void VQA_Free( _VQAHandle * ) {} -//void VQA_Close( _VQAHandle * ) {} -//long VQA_Play( _VQAHandle *, long ) { return (0); } - -//void VQA_Init(VQAHandle *, long(*)(VQAHandle *vqa, long action, void *buffer, long nbytes)){} - -//long VQA_Open(VQAHandle *, char const *, VQAConfig *) -//{ -// return (0); -//} - -//void VQA_Close(VQAHandle *){} - -//long VQA_Play(VQAHandle *, long) -//{ -// return (0); -//} - - -unsigned char *VQPalette; -long VQNumBytes; -unsigned long VQSlowpal; -bool VQPaletteChange = false; - - -extern "C"{ - void __cdecl SetPalette(unsigned char *palette,long numbytes,unsigned long slowpal); -} - - - -void Flag_To_Set_Palette(unsigned char *palette,long numbytes,unsigned long slowpal) -{ - VQPalette = palette; - VQNumBytes = numbytes; - VQSlowpal = slowpal; - VQPaletteChange = true; -} - - - -void Check_VQ_Palette_Set(void) -{ - if (VQPaletteChange){ - SetPalette(VQPalette, VQNumBytes, VQSlowpal); - VQPaletteChange = false; - } -} - - - - - -void __cdecl SetPalette(unsigned char *palette,long,unsigned long) -{ - for (int i=0 ; i<256*3 ; i++){ - *(palette+i)&=63; - } - Increase_Palette_Luminance(palette , 15 , 15 , 15 ,63); - - if (PalettesRead){ - memcpy (&PaletteInterpolationTable[0][0] , InterpolatedPalettes[PaletteCounter++] , 65536); - } - Set_Palette(palette); -} - - - -/*********************************************************************************************** - * Memory_Error_Handler -- Handle a possibly fatal failure to allocate memory * - * * - * * - * * - * INPUT: Nothing * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 5/22/96 3:57PM ST : Created * - *=============================================================================================*/ -void Memory_Error_Handler(void) -{ - GlyphX_Debug_Print("Error - out of memory."); - VisiblePage.Clear(); - Set_Palette(GamePalette); - while (Get_Mouse_State()){Show_Mouse();}; - CCMessageBox().Process("Error - out of memory.", "Abort", false); - Invalidate_Cached_Icons(); - - // Nope. ST - 1/10/2019 10:38AM - //PostQuitMessage( 0 ); - //ExitProcess(0); -} - - - - - - - - - - - -GraphicBufferClass* Read_PCX_File(char* name, char* Palette, void *Buff, long Size); - - - -/*********************************************************************************************** - * Load_Title_Screen -- loads the title screen into the given video buffer * - * * - * * - * * - * INPUT: screen name * - * video buffer * - * ptr to buffer for palette * - * * - * OUTPUT: Nothing * - * * - * WARNINGS: None * - * * - * HISTORY: * - * 7/5/96 11:30AM ST : Created * - *=============================================================================================*/ - -void Load_Title_Screen(char *name, GraphicViewPortClass *video_page, unsigned char *palette) -{ - - GraphicBufferClass *load_buffer; - - - load_buffer = Read_PCX_File (name, (char*)palette, NULL, 0); - - if (load_buffer){ - load_buffer->Blit(*video_page); - delete load_buffer; - } -} - - - -#include "filepcx.h" - -/*************************************************************************** - * READ_PCX_FILE -- read a pcx file into a Graphic Buffer * - * * - * GraphicBufferClass* Read_PCX_File (char* name, char* palette ,void *Buff, long size ); * - * * - * * - * INPUT: name is a NULL terminated string of the fromat [xxxx.pcx] * - * palette is optional, if palette != NULL the the color palette of * - * the pcx file will be place in the memory block pointed * - * by palette. * - * Buff is optinal, if Buff == NULL a new memory Buffer * - * will be allocated, otherwise the file will be placed * - * at location pointd by Buffer; * - * Size is the size in bytes of the memory block pointed by Buff * - * is also optional; - * * - * OUTPUT: on succes a pointer to a GraphicBufferClass cointaining the * - * pcx file, NULL othewise. * - * * - * WARNINGS: * - * Appears to be a comment-free zone * - * * - * HISTORY: * - * 05/03/1995 JRJ : Created. * - * 04/30/1996 ST : Tidied up and modified to use CCFileClass * - *=========================================================================*/ - -#define POOL_SIZE 2048 -#define READ_CHAR() *file_ptr++ ; \ - if ( file_ptr >= & pool [ POOL_SIZE ] ) { \ - file_handle.Read (pool , POOL_SIZE ); \ - file_ptr = pool ; \ - } - -/* -** The old RGB was signed, so the shift right didn't work. ST - 1/4/2019 4:49PM -*/ -typedef struct { - unsigned char red ; - unsigned char green ; - unsigned char blue ; -} PG_RGB ; - -GraphicBufferClass* Read_PCX_File(char* name, char* palette, void *Buff, long Size) -{ - int i, j; - unsigned rle; - unsigned color; - int scan_pos; - unsigned char *file_ptr; - int width; - int height; - unsigned char *buffer; - PCX_HEADER header; - PG_RGB *pal; - unsigned char pool [POOL_SIZE]; - GraphicBufferClass *pic; - - CCFileClass file_handle(name); - - if (!file_handle.Is_Available()) return (NULL); - - file_handle.Open(READ); - - file_handle.Read (&header, sizeof (PCX_HEADER)); - - if (header.id != 10 && header.version != 5 && header.pixelsize != 8 ) return NULL ; - - width = header.width - header.x + 1; - height = header.height - header.y + 1; - - if (Buff) { - buffer = (unsigned char*) Buff; - i = Size / width; - height = MIN (i - 1, height); - pic = new GraphicBufferClass(width, height, buffer, Size); - if ( !(pic && pic->Get_Buffer()) ) return NULL ; - } else { - pic = new GraphicBufferClass(width, height, NULL, width*(height+4)); - if ( !(pic && pic->Get_Buffer()) ) return NULL ; - } - - buffer = (unsigned char *) pic->Get_Buffer(); - file_ptr = pool ; - file_handle.Read (pool , POOL_SIZE); - - if ( header.byte_per_line != width ){ - - for ( scan_pos = j = 0 ; j < height ; j ++, scan_pos += width ) { - for ( i = 0 ; i < width ; ) { - rle = READ_CHAR (); - if ( rle > 192 ) { - rle -= 192 ; - color = READ_CHAR (); ; - memset ( buffer + scan_pos + i , color , rle ); - i += rle; - } else { - *(buffer+scan_pos + i++ ) = (char)rle; - } - } - } - - if ( i == width ) rle = READ_CHAR (); - if ( rle > 192 ) rle = READ_CHAR (); - - } else { - - for ( i = 0 ; i < width * height ; ) { - rle = READ_CHAR (); - rle &= 0xff; - if ( rle > 192 ) { - rle -= 192 ; - color = READ_CHAR (); - memset ( buffer + i , color , rle ); - i += rle ; - }else{ - *(buffer + i++) = rle; - } - } - } - - if ( palette ) { - file_handle.Seek (- (256 * (int)sizeof ( PG_RGB )) , SEEK_END ); - file_handle.Read (palette , 256L * sizeof ( PG_RGB )); - - pal = ( PG_RGB * ) palette; - for (i = 0 ; i < 256 ; i ++) { - pal ->red >>= 2; - pal ->green >>= 2; - pal ->blue >>= 2; - pal ++ ; - } - } - - file_handle.Close(); - return pic; -} \ No newline at end of file diff --git a/code/TIBERIANDAWN/WWALLOC.H b/code/TIBERIANDAWN/WWALLOC.H deleted file mode 100644 index 1cb86f5..0000000 --- a/code/TIBERIANDAWN/WWALLOC.H +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\wwalloc.h_v 2.18 16 Oct 1995 16:47:52 JOE_BOSTIC $ */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -** This should be located in the wwlib32.h file, but is located here for -** test purposes. -*/ -#ifdef __FLAT__ -#define PRIVATE static -#endif - -typedef enum MemoryFlagType { - MEM_NORMAL = 0x0000, // Default memory (normal). - MEM_PUBLIC = 0x0000, // Default memory (normal). - MEM_CHIP = 0x0000, // Graphic & sound buffer memory (Amiga). - MEM_UNUSED = 0x0001, // - MEM_SYSTEM = 0x0002, // Allocate out of system heap (XMS or EMS only). - MEM_RELAXED= 0x0004, // Don't worry about page conservation in EMS. - MEM_TEMP = 0x0008, // Temporary allocation (used by library only). - MEM_CLEAR = 0x0010, // Fill memory with '\0' characters. - MEM_PARA = 0x0020, // Paragraph aligned (IBM only). - MEM_XMS = 0x0040, // XMS memory. - MEM_EMS = 0x0080, // EMS memory (not implemented). - MEM_X = 0x8000 // Here to force this enum to be unsigned sized. -} MemoryFlagType; -MemoryFlagType operator |(MemoryFlagType, MemoryFlagType); -MemoryFlagType operator &(MemoryFlagType, MemoryFlagType); -MemoryFlagType operator ~(MemoryFlagType); - - -/* Prototypes for functions defined in this file */ -void * __cdecl Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags); -void __cdecl Free(void const *pointer); -void * __cdecl Resize_Alloc(void const *original_ptr, unsigned long new_size_in_bytes); -long __cdecl Ram_Free(MemoryFlagType flag); -long __cdecl Total_Ram_Free(MemoryFlagType flag); -long __cdecl Heap_Size(MemoryFlagType flag); - -extern unsigned long __cdecl MinRam; // Record of least memory at worst case. -extern unsigned long __cdecl MaxRam; // Record of total allocated at worst case. - -#ifdef __cplusplus -} -#endif - diff --git a/code/TIBERIANDAWN/WWFILE.H b/code/TIBERIANDAWN/WWFILE.H deleted file mode 100644 index 9910ff2..0000000 --- a/code/TIBERIANDAWN/WWFILE.H +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright 2020 Electronic Arts Inc. -// -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free -// software: you can redistribute it and/or modify it under the terms of -// the GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. - -// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed -// in the hope that it will be useful, but with permitted additional restrictions -// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT -// distributed with this program. You should have received a copy of the -// GNU General Public License along with permitted additional restrictions -// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection - -/* $Header: F:\projects\c&c\vcs\code\wwfile.h_v 2.15 16 Oct 1995 16:46:06 JOE_BOSTIC $ */ -/*********************************************************************************************** - *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** - *********************************************************************************************** - * * - * Project Name : Westwood Library * - * * - * File Name : WWFILE.H * - * * - * Programmer : Joe L. Bostic * - * * - * Start Date : August 8, 1994 * - * * - * Last Update : August 8, 1994 [JLB] * - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#ifndef WWFILE_H -#define WWFILE_H - -//#include - - -#ifndef _READ -#define READ 1 -#define WRITE 2 -#endif - - -#ifndef READ -#define READ _READ -#endif -#ifndef WRITE -#define WRITE _WRITE -#endif - -class FileClass -{ - public: - virtual ~FileClass(void) {}; - virtual char const * File_Name(void) const = 0; - virtual char const * Set_Name(char const *filename) = 0; - virtual int Create(void) = 0; - virtual int Delete(void) = 0; - virtual int Is_Available(int forced=false) = 0; - virtual int Is_Open(void) const = 0; - virtual int Open(char const *filename, int rights=READ) = 0; - virtual int Open(int rights=READ) = 0; - virtual long Read(void *buffer, long size) = 0; - virtual long Seek(long pos, int dir=SEEK_CUR) = 0; - virtual long Size(void) = 0; - virtual long Write(void const *buffer, long size) = 0; - virtual void Close(void) = 0; - - operator char const * () {return File_Name();}; -}; - -#endif